Debian下安装配置Ocserv搭建Cisco Anyconnect的开源服务端

本文编写于3592天前,最后编辑于 2898天前,部分内容可能已经过时,请您自行斟酌确认。

Ocserv(OpenConnect Server)是由GnuTLS的作者Nikos Mavrogiannopoulos开发的一个能够兼容Cisco Anyconnect的开源服务端(SSL VPN),支持*nix/BSD平台,最早是作为OpenConnect(Linux下的兼容Cisco ASA的开源客户端)对应的服务端,在后续版本(0.3.0开始)中加入了对Cisco Anyconnect客户端的支持。测试平台为Debian7.5
一.ocserv使用GnuTLS作为SSL的library,所以编译时需要对应的dev包。Debian stable里面带的版本太老(2.12.20),而ocserv需要的包版本在3.1.10以上,所以需要从backports安装:

vim /etc/apt/sources.list

添加如下

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

或者使用如下命令

echo "deb http://ftp.debian.org/debian wheezy-backports main contrib non-free" >> /etc/apt/sources.list

然后

apt-get update && apt-get -t wheezy-backports install libgnutls28-dev

安装依赖包

apt-get install libgmp3-dev m4 gcc pkg-config make gnutls-bin build-essential libwrap0-dev libpam0g-dev libdbus-1-dev libreadline-dev libnl-route-3-dev libprotobuf-c0-dev libpcl1-dev libopts25-dev autogen libseccomp-dev liblz4-dev git build-essential -y

安装freeradius-client

git clone https://github.com/FreeRADIUS/freeradius-client.git
cd freeradius-client
./configure --sysconfdir=/etc && make && make install
echo "/usr/local/lib" >> /etc/ld.so.conf
ldconfig

顺便把freeradius-client的配置文件复制过来,因为安装过pptp的freeradius插件所以直接复制过来

mkdir /etc/radiusclient/
cp /usr/local/radius/etc/radiusclient/radiusclient.conf /etc/radiusclient/
cp /usr/local/radius/etc/radiusclient/dictionary /etc/radiusclient/
cp /usr/local/radius/etc/radiusclient/servers /etc/radiusclient/

也可以重新配置

cat >>/etc/radiusclient/servers<<EOF
radius.enshi.us   testing123
EOF
sed -i 's/localhost/radius.enshi.us/g' /etc/radiusclient/radiusclient.conf

安装LZ4

wget https://github.com/Cyan4973/lz4/archive/r127.tar.gz
tar zxvf r127.tar.gz
cd lz4-r127
make && make install

安装Ocserv,目前最新版为0.10.4

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

1111111111111111111111111111111111111111111111111111111111111111111111111
生成CA证书和服务端证书

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

cat << _EOF_ > ca.tmpl
cn = "VPN CA"
organization = "AEVPN 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 >>server.tmpl<<EOF
cn = "www.aevpn.com"
organization = "AEVPN"
serial = 2
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

生成之后把服务器证书和私钥放到/etc/ocserv。
1111111111111111111111111111111111111111111111111111111111111111111111111

 mkdir /etc/ocserv

cp ca-cert.pem /etc/ocserv
cp ca-key.pem /etc/ocserv
cp server-cert.pem /etc/ocserv
cp server-key.pem /etc/ocserv

证书部分现在使用startssl的免费证书,把生成的证书ssl.crt,ssl.key上传到/etc/ocserv.

cd /etc/ocserv
wget http://cert.startssl.com/certs/ca.pem
wget http://cert.startssl.com/certs/sub.class1.server.ca.pem
cat ssl.crt > server-cert.pem
cat sub.class1.server.ca.pem >> /etc/ocserv/server-cert.pem
cat ca.pem >> /etc/ocserv/server-cert.pem

接下来是配置文件,建立/etc/ocserv并把doc/sample.config拷到该文件夹下,改名为ocserv.conf:

cp doc/sample.config /etc/ocserv/ && mv /etc/ocserv/sample.config /etc/ocserv/ocserv.conf
编辑配置文件

vim /etc/ocserv/ocserv.conf

