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下用自由软件就根本不存在这样的问题。