被IBM公有云的Abuse Department折磨半死

大概十几天以前,我的一个客户站点无法访问,然后我调查半天没调查明白,奇怪的是服务器上其它站点都正常。


(图源 :pixabay)

服务器是IBM公有云中的裸金属(我一直以为这个翻译怪怪的)其实就是独立服务器。于是想着登录一下它们的后台看看到底发生了什么事情。

自从SOFTLAYER被IBM收购以后,不得不说的是它们的后台是越来越复杂也越来越难用了,如果是国内访问的话,还要加上难以登录,费了九牛二虎之力爬上去之后,竟然发现这样一条Support Case:

SoftLayer Security has received the following MALWARE URL complaint in reference to an IP hosted on your server. A copy of the complaint is listed below or attached to this ticket for your review. Please disable or remove this activity immediately as it is direct abuse of the network services and a violation of your TOS and AUP. Failure to resolve this issue in an expeditious manner could lead to service interruption for this server. Please update this ticket with resolution to this issue. We thank you in advance for your quick action and cooperation.

然后发了一个网址过来,过两天又发来一个更新:

In order to prevent further abuse of our AUP/TOS, we have blocked access to the IP ADDRESS associated with this abuse report.

我擦,竟然没有收到邮件没有收到电话通知,直接被屏蔽IP了。懒得纠结为啥没有收到邮件,我告知它们马上解封IP,我好调查一下。

它们倒是很快地解封了IP,然后我调查一下,涉及到用户页面就是很正常的产品介绍页面,非常简单的HTML,也不包含任何脚本,而且这个用户站点里边内容最近一次更新是2014年1月5日,已经6年多没有更新过了,哪里来的啥恶意软件。

把服务器上ls命令截图发过去,并和他们说明以后,他们说这个页面被https://www.virustotal.com的两个引擎报有问题,可是要知道,virustotal.com上其它近百个引擎可是判断这个页面是没问题的,这很明显是误报嘛。

把这个消息回复过去后,我就没再怎么理会,明显的误报嘛,给他们说明了,应该就没问题了。

可是今天突然发现整台服务器都无法访问,我以为是他们网络维护导致的,费了半天近登上去一看,发现我擦,竟然整台服务器被拔网线了。

In order to prevent further abuse of our AUP/TOS, we have blocked access to the SERVER associated with this abuse report.

好吧,其实之前有几次要求我继续跟进的内容,可是我根本就没有收到邮件啊。况且就算不是误报,是恶意网页,你屏蔽了IP就足够了啊,这下被客户们骂惨了。

我要求他们马上恢复服务器访问,倒是很快访问了,但是还是要求我继续跟进那个问题。打电话和这个站点的用户后,他表示最近也没精力检查和维护,让我直接删了吧。

这个他们说的MALWARE URL问题算是解决了,不过我还是很不高兴,更新CASE,总得发个邮件吧?况且明明屏蔽IP就够用为啥拔网线,我怒斥了他们。

他们回复说邮件都发送了,是不是我没收到?另外告诉我可以做到每次行政行动之前都打电话给我:

Additionally, as previously mentioned, we would be happy to make a courtesy call prior to administrative action in the future. Let us know which number to call and we will make an account note.

并且强调:

Additionally, if the site is clean, I recommend reaching out to Google and disputing their flagging of this site. Any sites flagged by google will set off warnings in user browser advising against visiting the site.

好吧,你们店大,怎么说都有理,我也拿不出证据证明我没收到邮件(然而确实没收到)。跟他们打交道太累了,这十几年无数次的误报,无数次的DMCA投诉啥的,每次处理一个CASE,都感觉累得脱了一层皮。以前后台登录方便,还便于及时处理,现在简直是令人难以忍受的折磨。


(图源 :pixabay)

好在我计划不再和他们打交道了,和傲慢的IBM 公有云Abuse Department 说白白啦,再也不必被各种匪夷所思的CASE折磨了,想想就觉得很美好。


