最近听了 IoT 长连接 Erlang 研发同学的技术分享,部分分享内容涉及到到了 HTTP/2,刚好在草稿箱里翻到了两年前攒的这篇文章,趁这个机会补充一下把他放出来吧。

HTTP/2 不叫 HTTP/2.0,是因为标准委员会不打算再发布子版本了,下一个新版本将是 HTTP/3。

0x00 HTTP Frames

HTTP/1.1 版的头信息肯定是文本(ASCII编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为”帧”(frame):头信息帧和数据帧。

HTTP/2 相较于 HTTP/1.* 的不同点在于,HTTP/2 将 HTTP 协议通信分解为二进制编码Frame的交换,这些Frame对应着特定Stream中的Message。所有这些都在一个 TCP 连接内复用。这是 HTTP/2 协议所有其他功能和性能优化的基础。

二进制协议的一个好处是,可以定义额外的帧。HTTP/2 定义了近十种帧,为将来的高级应用打好了基础。如果使用文本实现这种功能,解析数据将会变得非常麻烦,二进制解析则方便得多。

Frame 的基础结构由五部分组成:

  • Length: 表示 Frame Payload 的大小,是一个 24-bit 的整型,表明 Frame Payload 的大小不应该超过 2^24 – 1 byte,但其实 payload 默认的大小是不超过 2^14 byte,可以通过 SETTING Frame 来设置 SETTINGS_MAX_FRAME_SIZE 修改允许的 Payload 大小;
  • Type: 表示 Frame 的类型,目前定义了 0-9 共 10 种类型;
  • Flags: 为一些特定类型的 Frame 预留的标志位,比如 Header, Data, Setting, Ping 等,都会用到;
  • R: 1-bit 的保留位,目前没用,值必须为 0;
  • Stream Identifier: Steam 的 id 标识,表明 id 的范围只能为 0 到 2^31 – 1 之间,其中 0 用来传输控制信息,比如 Setting, Ping;客户端发起的 Stream id 必须为奇数,服务端发起的 Stream id 必须为偶数;并且每次建立新 Stream 的时候,id 必须比上一次的建立的 Stream 的 id 大;当在一个连接里,如果无限建立 Stream,最后 id 大于 2^31 时,必须从新建立 TCP 连接,来发送请求。如果是服务端的 Stream id 超过上限,需要对客户端发送一个 GOWAY 的 Frame 来强制客户端重新发起连接。

Continue reading

上周遇到了一个非常奇怪的问题,我们组维护的容器化平台的CI组件用的是Harbor做public/private镜像仓库,HA做了alive/alive,上层通过LVS做Load Balence, 两台计算节点间使用redis共享session。这是一套新搭建的环境,上线前只是简单测了测,当时没有发现大问题。但是这周新系统上线之后组里同事反馈说Harbor API调用偶尔会出现401错误,很常见的未授权错误。

于是乎找了harborclient的Python库写了个小脚本来复现这个错误。这个问题通常是在client一段时候没有call Harbor API之后再调用时出现的,而且只出现一次,很少会有连续报错的情况。

接下来就是查log了,tail -f调出两台server的log观察,发现问题都会出现在/login(get a token from administrator)和/get/post(request with the privious token)的两个请求被LVS分别打到不同机器上, 官方log还挺详细的,提示说

[DEBUG] [base.go:132]: No valid user id in session.
[WARNING] No user id in session, canceling request

问题解决思路这下就非常清楚了,八成就是session共享没有成功。

Continue reading

Kernel 4.9 正式版本的发布带来了一些令人激动的特性以及一些驱动的更新。 其中来自 Google 的 TCP BBR (Bottleneck Bandwidth and RTT) 拥塞控制算法也在这个版本并入了主线。

0x00 Background

几个月前就在Github上fork了Google开源的神器BBR算法,但是一直都没有深入去分析研究。最近看Kubernetes相关的文档突然想起了这个神器,于是我大晚上的搭了一台测试机对TCP BBR进行了测试。

根据以往的传统,G家总是先在自家的生产环境上线运用后,才会将代码开源,此次也不例外。我在一台代理服务器节点上部署了TCP BBR 拥塞控制算法。从电信出口到日本Vultr的实测下载速度从381KB/s提高到了4.26MB/s.

补充测试环境说明:是在日本的Vultr服务器上配置了 BBR,日本的服务器是数据的发送方。这个服务器是访问墙外资源的 HTTP 代理。我本地的电信出口到代理服务器之间不是dedicated专线,走的是公网,电信出口这边是 10Mbps 无限速(但是要跟其他人share),代理服务器实测是限速1Mbps。RTT 是 96 ms。实测结果这么好,也是因为大多数人用的是 TCP Cubic (Linux) / Compound TCP (Windows),在有一定丢包率的情况下,TCP BBR 更加激进,抢占了更多的公网带宽。因此也是有些不道德的感觉。

Continue reading

0x00 Readme.md

最近在看米特尼克的《反欺骗的艺术》,所以对欺骗的艺术特别感兴趣。上周在我师傅保平哥和我师父的师傅宇神的帮助下,成功搞定了etcd集群的SSL客户认证,后来在总结中发现里面用easy-rsa的部分和我之前搞过的4G流量“免流”还是有好多的相似点,今天就来分享一下我的经历,有这方面的大神希望也可以一起来探讨。

0x01 为什么会有免流漏洞?

以联通举例,大家都知道,联通手机号访问“联通营业厅”,或者参加一些免流量活动是免流量费的,那么运营商是如何区分用户使用的是免流量业务还是正常访问互联网的呢,这里就要说到我们平常所说的免流IP了,当计费系统检测到用户访问的是白名单中的网址时就不会进行扣费。 问题就出现在这里,当用户通过蜂窝网络访问互联网时,会向服务器发送一条请求头,其中包含有:url、UA、网络协议、host、cookie、来源地址和文件类型等多种信息。

如果我们通过某种方法欺骗运营商,让运营商认为我们所有的流量都是访问“联通营业厅”产生的,那么联通就会免掉这部分的流量。具体方法和配置请往下看:)

