2010年11月8日星期一

用Linux节省手机上网流量

Part 0

最近发现手机的Internet共享功能可以非常简单地让电脑分享手机的互联网连接。可是手机流量那么珍贵(我的套餐是100M的),用电脑上网的话,很多后台程序就偷偷地把流量消耗光了啊。我想用iptables可以搞定这个问题。后来真就搞定了。


Part 1

我想把所有的网络活动都禁止掉,然后需要什么功能开什么功能。

禁止所有功能,需要在你防火墙脚本的最后这样写:

   # Reject all inbound and outbound traffic first
   iptables -A INPUT -j DROP
   iptables -A OUTPUT -j DROP
   iptables -A FORWARD -j DROP

或者这样也行:

   # Same effects as above, but won't record dropped packets
   iptables -P INPUT DROP
   iptables -P OUTPUT DROP
   iptables -P FORWARD DROP

我最想用的是Gtalk功能,于是从头添加:

   # Allow Gtalk(xmpp-client) traffic
   iptables -A OUTPUT -p tcp --dport 5222 --sport $unprvports -j ACCEPT

这个$unprvports(Unprivileged Ports)是在脚本开头定义的:

   unprvports='1024:65535'

5222的端口是pidgin里面自动填写的Gtalk的Jabber服务器的端口。

忘了一条:没有DNS,什么也干不了。所以首先应该是考虑的是开放53端口:
 
   # Allow DNS queries and the replies
   iptables -A OUTPUT -p udp --dport 53 --sport $unprvports -j ACCEPT

前面都容许了OUTPUT其实还是不够的,我们还需要让已经建立的连接容许进来数据,要不让只能出不能进也没用:

   # Allow previously established connections
   iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

把前面的内容整理出来,就形成了一个只能上Gtalk聊天的防火墙:

   #! /bin/bash

   # Flush then delete all user-defined chains
   iptables -F
   iptables -X
 
   unprvports='1024:65535'
 
   # Allow previously established connections
   iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
 
   # Allow DNS queries and the replies
   iptables -A OUTPUT -p udp --dport 53 --sport $unprvports -j ACCEPT
 
   # Allow Gtalk(xmpp-client) traffic
   iptables -A OUTPUT -p tcp --dport 5222 --sport $unprvports -j ACCEPT

   # Reject all inbound and outbound traffic
   iptables -A INPUT -j DROP
   iptables -A OUTPUT -j DROP
   iptables -A FORWARD -j DROP

如果还需要别的应用,可以如法炮制把相关的端口开放。以下的内容可以根据需要添加或者注释掉:

   self='127.0.0.1'
   vps='your.server.ip.address'
 
   # Allow Gmail(imaps and ssmtp) traffic
   #iptables -A OUTPUT -p tcp --dport 993 --sport $unprvports -j ACCEPT
   #iptables -A OUTPUT -p tcp --dport 465 --sport $unprvports -j ACCEPT
 
   # Allow MSN traffic, also need 443 port
   iptables -A OUTPUT -p tcp --dport 1863 --sport $unprvports -j ACCEPT
 
   # Allow QQ traffic. May use udp depends on your settings.
   #iptables -A OUTPUT -p tcp --dport 8000 --sport $unprvports -j ACCEPT
 
   # Allow HTTPS traffic, and MSN need this
   iptables -A OUTPUT -p tcp --dport 443 --sport $unprvports -j ACCEPT
 
   # Allow HTTP traffic
   #iptables -A OUTPUT -p tcp --dport 80 --sport $unprvports -j ACCEPT
 
   # Allow PPTP
   #iptables -A OUTPUT -p gre -d $vps -j ACCEPT
   #iptables -A OUTPUT -p tcp -d $vps --dport 1723 --sport $unprvports -j ACCEPT
 
   # Allow OpenVPN. May use tcp depends on your settings.
   #iptables -A OUTPUT -p udp -d $vps --dport 1194 --sport $unprvports -j ACCEPT
 
   # Allow NTP, which uses port 123 for outgoing packets by default, so we do not specifiy unprivileged source ports.
   iptables -A OUTPUT -p udp --dport 123 -j ACCEPT
 
   # Allow domestic traffice, e.g dictd.
   iptables -A OUTPUT -p tcp -s $self -d $self -j ACCEPT

