Archive for 技术文档

还算比较有价值的文章.

memcached 竟态条件 bug, Update 3

在说这个 bug 之前, 需要注意 memcached daemon 有一个 -t 参数.
该问题在有 -t 1 参数时(或者没编译多线程支持时)不会重现, 因为此时不存在竞争的问题.

问题的背景请看 谈 mixi 访问故障事件.

patch: http://gist.github.com/524517

主要的修改是对多线程条件下的计数器做了修正(例子如下), 并对链表操作加了 mutex.
- base->event_count--;
+ __sync_sub_and_fetch(&(base->event_count), 1);

未加锁的情况下 event_count 有可能会被破坏.
event_haveevents() 的代码很简单 (return (base->event_count > 0); ).
在 event_count 被破坏掉之后, event_haveevents() 返回 false.
/* If we have no events, we just exit */
if (!event_haveevents(base)) {
event_debug(("%s: no events registered.", __func__));
return (1);
}

这样, memcached 就这样无声无息的结束了自己. 这是 mixi 版的问题.

更深层的原因要先注意一下其它错误的信息.
[err] event_queue_remove: 0×15ea9d88(fd 30) not on queue 8
queue 8 即 EVLIST_ACTIVE (event.h)
在什么情况下 ev_flags 会被改动呢? 注意 do_accept 在连接数过多变成 false 的情况.

