Kevin Blog

AnyConnect 带来 iPhone 上的新生活

现在换 IKEv2 也是不错的选择, 另外有个神器可以一键配置 https://github.com/ftao/vpn-deploy-playbook

假如说我越狱的理由有两个的话,一个是我可以高性能运行像 PPSSPP 这样的模拟器,另外一个就是可以带来 Client 端的分流,更开心的上网。

然而我都没有越狱,7.1 发布后更是没有机会去越狱了。

幸福的是 AnyConnect 改变了我窘迫的现状。

  1. 不会断线
  2. 可以给客户端下发走 VPN 的路由表
  3. 稳定

So,我们来聊一聊如何通过 Ocserv 在 Ubuntu 13.10 搭建你的 AnyConnect。

这里不选择 12.04 的原因是他的包比较旧,需要你很折腾才能编译 Ocserv,另外 14.04 已经 On the way 了。

PS.如果想要在 Ubuntu 12.04 上安装,那么需要参考这文章安装 NettleGnutls

安装 Ocserv

下载 Ocserv 0.3.2

wget ftp://ftp.infradead.org/pub/ocserv/ocserv-0.3.2.tar.xz
tar xvf ocserv-0.3.2.tar.xz
cd ocserv-0.3.2

安装编译依赖

sudo apt-get install build-essential libwrap0-dev libpam0g-dev libdbus-1-dev \
libreadline-dev libnl-route-3-dev libprotobuf-c0-dev libpcl1-dev\
 libopts25-dev autogen libgnutls28 libgnutls28-dev  libseccomp-dev 

编译

./configure --prefix=/usr --sysconfdir=/etc && make && sudo make install

生成证书

这里你需要先仔细阅读官方的文档 简单的来说,如下几步

创建工作文件夹

mkdir CA
cd CA

生成 CA 证书

certtool --generate-privkey --outfile ca-key.pem
vim ca.tmpl

#输入一下内容

cn = "VPN CA"
organization = "Big Corp"
serial = 1
expiration_days = 3650
ca
signing_key
cert_signing_key
crl_signing_key

#保存退出文件编辑

certtool --generate-self-signed --load-privkey ca-key.pem \
--template ca.tmpl --outfile ca-cert.pem

生成本地服务器证书

certtool --generate-privkey --outfile server-key.pem
vim  server.tmpl

# 输入以下内容

cn = "www.example.com"
organization = "MyCompany"
serial = 2
expiration_days = 3650
encryption_key
signing_key
tls_www_server

#保存退出文件编辑

certtool --generate-certificate --load-privkey server-key.pem \
--load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem \
--template server.tmpl --outfile server-cert.pem

生成之后

server-cert.pem 放到/etc/ssl/certs server-key.pem 放到/etc/ssl/private

配置文件

工作目录是最初解压出来的 ocserv-0.3.2

sudo mkdir /etc/ocserv && \ 
sudo cp doc/sample.config /etc/ocserv/ && \
 sudo mv /etc/ocserv/sample.conf /etc/ocserv/ocserv.conf

编辑配置文件

vim /etc/ocserv/ocserv.conf

修改如下

auth = "plain[/etc/ocserv/ocpasswd]"
#ocserv支持多种认证方式,这是自带的密码认证,使用ocpasswd创建密码文件
#ocserv还支持证书认证,可以通过Pluggable Authentication Modules (PAM)使用radius等认证方式

#证书路径
server-cert = /etc/ssl/certs/server-cert.pem
server-key = /etc/ssl/private/server-key.pem

#同一个用户最多同时登陆数
max-same-clients = 10 

#运行组
run-as-group = nogroup

#分配给VPN客户端的IP段
ipv4-network = 10.10.0.0

#DNS
dns = 8.8.8.8
dns = 8.8.4.4

#注释掉route的字段,这样表示所有流量都通过 VPN 发送
#route = 192.168.1.0/255.255.255.0
#route = 192.168.5.0/255.255.255.0

创建用户

sudo ocpasswd -c /etc/ocserv/ocpasswd username
#username为你要添加的用户名

修改系统配置,允许转发

vim /etc/sysctl.conf
#修改这行
net.ipv4.ip_forward = 1
#保存退出
sysctl -p

修改 iptables 规则 你可以参考 Linode 的文章 来配置 iptables

*filter

#  Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT

#  Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#  Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

#  Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
#  Allow SSH connections
#
#  The -dport number should be the same port number you set in sshd_config
#
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

#  Allow ping
-A INPUT -p icmp -j ACCEPT

#  Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

-A INPUT -j DROP

COMMIT

特别需要主意的是,一定不要存在这样的一句话 不然能连上也是哪里都不能访问……

-A FORWARD -j DROP #不要存在这句

在你的 /etc/rc.local 的exit 前面加上这句 来开启 NAT

iptables -t nat -A POSTROUTING -j MASQUERADE
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 

Debug

现在我们可以开启服务器试试了

sudo ocserv -c /etc/ocserv/ocserv.conf -f -d 1

如果你出现了这样的错误

DBUS connection error (Connection ":1.225" is not allowed to own the service "org.infradead.ocserv" due to security policies in the configuration file)Cannot create command handler

那么你需要这样处理

sudo cp ocserv-0.3.2/doc/dbus/org.infradead.ocserv.conf /etc/dbus-1/system.d/

Thanks to sskaje

拿起你的 iPhone,下载思科的 AnyConnect 客户端

然后输入你的服务器地址,以及你的用户名密码。 出现问题可以看debug的返回信息,如果信息不详细,可以把 1 改成 10

另外也可以通过 ifconfig 来看下你的设备名,我的是 vpns3,然后通过 tcpdump 抓包来看下数据

sudo tcpdump -i vpns3 -vv

配置启动文件

现在我们需要一个脚本来管理 Ocserv

你可以在这里找到, Thanks to Tony

把这个文件复制到 /etc/init.d/ocserv

然后

sudo chmod 755 /etc/init.d/ocserv
sudo update-rc.d ocserv defaults

就可以开机启动了。

你也可以通过

/etc/init.d/ocserv start

这样子来管理。

下发路由

我想这个功能是最激动人心的,因为我们手机如果长期连接,那么肯定是某些服务走 VPN,而国内的网站可以走手机自己的网络体验最好。

但是这里的一个问题是,AnyConnect 有下发路由表的 64 条数限制。

所以我们只能保证下某几个常用的服务是可用的,比如 Google Facebook 以及 Twitter

编辑配置文件

sudo vim /etc/ocserv/ocserv.conf

找到 route = 的字段

你可以使用我的路由表,把这些复制到里面。 保存后重新启动 VPN 服务器,就可以了。

/etc/init.d/ocserv restart

另外这里也有一个我写的 ruby 脚本,用来转换 72.52.99.0/24 > 72.52.99.0/255.255.255.0 这样格式的路由 CIDR to Wildcard mask。

这样你可以自行通过 nslookup

nslookup www.google.com

这样来获取服务器的A地址,然后转换成我们需要的格式。

一个可行的方案

如果你有台国内的VPS,那么你可以通过在 VPN 服务器上配置策略路由,来用国内服务器代理国内IP的请求。你可以参考我的 TomatoAutoVPN 来配置这样的特性。

现在我的手机已经连接了 8 个小时,非常愉快的使用着,希望你也能享受这样的快乐。

如果你遇到了任何问题,欢迎回复