将树莓派打造成自带VPN的无线路由

为什么选择这样的组合?

Raspberry Pi很有让人DIY的冲动,尤其是摆脱了24小时开server不低碳的罪恶感。作为标准的linux on ARMv6,相对于Openwrt或者dd-wrt,有更好的可配置性。

PPTP与L2TP在国内已经部分不能使用;相对地,OpenVPN可以选择TCP链接、内容加密,能够更好地规避流量过滤的限制。并且,可以设置http代理,避免Remote IP被封的尴尬。更为重要的,OpenVPN对IPv6的支持相对较好。

但OpenVPN由于是私有协议,需要专有的客户端,因此在Android(CM9对OpenVPN提供有支持)、iOS、WP8上的使用比较困难。把Raspberry Pi和OpenVPN结合起来搭建软AP可以较方便的解决这些问题。

需要准备的

  • Raspberry Pi:(如果长时间使用,建议在CPU和以太网芯片上加散热片);
  • OpenVPN Service:远端的OpenVPN服务,最好使用TCP/443端口;
  • nano无线网卡:由于要用到nl80211驱动,并且支持AP模式或master模式,无线网卡的选择比较困难,参见Linux Wireless Doc。我用的是RT5730芯片的TENDA W311M,RMB29;
  • 如果使用ssh连接,可能会遇到网络down掉的情况,可能需要备用一个键盘+HDMI显示器(注:如无硬件环境,也可选择使用Screen命令防止由于网络问题造成ssh连接断开);
pi@raspberrypi ~ $ lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 
Bus 001 Device 004: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter
pi@raspberrypi ~ $ iw list
Supported interface modes:
	 * IBSS
	 * managed
	 * AP
	 * AP/VLAN
	 * WDS
	 * monitor
	 * mesh point

关于IPv6的说明

OpenVPN在2.3版本以后开始原生支持IPv6,但Debian/Raspbian还没有release相应的deb。

  • 如果Raspberry Pi使用Arch Linux ARM,已经有OpenVPN 2.3的pkg;
  • 如果选择Raspbian(Debian)可能需要从源编译OpenVPN,没有亲自试过。

后面的例子使用Raspbian(我的环境暂时没有IPv6),相信使用Arch的同学必须毫无压力。

  • Arch可能遇到的问题:发现如果hostapd起来,会自动把eth0 down掉,开始一直检查配置,后来发现是USB供电不足。。

开始配置

Raspberry Pi上需要用到的deb:

pi@raspberrypi ~ $ sudo apt-get install hostapd dnsmasq openvpn

如果使用ssh连接,可能会遇到网络down掉的情况,可能需要备用一个键盘+HDMI显示器。
首先配置hostapd:

pi@raspberrypi ~ $ sudo vi /etc/hostapd/hostapd.conf
interface=wlan0
driver=nl80211
ssid=RaspberryPi
hw_mode=g
channel=11
wpa=1
wpa_passphrase=YOUR_PASS
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP
wpa_ptk_rekey=600
macaddr_acl=0

这时可以test一下hostapd:

sudo hostapd /etc/hostapd/hostapd.conf

用Wifi应该可以扫描到AP,并且输入密码应该可以连接,但获取不到IP。配置无误,添加hostapd的默认启动:

pi@raspberrypi ~ $ sudo vi /etc/default/hostapd
DAEMON_CONF="/etc/hostapd/hostapd.conf"

更改wlan0的连接和IP:

pi@raspberrypi ~ $ sudo vi /etc/network/interfaces 
auto wlan0
iface wlan0 inet static
address 192.168.200.1
netmask 255.255.255.0

之后配置dnsmasq,提供dhcp和dns(如果静态配置地址,不需要)。

pi@raspberrypi ~ $ sudo vi /etc/dnsmasq.conf 
interface=wlan0
dhcp-range=192.168.200.100,192.168.200.200,255.255.255.0,12h
pi@raspberrypi ~ $ sudo ifconfig wlan0 192.168.200.1
pi@raspberrypi ~ $ sudo service dnsmasq restart

此时,客户端应该可以连接并获取IP,ping 192.168.200.1应该可以ping通。

配置OpenVPN

需要提供与服务器端匹配的config,可以直接参考其他linux的配置文件,例如我的是:

pi@raspberrypi ~ $ sudo vi /etc/openvpn/client.conf 
client
remote SERVER_ADDR PORT
proto tcp
dev tun
resolv-retry infinite
ca /etc/openvpn/ca.crt
cert /etc/openvpn/client.crt
key /etc/openvpn/client.key  # This file should be kept secret
persist-key
persist-tun
comp-lzo
pull dhcp-options
nobind
verb 3
cipher none

可以设置上电自启动该client:

pi@raspberrypi ~ $ sudo vi /etc/default/openvpn 
AUTOSTART="client"

这时,可以测试下OpenVPN:

pi@raspberrypi ~ $ sudo service openvpn restart

数秒之后,在ifconfig中应该可以看到tun0出现。

配置路由

这里用的NAT方式(bridge方式略过),因此使用iptables设置路由。

iptables -t nat -A POSTROUTING -o tun0 -s 192.168.200.0/16 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

当然,可以根据需要灵活配置路由,这也是Raspberry Pi最大的优势,利用iptables分拣包。例如,把国内的包自动转向eth0直接处理,国外的包tun0发送。

可以放在/etc/networ/if-up.d/up.sh,也可以放在/etc/rc.local

这时可以重启Raspberry Pi,应该已经是一个完整的自VPN的Router。

可能的问题

  • hostapd出错,一般是无线网卡的驱动。为了避免驱动的麻烦,尽量反复确认nl80211的支持。
  • 无法获取IP,客户端提示“超过了普通的时间。。”,一般是DHCP没有工作,可以检查dnsmasq的状态。
  • OpenVPN无法建立连接,一般证书匹配、配置文件的问题比较大。

原文载于:Willings Blog