(memcached.c)
void do_accept_new_conns(const bool do_accept) {
...
if (do_accept) {
update_event(next, EV_READ | EV_PERSIST);
if (listen(next->sfd, settings.backlog) != 0) {
perror("listen");
}
}
else {
update_event(next, 0); //look at me
if (listen(next->sfd, 0) != 0) {
perror("listen");
}
}
...

参考资料:
mixi大規模障害について
memcachedの件: その2

ps:
/* You cannot use this interface for multi-threaded apps */

ps2:
/* not thread safe */

ps3:
(diff)
if (!event_haveevents(base)) {
event_debug(("%s: no events registered.", __func__));
- return (1);
}

ps4:
给 update_event 加个锁? 好像没必要.
update_event 调用 event_del 再调用 event_queue_remove, 这个已经 patch 过了…
同理调用 event_add 再调用 event_queue_insert 也修掉了.
更特别的, event_queue_remove(base, ev, EVLIST_ACTIVE); 被保护起来了.

ps5:
三家联合, 力量果然大.

ps6:
thread safe 真是麻烦事… :D

ps7:
这 ps 数量破记录了吧… :D

ps8:
在这顺便牢骚一下啊. GR 不是有个 Like 功能嘛. 你要喜欢就点哪.
你不给偶反馈偶怎么知道文章好不好啊.

Update1:

http://kzk9.net/blog/memcached-fix-accept-new-conns-race.patch.txt

Update2:
mixi大規模障害について 解明編

Update3:
http://groups.google.com/group/memcached/browse_thread/thread/fe1ccd05242a5f05 (小心有墙)

Tags:
Comments

谈 mixi 访问故障事件. Update 6

mixi 于 2010.8.10-12 碰到了一次由于 memcached 负载过高引起的故障.
几台 memcached 服务器因连接数过多意外的挂掉了, 负载压到了 DB 身上.
数据库处理能力不足, 页面载入速度变慢, 甚至于不能访问. 故障影响了 mixi 的所有服务.

加 memcached 服务器, 使每台 memcached 服务器不承担那么多连接. 这个问题就解决了.
但这显然不是长久之计.

这个问题从多个方面来看.

1 意外的挂掉
意外指的是什么? 这是一个还没有弄清楚的问题.
memcached 对各方面性能的要求并不苛刻.
可能的进程死掉的原因第一个要算在 OOM Killer 身上.
但人家说, 要是 log 里有这种东西, 那早不就注意到了.

另外 OOM 是可以关掉的.
echo 0 > /proc/sys/vm/oom-kill # 关掉
echo -17 > /proc/PID/oom_adj # 降低 OOM 评分, 所以杀不掉

有些原因是可以排除掉的. 因为挂掉的不只一台.
内存容量被限制住了, 肯定要为内核留一定的余量.
连接数量多也是内核在用内存, 杀掉用户进程实在是不厚道? :D 当然这事情不是这样的.

代码上还有问题吗? 这个很难说, 这么多眼睛盯着呢…

2 容量规划
容量规划也应该包括连接数规划, 之前也确实没怎么注意这个问题. 当然这只是一个方面.
hmm… 难道说以后故障规划也会流行起来? :D
数据库的连接数/处理能力问题全让缓存给盖住了.

说前些日子看过笑话, 数据库 100 连接数授权加上某软件之后就能承担 1000 连接数. 答案见 ps.
这都超过了 C10K 了, 再用这种东西好像没什么用了. :D
mixi 也没有说自己用的是 udp 还是 tcp 来连接 memcached. 不过这应该不是主要问题.

3 架构问题
都在喊优雅降级. 要做到容易吗? 不容易的.
memcached 挂掉, 用 consistent hashing 也不行.
特别是一台机器上插着那么多内存, 那挂了损失是多少?
对 DB 的查询次数可以近似看作 内存大小 除以 缓存项平均大小
(实际还有个压缩问题, 当然不一定非是这个数, 只是说这个意思).
要是用个 SSD (这里是容量大的意思) 做缓存挂了岂不更惨? 你要用多少时间去做这个恢复?
(当然, 这里有 mapreduce 思想可以套用一下)
这种东西这么重要, 不把它当作单点看待行吗?

说这种问题一旦重现(偶给你关上几台 memcached 机器的电源), 让你降级试试? 牵一发而动全身.
DB 都挺不住, 页面逻辑那么复杂, 需要多少多少个查询才能完成, 就因为负载的问题完不成请求, 那当然就要出故障了.
t.sina.com.cn 在说用纯缓存的架构, 这真是一个警钟哪,
虽说现在好像没什么问题, 也许是因为知道 memcachedb 承受不了那么多连接.
这都是猜的. hoho

也许这种情况 redis 或者其它带实际存储的系统更好一些,
因为至少有个硬盘 snapshot. 重新起来之后还能撑上一会.

当然 mixi 还有一个问题. 所有服务同时挂掉. 缓存没有分开. 这个相对来说是容易解决的.

mixi 自己的总结 (非直译)
1 降低缓存系统负载
2 为将来负载增加的情况做准备, 对故障发生时 memcached 异常终止问题进行调查, 研究提高缓存系统可靠性的方法.
3 重新设计/部署缓存系统以减小故障影响范围.

八卦时间
1 mikio 同学离开了 mixi.
Kyoto Cabinet 是 GPL 授权的(附加条款: 链接除外). 商业授权可以收钱.
mixi 的架构设计 mikio 居然没有参与. 很令人意外…
2 有人说是 love machine 把 mixi 弄挂的.
3 谣言说 mixi 申请破产. 不过股价确实跌了有不到 3%.

ps:
答案是连接池

Update1:
问题可能和 libevent 版本有关.
mixi 使用了 memcached-1.4.4 和 libevent-1.3b 的组合. 而后者是老东西了. (现在普遍使用 1.4 系列)

这个肯定要动用 strace 之类的东西, 个人认为要用排除法了, 问题重现的难度并不低.
就在这时某些无聊人在 Twitter 上大谈 Linux 服务器发行版的选择问题. 在此做个记录.

Update2:
找到了 1.3b 有嫌疑的一个地方, 但此处已在 1.4 系列中修正.

[err] event_queue_remove: 0×15ea9d88(fd 30) not on queue 8
类似错误在 libevent 1.4 系列较新版本中仍有发现. 详情待查.

Update3:
使用该代码可使 memcached 重现上述错误 http://gist.github.com/522741
详情见 memcachedの件: その2
这次的调查团队阵容很强大. mixi, hatena, Preferred Infrastructure 都有工程师参与.

Update4:
bug 确由 libevent 引起.

Update5:
问题与 memcached 也有关系, 发现人 @llamerada. 相关 bug: http://code.google.com/p/memcached/issues/detail?id=99

http://kzk9.net/blog/memcached-fix-accept-new-conns-race.patch.txt

Update6:
mixi大規模障害について 解明編

Tags:
Comments

GAppProxy2 v0.99.9 is Here

gappproxy2-0_99_9.tar.gz

sha1sum:
702531d5ed38852471a6849f3155c9fe68b93ae4 gappproxy2-0_99_9.tar.gz

感谢 Wallproxy 作者 @hexieshe 的大力支持…

Changelog 很长, 不写了. 压缩包里有.
请务必配套使用 client 和 server. 不配套使用后果自负… :D

为了方便大家部署, 这次提供了 app.yaml. 并开启了 precompile 的支持.
(需要较新的 App Engine Python SDK 支持)

撒花庆祝吧. hohoho. (第一次用这个词, 不习惯呢) :D

ps:
Q: WallProxy 有自动签名的证书, 这个为什么没有?
A: 在 CNNIC ROOT 当道的时候手动验证证书还来不及呢. 这种安全性真是令人担忧哪.

ps2:
这次的断点续传达到了下载软件的水平. Content-Range 头都给你造好了.
有的论坛有 bug 的也都发现了. (当然承认由于 GAE 的原因下不了那也没办法)
想下大文件的这次真的可以拼命去下了.

ps3:
欢迎大家测试 ipv6… ipv6 上有 youtube, 有 google, 有 facebook, 有 GAE …
可以借代理 [2001:470:1f0e:456::X]:80 上 twitter… (故意的马赛克).

ps4:
配置文件 proxy.conf, 去掉 # 就不是注释了… 也就是说… 自己理解吧… :D

Tags:
Comments

简评 Taobao Tair: 四不像

Taobao Tair 是一个分布式 key-value store. 于 2010.6.29 正式开源.

Tair 支持内存 hash (MDB) 和文件存储引擎 (FDB).
(如果你熟悉 Tokyo Cabinet 的话, 对应 TCMDB 和 TCHDB)
存储引擎可以扩展 (但这个 API 个人觉得很难看).

Memcached 和 Redis 的一些特性也被搬到了这里.
比如原子计数器支持, Item 支持, 版本号支持.

可是压根它就不打算支持 Memcached 协议 (也许以后会有吧, 写个 Proxy?). :D

Tair 没有使用 Consistent Hashing (这个应该没看错).
但使用了 Dynamo 论文 Page 12 中的 Strategy 3 以保证节点分布与数据完整性.
(但就这个也不像! 因为没用 Consistent Hashing, 所以不符合论文, 见下 GFS 相关讨论)
并提供了两种节点分布方式: 负载平衡优先, 数据安全优先.
这种方式虽然偶不太喜欢, 不过倒是个可以接受的方案.
纯 Consistent Hashing + Buckets + 多 Hash Ring (每个 Ring 不能在同一网段以提高可用性) 也是一种做法, 不过缺点是复制份数不能随负载而调整了.

插嘴: Riak 和 Voldemort 应该是暂时最像 Dynamo 的实现了吧…

如果非要做个比较的话, Google File System (GFS) 的 Block 分配也是这样的, 有 Master 负责 Block 到机器的对应查询.
这个 Buckets 的数量是一定的 (这是没办法). 但 Buckets 太多, configserver 就要耗费更多的时间去同步对应表.
仔细考虑一下, 增加减少节点时重新平衡的行为, 和 GFS 确实太相似了.
区别只是 GFS Block 的数量是可变的, 这个是不可变的. 反着看的话, Blocksize 是不固定的.

整体上说, 如果数据完整性对你很重要, Tair 是不错的选择. (这话没说完就这么放着了… :D )

代码: 客户端直接取模就得到服务器了. (tair_client_api_impl.cpp)
if (my_server_list.size() > 0U) {
hash %= bucket_count;
for(uint32_t i=0;i < copy_count && i < my_server_list.size(); ++ i){
uint64_t server_id = my_server_list[hash] + i * bucket_count;
if(server_id != 0){
server.push_back(server_id);
}
}
}

关于 Tair 自带的 FDB, 自称树形存储引擎 (这个树实际上和排序没有太大关系, 仅用于索引查询).

如果没看错的话是这样的:
用 h(x) 计算出 bucket number (这属于前面的分布式部分), 找到 bucket 对应的(数据和索引)文件完成写入, 索引使用的是二叉树.

索引的定义:
typedef struct _item_index {
uint32_t left;
uint32_t right;
uint64_t size:24;
uint64_t offset:40;
uint64_t hashcode;
} item_index;

个人认为索引方面有缺陷. 应该引入 Cache-Oblivious 的树形数据结构 (二叉树需要的内存访问次数太多了), 即便它能够缓存在内存中.

FDB 具体实现很像 Facebook 的图片存储系统. 适合 Object 修改次数极少的情况.
使用了空间池 (free_blocks_manager) 以提高空间利用率.

关于 MDB 的实现偶没有评估的能力.

希望以上描述能够帮助大家更快的评估 Tair. 如有疑问请丢邮件过来.

ps:
那 Dynamo 的论文写 Consistent Hashing 干嘛?

ps2:
写网络应用程序不支持 IPv6 怎么行? :D

ps3:
四不像, 这个概括还是比较准确的. :D 你说它不像什么?

Tags:
Comments

IPv6 两月使用总结 v1.25

条条大路通 IPv6.
原生 IPv6, 6to4, ISATAP, Teredo, (SSH, VPN), (sixxs) …

注1: Tunnel Broker 属于 6to4, Gateway6 / gogo6 支持 6to4, 4to6, 一般还是用 6to4.
注2: ISATAP 需要使用 IP Protocol 41 类型的数据包. 这种类型的数据包可能无法穿透路由器.
注3: sixxs 只是一个服务, 玩玩可以, 可用性很差…
注4: 某些服务故意漏掉了.

不推荐使用 Windows XP 上原生 IPv6, WinXP 对 IPv6 支持不够完善. 虽然说凑合用是可以的. 至少设置 ipv6 dns 挺麻烦, 只有命令行可以用, 这里不写了.

推荐使用 Gateway6 上 IPv6 (不幸的是大陆的服务商基本没人搞这个), 用 ISATAP 可能会更快, 但 ISATAP 与 Teredo 都会泄漏你的 IPv4 地址.
(提取 ipv4 地址的工具: ipv6calc, 各发行版安装 ipv6calc 即可)

Teredo 玩玩是可以的, 但速度实在不敢恭维 (ipv6.google.com 确实很快, 说明 Google 网络部署上很厉害).

使用 Teredo 上 IPv6 的机器, 与另一台双栈机器连接时传输速度较快. (因为双机实际在用 IPv4 连接传输). 和纯 IPv6 机器时需要经过中转, 这个速度比较慢.
Gateway6 这种连接方式数据全部需要服务器中转(例外: 与 Teredo 双栈机通信有一部分走 IPv4), 但挑一个快速的服务器就全补回来了.

Gateway6: Ubuntu 下安装 gw6c (Debian 装 gogoc), 配置好 Tunnel Broker Server 即可.
服务器填 tb.ipv6.apol.com.tw 就不错. 当然还有别的, 可以搜搜看.
Teredo: 安装 miredo 启动即可. ping ipv6.google.com 即可测试.

WinXP SP1+ 补: ipv6 install; netsh interface ipv6 set teredo client

和开源相关的东西多数都有 IPv6 镜像, 但非常不幸, kernel.org 没有.
想要 Tarball 的话可以到 Gentoo Mirrors 上翻一翻, 当然要先学会看 ebuild.
对 Ubuntu 来说, mirror.switch.ch 速度挺不错.

随便哪个主流发行版, 这个找一找就会有的.

IPv6 资源并不丰富, 但 Hurricane Electric(HE) 和 Google IPv6 部署的还不错. 于是用之.

HE DNS: 2001:470:20::2 / 74.82.42.42
如果还想要其它 DNS 服务器可以看这个:
http://www.chaz6.com/files/resolv.conf

个人 Ping(6) 值最小的 IP(v6) 段:
Google 2404:6800:8005
Youtube 2404:6800:4001

偶推测的 Google IPv6 的大概情况是这样的.
1 ipv6.google.com 可以作为 HTTP 代理间接访问其它 Google 服务. (Youtube 可能要除外)
2 IPv6 地址的尾数有特殊意义(这和 IPv4 的情况是一样的). 尾数和 SSL 证书部署有紧密的联系. 遍历一遍就可以得到一个大概结果.
3 IP(v6) 前缀代表不同数据中心(都知道), 只要部署状况允许就可以随意切换.

以下是 2001:4860:8001 段的 SSL 证书扫描结果.

mail.google.com 2404:6800:8001::11
mail.google.com 2404:6800:8001::12
mail.google.com 2404:6800:8001::13
*.recaptcha.net 2404:6800:8001::18
*.google.com.tr 2404:6800:8001::20
*.google.com.au 2404:6800:8001::21
*.google.com.vn 2404:6800:8001::22
*.google.com.pk 2404:6800:8001::23
*.google.com.my 2404:6800:8001::24
*.google.com.pe 2404:6800:8001::25
*.google.co.za 2404:6800:8001::26
*.google.co.ve 2404:6800:8001::27
*.google.com.ph 2404:6800:8001::28
*.google.com.ar 2404:6800:8001::29
*.google.co.nz 2404:6800:8001::2a
*.google.lt 2404:6800:8001::2b
*.google.cn 2404:6800:8001::2c
*.google.com.sg 2404:6800:8001::2d
*.google.com.hk 2404:6800:8001::2e
*.google.com.tw 2404:6800:8001::2f
*.google.co.jp 2404:6800:8001::30
*.google.ae 2404:6800:8001::31
*.google.co.uk 2404:6800:8001::32
*.google.com.gr 2404:6800:8001::33
*.google.de 2404:6800:8001::34
*.google.co.il 2404:6800:8001::35
*.google.fr 2404:6800:8001::36
*.google.it 2404:6800:8001::38
*.google.lv 2404:6800:8001::39
*.google.ca 2404:6800:8001::3a
*.google.pl 2404:6800:8001::3b
*.google.ch 2404:6800:8001::3c
*.google.ro 2404:6800:8001::3d
*.google.nl 2404:6800:8001::3e
*.google.com.ru 2404:6800:8001::3f
*.google.at 2404:6800:8001::40
adwords.google.sk 2404:6800:8001::41
*.google.be 2404:6800:8001::42
*.google.co.kr 2404:6800:8001::44
*.google.com.ua 2404:6800:8001::45
*.google.fi 2404:6800:8001::48
*.google.co.in 2404:6800:8001::49
*.google.pt 2404:6800:8001::4a
*.google.com.ly 2404:6800:8001::4b
*.google.com.mx 2404:6800:8001::4d
*.google.es 2404:6800:8001::4e
*.google.dk 2404:6800:8001::4f
sandbox.google.com 2404:6800:8001::51
*.googlecode.com 2404:6800:8001::52
mail.google.com 2404:6800:8001::53
accounts.google.com 2404:6800:8001::54
*.google.com 2404:6800:8001::5b
*.google.com 2404:6800:8001::5d
*.googleapis.com 2404:6800:8001::5f
www.googleadservices.com 2404:6800:8001::60
*.google-analytics.com 2404:6800:8001::61
*.google.com 2404:6800:8001::62
www.google.com 2404:6800:8001::63
*.google.com 2404:6800:8001::64
*.google.com 2404:6800:8001::65
*.google.com 2404:6800:8001::66
www.google.com 2404:6800:8001::67
www.google.com 2404:6800:8001::68
www.google.com 2404:6800:8001::69
www.google.com 2404:6800:8001::6a
adwords.google.com 2404:6800:8001::70
*.google.com 2404:6800:8001::71
checkout.google.com 2404:6800:8001::73
upload.video.google.com 2404:6800:8001::74
*.google.com 2404:6800:8001::76
ssl.gstatic.com 2404:6800:8001::78
wifi.google.com 2404:6800:8001::7b
*.googleusercontent.com 2404:6800:8001::84
*.google.com 2404:6800:8001::88
*.googlegroups.com 2404:6800:8001::89
*.google.com 2404:6800:8001::8a
*.google.com 2404:6800:8001::8b
*.appspot.com 2404:6800:8001::8d
*.au.doubleclick.net 2404:6800:8001::8e
*.uk.doubleclick.net 2404:6800:8001::90
*.fr.doubleclick.net 2404:6800:8001::91
*.jp.doubleclick.net 2404:6800:8001::92
www.google.com 2404:6800:8001::93
*.doubleclick.net 2404:6800:8001::94
*.doubleclick.net 2404:6800:8001::95
tpc.googlesyndication.com 2404:6800:8001::98
*.g.doubleclick.net 2404:6800:8001::9a
*.g.doubleclick.net 2404:6800:8001::9b
*.g.doubleclick.net 2404:6800:8001::9c
*.g.doubleclick.net 2404:6800:8001::9d
*.googleadservices.com 2404:6800:8001::a4
*.googleadservices.com 2404:6800:8001::a5
*.googleadservices.com 2404:6800:8001::a6
*.googleadservices.com 2404:6800:8001::a7
service.urchin.com 2404:6800:8001::b8
*.mail.google.com 2404:6800:8001::bd
*.google.com 2404:6800:8001::be
*.blogger.com 2404:6800:8001::bf
m.google.com 2404:6800:8001::c1
jmt0.google.com 2404:6800:8001::d2

如何上 IPv4 网站:
1 gappproxy2
当然偶不是说 gappproxy 不行. 不喜欢当小白鼠的就用原版, 偶没意见.
可以用 ipv6.google.com:80 做代理, 但这样安全性上有一定缺陷.
在 hosts 加入 [ipv6.google.com 的 IPv6 地址] xxxx.appspot.com 并…
2 sixxs.org (好像不支持 Cookies)
3 https://dtw6 (全名不写了)
4 google.com/gwt/n (很熟悉吧, 不过这个也就是玩玩而已)
5 google 网页快照 (紧急情况专用?)
6 代理服务器 (含透明代理)
[2001:470:1f0e:456::X]:80 故意隐掉, 感谢 dtw6 的开发者.
7 VPN / SSH
这个也许是要银子的.

如果你有 IPv4 服务器 (内网也可以 NAT):

1 安装 gateway6 并设置 Tunnel Broker. 记录 IPv6 地址 (可能是动态的, 有些服务器提供静态 IP).
2 架设 OpenSSH Server.
3 连接到 SSH 服务器. 设置 Dynamic Port Forwarding. 完.

一些问题.
第一条, Hosts 文件不要改的太过分, 也就是说有选择性的找 hosts 文件并添加.
如果 DNS 工作正常的话, 除了 google (含 youtube) 相关的网站, 其他的可以基本不加. (twitter 的问题不属于本文讨论范围)

第二条, 注意 IPv4 DNS 泄露问题, 比如上面的 dtw6 访问时, 如果 ipv4 优先的话…
(注: 如果考虑到这个问题, hosts 文件里多写点倒是没错的. 平时学着用用 wireshark 或者 tcpdump 吧.)

第三条, 注意 SSL 证书问题. CNNIC ROOT / SSL 该去的还是要去.

第四条, 注意软件安全性.
Linux 下这个都好说, 包都带签名.
Win32 / 64 就麻烦多了, 什么公司都会签名, 流氓软件也签.
用 win32 的同学可以过来问一下哪些软件能用, 哪些软件不能用 (主要是网络相关的软件).
很多所谓杀毒安全软件本身就是问题的来源. 就点一个名好了, (2^3) * (3^2) * 5. 反正国内的非开源软件都躲着走吧.

关于双栈 Hosts 问题:

用两行指同一个域名当然是可以的. 这两行分别指向 ipv4 和 ipv6 则更好.
但如果 hosts 里面存在了某个域名, 则这个域名只能使用 hosts 文件指定的 ip.
也就是说如果对双栈网站只指定了 ipv4/v6 地址, 则只能使用对应的方式上该网站.

关于 Google Service SSL 问题.
wget https://IP 不加 -k 参数时会出现如下错误:
ERROR: certificate common name `*.google.com' doesn't match requested host name `xxx.xxx.xxx.xxx'.

如果这个 IP 没有被墙, 请务必记下这个 IP 及对应的 common name (即证书对应域名).
可以使用 hosts 文件将相应域名绑定到该 IP 上以实现绕墙.

Tags:
Comments

Gappproxy2 正式发布

Gappproxy2 是 Gappproxy 的一个分支版本. 作者 fcicq.
代码授权与 Gappproxy 相同, 均为 GPLv3. 感谢原作者 XiaoGang.

第一版本 0.99, 代码来自 gappproxy svn r102.

gappproxy2 的服务器端 fetch.py 与原 gappproxy 客户端不兼容.

gappproxy2 不附带 app.yaml 及 ssl/LocalProxyServer.cert, ssl/LocalProxyServer.key 文件. 有需要者请自己动手.

没有 Win32 可执行文件版本.

最简单的自签名证书生成方法:
openssl req -x509 -days 365 -newkey rsa:1024 -keyout LocalProxyServer.key -nodes -out LocalProxyServer.cert

不想当小白鼠的同学就别下了…

去看看 FAQ 吧: Gappproxy2 FAQ

下载地址及 sha1sum, 2010.7.21 15:00 更新 0.99.9 版
gappproxy2-0_99_9.tar.gz, 参见 GAppProxy2 v0.99.9 is Here

安装方法和 gappproxy 一样, 如果你有准备好的 GAE app 的话, 替换 fetch.py 并更换新客户端即可.
0.99.9 版已添加 app.yaml 文件.

报告成功/问题, 请丢邮件到 fcicq at fcicq dot nospam dot net
(小声说: 在推上 @fcicq 也可以, 应该能看见.)

Have Fun :)