This page is synchronized from the post: ‘被IBM公有云的Abuse Department折磨半死’

每天进步一点点:transfer_to_vesting / Power UP

昨天在测试memo的时候,放了几段长长的古文,比如《得道多助,失道寡助》之类的,结果用力过猛,@oflyhigh.test RC不够用了。


(图源 :pixabay)

RC告急

看着这段提示就很闹心,何况还要等很久等RC恢复,这我不能忍受😳

‘plugin exception:Account: oflyhigh.test has 436004956 RC, needs 535083479 ‘
‘RC. Please wait to transact, or power up HIVE.rethrow’

大家都知道RC和HP相关,HP越多,可用RC越多,恢复起来也越快,既然RC不够了,还要继续测试memo,那么只好Power UP了,于是用cli_wallet 的transfer_to_vesting功能给@oflyhigh.test Power UP了一些HP,总算可以继续愉快地测试了。

image.png

不过等忙完memo的事,我不禁想,自己在写程序,然后还要用cli_wallet来搞定Power UP,这多嘲讽啊,应该直接搞一个Power UP的功能嘛。

Power UP 功能

其实Power UP的功能很好搞,首先定义如下operation:

1
2
3
4
5
op_transfer_to_vesting = ['transfer_to_vesting',{
'from': '',
'to':'',
'amount':''
}]

然后写类似如下的代码:

op[1]['from'] = from_account
op[1]['to'] = to_account
op[1]['amount'] = HIVE_ASSET(asset)

trx.append_op(op)
trx.sign_digest(wif)
trx.broadcast()

将其中的asset设置为1.000 HIVE并广播,广播出去的transaction类似如下:

image.png

https://hiveblocks.com/ 上查看,可见Power UP已经成功了:

image.png

其它测试

虽然明知道Power UP HBD是不可以的,还是忍不住用1.000 HBD测试了一下:

‘Assert Exception:amount.symbol == STEEM_SYMBOL || ( amount.symbol.space() == ‘
‘asset_symbol_type::smt_nai_space && amount.symbol.is_vesting() == false ): ‘
‘Amount must be HIVE or SMT liquid’

注意到这个内容了吗?Amount must be HIVE or SMT liquid,好熟悉既陌生的SMT字样,也不知道SMT何时能上线啊?

不感慨SMT的事情了,总之transfer_to_vesting / Power UP功能搞定了,以后可以愉快地用自己的工具Power UP啦。


This page is synchronized from the post: ‘每天进步一点点:transfer_to_vesting / Power UP’

每天进步一点点:终于搞定了memo加密/解密

经过了几个昼夜的学习和测试,终于搞定了memo的加密解密。原本以为这块不会有多复杂,但是实际沉浸下去才发现涉及的内容还很多。


(图源 :pixabay)

涉及内容

简单回顾一下涉及的主要内容:

  • 理论基础:Pub(Alice) * Priv(Bob) = Pub(Bob) * Priv(Alice)
  • 内容加密:AES (Advanced Encryption Standard),CBC模式
  • nonce、check:打包时字节序 / Byte Order的问题
  • 打包长内容时长度编码的问题:Varint编码

回头再看,可能都不是有多难,可是为了把他们弄明白,我还是下了一番苦功夫的,一调试就调试到下半夜。

MEMO“协议”

把这些都弄懂之后,自己写了程序能加密/解密/打包/解包MEMO了,然而发送给自己测试账户的钱包里的memo要么显示Invalid memo要么内容短缺一大块。

其实原因我是清楚的,涉及到通信,一个最重要的地方就是通信双方要依据相同的标准,这就是所谓的协议。我自己的打包解包都是自己的标准当然没问题,但是钱包中用的流程未必和我一样啊。

为了搞明白钱包中用的流程,我读了steem-python的代码/beem的代码/cli_wallet的代码,最终还是找到BM的一篇早期文章,才彻底搞懂。