需要说明几点。在Thunderbird里面用IMAPS收信,会读取所有邮件头,很浪费流量,我还没找到怎么把它设置得合适;根据我的观察,MSN和QQ的流量比Gtalk多,Gtalk的Jabber协议很安静。


Part 2

上面设置好防火墙,只是节省流量的第一步。下一步是选择合适的网络应用。

在上网的时候,我开着GNOME System Monitor监视网络,这样可以随时看到当前的上行和下行速率,以及累计传输的字节数。

还有一个更加强大的软件来帮助我们。同时打开Wireshark抓包软件,实时抓取和监视流过因特网接口的每一个数据包。额外说两句,Wireshark这个软件真的非常棒。GUI简单明了,但是又有高级的设置和复杂的功能。小到查看流过网线的每个比特,大到对抓取数据的多方面的统计分析,都可以非常简单地实现。通过Wireshark,可以看到和哪里、有什么协议发生了数据交换。如果有不明连接,可以通过sudo netstat --tcp --udp --numeric --program查看还活着的连接。

Gtalk聊天开始我用的是Pidgin,但这是图形界面的,头像啊、自定义表情啊神马的还是费流量,所以我想以后用Finch。这是Pidgin的文本版。

看网页的话(这里说的是本地页面),可以用Firefox,因为有个方便的Work Offline功能。如果要上网,Firefox需要去掉一些功能,如不显示图片,禁用掉Flash插件,不报告攻击和钓鱼网站,不发送崩溃报告,不自动更新,不到OCSP(Online Certificate Status Protocol)服务器上验证证书,把自带的RSS删除掉。要用浏览器打开手机网页,而不是桌面网页,因为桌面网页上无用信息太多。

其实我更喜欢用的是w3m文本浏览器,不用像Firefox那样设置很多,而且功能丰富,快捷键操作迅捷,只是快捷键太多了不好记。而且后退页面的时候,是立刻显示的,而不是像Firefox那样似乎要重新连接服务器。

查Gmail的话,不要用Thunderbird这样的软件,因为它不是为了我这种极端的需求设计的,通过IMAP同步邮件根本不值得。我推荐用Gmail的手机网页版。

我一般情况下是关闭80端口的,因为常上的网站都是HTTPS的,这样也省去了点开太多外部链接的分心。而且80端口很常用,很多后台的程序可能都会从这个端口联网。比如apt的自动更新就是HTTP的,如果你的Ubuntu开了自动更新,而且是下载完后再提示,那如果不小心下载了一堆deb包,你可能真要哭了。还有,印象中Xscreensaver或者GNOME Screensaver有几个屏保都会联网的。所以一定要开着GNOME System Monitor监视,最好也开着Wireshark。


Part 3

通过手机共享因特网给电脑,是很有用的。比如在火车上,在没有网络的地方,只要有手机信号,就可以用电脑上网了。这样上网,不仅经济,而且舒畅,还更安全。

   经济。因为手机上没法像电脑一样进行有力的网络监控,不知道哪些程序在联网,所以必然有未知去向的流量。
   舒畅。电脑屏幕比手机大十几倍,上网的体验自然要好多了。我这样上网后,觉得以前用手机看Reader真是有点自己跟自己过不去。
   安全。智能手机上那些偷窥隐私的软件你是发现不了的,用的手机软件越多,隐私遭窃的风险也越大。在电脑上任何网络活动都难逃Wireshark的法眼,再说Ubuntu下用自由软件就根本不存在这样的问题。

2010年10月1日星期五

Google Mobile的问题