# Changelog:
修改记录

# Removed logging
关闭 logging 功能.

# Dropped support of google_proxy & load_balancing. Merged common.py to proxy.py.
去掉了 google_proxy 和 load_balancing 功能. 去掉了 common.py 并合并到 proxy.py.

# Disable SSL Support by default (client)
客户端默认屏蔽 HTTPS 代理能力. 可在 proxy.conf 中重新打开. (ssl_disabled=false)

(加注: 该屏蔽不影响 fetch_server 设置为 https://fetch-server-uri.)

Gappproxy FAQ 片断:
为支持 HTTPS, GAppProxy 使用了一种妥协的方式, 该方式从原理上破坏了 HTTPS 固有的安全性, 将 HTTPS 的安全级别降到了 HTTP 级, 所以如果你要传输重要数据, 请不要使用该 HTTPS 代理. 此外 HTTPS 不支持服务器 / 客户认证, 这也和 GAE 有关.

# Block non localhost access by default (client)
客户端默认屏蔽非本地用户访问. 可在 proxy.conf 中重新打开. (localhost_only=false)

# Added Caching to some Mines-types, with 200, 304, 404 support. Saves some bandwidth :)
# You can use status page or HTTP Header (x-hit) to make sure cache is working
对部分 mine 类型使用 memcache 缓存, 对 if-modified-since 请求能够返回 HTTP 304. 一般缓存支持 HTTP 200, 404. 默认超时时间是 6 小时.
缓存命中时会返回 HTTP Header x-hit. 有屏蔽缓存的判断.

# Added more forbid_headers.
部分 http headers 被加入过滤表, 不会发送到目标服务器.

# Try to fetch 2 times for GET / HEAD request.
# Fixed a bug that POST request more than once, and make the timeout of post requests longer.
修改重试次数为 2 次. (原版为 3 次)
对 POST 请求只发送一次, 防止部分重复提交问题. 对 POST 请求和重试的请求延长了超时时间.

# Added status & headers pages (http://gappproxy/status or headers)
增加了状态页面. 使用 http://gappproxy/status 查看缓存命中情况(如已有其它服务, 则此项不准确). http://gappproxy/headers 查看客户端头发送情况.

# Fixed 206 Support by checking content-length
服务器端修正了 Range_supported 判断.
客户端增加任意大小的 HTTP 206 请求支持. 默认分块大小改为 512 KBytes.

# Added some exceptions.
增加了部分判断以方便查看问题来源.
(服务器端: apiproxy_errors.OverQuotaError, urlfetch_errors.DownloadError, urlfetch_errors.ResponseTooLargeError. 客户端 socket 相关判断)

# Fixed multi-part POST request by using base64 in post_data.
# Fixed some encoding problem by using base64 in header data, dropping utf-8 encoding. REQUIRES client upgrade.
使用 Base64 保证 headers 和 post_data 完整性. (修复 Wrong length of post data 问题)
POST 请求限制更正为 768 KBytes. 上传功能已可用.
(重要: **与以前的客户端不兼容**)

Tags:
Comments

Wireless Series(12): 问与答 (全文完)

问: 有没有其他的破解 WPA 的方法?
答: 当然有. :D

比如有一种路由器品牌叫 FASTWEB, 这个品牌在意大利比较流行.
有人使用 IDA Pro 调试时找到了其出厂 WPA 密钥生成的算法. Source

假设原 SSID 为 FASTWEB-1-00193EA1B2C3.
将 0×00,0×19,0×3E,0xA1,0xB2,0xC3 与此密钥相连.
0×22,0×33,0×11,0×34,0×02,0×81,0xFA,0×22,0×11,0×41,
0×68,0×11,0×12,0×01,0×05,0×22,0×71,0×42,0×10,0×66
计算 md5 (二进制形式), 每次取 5 bits, 共取 5 次.
每一段的数值如果小于 0xA 就加上 0×57. 变换为 16 进制即为结果.

用命令行计算 md5.
echo -en "\x00\x19\x3E\xA1\xB2\xC3\x22\x33\x11\x34\x02\x81\xFA\x22\x11\x41\x68\x11\x12\x01\x05\x22\x71\x42\x10\x66" |md5sum

php 版, 能够直接输出密钥. SSID 在代码第一行.

< ?php
//By fcicq (http://www.fcicq.net/wp/), Released under GPLv2
$a = sprintf("%c%c%c%c%c%c",0x00,0x19,0x3e,0xa1,0xb2,0xc3);
$b = sprintf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
0x22,0x33,0x11,0x34,0x02,0x81,0xFA,0x22,0x11,0x41,
0x68,0x11,0x12,0x01,0x05,0x22,0x71,0x42,0x10,0x66);
$md5 = md5($a.$b,true);
//only the first 4 bytes is needed.
sscanf($md5, "%c%c%c%c", $m0, $m1, $m2, $m3 );
$k1 = ((ord($m0) & 0xF8) / 8); //11111000
$k2 = ((ord($m0) & 0x07) * 4) + ((ord($m1) & 0xC0) / 64); //00000111 11000000
$k3 = ((ord($m1) & 0x3E) / 2); //00111110
$k4 = ((ord($m1) & 0x1) * 16) + ((ord($m2) & 0xF0) / 16); //00000001 11110000
$k5 = ((ord($m2) & 0xF) * 2) + ((ord($m3) & 0x80) / 128); //00001111 10000000
if ($k1 >= 0xA) $k1+=0x57;
if ($k2 >= 0xA) $k2+=0x57;
if ($k3 >= 0xA) $k3+=0x57;
if ($k4 >= 0xA) $k4+=0x57;
if ($k5 >= 0xA) $k5+=0x57;
printf("%02x%02x%02x%02x%02x\n", $k1, $k2, $k3, $k4, $k5);
?>

