使用 dnsmasq 配合 openvpn
使用 openvpn 并配合 chnroutes 脚本上网已经很完美了,在访问国外的 ip 时自动使用 vpn 线路,在访问国内的 ip 时则自动选用非 vpn 线路,为什么还要使用 dnsmasq 呢?原因如下:
由于有域名污染,所以 dns 只能使用 8.8.8.8 或者 opendns 之类的进行解析;而使用国外的 dns 之后,在解析某些使用了智能 dns 的服务时,智能 dns 服务器往往会选择错 ip 地址,就会导致:
- 明明是国内的服务,却解析到一个国外的 ip,并使用 vpn 进行访问,导致速度慢
- 自己的电信的线路,却解析到网通的 ip,访问同样也会受到影响
为了解决上述问题,就需要将这些域名转发到自己所在的 isp 提供的 dns 进行解析。一般的 dns 服务器软件都提供这样的功能,不过这里用不到那么复杂的功能。而之前介绍 dns 缓存的时候使用到的 dnsmasq 也能提供转发功能,因此这里就继续使用 dnsmasq。配置极其简单,只需要在配置文件 /etc/dnsmasq.conf 中对 server 字段进行配置即可,比如我的配置:
no-resolv
no-poll
server=8.8.8.8
server=8.8.4.4
server=/qq.com/192.168.1.1
表示默认使用 8.8.8.8 和 8.8.4.4 解析,当解析 *.qq.com 的时候使用 192.168.1.1 解析。你需要把 192.168.1.1 换成你 isp 提供的 dns 服务器。
最后,启动 dnsmasq 服务,把自己的 dns 服务器指向 127.0.0.1 即可,由于我使用了 resolvconf,所以直接在 /etc/resolvconf.conf 中加入一下配置即可:
name_servers=127.0.0.1
下面可以使用 dig 命令进行一个简单的测试:
$ dig @8.8.8.8 web2.qq.com
; <<>> DiG 9.8.0 <<>> @8.8.8.8 web2.qq.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6525
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;web2.qq.com. IN A
;; ANSWER SECTION:
web2.qq.com. 221 IN A 112.90.138.163
web2.qq.com. 221 IN A 112.90.138.164
web2.qq.com. 221 IN A 112.90.141.88
;; Query time: 217 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Wed Jul 20 00:17:59 2011
;; MSG SIZE rcvd: 77
$ dig @192.168.1.1 web2.qq.com
; <<>> DiG 9.8.0 <<>> @192.168.1.1 web2.qq.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13332
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;web2.qq.com. IN A
;; ANSWER SECTION:
web2.qq.com. 101 IN A 183.62.126.217
web2.qq.com. 101 IN A 183.60.3.126
web2.qq.com. 101 IN A 121.14.74.112
web2.qq.com. 101 IN A 183.60.3.84
;; Query time: 10 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Wed Jul 20 00:18:06 2011
;; MSG SIZE rcvd: 93
$ dig @127.0.0.1 web2.qq.com
; <<>> DiG 9.8.0 <<>> @127.0.0.1 web2.qq.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23246
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;web2.qq.com. IN A
;; ANSWER SECTION:
web2.qq.com. 94 IN A 183.60.3.84
web2.qq.com. 94 IN A 121.14.74.112
web2.qq.com. 94 IN A 183.60.3.126
web2.qq.com. 94 IN A 183.62.126.217
;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Jul 20 00:18:13 2011
;; MSG SIZE rcvd: 93
$ dig @127.0.0.1 twitter.com
; <<>> DiG 9.8.0 <<>> @127.0.0.1 twitter.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57641
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;twitter.com. IN A
;; ANSWER SECTION:
twitter.com. 19 IN A 199.59.149.198
twitter.com. 19 IN A 199.59.149.230
twitter.com. 19 IN A 199.59.148.10
;; Query time: 205 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Jul 20 00:26:57 2011
;; MSG SIZE rcvd: 77
可以看到使用 8.8.8.8 时解析到了网通的地址,而使用 127.0.0.1 后,则可以正确的解析为电信的地址。同时解析 twitter.com 也能正确的返回结果。
我的 xmonad 配置
本文讲述我的 xmonad 桌面的配置,它使用 xmobar 显示各种状态,使用 taryer 来提供 systray。
xmonad 是一种平铺式窗口管理器,窗口之间不会遮挡,且自动调整大小以填充整个屏幕,这样就节省了使用鼠标调整各个窗口位置的时间,一切的操作都可以通过自定义的快捷键来完成。
xmonad 是由 Haskell 开发的,其配置文件也是使用 Haskell 来配置的,不过了解一些简单的语法之后,配置起来也是很方便的。当然默认的配置就已经非常好用了,我也只是在默认的配置上进行了一点小的修改而已。
下面是我的 xmonad 配置与默认配置之间的差异(只是为了表现差异,最后会有整个配置文件的下载):
--- /usr/share/xmonad-0.9.2/ghc-7.0.4/man/xmonad.hs 2011-07-05 00:22:51.800397623 +0800
+++ .xmonad/xmonad.hs 2011-07-14 22:39:43.118625125 +0800
@@ -14,10 +14,15 @@
import qualified XMonad.StackSet as W
import qualified Data.Map as M
+import XMonad.Util.Run
+import XMonad.Hooks.DynamicLog
+import XMonad.Hooks.ManageHelpers
+import XMonad.Util.Cursor
+
-- The preferred terminal program, which is used in a binding below and by
-- certain contrib modules.
--
-myTerminal = "xterm"
+myTerminal = "gnome-terminal"
-- Whether focus follows the mouse pointer.
myFocusFollowsMouse :: Bool
@@ -32,7 +37,7 @@
-- ("right alt"), which does not conflict with emacs keybindings. The
-- "windows key" is usually mod4Mask.
--
-myModMask = mod1Mask
+myModMask = mod4Mask
-- The mask for the numlock key. Numlock status is "masked" from the
-- current modifier status, so the keybindings will work with numlock on or
@@ -127,6 +132,12 @@
-- Deincrement the number of windows in the master area
, ((modm , xK_period), sendMessage (IncMasterN (-1)))
+ -- screenshot screen
+ , ((modm , xK_Print), spawn "/usr/bin/screenshot scr")
+
+ -- screenshot window or area
+ , ((modm .|. shiftMask, xK_Print), spawn "/usr/bin/screenshot win")
+
-- Toggle the status bar gap
-- Use this binding with avoidStruts from Hooks.ManageDocks.
-- See also the statusBar function from Hooks.DynamicLog.
@@ -221,6 +232,7 @@
myManageHook = composeAll
[ className =? "MPlayer" --> doFloat
, className =? "Gimp" --> doFloat
+ , isFullscreen --> doFloat
, resource =? "desktop_window" --> doIgnore
, resource =? "kdesktop" --> doIgnore ]
@@ -239,9 +251,13 @@
-- Status bars and logging
-- Perform an arbitrary action on each internal state change or X event.
--- See the 'XMonad.Hooks.DynamicLog' extension for examples.
+-- See the 'DynamicLog' extension for examples.
+--
+-- To emulate dwm's status bar
+--
+-- > logHook = dynamicLogDzen
--
-myLogHook = return ()
+myLogHook = dynamicLog
------------------------------------------------------------------------
-- Startup hook
@@ -251,14 +267,19 @@
-- per-workspace layout choices.
--
-- By default, do nothing.
-myStartupHook = return ()
+myStartupHook = do
+ spawn "fcitx"
+ setDefaultCursor xC_left_ptr
+ spawn "feh --bg-scale /home/zhanglei/Pictures/mlxmonadwall1trans.png"
+ spawn "trayer --edge top --align right --widthtype percent --width 10 --SetDockType true --SetPartialStrut true --transparent true --alpha 0 --tint 0x000000 --expand true --heighttype pixel --height 25"
+ --return ()
------------------------------------------------------------------------
-- Now run xmonad with all the defaults we set up.
-- Run xmonad with the settings you specify. No need to modify this.
--
-main = xmonad defaults
+main = xmonad =<< xmobar defaults
-- A structure containing your configuration settings, overriding
-- fields in the default config. Any you don't override, will
以上修改的一些简单说明:
- 使用 gnome-terminal 作为我的终端
- 使用 Win 健作为 xmonad 的 Mod 健,默认为 Alt,但是会和 bash 的一些快捷键冲突
- 增加了两个快捷键 Win + Print 与 Win + Shift + Print 用来进行截图
- 加入 isFullscreen –> doFloat 以解决 flash 不能全屏的问题
- myLogHook = dynamicLog 可以让 xmobar 显示出当前的状态
- 在 myStartupHook 函数中加入我的启动项:
- fcitx 输入法
- 设置鼠标样式
- 使用 feh 设置桌面背景
- 启动 trayer 以显示 systary
- 最后,main 函数中使用 xmobar 函数启动 xmobar
下面是一些经常使用到的快捷键:
- Win + Shift + Enter: 启动 Terminal
- Win + P: 启动 dmenu,用于启动各种命令
- Win + 1 – 9: 在 1 – 9 虚拟桌面中进行切换
- Win + Shift + 1 – 9: 将当前的窗口移动到指定的虚拟桌面
- Win + Tab: 在同一虚拟桌面中的窗口之间切换
- Win + Shift + C: 杀死当前窗口
- Win + Q: 重启 xmonad,用于改为配置之后使其生效
下面是我的 xmobar 的配置,其配置文件为 .xmobarrc
Config { font = "xft:WenQuanYi Zen Hei Mono-12"
, bgColor = "black"
, fgColor = "grey"
, position = TopW L 90
, lowerOnStart = True
, commands = [ Run Weather "ZGSZ" ["-t",": C","-L","18","-H","25","--normal","green","--high","red","--low","lightblue"] 36000
, Run Network "eth0" ["-L","0","-H","32","--normal","green","--high","red"] 10
, Run Network "eth1" ["-L","0","-H","32","--normal","green","--high","red"] 10
, Run Cpu ["-L","3","-H","50","--normal","green","--high","red"] 10
, Run Memory ["-t","Mem: %"] 10
, Run Swap [] 10
, Run StdinReader
, Run Com "uname" ["-s","-r"] "" 36000
, Run Date "%a %b %_d %Y %H:%M:%S" "date" 10
]
, sepChar = "%"
, alignSep = "}{"
, template = "%cpu% | %memory% * %swap% | %eth0% | %StdinReader% }{ <fc=#ee9a00>%date%</fc> | %ZGSZ% | %uname%"
}
其中有三点值得注意:
- position 指定了 xmobar 的位置:左上,长度 90%,而 trayer 的则为右上,长度 10%。刚好能够接上。
- 深圳天气的代码为 ZGSZ,其他地方的可以到这个页面进行查询。
- 需要有 StdinReader,否则在 xmonad 中的 dynamicLog 函数就不会起作用。
使用 vps 搭建 openvpn
本文讲述使用 vps 搭建 openvpn,以及在 Gentoo 中使用 chnroutes 修改路由表,将国内 ip 的访问重新指定为非 vpn 线路。
条件
服务器为支持 Tun/Tap 的 vps: 我自己的 Directspace 的 vps,默认是没有开启的,需发 Tk 开启。免费的 AWS EC2 是默认开启了的。我这里的 vps 安装的操作系统为 Debian。
客户端为 Linux:我用的为 Gentoo,其他发行版的脚本和启动 openvpn 的方式可能会不一样
在 vps 中安装与配置 openvpn 服务器
安装 openvpn 软件,很简单:
aptitude install openvpn
生产服务器证书:
cd /etc/openvpn/
cp /usr/share/doc/openvpn/examples/easy-rsa/2.0/* .
source ./vars
./clean-all
./build-ca
./build-key-server server
./build-dh
./build-key client1
在 ./build-key-server server 和 ./build-key client1 两步时会询问是否签名,回答是,如下,其他使用默认即可:
...
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
好了,此时,在 /etc/openvpn/keys 目录下面就有了服务器和客户端所需的证书
下面修改服务器配置文件:/etc/openvpn/server.conf,我只提取有用部分:
port 53
proto udp # 我这里采用 udp 的 53 端口通信,和 dns 解析用的端口一样 ...
dev tun
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh1024.pem # 以上4个指定服务器证书的路径
server 10.8.0.0 255.255.255.0 # 配置ip地址段
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp" # 默认路由走 vpn,后面在客户端设置时会将国内的 ip 再修改回非 vpn 的路由
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4" # 使用 Google 的 DNS
client-to-client # vpn 客户端之间可以通信
duplicate-cn # 多个客户端可以使用同一个证书
keepalive 10 120
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
log /var/log/openvpn.log
verb 3
一些注释都在上面了。然后启动 openvpn 服务器了
/etc/init.d/openvpn start
服务器上面还有最后两件事情:打开路由转发选项和配置 SNAT 规则
打开路由转发:修改 /etc/sysctl.conf 文件,将 net.ipv4.ip_forward=1 前面的注释去掉
...
net.ipv4.ip_forward=1
...
然后执行命令:
sysctl -p
最后设置 MASQUERADE 规则,将 10.8.0.0 网段过来的数据包转发出去后都将源地址修改为本机的 IP 地址,以使回复包能够正确的回到 vps 上。命令:
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
其中 eth0 要改为 vps 上面的网络接口名称,比如在 Directspace 上面就为 venet0;
当然这样只是当前生效,vps 重启之后还得重新配置 MASQUERADE 规则,可以使用如下语句将当前的 iptables 规则保存起来,然后在开机的时候加载
iptables-save > /etc/openvpn/iptables
在 /etc/rc.loacl 中加入如下语句:
iptables-restore < /etc/openvpn/iptables
好了,服务器配置就完成了
在 Gentoo 下配置 openvpn 客户端
首先同样为安装 openvpn 软件,我这里是 Gentoo,你需要使用你用的发行版的包管理安装
emerge openvpn openresolv iproute2
安装 openresolv 是为了需要 resolvconf 程序,用于修改 dns 配置的,其他发行版可能不太一样
安装 iproute2 是为了获得 ip 程序,在修改路由时会使用到。
客户端需要使用在配置服务器端时生成的 key,需要如下三个文件:
ca.crt client1.crt client1.key
同样,我这里也放到了 /etc/openvpn/keys 目录
然后配置 /etc/openvpn/client.conf
client
dev tun
proto udp
remote xxx.xxx.xxx.xxx 53 # 这里需要换成你自己的服务器,域名或 IP
resolv-retry infinite
nobind
persist-key
persist-tun
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/client1.crt
key /etc/openvpn/keys/client1.key # 你自己的证书路径
comp-lzo
verb 3
redirect-gateway
script-security 2
创建启动脚本
ln -vs openvpn /etc/init.d/openvpn.client
然后使用如下命令启动即可
/etc/init.d/openvpn.client start
但是,这样启动之后,所有的流量都回走 vpn,因此访问国内资源时很慢,且有可能会有限制,所以接下来就需要使用 chnroutes 的方法将访问国内 ip 的路由修改为非 vpn 的线路
下载 chnroutes.py 文件,然后执行
python chnroutes.py -p linux
之后,目录下面就会多出两个文件:
ip-pre-up ip-down
然后将这两个文件拷贝到 /etc/openvpn/ 目录并改名,同时加上可执行权限:
cp ip-pre-up /etc/openvpn/openvpn.client-up.sh
cp ip-down /etc/openvpn/openvpn.client-down.sh
chmod 755 /etc/openvpn/openvpn.client-up.sh
chmod 755 /etc/openvpn/openvpn.client-down.sh
Gentoo 下面会在 vpn 启动和停止的时候自动调用上面两个脚本。这时再运行
/etc/init.d/openvpn.client start
过不一会儿,使用 ip 命令查看路由表信息就可以看到国内的 ip 都走了非 vpn 的线路
$ ip r
0.0.0.0/1 via 10.8.0.9 dev tun0
default via 192.168.1.1 dev eth0 metric 2
1.0.1.0/24 via 192.168.1.1 dev eth0
1.0.2.0/23 via 192.168.1.1 dev eth0
1.0.8.0/21 via 192.168.1.1 dev eth0
1.0.32.0/19 via 192.168.1.1 dev eth0
1.1.0.0/24 via 192.168.1.1 dev eth0
1.1.2.0/23 via 192.168.1.1 dev eth0
1.1.4.0/22 via 192.168.1.1 dev eth0
1.1.8.0/21 via 192.168.1.1 dev eth0
...
好了,现在可以打开 Youtube 看下视频了,AWS EC2 的免费 vpn 速度可以到 400K,已经很不错了,不过流量每月只有 30G :)
IE 不支持 deflate
最近在做http的压缩,稍微了解了下gzip,deflate,zlib的关系:
- deflate(RFC1951):一种压缩算法,使用LZ77和哈弗曼进行编码;
- zlib(RFC1950):一种格式,是对deflate进行了简单的封装;
- gzip(RFC1952):一种格式,也是对deflate进行的封装。
可以看出deflate是最核心的算法,而zlib和gzip格式的区别仅仅是头部和尾部不一样,而实际的内容都是deflate编码的,即:
gzip = gzip头 + deflate编码的实际内容 + gzip尾
zlib = zlib头 + deflate编码的实际内容 + zlib尾
在HTTP/1.1的RFC2616文档中说明了Content-Encoding字段的值可以为:gzip, deflate等。
gzip格式大家都支持的很好很标准,这里说下deflate格式,Content-Encoding的说明中指出deflate指的是在RFC1950说明的zlib格式。也就是说当Content-Encoding为deflate时,内容应该为zlib格式。
但是,实际上,如果真的按照这个标准来,那么在IE上面是打不开页面的,包括IE6,IE7,IE8,提示为一片空白或者出错。但是在其他的浏览器如Firefox,Chrome,Opera等上面都能正常打开。要让IE能够正常打开页面,内容必须是deflate原始格式的数据,即去掉zlib头和zlib尾。不知道IE为什么不修改这个Bug,按理说在IE6就出现的这种很简单的问题,IE8不应该出现才对。
为了照顾IE,只好在压缩deflate的时候去掉zlib头和zlib尾,还好其他的浏览器也都能正常处理这种原始的deflate格式。
当然,这样的话,那些受够了IE Only的人们倒是可以创建出一个IE不能正常访问的网站了。
09 年总结
现在再过半个小时就到10年了,利用这半个小时的时间对我的09年做个总结。
总的来说,09年是一个杯具年。
- 奶奶去世,让我伤心了好久,我奶奶身体一向很好,过年的时候还经常种菜什么的,没想到说走就走
- 手机的丢失,刚买了不到一年的钻石,在一次喝多了之后就再也找不到了
- GFW越来越高,越来越多的网站需要翻墙,而翻墙也越来越有难度
- 墙内越来越和谐,基本上是个新闻都是不让评论的,当然,人家说网上言论非常活跃,也许我错了
“中国以及和中国一起混的国家都是些流氓国家”,终于觉得我同事这句活说的太好了
当然09年也不是什么都不好
- 换了房子,从离公司很远的地方搬到了离公司还是很远的地方…不过一个在关外,一个在关内,总算住在深圳市内了…
- 买了自行车,除了每周踢球外,另一个锻炼身体的运动
- 买了望远镜,每当心情不好的时候就看看美丽的宇宙,顿觉人类的渺小,于是什么不开心的事都坦然了
- 买了个佳能500D,我承认目的只是想用来拍星空的,不过出去的时候带上拍拍其他的东西也不错
- 买个域名和空间,开始了我的独立博客,都是买的国外的,国内的不放心
好了,已经到10年了,其他的也没什么好说的了,都是老样子。