Openconnect服务部署

Openconnect服务器(ocserv)是一个SSL VPN服务器,适用于需要细致进行用户管理和控制。Openconnect服务器提供企业环境中所需的用户管理界面和后端,以及安全功能,例如隔离连接的客户端,以及现有VPN服务器都不具备的功能

它是如何工作的? design.png

个人理解与WireGuard对比,它的验证更为丰富,更为精确的支持为每个客户端或客户端组设置资源限制,带宽,网络优先级等。但这并不是说ocserv要比WireGuard要好,主要还是看使用场合吧,在一个多用户(甚至超过2000人)办公场合,对于管理员来说前者显然是更好的选择;而对于需要连接到有N多云服务器的环境来说,WireGuard要更好。两者都是非常安全且实用的工具,不同点只是使用场景不一而已,所以也记录一下ocserv服务的部署吧。

ocserv-new.png

安装

  • 包管理器

可以通过编译或者包管理器进行安装,截止目前,Ubuntu 18.04.2 LTS默认源的版本为0.11.9,而debian源的版本相对较新。

通过包管理器可以快速的安装,只需使用命令

1
2
sudo apt-get update
sudo apt-get install ocserv

即可完成安装。

  • 源码编译

本人使用的是Ubuntu,因为想使用官方最新版本,所以只有通过编译源码的方式进行。

下载 官方提供FTP服务进行下载,当然了也可以到gitlab拉取源码,或者根据tag进行下载。 截止当前最新发布的版本为0.12.3

1
2
wget ftp://ftp.infradead.org/pub/ocserv/ocserv-0.12.3.tar.xz
tar Jxf ocserv-0.12.3.tar.xz

依赖安装 准备编译环境,需要安装一些依赖:

1
2
3
4
sudo apt-get install build-essential pkg-config \
libgnutls28-dev libev-dev \
libpam0g-dev liblz4-dev libseccomp-dev libreadline-dev \
liboath-dev

编译 配置编译

1
2
cd ocserv-0.12.3
./configure && make && make check

上面的命令包含编译后的测试,测试结果理论上不应该含错误信息,例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
============================================================================
Testsuite summary for ocserv 0.12.3
============================================================================
# TOTAL: 47
# PASS:  14
# SKIP:  33
# XFAIL: 0
# FAIL:  0
# XPASS: 0
# ERROR: 0
============================================================================

下一步使用sudo make install进行安装即可.

安装的工具包含

  1. ocserv: /usr/local/sbin/ocserv 主服务应用程序
  2. occtl: /usr/local/bin/occtl 服务器的控制工具。允许用户查询服务器的信息
  3. ocpasswd: /usr/local/bin/ocpasswd 一个管理简单密码文件的工具

启动文件

默认的systemd文件没有被安装,它在如下位置:

1
2
./doc/systemd/standalone/ocserv.service
./doc/systemd/socket-activated/ocserv.service

当使用standalone文件时

1
2
sudo cp ./doc/systemd/standalone/ocserv.service /lib/systemd/system/
sudo systemctl enable ocserv

而socket模式时,端口会被init占用并一直保留,直到将其socket也停止后才被释放。 当我刚开始使用包管理器安装并开启服务时,检查ocserv默认443端口返回是这样的: sudo netstat -ntlp | grep :443 tcp6 0 0 :::443 :::* LISTEN 1/init

而当使用sudo systemctl stop ocserv后,被提示 Warning: Stopping ocserv.service, but it can still be activated by: ocserv.socket

使用命令行方式启用被提示端口被占用,查看443端口依旧是上面的结果。

这里正确的终止命令应该是sudo systemctl stop ocserv.socket 如果要使用这种模式请这样复制systemd文件

1
2
sudo cp ./doc/systemd/socket-activated/ocserv* /lib/systemd/system/
sudo systemctl enable ocserv.socket

