首页 > Linux > VPS上基于Debian搭建和配置ocserv(兼容Cisco AnyConnect客户端)

VPS上基于Debian搭建和配置ocserv(兼容Cisco AnyConnect客户端)

2014年9月24日 LTNS     访问次数 263 发表评论 阅读评论

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-clibhttp-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\FIPSAlgorithmPolicyEnabled键值(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-clibhttp-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-clibhttp-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

 

分类: Linux 标签: , , , , , , ,
  1. robay
    2015年3月12日15:17 | #1

    很感激博主的分享,我按此教程,配置成功,谢谢

  2. Houseware
    2015年5月6日15:15 | #2

    楼主,你好。我用的最新的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

    不知道问题出在哪儿。请楼主帮忙看看啊。

    • LTNS
      2015年5月7日22:49 | #3

      似乎是Ubuntu系统缺少tun模块,问下你的vps服务商是否启用了该模块吧

  3. Houseware
    2015年5月8日22:26 | #4

    谢谢,可能还与我安装过不同的版本有关,重装系统之后折腾了很久已解决。我用的4.0版的客户端,发现其实不存在你说的问题。@LTNS

  4. Kung
    2015年7月23日19:02 | #5

    您好,我已经顺利的在服务器上安装了服务端,同时在windows上也可以连接,但是连接成功后系统提示无Internet访问权,无法打开任何网站,查看适配器,分到的IP和网管都是正确的。
    请问是什么原因呢?

  5. LTNS
    2015年7月29日22:57 | #6

    @Kung
    请问用的是哪个windows客户端?建议先检查一下服务端的NAT设置、推送的DNS,等等

  1. 2015年1月4日01:46 | #1
1 * 7 = (必填)