修改如下
server-cert和server-key分别指向之前生成的证书和服务器私钥。run-as-group改为nogroup。
ipv4-network为分配客户端的子网网段,比如ipv4-network=192.168.1.0即为192.168.1.1-255的子网。(配合子网掩码) dns为推送给客户端的dns。
route为推送给客户端的路由表,如果采用split-tunnel-policy tunnelall模式(所有流量通过VPN)的话删掉该行即可。
user-profile改为user-profile = /etc/ocserv/profile.xml,并且去掉cisco-client-compat = true的注释。
pam验证的话需要系统里有着这个账户.

auth = "plain[/etc/ocserv/ocpasswd]"
#ocserv支持多种认证方式,这是自带的密码认证,使用ocpasswd创建密码文件
#ocserv还支持证书认证,可以通过Pluggable Authentication Modules (PAM)使用radius等认证方式,0.9.0版本支持原生的radius验证,需要安装freeradius-client

#证书路径
server-cert = /etc/ocserv/server-cert.pem
server-key = /etc/ocserv/ssl.key
ca-cert = /etc/ocserv/ca.pem

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

#运行组
run-as-group = nogroup

#分配给VPN客户端的IP段
ipv4-network = 10.11.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

几个需要注意的地方

1. isolate-workers 要设置成 false,如果为true,windows客户端很难连接成功
2. try-mtu-discovery = true建议打开。
3. predictable-ips 设置成 false,如果为true,同用户名分配的ipv6地址是相同的

1111111111111111111111111111111111111111111111111111111111111111111111111
这里使用PAM连接到radius做认证,所以去掉auth = "pam"前面的注释并且注释掉auth = "plain[./sample.passwd]"。
安装PAM Radius:

apt-get install libpam0g-dev libpam-radius-auth

然后建立/etc/pam.d/ocserv:

# PAM Configuration for OpenConnect Server
# Created by tony, 11/13/13
# This is designed to work with RADIUS PAM Module
auth    required        /lib/security/pam_radius_auth.so

同时需要建立/etc/pam_radius_auth.conf:

#  pam_radius_auth configuration file.  Copy to: /etc/raddb/server
#
#  For proper security, this file SHOULD have permissions 0600,
#  that is readable by root, and NO ONE else.  If anyone other than
#  root can read this file, then they can spoof responses from the server!
#
#  There are 3 fields per line in this file.  There may be multiple
#  lines.  Blank lines or lines beginning with '#' are treated as
#  comments, and are ignored.  The fields are:
#
#  server[:port] secret [timeout]
#
#  the port name or number is optional.  The default port name is
#  "radius", and is looked up from /etc/services The timeout field is
#  optional.  The default timeout is 3 seconds.
#
#  If multiple RADIUS server lines exist, they are tried in order.  The
#  first server to return success or failure causes the module to return
#  success or failure.  Only if a server fails to response is it skipped,
#  and the next server in turn is used.
#
#  The timeout field controls how many seconds the module waits before
#  deciding that the server has failed to respond.
#
# server[:port] shared_secret      timeout (s)
localhost       yourradiusserversecret  5

#
# having localhost in your radius configuration is a Good Thing.
#
# See the INSTALL file for pam.conf hints.

里面填写连接到radius服务器使用的secret。
1111111111111111111111111111111111111111111111111111111111111111111111111
0.9.0版本配置文件示例

