于2015/3/21更新

在网络环境越来越严苛的今天,如何维护一个较为良好的网络环境成为了我最关心的问题。现在看来,Ocserv(即Openconnect Server)是一个良好的解决方法。原因如下:

  1. Ocserv基于一个还算“可靠”的系统,这个可靠并不指安全性这一点,因为安全性这点上与它一致或比它好的VPN服务并不少……主要是,Ocserv其实是一个基于Cisco的Anyconnect系统的VPN服务端。只这点就相对来说比较有保障了,毕竟这条路断了的话也很有可能影响正常的经济运行呢……此中深意只要稍微了解一下VPN真正的用途就明确了。

  2. Anyconnect这套协议是在TLS/DTLS上的,换句话说,在真正建立连接的时候,刚开始的几步和其余使用TLS的协议并无太大差距。换句话说,如果你把这个服务的TCP监听端口放在443、并只启用TLS的话,那么你真正交互内容的过程在外界看来和HTTPS没什么大区别,只是流量比较大而已。

  3. Anyconnect可以只基于TCP,也可以通过TCP完成连接、认证等必要步骤后使用DTLS/UDP进行真正的数据通信。其实,在可以使用UDP的环境下,还是尽量要使用UDP,因为,TCP实在是太过“沉重”了,并不适合VPN的应用,尤其是如果VPN基于TCP的话,那么TCP over TCP的情况将会经常产生,这是非常低效的……(虽然PPTP也是这么干的……但还是不吐槽了)

  4. Ocserv的运行只需要系统对TUN/TAP的支持,所以OVZ用户也存在使用Ocserv的可能。

基于以上四点,再加上OpenWRT可以直接通过OpenConnect直接与Ocserv服务连接,所以,目前我的主要维护优良上网环境的方式就是它了。下面是Debian系Linux配置Ocserv的重点步骤。

Step 0. 如果你用的是Ubuntu的话,只要更新好了就可以忽略此步骤;如果你用的是Debian Wheezy的话,那么一定要在 /etc/apt/sources.list后加上wheezy-backports的源:

deb http://ftp.us.debian.org/debian/ wheezy-backports main contrib non-free

当然,上面的源地址可以根据你的喜好更改。

Step 1. 到了这里,我们要安装编译Ocserv必要的东西了:

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

(注:如果wheezy下出现找不到包的情况,请在apt-getinstall间加上-t wheezy-backports

Step 2. 先到 ftp://ftp.infradead.org/pub/ocserv/ 上确认目前 Ocserv 的最新版本,然后将网址复制下来,到服务器上进行下载、解压、编译、安装:

wget ftp://ftp.infradead.org/pub/ocserv/ocserv-0.9.0.1.tar.xz
tar Jxvf ocserv-0.9.0.1.tar.xz
cd ocserv-0.9.0/
./configure --prefix=/usr --sysconfdir=/etc
make
sudo make install

如果上述Step 1.做好了的话,这里应该不会出现任何错误的……

Step 3. 进行Ocserv的配置。首先,在你执行make的目录中执行:

sudo mkdir /etc/ocserv
cp doc/sample.config /etc/ocserv/ocserv.conf

接下来就按照文件中的注释去修改/etc/ocserv/ocserv.conf文件吧……

如果使用用户证书认证的话,你需要把生成用户证书的跟证书放在配置文件的ca-certificate属性中,并在上面的认证配置中选择证书认证。

如果你使用的是plain认证,那么你可以通过ocpasswd来生成对应的密钥文件:

ocpasswd -c /path/to/.ocpasswd <username>

当然,Ocserv为SSLVPN,所以,你需要证书。如果是自签名证书的话其实很麻烦的……所以推荐使用StartSSL的免费证书。只要别忘了把StartSSL的Intermediate证书和CA证书放在你的证书后面就好,即你的证书(不是密钥)中的内容顺序是:证书-Intermediate-CA。然后就好好设置server-certserver-key属性。

当然,还有一个重要的地方是,为了实现全局路由,并不能直接route=0.0.0.0/0.0.0.0解决,而需要拆分成route=0.0.0.0/128.0.0.0route=128.0.0.0/128.0.0.0才可以,这样会避免一些过于奇妙的情况。

配置文件中还可以选择监听端口,虚拟地址段等等。这些都可以自己通过注释去配置。

Step 4. 创建对应的守护进程脚本,放在/etc/init.d/ocserv

#!/bin/sh
### BEGIN INIT INFO
# Provides:          ocserv
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO
# Copyright Rene Mayrhofer, Gibraltar, 1999
# This script is distibuted under the GPL
 
PATH=/bin:/usr/bin:/sbin:/usr/sbin
DAEMON=/usr/sbin/ocserv
PIDFILE=/var/run/ocserv.pid
DAEMON_ARGS="-c /etc/ocserv/ocserv.conf"
 
case "$1" in
start)
if [ ! -r $PIDFILE ]; then
echo -n "Starting OpenConnect VPN Server Daemon: "
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS > /dev/null
echo "ocserv."
else
echo -n "OpenConnect VPN Server is already running.\n\r"
exit 0
fi
;;
stop)
echo -n "Stopping OpenConnect VPN Server Daemon: "
start-stop-daemon --stop --quiet --pidfile $PIDFILE --exec $DAEMON
echo "ocserv."
rm -f $PIDFILE
;;
force-reload|restart)
echo "Restarting OpenConnect VPN Server: "
$0 stop
sleep 1
$0 start
;;
status)
if [ ! -r $PIDFILE ]; then
# no pid file, process doesn't seem to be running correctly
exit 3
fi
PID=`cat $PIDFILE | sed 's/ //g'`
EXE=/proc/$PID/exe
if [ -x "$EXE" ] &&
[ "`ls -l \"$EXE\" | cut -d'>' -f2,2 | cut -d' ' -f2,2`" = \
"$DAEMON" ]; then
# ok, process seems to be running
exit 0
elif [ -r $PIDFILE ]; then
# process not running, but pidfile exists
exit 1
else
# no lock file to check for, so simply return the stopped status
exit 3
fi
;;
*)
echo "Usage: /etc/init.d/ocserv {start|stop|restart|force-reload|status}"
exit 1
;;
esac
 
exit 0

之后需要做的事情就是chmod +x /etc/init.d/ocserv设置运行权限,以及update-rc.d ocserv defaults设置开机自动启动,还有service ocserv start启动服务了。

Step 5. 设置转发和防火墙。首先要将/etc/sysctl.conf中的net.ipv4.ip_forward=1前的注释去掉,执行sysctl -p,这样开启内核转发。

接下来防火墙设置就是:iptables -t nat -A POSTROUTING -s <你定义的网段的CIDR表示> -o eth0 -j MASQUERADE。如果使用的是OVZ的话,那么iptables的设置应该是这样的:iptables -t nat -A POSTROUTING -s <配置VPN时定义的网段CIDR> -j SNAT --to-source <你的服务器外网IP>

现在应该一切妥当了……