BM文章中memo_data结构如下:

public_key from
public_key to
uint64_t nonce
uint32_t check
vector<char> encrypted

BM文章中核心代码如下:

shared_secret = from_private_key.get_shared_secret( to );
/// concatenate nonce and shared secret (binary)
encryption_key = sha512( nonce + shared_secret )
///< check is first 64 bit of sha256 hash treated as uint64_t truncated to 32 bits.
check = sha256( encryption_key )._hash[0]
/// pack the memo as a length-prefixed string, length is serialized as varint
plain_text = pack( memo_text)
encrypted = aes_encrypt( encryption_key, plain_text )

最后使用memo_data打包并转换成base58编码:

string result = '#' + to_base58( pack( memodata ) );

而我的代码之所以不被识别,是因为BM的代码中先对memo_text原文进行了一次处理,变成了加上varint前缀的二进制串;然后pack( memodata )再对encrypted数据加上varint前缀,我缺少了其中第一个步骤,所以内容总是没法别识别。

测试代码

有了上述理论基础以及通信双方遵循的协议,再实现起来就好办多了,当然,说是好办也不容易,测试N多次经历N次失败后,总算完成了两个函数:

encode_memo(wif, pk, message)
decode_memo(wif, message)

其中wif是账户的私钥,pk是账户的公钥。加密memo时,使用的是发送方私钥和接收方公钥,解密memo时可以使用任何一方私钥。

用如下代码测试一下:

message = "12345678"
memo_encoded = encode_memo(wif_test, receiver_pk, message)
print(memo_encoded)
print("decode with sender's memo private key: ", decode_memo(wif_test, memo_encoded))
print("decode with receiver's memo private key: ", decode_memo(wif_abc, memo_encoded))
client.transfer("oflyhigh.test", "oflyhigh.abc", "0.001 HBD", memo_encoded, wif_test_active)

我们会得到如下编码后的memo:

#C3JiuC9zrPkJRTK3bfz1HHJHvUuLPw4yiWS3bGYMABMvV84UYvmF7jqR58Hg5nor2F1uoSJjWMDsbuAjZJBxLyafj6qLqQcJW8hReTuLt48dpR7iG7kMWQr6VaQg4d7C4

分别用发送方和接收方私钥解密:

image.png

image.png

广播出去的transaction:

image.png

可见,和普通的transaction无什么区别。在https://hiveblocks.com/ 查看一下:

image.png

登录钱包查看一下,发现解密是正常的:

image.png

长文本

另外,一个就是长文本的支持,既然可以用varint表示长度,理论上memo可以很长,然而我打算放一篇《出师表》进去,却被提示如下错误:

‘Assert Exception:memo.size() < STEEM_MAX_MEMO_SIZE: Memo is too large’

查了一下代码,有如下定义:

#define STEEM_MAX_MEMO_SIZE 2048

所以长度不能太长哦,好在我试着放点其它文章还是没问题的,比如如下两条:

image.png

image.png

其实长文本和memo加密这块关系不大,不过想到哪就写到哪吧,记下来以免以后忘记了。

其它

代码中使用了手工encode/decode,这需要进一步改进,比如说消息前边有#号的自动进行encode处理,没有#号的则忽略。把这个功能放到transfer函数中,那么我们就可以使用如下方法直接进行了。

client.transfer("oflyhigh.test", "oflyhigh.abc", "0.001 HBD", "#Hello world", wif_test_active)

不过这样一改,transfer函数就有些复杂,比如我想传递明文的#文本,transfer就无能无力了,而现在的transfer是支持的。

image.png

有意思的是,网页钱包反而把这个识别成为:Invalid memo

哎,还是老老实实按着标准来吧,凡是#号开头,一律先加密:)

相关链接


This page is synchronized from the post: ‘每天进步一点点:终于搞定了memo加密/解密’

和蜂巢快递柜说白白