auth = "radius[/etc/radiusclient/radiusclient.conf,groupconfig]"
isolate-workers = false
max-clients = 50
max-same-clients = 2
tcp-port = 443
udp-port = 10443
listen-clear-file = /var/run/ocserv-conn.socket
stats-report-time = 360
keepalive = 32400
dpd = 90
mobile-dpd = 1800
try-mtu-discovery = true
server-cert = /etc/ocserv/server-cert.pem
server-key = /etc/ocserv/ssl.key
ca-cert = /etc/ocserv/ca.pem
compression = true
no-compress-limit = 256
tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0"
auth-timeout = 40
idle-timeout = 1200
mobile-idle-timeout = 2400
cookie-timeout = 86400
deny-roaming = false
rekey-time = 172800
rekey-method = ssl
use-utmp = true
use-occtl = true
pid-file = /var/run/ocserv.pid
socket-file = /var/run/ocserv-socket
run-as-user = nobody
run-as-group = nogroup
device = vpns
predictable-ips = false
default-domain = jp5.enshi.us
ipv4-network = 10.11.0.0
ipv4-netmask = 255.255.255.0
dns = 168.95.192.1
ipv6-network = fda9:4efe:7e3b:03ea::/64
ping-leases = false
route = 192.168.1.0/255.255.255.0
route = 101.0.0.0/255.0.0.0
route = 103.0.0.0/255.0.0.0
route = 106.0.0.0/255.0.0.0
route = 107.0.0.0/255.0.0.0
route = 108.0.0.0/255.0.0.0
route = 109.0.0.0/255.0.0.0
route = 117.0.0.0/255.0.0.0
route = 125.0.0.0/255.0.0.0
route = 128.0.0.0/255.0.0.0
route = 141.0.0.0/255.0.0.0
route = 153.0.0.0/255.0.0.0
route = 160.0.0.0/255.0.0.0
route = 166.0.0.0/255.0.0.0
route = 168.0.0.0/255.0.0.0
route = 17.0.0.0/255.0.0.0
route = 173.0.0.0/255.0.0.0
route = 174.0.0.0/255.0.0.0
route = 176.0.0.0/255.0.0.0
route = 178.0.0.0/255.0.0.0
route = 184.0.0.0/255.0.0.0
route = 190.0.0.0/255.0.0.0
route = 192.0.0.0/255.0.0.0
route = 194.0.0.0/255.0.0.0
route = 198.0.0.0/255.0.0.0
route = 199.0.0.0/255.0.0.0
route = 203.0.0.0/255.0.0.0
route = 204.0.0.0/255.0.0.0
route = 205.0.0.0/255.0.0.0
route = 206.0.0.0/255.0.0.0
route = 208.0.0.0/255.0.0.0
route = 209.0.0.0/255.0.0.0
route = 210.0.0.0/255.0.0.0
route = 216.0.0.0/255.0.0.0
route = 220.0.0.0/255.0.0.0
route = 23.0.0.0/255.0.0.0
route = 3.0.0.0/255.0.0.0
route = 31.0.0.0/255.0.0.0
route = 4.0.0.0/255.0.0.0
route = 46.0.0.0/255.0.0.0
route = 50.0.0.0/255.0.0.0
route = 54.0.0.0/255.0.0.0
route = 58.0.0.0/255.0.0.0
route = 59.0.0.0/255.0.0.0
route = 61.0.0.0/255.0.0.0
route = 63.0.0.0/255.0.0.0
route = 64.0.0.0/255.0.0.0
route = 67.0.0.0/255.0.0.0
route = 68.0.0.0/255.0.0.0
route = 69.0.0.0/255.0.0.0
route = 70.0.0.0/255.0.0.0
route = 72.0.0.0/255.0.0.0
route = 73.0.0.0/255.0.0.0
route = 74.0.0.0/255.0.0.0
route = 75.0.0.0/255.0.0.0
route = 76.0.0.0/255.0.0.0
route = 77.0.0.0/255.0.0.0
route = 78.0.0.0/255.0.0.0
route = 79.0.0.0/255.0.0.0
route = 8.0.0.0/255.0.0.0
route = 92.0.0.0/255.0.0.0
route = 93.0.0.0/255.0.0.0
route = 96.0.0.0/255.0.0.0
route = 97.0.0.0/255.0.0.0
cisco-client-compat = true
user-profile = /etc/ocserv/profile.xml

ocserv的配置文件到这里就算修改完毕了,然后是/etc/ocserv/profile.xml:

nano /etc/ocserv/profile.xml
<?xml version="1.0" encoding="UTF-8"?>
<AnyConnectProfile xmlns="http://schemas.xmlsoap.org/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/encoding/ AnyConnectProfile.xsd">

<ClientInitialization>
<AutoUpdate>true</AutoUpdate>
<BypassDownloader>true</BypassDownloader>
<UseStartBeforeLogon>false</UseStartBeforeLogon>
<StrictCertificateTrust>false</StrictCertificateTrust>
<RestrictPreferenceCaching>false</RestrictPreferenceCaching>
<RestrictTunnelProtocols>IPSec</RestrictTunnelProtocols>
<CertEnrollmentPin>pinAllowed</CertEnrollmentPin>
<CertificateMatch>
<KeyUsage>
<MatchKey>Digital_Signature</MatchKey>
</KeyUsage>
<ExtendedKeyUsage>
<ExtendedMatchKey>ClientAuth</ExtendedMatchKey>
</ExtendedKeyUsage>
</CertificateMatch>
</ClientInitialization>