考虑到品牌厂商的 MAC 前缀数量有限, 其 MAC 可能性为 256^3 * MAC 段数.
而密钥可能性为 32^5, 所以密钥的全部组合更适合作为字典使用.
以全部密钥作为字典只需要占用 32^5*(10+1) = 352 M 空间.
但如果不知道密钥范围的话就比较麻烦了. 256^5 = 2^40 给人的感觉就太大了.

看过这个之后, 你是不是想测试一下自己的路由器是否也内置一种默认密码算法?
或许某些人会往这个方向努力的.

问: 什么样的字典适合 WPA?
答: 首先要考虑覆盖面大的弱字典. 事实上偶的 unidict-20100410 就是这样考虑的.
其次是社会工程方面, 知道的信息越多越好. 如果这些都弄不出来的话用一些字典生成器也可以, 但希望就不太大了.

问: 方便的手机号生成器?
答: 有个现成的号段表, Download
使用方法:
awk '{j=$1*10000; for(i=0;i<10000;i++) printf("%.f\n",i+j);}' 0397.txt > 0397-mobile.txt

问: 一台破解一台连接是否有用?
答: 没有用. 但不可否认的是, IV 确实增加了. 建立连接时得到的数据包不可重发.
对 WPA/WPA2 来说抓到的是错误的握手包, 不会有 Data 产生, 并得到 Deauth Packets.