Continue reading

0x00 About Disaster Recovery

etcd的备份可以写个定时脚本执行。

备份方式用etcdctl backup命令将数据存到指定位置,然后用Rsync同步到其他两个机房。

这部分数据可以用来灾难恢复,只有数据而没有集群状态。


0x01 Specific Steps of Disaster Recovery

在使用etcd集群的过程中,有时会出现少量主机故障,这时我们需要对集群进行维护。然而,在现实情况下,还可能遇到由于严重的设备或网络的故障,导致超过半数的节点无法正常工作。

在etcd集群无法提供正常的服务,我们需要用到一些备份和数据恢复的手段。etcd背后的raft,保证了集群的数据的一致性与稳定性。所以我们对etcd的恢复,更多的是恢复etcd的节点服务,并还原用户数据。

首先,从剩余的正常节点中选择一个正常的成员节点, 使用 etcdctl backup 命令备份etcd数据。

$ ./etcdctl backup --data-dir /var/lib/etcd -backup-dir /tmp/etcd_backup
$ tar -zcxf backup.etcd.tar.gz /tmp/etcd_backup

这个命令会将节点中的用户数据全部写入到指定的备份目录中,但是节点ID,集群ID等信息将会丢失, 并在恢复到目的节点时被重新。这样主要是防止原先的节点意外重新加入新的节点集群而导致数据混乱。

Continue reading

在OpenStack平台的虚拟机上使用k8s搭建一个容器集群,一个Master节点和三个Node节点。这里通过 etcdctl 查询集群状态,出现了如下错误:

Error: client: etcd cluster is unavailable or misconfigured
error #0: x509: certificate signed by unknown authority
error #1: x509: certificate signed by unknown authority
error #2: x509: certificate signed by unknown authority

Solution:

刚开始是以为etcd的配置问题,但是查看etcd的状态,服务是起来的。

[root@k6770v bin]# systemctl status etcd.service
● etcd.service - Etcd Server
Loaded: loaded (/usr/lib/systemd/system/etcd.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2016-06-28 15:02:55 CST; 1 months 0 days ago
Main PID: 24622 (etcd)
CGroup: /system.slice/etcd.service
└─24622 /usr/bin/etcd

这个问题是因为没有加载ssl参数,现在这个线上是走ssl认证的,不能直接etcdctl set和get,这里模拟一下ssl认证:

[root@k6770v ssl]# etcdctl --ca-file=/etc/kubernetes/ssl/ca.crt --cert-file=/etc/kubernetes/ssl/etcd-client.crt --key-file=/etc/kubernetes/ssl/etcd-client.key set testkey Hello,etcd
Hello,etcd

导师交代下来一个yum源提供http api展现rpm包信息的任务,已经有一个webpy + memcache的bata版本了,但是现在需要把它改成go/python + redis的多线程方案,下面就分析一下memcacheredis的主要区别。

1、Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等。
2、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。
3、虚拟内存–Redis当物理内存用完时,可以将一些很久没用到的value交换到磁盘
4、过期策略–memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire设定,例如expire name 10
5、分布式–设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从
6、存储数据安全–memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化)
7、灾难恢复–memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复
8、Redis支持数据的备份,即master-slave模式的数据备份。

etcd作为一个受到ZooKeeper与doozer启发而催生的项目,除了拥有与之类似的功能外,更专注于以下四点。
简单:基于HTTP+JSON的API让你用curl就可以轻松使用。
安全:可选SSL客户认证机制。
快速:每个实例每秒支持一千次写操作。
可信:使用Raft算法充分实现了分布式。

分布式系统中的数据分为控制数据和应用数据。etcd的使用场景默认处理的数据都是控制数据,对于应用数据,只推荐数据量很小,但是更新访问频繁的情况。

应用场景有如下几类:
场景一:服务发现(Service Discovery)
场景二:消息发布与订阅
场景三:负载均衡
场景四:分布式通知与协调
场景五:分布式锁、分布式队列
场景六:集群监控与Leader竞选

举个最简单的例子,如果你需要一个分布式存储仓库来存储配置信息,并且希望这个仓库读写速度快、支持高可用、部署简单、支持http接口,那么就可以使用etcd。

目前,cloudfoundry使用etcd作为hm9000的应用状态信息存储,kubernetes用etcd来存储docker集群的配置信息等。

via: etcd, 从应用场景到实现原理的全方位解读

回学校以后网络环境变了,想要换一条更快的代理路线,但是发现我的代理提供商以手工输入帐号信息进行配置容易出错为由把密码给屏蔽了,取而代之的是一个QR code,都是套路。

楼下使用openwrt和Mac的用户都炸了,没有密码配置个鬼啊,不过这可难不倒宝宝。

解码二维码之后的字符串是一堆字母数字,最后有一个等号,看到这串Base64编码让我想起了一种似曾相识的感觉。

YWVzLTI1Ni1jZmI6OTI4MzMqKipANzYuMTY0LjIyNC4qKjo1MzMqKg==

光速解码之后就是我需要的信息哈哈 [Encrypt Method:Password@Server:Remote Port]

aes-256-cfb:92833***@76.164.224.**:533**