或者,习惯使用init方式的,使用这个脚本即可

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
sudo sh -c 'umask 077; cat > /etc/init.d/ocserv' <<EOF
#! /bin/sh
### BEGIN INIT INFO
# Provides:		ocserv
# Required-Start:	$remote_fs $syslog dbus
# Required-Stop:	$remote_fs $syslog dbus
# Default-Start:	2 3 4 5
# Default-Stop:		0 1 6
# Short-Description:	OpenConnect SSL VPN server
# Description:          secure, small, fast and configurable OpenConnect SSL VPN server
### END INIT INFO
set -e

NAME=ocserv
DESC="OpenConnect SSL VPN server"

DAEMON=/usr/sbin/ocserv
DAEMON_CONFIG=/etc/${NAME}/${NAME}.conf
DAEMON_PIDFILE=/var/run/${NAME}.pid
DAEMON_ARGS="--pid-file $DAEMON_PIDFILE --config $DAEMON_CONFIG"

test -x $DAEMON || exit 0

umask 022

. /lib/lsb/init-functions

export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"

daemon_start()
{
    if [ ! -s "$DAEMON_CONFIG" ]; then
        log_failure_msg "please create ${DAEMON_CONFIG}, not starting..."
        log_end_msg 1
        exit 0
    fi
    log_daemon_msg "Starting $DESC" "$NAME" || true
    if start-stop-daemon --start --quiet --oknodo --pidfile $DAEMON_PIDFILE --exec $DAEMON -- $DAEMON_ARGS ; then
        log_end_msg 0 || true
    else
	log_end_msg 1 || true
    fi
}

case "$1" in
  start)
    daemon_start
    ;;
  stop)
    log_daemon_msg "Stopping $DESC" "$NAME" || true
    if start-stop-daemon --stop --quiet --oknodo --pidfile $DAEMON_PIDFILE; then
	    log_end_msg 0 || true
	else
	    log_end_msg 1 || true
	fi
	;;

  reload|force-reload)
	log_daemon_msg "Reloading $DESC" "$NAME" || true
	if start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile $DAEMON_PIDFILE --exec $DAEMON; then
	    log_end_msg 0 || true
	else
	    log_end_msg 1 || true
	fi
	;;

  restart)
	log_daemon_msg "Restarting $DESC" "$NAME" || true
	start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile $DAEMON_PIDFILE
        daemon_start
	;;

  try-restart)
	log_daemon_msg "Restarting $DESC" "$NAME" || true
	RET=0
	start-stop-daemon --stop --quiet --retry 30 --pidfile $DAEMON_PIDFILE || RET="$?"
	case $RET in
	    0)
		# old daemon stopped
                daemon_start
		;;
	    1)
		# daemon not running
		log_progress_msg "(not running)" || true
		log_end_msg 0 || true
		;;
	    *)
		# failed to stop
		log_progress_msg "(failed to stop)" || true
		log_end_msg 1 || true
		;;
	esac
	;;

  status)
	status_of_proc -p $DAEMON_PIDFILE $DAEMON $NAME && exit 0 || exit $?
	;;

  *)
	log_action_msg "Usage: /etc/init.d/$NAME {start|stop|reload|force-reload|restart|try-restart|status}" || true
	exit 1
esac

exit 0
EOF
sudo sh -c "chmod +x /etc/init.d/ocserv"

默认证书

即将编辑的配置文件当中,需要使用到CA证书以及服务器秘钥和证书,在刚开始配置的时候可以先使用默认的证书。 从编译目录拷贝到指定目录当中:

1
2
3
4
sudo mkdir -p  /etc/ocserv/certs
sudo cp ./tests/certs/ca.pem /etc/ocserv/certs
sudo cp ./tests/certs/server-cert-ca.pem /etc/ocserv/certs
sudo cp ./tests/certs/server-key.pem /etc/ocserv/certs

配置文件