问: 某些网卡显示频道不对, 133 频道什么的.
答: 既然不是 5 Ghz 的网络那就是 Bug. 参见 Aircrack-ng Ticket #670.
133 频道是正常的 6 频道. 每增加/减少 5 个频道等于正常增减的 1 个频道. 对应表就不列了. 1 频道是 Ch 108, 13 频道是 Ch 168. 不过好像很少见呢.

问: 利用 WPS / QSS 破解 WPA2 的可能性?
答: 已有专文叙述. 流言终结者: WPS, CSRF, 802.11n

问: 如何加固无线网络?
答: 换有线网络 :D
WPA2 都不能挡住 -0 这种攻击形式(当然这实际是两回事), 不换有线又能怎么办呢…
可以把整个无线网络全部切换到 802.11n 设备, 并使用 Greenfield mode (此时会失去 802.11b/g 的向后兼容性).
另一个好处是由于制式不同, 传输范围与速率都将增加.
再需要高安全性的就上 VPN 好了, 可是这样也不能解决 -0 这样简单的问题.

问: WAPI 安全性如何?
答: 市面上有 WAPI 路由器卖吗? 既然没卖的那怎么知道?

系列全部文章一览:

Wireless Series 预告篇
Wireless Series(1): 驱动与网卡芯片支持列表 (至 2010.4)
Wireless Series(2): 常用软件与工具 (Windows 平台)
Wireless Series(3): 常用软件与工具 (Linux 平台)
Wireless Series(4): 天线, 信号, 距离 (2010.4.30 Updated)
Wireless Series(5): 网卡好坏的判断标准
Wireless Series(6): Aircrack-ng (1), 基础篇
Wireless Series(7): Aircrack-ng (2), Aireplay-ng 模式
Wireless Series(8): Aircrack-ng (3), 总结篇
Wireless Series(9): FeedingBottle
Wireless Series(10): 高级应用 (1)
Wireless Series(11): 高级应用 (2)
Wireless Series(12): 问与答 (全文完)

