VPS上基于Debian搭建和配置ocserv(兼容Cisco AnyConnect客户端)
OpenConnect server (ocserv) 是一个开源的 SSL VPN服务器,使用 GnuTLS作为 SSL library,但 Debian 7 stable 里的 GnuTLS版本太旧,需要先升级至 2.15以上的版本。
如果在用的 VPS操作系统是 Debian 6,需要先把 Xen VPS从Debian 6 (Squeeze)升级到Debian 7 (Wheezy),然后用 WinSCP登录 VPS修改一下 /etc/apt/sources.list 文件里的源,添加如下一行
deb http://ftp.debian.org/debian wheezy-backports main contrib non-free
然后用 Putty 登录 VPS,安装 GnuTLS
apt-get update #更新一下软件源
apt-get -t wheezy-backports install libgnutls28-dev
下载并解压 ocserv源代码压缩包
cd /usr/src
wget ftp://ftp.infradead.org/pub/ocserv/ocserv-0.8.4.tar.xz
tar Jxvf ocserv-0.8.4.tar.xz
cd ocserv-0.8.4
编译前先进行配置,为了更清晰地显示出错信息,可把配置结果导出为一个临时文件如 /tmp/config,我这里提示缺少六个软件包
./configure --prefix=/usr --sysconfdir=/etc > /tmp/config
#反馈如下出错内容
root@(none):/usr/src/ocserv-0.8.4# ./configure --prefix=/usr --sysconfdir=/etc > /tmp/config
configure: WARNING:
***
*** autogen not found. Will not link against libopts.
***
configure: WARNING: ***
*** libprotobuf-c was not found.
***
configure: WARNING: ***
*** libtalloc was not found.
***
configure: WARNING: ***
*** libreadline or editline was not found. occtl will not be built.
***
configure: WARNING:
***
*** libhttp-parser not found.
*** An included version of the library will be used.
***
configure: WARNING:
***
*** libpcl (portable co-routines) was not found.
*** An included version of the library will be used.
***
于是根据参考文章安装依赖包
apt-get install libgmp3-dev m4 gcc pkg-config make gnutls-bin
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
重新配置,还是如上面一样的出错提示,继续安装依赖包
apt-get install libreadline-dev libpcl1-dev autogen libtalloc-dev
还是提示缺少 libprotobuf-c 和 libhttp-parser 这两个软件包,实在搞不定于是放弃(已解决,见本文末尾2015.01.03的更新)。继续编译和安装,没有提示 error但还是会有 warning,继续无视
make && make install
按照 官网教程 制作证书
cd
certtool --generate-privkey --outfile ca-key.pem
cat << _EOF_ >ca.tmpl
cn = "VPN CA"
organization = "Big Corp"
serial = 1
expiration_days = 9999
ca
signing_key
cert_signing_key
crl_signing_key
_EOF_
certtool --generate-self-signed --load-privkey ca-key.pem --template ca.tmpl --outfile ca-cert.pem
certtool --generate-privkey --outfile server-key.pem
cat << _EOF_ >server.tmpl
cn = "www.example.com"
organization = "MyCompany"
expiration_days = 9999
signing_key
encryption_key
tls_www_server
_EOF_
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
复制证书到指定的目录
cp server-cert.pem /etc/ssl/certs/
cp server-key.pem /etc/ssl/private/
生成 ocserv的配置文件
cd /usr/src/ocserv-0.8.4
mkdir /etc/ocserv && cp doc/sample.config /etc/ocserv/ && mv /etc/ocserv/sample.conf /etc/ocserv/ocserv.conf
根据 参考文章2修改配置文件 /etc/ocserv/ocserv.conf ,没有启用 PAM radius,下面列出我修改过的地方
#auth = "plain[./sample.passwd]"
auth = "plain[/etc/ocserv/ocpasswd]"
#auth = "pam"
...
#max-clients = 1024
max-clients = 16
...
#max-same-clients = 2
max-same-clients = 10
...
# TCP and UDP port number
tcp-port = 443
udp-port = 443
...
#server-cert = ../tests/server-cert.pem
#server-key = ../tests/server-key.pem
server-cert = /etc/ssl/certs/server-cert.pem
server-key = /etc/ssl/private/server-key.pem
...
#run-as-group = daemon
run-as-group = nogroup
...
# The pool of addresses that leases will be given from.
#ipv4-network = 192.168.1.0
ipv4-network = 10.10.0.0
ipv4-netmask = 255.255.255.0
...
# dns = fc00::4be0
#dns = 192.168.1.2
dns = 8.8.8.8
dns = 208.67.222.222
...
#route = 192.168.1.0/255.255.255.0
#route = 192.168.5.0/255.255.255.0
#route = fef4:db8:1000:1001::/64
添加用户名和密码,根据提示设置密码
ocpasswd -c /etc/ocserv/ocpasswd 用户名
运行如下命令实现 NAT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p udp --dport 443 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -o eth0 -j MASQUERADE
iptables -A FORWARD -s 10.10.0.0/24 -j ACCEPT
echo 1 > /proc/sys/net/ipv4/ip_forward
还要将如上五行添加到 /etc/rc.local文件里(添加在 exit 0那一行之前),以避免VPS重启后NAT功能失效。
现在可以调试运行一下
ocserv -c /etc/ocserv/ocserv.conf -f -d 1
正常的话就用 ctrl+c 组合键中断程序,用 WinSCP新建一个启动脚本 /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
设成开机自启动,最后重启系统
update-rc.d ocserv defaults
reboot
当然还可以在 /etc/rc.local文件中添加一行 ocserv服务端重启命令
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p udp --dport 443 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -o eth0 -j MASQUERADE
iptables -A FORWARD -s 10.10.0.0/24 -j ACCEPT
echo 1 > /proc/sys/net/ipv4/ip_forward
/etc/init.d/ocserv restart
顺便提一下,我在 Nexus 4(4.4.4)上使用 Cisco官方的 Android客户端,通过联通3G的话会提示出错“无法应用系统配置设置..” ,改用wifi走电信宽带就正常了,而换成 客户端OpenConnect 的话则都正常,Cisco官方的 iOS客户端、AnyConnect Secure Mobility Client 也都正常。
补充1:
ocserv服务端默认使用端口 TCP 443 和 UDP 443,可以在配置文件 /etc/ocserv/ocserv.conf 中自定义然后重启服务端,在客户端访问时只需在服务器栏里填入“VPS的公网ip或域名:端口”的格式即可。
补充2:
可以在 ocserv服务端配置路由推送,以便在如未越狱的iOS设备上实现自动分流翻WALL,只需在配置文件 /etc/ocserv/ocserv.conf 中添加一行或多行 “route = ip网段/子网掩码”,除访问相应的ip会走vpn通道之外,其余的流量还是走平时的通道(而如果没有设置过路由,则默认所有的流量都会走vpn通道,会明显影响访问国内网站的速度)。
ocserv服务端默认最多只能推送64条路由,不过按 这篇帖子 里的方法可以自定义。用 WinSCP 登录VPS,在源代码目录下的 src/vpn.h文件中找到如下的一行并修改掉默认的64(过大的数值可能会出错,按该帖子评论里的说法,iOS客户端 最多只能接受200条推送的路由)。
...
#define MAX_CONFIG_ENTRIES 64
修改完成后重新编译安装 ocserv,然后在配置文件 /etc/ocserv/ocserv.conf 中添加相应的路由,该帖子作者也提供了其个人维护的路由表供参考,已搬运到 这里 供下载。另外,这里 也有人提供了路由表供参考。
对于 Windows等平台的客户端(Android平台需要先root、iOS要先越狱),除了由 ocserv服务端推送之外,还可以在客户端本地自行加载更多的路由表。
最后,可能需要在客户端的设置里启用 “VPN FIPS Mode”,有时 ocserv服务端推送的 DNS无法正确解析域名(可用 ping等命令检查),导致推送的路由表亦不能发挥作用。
2015.01.02更新
Android或iOS等客户端在设置中启用 FIPS Mode很方便,而对于 Cisco官网的 AnyConnect Secure Mobility Client 客户端程序则要稍麻烦些,在win7环境里安装后需要修改 C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\AnyConnectLocalPolicy.xml 这个文件以启用 FIPS Mode,不过这样会造成最新版的 V4.0.00048启动时闪退,V3.1.06073则正常。
另外,按照 cisco官网的说明,启用 FIPS Mode之后比如 win7系统会自动修改注册表 HKLM\System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy 的 Enabled键值(0变成1),导致连接WinXP的RDP Server的话会提示 fips出错(连接win7的RDP Server则不受影响,无论NLA是否开启),注册表参数改回0就正常了,不过这时 AnyConnect Secure Mobility Client 启动又会出错,只能来回切换。
这时如果再把 AnyConnect Secure Mobility Client 从V3.1升级到 V4.0,则在启用 FIPS Mode的情况下不会闪退,似乎是 V4.0无法让 win7自动修改注册表的缘故?
2015.01.03更新
这篇文章 提到编译时提示缺少 libprotobuf-c 和 libhttp-parser 这两个软件包的解决办法,需要在 /etc/apt/sources.list 文件里添加如下一行
deb ftp://ftp.debian.org/debian/ jessie main contrib non-free
为防止已安装的软件包被更新至 backports 或者 jessie 版本,还需新建 /etc/apt/preferences这个文件,内容如下
Package: *
Pin: release wheezy
Pin-Priority: 900
Package: *
Pin: release wheezy-backports
Pin-Priority: 90
Package: *
Pin: release jessie
Pin-Priority: 60
现在可以安装 libprotobuf-c 和 libhttp-parser 这两个软件包了
apt-get update #更新一下软件源
apt-get -t jessie install libprotobuf-c-dev libhttp-parser-dev
最后重新编译安装 ocserv即可。
参考文章
1. http://luoqkk.com/linode-vps-debian-installation-and-configuration-ocserv-openconnect-server.html
2. http://aenes.com/post/716.html
3. http://www.infradead.org/ocserv/manual.html
4. http://www.v2ex.com/t/136431
很感激博主的分享,我按此教程,配置成功,谢谢
楼主,你好。我用的最新的Ocserv-0.10.4,无论在Win7下用OpenConnect,Cisco Anyconnect Secure Mobility Client连接,还是在安卓中用AnyConnect连接,服务端都出现形如这样的:
……
……
ocserv[1645]: main: tun.c:342: Can't open /dev/net/tun: No such file or directory
ocserv[1645]: main: *.*.*.*:52122 failed authentication attempt for user 'yuzhexie'
ocserv[1645]: main: *.*.*.*:52122 sending message 'auth cookie reply' to worker
ocserv[1690]: worker: *.*.*.*:52122 received auth reply message (value: 3)
ocserv[1690]: worker: *.*.*.*:52122 error receiving cookie authentication reply
ocserv[1690]: worker: *.*.*.*:52122 failed cookie authentication attempt
ocserv[1645]: main: *.*.*.*:52122 main-misc.c:423: command socket closed
ocserv[1645]: main: *.*.*.*:52122 removing client 'yuzhexie' with id '1690'
ocserv[1645]: warning: can't get client address: Connection reset by peer
ocserv[1691]: worker: *.*.*.*:25535 accepted connection
ocserv[1691]: GnuTLS error (at worker-vpn.c:734): The TLS connection was non-properly terminated.
ocserv[1645]: main: *.*.*.*:25535 main-misc.c:423: command socket closed
ocserv[1645]: main: *.*.*.*:25535 removing client '' with id '1691'
ocserv[1692]: worker: *.*.*.*:36847 accepted connection
ocserv[1692]: worker: *.*.*.*:36847 sending message 'resume data fetch request' to main
ocserv[1645]: main: *.*.*.*:36847 main received message 'resume data fetch request' of 34 bytes
ocserv[1645]: main: *.*.*.*:36847 TLS session DB resuming 58470f8431fbdbeb8451784ff09bdd1e60db1c987b5a0ddbd8e06289b77fdfb9
ocserv[1645]: main: *.*.*.*:36847 sending message 'resume data fetch reply' to worker
ocserv[1692]: worker: *.*.*.*:36847 TLS handshake completed
ocserv[1692]: worker: *.*.*.*:36847 received sid: HnPXgsT9Vhx+3DeF
ocserv[1692]: worker: *.*.*.*:36847 User-agent: 'AnyConnect Windows 4.0.02052'
ocserv[1692]: worker: *.*.*.*:36847 sent sid: HnPXgsT9Vhx+3DeF
ocserv[1645]: main: *.*.*.*:36847 main-misc.c:423: command socket closed
ocserv[1645]: main: *.*.*.*:36847 removing client '' with id '1692'
……
……
我的系统是Ubuntu14.04,配置文件如下:
auth = "plain[/etc/ocserv/ocpasswd]"
tcp-port = 4343
udp-port = 4343
run-as-user = nobody
run-as-group = nogroup
socket-file = /var/run/ocserv-socket
isolate-workers = false
max-clients = 16
max-same-clients = 10
keepalive = 32400
dpd = 90
mobile-dpd = 1800
try-mtu-discovery = true
server-cert = /etc/ssl/certs/server-cert.pem
server-key = /etc/ssl/private/server-key.pem
ca-cert = /etc/ssl/certs/ca-cert.pem
cert-user-oid = 0.9.2342.19200300.100.1.1
tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0"
auth-timeout = 40
max-ban-score = 50
ban-reset-time = 300
cookie-timeout = 86400
deny-roaming = false
rekey-time = 172800
rekey-method = ssl
use-occtl = true
pid-file = /var/run/ocserv.pid
net-priority = 5
device = vpns
predictable-ips = true
default-domain = example.com
ipv4-network = 10.10.0.0
ipv4-netmask = 255.255.255.0
dns = 8.8.8.8
dns = 208.67.220.220
ping-leases = false
no-route = 192.168.5.0/255.255.255.0
cisco-client-compat = true
不知道问题出在哪儿。请楼主帮忙看看啊。
似乎是Ubuntu系统缺少tun模块,问下你的vps服务商是否启用了该模块吧
谢谢,可能还与我安装过不同的版本有关,重装系统之后折腾了很久已解决。我用的4.0版的客户端,发现其实不存在你说的问题。@LTNS
您好,我已经顺利的在服务器上安装了服务端,同时在windows上也可以连接,但是连接成功后系统提示无Internet访问权,无法打开任何网站,查看适配器,分到的IP和网管都是正确的。
请问是什么原因呢?
@Kung
请问用的是哪个windows客户端?建议先检查一下服务端的NAT设置、推送的DNS,等等