同样的,配置文件也没有被安装。你可以在./doc/sample.config找到它,官网的文档首页也提供了一个标准的配置文件。 这里简略掉了说明直接写入配置文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
sudo cp ./doc/profile.xml /etc/ocserv
sudo sh -c 'umask 077; cat > /etc/ocserv/ocserv.conf' <<EOF
auth = "pam[gid-min=1000]"
# TCP and UDP port number
tcp-port = 443
udp-port = 443
run-as-user = nobody
run-as-group = daemon
#使用haproxy时取消注释
#listen-clear-file = /var/run/ocserv-conn.socket
socket-file = ocserv.sock
chroot-dir = /etc/ocserv
server-cert = /etc/ocserv/certs/server-cert-ca.pem
server-key = /etc/ocserv/certs/server-key.pem
ca-cert = /etc/ocserv/certs/ca.pem
isolate-workers = true
banner = "Welcome~"
max-clients = 16
max-same-clients = 2
#使用haproxy时取消注释
#listen-proxy-proto = true
keepalive = 32400
dpd = 90
mobile-dpd = 1800
switch-to-tcp-timeout = 25
try-mtu-discovery = true
cert-user-oid = 2.5.4.3
compression = true
no-compress-limit = 256
#禁用tls1.0和1.1
tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1"
auth-timeout = 240
min-reauth-time = 12
max-ban-score = 50
ban-reset-time = 300
cookie-timeout = 300
persistent-cookies = true
deny-roaming = false
rekey-time = 172800
rekey-method = ssl
use-utmp = true
use-occtl = true
pid-file = /var/run/ocserv.pid
device = vpns
predictable-ips = true
default-domain = 2333.lvmoo.com
ipv4-network = 192.168.7.0
ipv4-netmask = 255.255.255.0
dns = 192.168.7.2
ping-leases = false
route = 10.10.10.0/255.255.255.0
route = 192.168.0.0/255.255.0.0
no-route = 192.168.5.0/255.255.255.0
cisco-client-compat = true
dtls-legacy = true
#user-profile = profile.xml
[vhost:vpn.lvmoo.com]
auth = "plain[passwd=/etc/ocserv/ocserv.passwd]"
server-cert = /etc/ocserv/certs/server-cert-ca.pem
server-key = /etc/ocserv/certs/server-key.pem
ca-cert = /etc/ocserv/certs/ca.pem
ipv4-network = 192.168.8.0
ipv4-netmask = 255.255.255.0
cert-user-oid = 0.9.2342.19200300.100.1.1
EOF

至此,配置文件告一段落。

转发&防火墙设置

进行到这,使用客户端进行连接后通常来说,依旧无法正常使用的。 因为系统默认是不打开转发的,可以使用以下方式查看转发状态: 执行sysctl net.ipv4.ip_forward 或者cat /proc/sys/net/ipv4/ip_forward 又或者sudo sysctl -a | grep ip_forward 返回值为0的话就代表转发状态被关闭了。

可以临时修改设置检查联通性sudo sysctl -w net.ipv4.ip_forward=1 当然推荐修改配置永久修改状态

1
2
sed -i '/net.ipv4.ip_forward.*/d;$a\net.ipv4.ip_forward = 1' /etc/sysctl.conf
sysctl -p

而后修改防火墙NAT设置等,注意网络接口

1
2
3
4
sudo iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -I INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -I INPUT -p udp --dport 443 -j ACCEPT

这样,就算配置完成了

测试&启动

完成了以上全部环节之后,在启动前可以先做一个测试,以便排查某个步骤出现的问题:

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

返回的日志当中不应当出现error信息,否则你可能需要根据报错信心排查问题了。

一切就绪之后通过sudo systemctl start ocserv即可启动服务了。

occtl的使用

关于occtl的使用可以查看官方的文档

使用occtl show users列出当前的用户连接状态 使用occtl --json show usersjson格式打印最为详细的连接信息。

Licensed under CC BY-NC-SA 4.0
最后更新于 Jul 15, 2019 16:39 UTC
点击刷新🚌