至此整个系列就全部完结了.
这些文章以后如果有机会的话还会做一些补充与更新. 而这是转载者所做不到的.
就是转载也要遵守一些规则, 不要给图片再加一次水印, 保证文章链接的完整性. 这叫守 PageRank 奴?

推荐的转载方式是仅转载预告篇, 并保持链接完整.

对文章的反馈可以扔到留言板上去. 虽说需要审核. :D

这段时间耽误了不少正常文章的发布.
个人大修过的 gappproxy 将于近日放出, 敬请期待.

Tags:
Comments

Wireless Series(11): 高级应用 (2)

倒数第二篇. 原定的 Part 12 因为篇幅太短取消, 合并到最后一篇. :)

使用 dsniff 分析 pcap 文件, 获得机主相关信息.
攻击的部分就不写了, 主要原理是 ARP 欺骗. 这部分写出来危害比较大.

如果要获取未加密的密码信息, 使用 dsniff. 可以在线被动监听, 也可以使用 pcap 包文件.
无线相关加密的 cap 包必须先解密再用. 具体要不要保留 802.11 头你要自己试一试.
使用 -d 参数可以指定 pcap 包, -i 参数指定监听的网卡名称.
(不推荐用于无线网卡, 用 airodump-ng 等监听, 解密包再用 -d 参数查看)