想必大家都知道或者接触过蜂巢快递柜,有时候家里无人或者什么情况不便接收快递的时候用快递柜特别方便,尤其是在疫情期间,快递柜做无接触配送的一种方式,更是立下了汗马功劳。

image.png
(图源 :https://cn.bing.com/images/)

然而不知道是因为快递员懒惰还是因为和快递柜有合作关系,明明家中有人,配送也极其方便的情况下,他们还是把快递包裹投递到快递柜。

投递到快递柜也不是不行,大不了我出门的时候顺道取回来,自己多走几步路,让快递小哥们少些辛苦也未尝不可,可是让人郁闷的是,他们每次把快递投递到快递柜都不声不响,电话也不肯打一个。

电话不打也无所谓,我刷手机的时候有时候可能会看看短信,会在一堆垃圾短信中注意到蜂巢的信息,虽然有时候已经超时,不过找回一下取件码就可以取了。

然而这些无所谓助长了快递员的嚣张,现在几乎所有的件都给送快递柜,邻居们有的投诉过几次,还遭到某些快递员的谩骂和威胁,更雪上加霜的是,快递柜开始收费了。

按说提供服务并收费,这并无可厚非,然而问题是,大多数情况我们并不需要这样的服务,而是快递柜和快递员联合强加给我们的。

明明我们就在家,却不肯给快递送上门;明明我们已经付了快递费,却还要付蜂巢的保管费。虽然五毛、一元并不多,大家可能不在乎或者无所谓,但是不能因为花费少就认同这并不合理的收费啊?

如果我不方便接收快递,或者我指定快递们都送到蜂巢,那么我会心甘情愿地交这笔费用,哪怕再贵一些也能接受。可是现在明明是我并不需要,是被强加给我的,那么我就很难接受了。

网上找了蜂巢的服务电话:4000633333,打了半天,研究半天,也没搞明白怎么转人工服务,不过电话挂断后,收到一条短信,短信中有个链接,点开后会进到网页客服。

网页客服那里转人工,直接给我丢过来一段消息:

您好,这里是人工,我是丰巢客服小哈,很高兴为您服务! 快件屏蔽入柜方法:关注绑定【丰巢智能柜】微信公众号→会员中心→开通会员→个人设置代收偏好→根据个人意向,取消勾选并保存,后续将按设置禁止快递员投递入柜;如需开通请在改设置页面勾选保存。(因同时为多个客户解答问题,回复较慢,请谅解)

看来他们被投诉得有经验了,按上边说的方法,添加了公众号,开通了会员,拒绝所有快递放快递柜。这样以后快递想把我快递放快递柜都没辙了吧。

image.png
(图源 :https://cn.bing.com/images/)

总算和蜂巢快递柜说白白了,受同样问题困扰的伙伴,不妨试试文中的方法哦。


This page is synchronized from the post: ‘和蜂巢快递柜说白白’

白酒

大概春节疫情刚起的时候,都推荐用酒精消毒,导致酒精难以购买得到。考虑到酒精和白酒的主要成分都是酒精,于是我买了几箱二锅头用来消毒。


(图源 :pixabay)

当然了,后来按专家们的说法,白酒达不到酒精的浓度,什么渗透压一堆乱七八糟的术语,什么没法突破细胞壁云云,什么会在细胞表明形成保护层,总之总结起来就是一句话:白酒没法消毒。

虽然凭我的脑瓜依旧觉得没法理解,但是专家说不能消就不能消吧,况且好像因为很少出门,基本上也没啥需要消毒的时候和地方。

不过既然白酒没法消毒,那总不能浪费了啊,于是我想想,还是喝掉吧,尤其是我买的那种小玻璃瓶的红星二锅头,算下来也近20一瓶呢,想必味道会不错。

然而这么一喝,发现这味道真是太酸爽了,虽然我没有直接喝过酒精,但是感觉就是和酒精一个味。好吧,甚至可能比酒精味道更差,酒精大概是没这么辛辣的呛人的。

其实我是很少喝白酒的,包括一些聚会饭局之类的,白酒也是浅尝辄止,然后啤酒才是我的主要战场,但是酒精沙场,想完全避免也避免不了,所以无论是高端的低端的白酒差不多也都尝过。

但是总感觉这些年喝过的白酒,没有小时侯的好喝。当然我估计可能是因为喝白酒的场合大多之后都要喝一些啤酒,然后喝得烂醉,忘掉了白酒的滋味。

在我的印象中,小时侯的白酒都特别的香特别的浓,几岁的时候白酒兑汽水喝酒的事情就不再说了,但是每次父亲温一小壶白酒美滋滋地品味时,我都馋的直流口水。

另外还记得,逢年过节要么爸爸这边的亲戚来我家看望奶奶,要么妈妈那边的亲戚去舅舅家看望姥姥,总会有人带两瓶好酒过来,有时候是一些大有名气的好酒,有时候虽然没有名气但是喝起来也特别好喝。

而这些年,无论是名酒还是二锅头还是亲戚自己酿制的纯正粮食酒,喝起来感觉就是辛辣,稍微多喝一点就难受。

当然我觉得之所以这些年对白酒不感冒,可能和高中时期,自己一人几口干掉一瓶一斤装的白酒有关,简单说,就是喝伤了,好多年过去,还没缓过来。

二锅头难以下咽,却勾起了我的酒瘾,于是去京东买了一瓶舍得、一瓶剑南春,这几天吃饭时换着样的小酌一小杯,感觉又有点找回小时侯喝白酒馋白酒的感觉了。


(图源 :pixabay)

我也有些明白,为什么这些年喝白酒都没什么感觉了,原来啤酒适合聚会畅饮,白酒真的只适合独酌啊。


This page is synchronized from the post: ‘白酒’

每天进步一点点:Varint编码

在处理memo的时候,发现steem-python 以及 beem 等,都是假定编码后的字符串长度值可以存储在一个字节内,这样memo的长度只能限制在255个字节以内了。


(图源 :pixabay)

memo 长度问题

比如steem-python中处理message的部分代码如下:

image.png

那么memo到底支持多长的内容呢?在微信群中提出这个问题后,@abit 指出memo可以支持任意长度(受限于区块大小,RC等)

那么支持任意长度的话,长度信息是如何打包message当中呢?固定字节数我会取,不固定的咋办呢?在群里提出这个问题后,@abit 指出,长度的编码使用varint。

再回头看我截取的那段steem-python代码,注释中已经提到了varint,但是被我无视了,这回知道了方向,就好办了。

varint编码

简单了解了一下varint编码,我找到一篇讲解比较好的文章:《详解varint编码原理》,简单来讲呢,就是用字节的最高位表示有无后续字节(1表示有,0表示无),而剩余7位用于编码数字本身。

varint编码还有个需要注意的地方就是从表示从字节的数字低位开始编码放在最前边。编码的过程我简单总结一下:

  • 把数字表示成二进制的位
  • 从右往左依次取7个位放入新的字节中
  • 如果左边还有数位,那么新字节最高位设置为1,否则为0
  • 将新字节放到编码的字节串中
  • 依次进行2、3、4步,直到左侧没有数位

之前引用的文章中,里边有一副图挺直观,贴过来:

image.png
(图源:详解varint编码原理)

代码 & 测试

知道这些,就可以进行varint编解码了,另外steem-python中帮我们实现两组代码,可以拿来略作修改后直接使用:

image.png

测试代码如下:

encode = varint(123456)
decode = varintdecode((encode))
pprint(encode)
pprint(decode)

输出结果如下:

image.png

编码结果和文中示意图的结果完全一致,可见数字123456被正确的编码/解码,有了这个基础,我就可以处理任意长度的memo了。

相关链接


This page is synchronized from the post: ‘每天进步一点点:Varint编码’

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×