手机(Windows Mobile 6.1)的Google移动应用出问题了,想下载个新版,可是用Opera Mini在m.google.com怎么也找不到下载应用的链接。然后用电脑打开移动应用的页面,把下载链接用短信发到手机上,用收到的这个链接才能到下载文件。这个链接只有用手机打开才行,用电脑打开就到搜索框了。

2010年9月14日星期二

Skype登录证书被劫持

上月在Skype的网页上登录,发现了一个非常值得警惕的现象,在https://login.skype.com页面,Chrome提示如下警告:

这表明所浏览网站的SSL证书有问题。

浏览器警告证书有问题的情况并不罕见,多数情况是因为证书不是由所用浏览器认可的权威证书颁发机构颁发的。比如Savannah使用的是CACert颁发的证书,而Firefox之类的浏览器没有内置CACert作为权威证书颁发机构,所以打开会有警告,但是据说Debian下的Iceweasel含了CACert作为CA。还有清华大学的校园网用户登录页面,一直在用一个2003年就过期了的无效证书。在试图下载微软Office 2010试用版的时候,我还头回碰到网页证书被颁发机构召回的情况。
但是Skype的安全登录页面出现问题,那得警惕了。我点击Chrome地址栏左边的红色骷髅,打开了网页的证书,发现是个叫bb-in.com的网站自颁发的证书,这显然不是个CA。另外,证书的授予对象是他们网站,而不是login.skype.com。

此时,我没有登录。当我用OpenVPN翻墙后再打开这个页面,没有安全警告,证书也是可信任的:

可惜当时没有对假冒的证书抓图,第二天就去出差了。等出差回来,再试验发现又没有这个问题了。

Skype安全登录的证书变成一个莫名的证书,但是用了VPN翻墙就好了。是中间有人故意作梗想偷窃用户隐私,还是仅仅是技术错误,我现在还没有足够的证据来分析。但是,这件事件让我进一步感到,在中国上网有着这么多的陷阱,让人防不胜防。对于刚刚上网的无知初级网民,他们何时才能知道这些陷阱呢?

顺便友情提醒,在国内上skype.com会自动跳转到tom.skype.com,上面提供的Skype是接受中国监控的,这一点Skype公司本身也承认的,所以千万不要去下载上面的Skype。要下载的话,翻墙后再上,就不会被跳转了。
------------------------------------
即兴送上腾迅公司的Gmail钓鱼页面:

2010年9月9日星期四

OpenVPN的DNS推送