urlsnarf 可以从 pcap 包中提取用户所上的网站, 并输出为 Apache 日志格式, 并可以用相关工具分析. 用法和 dsniff 相似.

如果需要查看 DNS 请求情况则需要 tcpdump.
tcpdump -r XXXX.pcap -l -n 'udp && port 53'

查找 QQ 号则使用 Wireshark 等工具.

此外 Wifizoo 功能也不弱. 支持 pcap 读入. 但它的安装不太方便. 所以推荐找现成做好的发行版用.
用它做 cookies 劫持相当方便(因为自己能够作为 proxy 使用).

PPP(PPPoE) 的认证方式有以下几种:
PAP, CHAP, MS-CHAPv1, MS-CHAPv2. 其中 PAP 是明文的. 其余的几个可以使用 Cain & Abel 等软件挂字典破解(未测试).

使用 rp-pppoe 作为 PPPoE 服务器, 可以强制使用 PAP 认证以获取明文密码.
需要在 /etc/ppp/chap-secrets 中添加用户名密码, 并在 /etc/ppp/pppoe-server-options 中加入 show-password 和 require-pap.
当然会抓包的话只需要强制 pap 认证就可以了, 用 wireshark 就能看到密码.

有些无线猫用的是 WEP 加密, 需要再用拨号软件再拨一次号. 如果认证方法是 PAP, 那么可以解密抓包并截获密码. 如果是 WPA 就要另想办法.

有人说 MITM 中间人攻击很厉害, 偶承认这一点. 就比如说这个认证也是可以降级的. 但具体的方法这里不会说的.

偶一直不说 MDK3 的问题. MDK3 强归强, 某些功能影响了正常的网络就实在太不好了.
nmap, nbtstat 这类东西和无线没有太多的关系偶也不愿意写.
再往下写什么 ettercap, metasploit, (x)Hydra 之类的那就是在说黑客知识了.
这个系列总是要结束的嘛.

工具那么多, 就看你怎么用.
漏洞天天有, 看今天砸到谁.

:D

Tags:
Comments

Wireless Series(10): 高级应用 (1)

说到高级应用哪, 写点没人写过的最为好.