<ServerList>
<HostEntry>
<HostName>Server Profile Name</HostName>
<HostAddress>server.ip.address</HostAddress>
</HostEntry>
</ServerList>
</AnyConnectProfile>

防火墙设置这里就不说了!

iptables -A FORWARD -s 10.11.0.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.11.0.0/24 -o eth0 -j MASQUERADE
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
iptables -A FORWARD -o vpns+ -j ACCEPT
iptables -A FORWARD -i vpns+ -j ACCEPT
iptables-save > /etc/iptables.up.rules

建立系统启动加载文件

cat >>/etc/network/if-pre-up.d/iptables<<EOF
#!/bin/bash
/sbin/iptables-restore < /etc/iptables.up.rules
EOF

给予执行权限

chmod +x /etc/network/if-pre-up.d/iptables

启动脚本

nano /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设成开机启动。DAEMON_ARGS中可以加入--http-debug -d来打开调试信息。
最后在iptables中打开tcp和udp的443端口即可。ocserv使用tcp的443端口认证,udp用于传输数据。

Debug

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

下发路由

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

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

所以我们只能保证下某几个常用的服务是可用的,比如 Google Facebook 以及 Twitter
你可以使用以下路由表,把这些复制到里面。 保存后重新启动 VPN 服务器,就可以了。

/etc/init.d/ocserv restart

编辑配置文件

sudo vim /etc/ocserv/ocserv.conf

找到 route = 的字段

route = 8.0.0.0/255.0.0.0
route = 58.0.0.0/255.0.0.0
route = 23.0.0.0/255.0.0.0
route = 117.0.0.0/255.0.0.0
route = 199.0.0.0/255.0.0.0
route = 190.0.0.0/255.0.0.0
route = 198.0.0.0/255.0.0.0
route = 173.0.0.0/255.0.0.0
route = 174.0.0.0/255.0.0.0
route = 168.0.0.0/255.0.0.0
route = 69.0.0.0/255.0.0.0
route = 128.0.0.0/255.0.0.0
route = 107.0.0.0/255.0.0.0
route = 109.0.0.0/255.0.0.0
route = 101.0.0.0/255.0.0.0
route = 141.0.0.0/255.0.0.0
route = 192.0.0.0/255.0.0.0
route = 72.0.0.0/255.0.0.0
route = 176.0.0.0/255.0.0.0
route = 78.0.0.0/255.0.0.0
route = 73.0.0.0/255.0.0.0
route = 74.0.0.0/255.0.0.0
route = 208.0.0.0/255.0.0.0
route = 205.0.0.0/255.0.0.0
route = 206.0.0.0/255.0.0.0
route = 210.0.0.0/255.0.0.0
route = 220.0.0.0/255.0.0.0
route = 216.0.0.0/255.0.0.0
route = 54.0.0.0/255.0.0.0
route = 50.0.0.0/255.0.0.0
route = 59.0.0.0/255.0.0.0
route = 63.0.0.0/255.0.0.0
#route = 66.0.0.0/255.0.0.0
route = 92.0.0.0/255.0.0.0
route = 93.0.0.0/255.0.0.0
route = 97.0.0.0/255.0.0.0
route = 96.0.0.0/255.0.0.0
route = 125.0.0.0/255.0.0.0

你也可以自行通过 nslookup

nslookup www.google.com

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

开机启动

sed -i '$i\/etc/init.d/ocserv restart' /etc/rc.local

本位抄袭自出处1出处2

Debian下安装配置Ocserv搭建Cisco Anyconnect的开源服务端》上有 6 条评论

  1. monk monk

    执行 cat ssl.crt > server-cert.pem 提示没有ssl.crt这个文件。这是咋会儿了,一步步下来之,前面步骤都没问题,到这里卡住了。怎么弄?

    回复

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注