在OpenVPN Access Server管理页面中的VPN Settings下面,有DNS Settings,可以让客户端使用和服务器端相同的DNS。在Windows下用OpenVPN后,DNS自动变成了服务器端的,所以twitter.com、facebook.com等被DNS污染的网站,也可以上去。同样的VPN,在Linux下用OpenVPN命令连接后(# openvpn --config client.ovpn),DNS还是不变,因此被DNS污染了的网站也上不去。这个待深入研究。

2010年8月17日星期二

撞墙

以前好好设置的OpenVPN,能建立VPN,但是死活无法转发包,最近不知怎么却可以了。我开始试用全局VPN下的翻墙。照旧用常见的墙外网站测试,发现三个最知名的网站:twitter.com,facebook.com和youtube.com用OpenVPN竟然翻不过去,连接很长一段时间之后显示连接超时。其它测试过的有blogger.com,blogspot.com,bbc.co.uk/chinese和foursquare.com等,都可以成功翻越。但是,如果用更加简单的SSH Tunnel代理方式翻墙,那么上面所述的所有网站都可以翻越。

后来发现在本地进行DNS查询,twitter, facebook和youtube的IP地址每次都是不一样的,系统返回一个随机的值。但是用可信的DNS服务器,或者直接从国外的VPS上查询,才会返回正确的值。

我的ISP是北京联通的小区宽带。用系统分配的DNS服务器查询结果:
tux@Neverland:~/Desktop$ dig +nocmd +nocomments twitter.com
;twitter.com.            IN    A
twitter.com.        35888    IN    A    93.46.8.89
;; Query time: 493 msec
;; SERVER: 202.106.46.151#53(202.106.46.151)
;; WHEN: Tue Aug 17 23:22:53 2010
;; MSG SIZE  rcvd: 45

tux@Neverland:~/Desktop$ dig +nocmd +nocomments facebook.com
;facebook.com.            IN    A
facebook.com.        300    IN    A    59.24.3.173
;; Query time: 496 msec
;; SERVER: 202.106.46.151#53(202.106.46.151)
;; WHEN: Tue Aug 17 23:22:54 2010
;; MSG SIZE  rcvd: 46

tux@Neverland:~/Desktop$ dig +nocmd +nocomments youtube.com
;youtube.com.            IN    A
youtube.com.        180    IN    A    37.61.54.158
;; Query time: 503 msec
;; SERVER: 202.106.46.151#53(202.106.46.151)
;; WHEN: Tue Aug 17 23:23:51 2010
;; MSG SIZE  rcvd: 45
上面的结果,重复查询每次都不一样, 而且有的IP会在不同的网址查询结果中出现,facebook.com和youtube.com就出现过同一个结果37.61.54.158。但有时候又会返回正确的IP,这大概是GFW的策略,随机出现随机的错误IP。很明显这些域名遭遇了所谓的DNS污染。如果我们用可信的DNS服务器8.8.8.8来查询,得到正确的结果,就可以更加确凿无疑地证明受到了DNS污染。
tux@Neverland:~/Desktop$ dig @8.8.8.8 +nocmd +nocomments twitter.com
;twitter.com.            IN    A
twitter.com.        8    IN    A    128.242.240.52
twitter.com.        8    IN    A    168.143.162.100
twitter.com.        8    IN    A    128.242.240.116
;; Query time: 277 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Aug 17 23:28:49 2010
;; MSG SIZE  rcvd: 77


tux@Neverland:~/Desktop$ dig @8.8.8.8 +nocmd +nocomments facebook.com
;facebook.com.            IN    A
facebook.com.        441    IN    A    69.63.189.11
facebook.com.        441    IN    A    69.63.181.12
facebook.com.        441    IN    A    69.63.181.11
facebook.com.        441    IN    A    69.63.189.16
;; Query time: 271 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Aug 17 23:31:21 2010
;; MSG SIZE  rcvd: 94


tux@Neverland:~/Desktop$ dig @8.8.8.8 +nocmd +nocomments youtube.com
;youtube.com.            IN    A
youtube.com.        140    IN    A    74.125.127.93
youtube.com.        140    IN    A    74.125.95.93
;; Query time: 300 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Aug 17 23:31:25 2010
;; MSG SIZE  rcvd: 61

如果没有受到DNS污染,那么即使是被GFW盾的网站,国内外的解析结果也没有什么不同。
tux@Neverland:~/Desktop$ dig +nocmd +nocomments foursquare.com
;foursquare.com.            IN    A
foursquare.com.        3014    IN    A    184.73.159.65
;; Query time: 521 msec
;; SERVER: 202.106.46.151#53(202.106.46.151)
;; WHEN: Tue Aug 17 23:33:38 2010
;; MSG SIZE  rcvd: 48


tux@Neverland:~/Desktop$ dig @8.8.8.8 +nocmd +nocomments foursquare.com
;foursquare.com.            IN    A
foursquare.com.        1409    IN    A    184.73.159.65
;; Query time: 277 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Aug 17 23:33:43 2010
;; MSG SIZE  rcvd: 48
问题的解决也简单,就是把/etc/resolv.conf里面的DNS换成可信的。OpenVPN应该支持DNS推送的功能,这样就可以自动解决这个问题,待我后续再研究。另外,用SSH Tunnel代理翻墙就不会出现上述的问题,这至少证明了比起用OpenVPN,用SSH Tunnel代理翻墙并不是那么弱。