高级里面也有基础. :)
用 airdecap-ng 可以解密已知密钥的 cap 抓包文件, WEP 和 WPA 都可以.
其中对 WPA 只能解密抓到四次握手包之后传输的数据.
注1: Wireshark 可以即时解密已知 WEP 密钥的数据包, 但偶不推荐这样做, 开销比较大.
注2: Cain & Abel 也有这个能力.
注3: 使用 airdecap-ng 的 -l 参数可以保留数据包的 802.11 头.

假定有一个抓包文件为 1.cap, 使用 -l 参数解密得到 1-dec-l.cap, 不使用 -l 参数解密得到 1-dec.cap.

首先是 MAC 过滤与绑定问题.
使用 aircrack-ng 1-dec-l.cap 可以直接看到 IP 地址 (这样不能取得明确的 IP – MAC 对应关系). 所以不推荐这种方法.
也可以使用 pcaputils 工具组里的 pcapuc.

小知识:
pcaputils 系列工具基本都支持 BPF syntax.
Wireshark “eth.src == xx:xx:xx:xx:xx:xx” 相当于 TCPDump (BPF) 的 “ether host xx:xx:xx:xx:xx:xx”

依照数据包数量排序 IP
pcapuc -r 1-dec.cap -S | sort -k2nr | head
过滤客户端 MAC 后立刻看到 IP 地址 (MAC 自己从 airodump-ng 界面去找, 用 CSV 文件也可以)
pcapuc -r 1-dec.cap -S -f "ether host xx:xx:xx:xx:xx:xx" | sort -k2nr | head

如果 airodump-ng 输出的 CSV 文件丢失了怎么办?
airodump-ng -r capture-file -w output-file

使用双网卡注入的方法:

简单说就是用 aireplay-ng -2 来发送其他网卡截取的包. 仅限 -2, -3 和已获得密钥生成注入包的 -4, -5 使用.
如果你有一块功率大而接收一般的卡, 一块功率小但接收很好的卡就可以用此法. 虽然偶这里写的很简单, 但你会发现这种方法的厉害.
airtun-ng 也可以做这种事情, 不过面对的对象不一样. 你可以自己试试看.

远程操作注入的方法:

在目标机器上启动 airserv-ng, 需要用 -d 来指定物理无线网卡.
airserv-ng 默认监听 TCP 666 端口. 需要先用 airmon-ng 设置网卡为监听模式.
在使用其它套件时可以把 127.0.0.1:666 指定为 interface.
将 127.0.0.1 换成远程 IP (注意在防火墙上开放该端口) 即可截取/注入远程网卡.

Wardriving 简单总结:

gpsd -N -n -D 3 /dev/ttyUSB0
kismet # 需要换一个 terminal 窗口, 自己配置一下监听网卡
giskismet -x XXXXX.netxml
giskismet -q "select * from wireless" -o output.kml

注1: gpsd 和 kismet 运行需要 root 权限, 打开 gpsd 之前先杀掉现有的 gpsd.
注2: USB GPS 设备可能不是 /dev/ttyUSB0.
注3: 请自备 giskismet 以导出为 Google Earch KML 文件.
注4: 请选择信号接收良好, 设备驱动完善的网卡. 较新的驱动对 rtl8187l 支持不佳.
注5: 关于 gpsd, 等定位完成之后再打开 kismet.
注6: kismet 输出的 pcapdump 文件有较大的研究价值, 通过 Beacon Frames 可以看到很多东西.
注7: GPS 如果失去定位的话 kismet 应该会有声音提示.
(自己试试看, 尽量设法调出这个声音来再出发, 日后会省不少麻烦.
kismet 会把失去定位时测到的 AP 的坐标设为一个你不希望看到的地点.
对 Warwalkers 和 Warbikers 来说一定要注意, 失去定位的可能性还是相当大的)
注8: giskismet 执行完带 -x 参数的命令之后会生成一个 sqlite 数据库文件, 有非常大的分析价值.
注9: 强烈不推荐使用 airodump-ng 做 wardriving 相关活动. 加上 gpsd 参数也不行.
注10: 尽量不要用 kismet 自带的 gps 功能, 要开启单独的 gpsd 进程.

通过 Wardriving 究竟能发现些什么东西呢? 总之偶能分析到的东西比某些人多得多. :D

Tags:
Comments

Wireless Series(9): FeedingBottle

FeedingBottle 是 aircrack-ng 工具组的 GUI, 主要运行环境为基于 Tiny Core Linux 的 Beini 系统. 作者赵春生.

FeedingBottle 封装了几乎全部常用的 aircrack-ng 命令组合(-6, -7 攻击模式除外).
高级模式给用户以更大的自由度. 普通模式和 spoonwep 几乎无异.
高级模式下点击按钮就能完成对应的操作, 所以偶前面也没必要把命令全摆出来.

这一篇事实上没什么可写的. 顺便说说 Beini 做的一些修正之处, 凑个字数 :D

最值得一提的是修正了 Aireplay-ng -1 模式不支持中文 SSID 的问题.

这个问题目前有两种修复途径.

第一种是 Patch: 修改 aireplay-ng 代码,使其支持中文 SSID 的伪连接操作

第二种是暴力伪连接. 原理是修改 wpa_supplicant 的配置文件以达到同样的连接效果.
这种方式速度较慢, 推荐在不支持 -1 的网卡上一用. 当然偶不反对大家用这个模式来碰运气.
minidwep-gtk 也支持这种暴力伪连接, 并使用这种方式绕过了打补丁的问题, 即对使用中文 SSID 的 AP 不使用 -1.

Tags:
Comments

Page 1 of 131234567810...Last »