前言
在多年以前曾写过《Openconnect服务部署》,和《Openconnect密码认证》、《Openconnect证书认证》,但未曾写过调用Radius来做认证。
现在公司的VPN使用的是飞塔防火墙的解决方案,拨入困难是一个点;拨入使用的VPN账户密码模式(公用且长期不修改账户密码)则是更大的安全隐患。
目前已有了微软AD服务,考虑部署ocserv作为接入公司内网VPN,鉴于账户密码能少一个是一个的原则,于是就有了ocserv使用Radius认证,Radius再接入到AD。这样,登录VPN就可以使用AD的账户密码了。
因为操作的过程还是踩了不少坑的,故整理记录📝一下,这个需求毕竟还是比较常见的。
环境
- 操作系统 : Ubuntu 22.04.1 LTS
- ocserv : 1.1.6(写文时的最新版本)
- freeradius : 3.0.26 (apt直接安装)
ocserv与freeradius安装在同一台服务器上,AD则是先有的一台Windows Server 2012 R2服务器。
安装kay用户有sudo
权限(向来是不推荐直接使用root用户操作的)
安装
安装在《Openconnect服务部署》一文已经写的很清楚了,考虑到是2019年写的,还是重新记录一下。
依赖安装
直接使用apt-get
安装。
1
2
3
4
5
6
7
8
9
10
|
# Required
sudo apt-get install -y libgnutls28-dev libev-dev
# Optional functionality and testing
sudo apt-get install -y libpam0g-dev liblz4-dev libseccomp-dev \
libreadline-dev libnl-route-3-dev libkrb5-dev libradcli-dev \
libcurl4-gnutls-dev libcjose-dev libjansson-dev libprotobuf-c-dev \
libtalloc-dev libhttp-parser-dev protobuf-c-compiler gperf \
nuttcp lcov libuid-wrapper libpam-wrapper libnss-wrapper \
libsocket-wrapper gss-ntlmssp iputils-ping freeradius \
gawk gnutls-bin iproute2 yajl-tools tcpdump
|
源码包准备
最新的源码包可以在官网查看,1.1.6是写文时的最新版本。
进行下载和解压缩。
1
2
3
4
5
6
|
cd /tmp
wget https://www.infradead.org/ocserv/download/ocserv-1.1.6.tar.xz
#wget https://www.infradead.org/ocserv/download/ocserv-1.1.6.tar.xz.sig
#gpg --verify ocserv-1.1.6.tar.xz.sig ocserv-1.1.6.tar.xz
#使用.sig签名验证文件不是必须的步骤
tar Jxvf ocserv-1.1.6.tar.xz
|
编译源码
上面我们已经下载好了源码并且解压缩成功,接下来进行源码编译,并进行测试。
默认安装在/usr/local/bin
,如果要自定义安装路径请使用--prefix
指定。
1
2
3
4
|
cd ocserv-1.1.6
./configure
make && make check
sudo make install
|
在编译和测试后无误,进行安装。
可以看到二进制文件分别安装在了/usr/local/bin
和/usr/local/sbin
,特别注意的是ocserv
是安装在后者的目录。
配置
freeradius配置
ldap配置
freeradius的默认ldap配置文件如下,需要修改处进行了注释解释
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
|
sudo cat /etc/freeradius/3.0/mods-available/ldap | grep -Ev '#|^$'
ldap {
server = '192.168.xxx.xxx' #修改为AD服务器地址
port = 389 #AD端口号默认389
identity = 'cn=Administrator,cn=Users,dc=lvmoo,dc=com' #指定域控账户
password = DemoPassWord #域控账户密码
base_dn = 'dc=lvmoo,dc=com'
sasl {
}
update {
control:Password-With-Header += 'userPassword'
control: += 'radiusControlAttribute'
request: += 'radiusRequestAttribute'
reply: += 'radiusReplyAttribute'
}
edir = no #取消注释此行内容
user_dn = "LDAP-UserDn"
user {
base_dn = "${..base_dn}"
filter = "(samaccountname=%{%{Stripped-User-Name}:-%{User-Name}})" #使用AD的话uid修改为samaccountname
sasl {
}
}
group {
base_dn = "${..base_dn}"
filter = '(objectClass=posixGroup)'
membership_attribute = 'memberOf'
}
profile {
}
client {
base_dn = "${..base_dn}"
filter = '(objectClass=radiusClient)'
template {
}
attribute {
ipaddr = 'radiusClientIdentifier'
secret = 'radiusClientSecret'
}
}
accounting {
reference = "%{tolower:type.%{Acct-Status-Type}}"
type {
start {
update {
description := "Online at %S"
}
}
interim-update {
update {
description := "Last seen at %S"
}
}
stop {
update {
description := "Offline at %S"
}
}
}
}
post-auth {
update {
description := "Authenticated at %S"
}
}
options {
chase_referrals = yes
rebind = yes
res_timeout = 10
srv_timelimit = 3
net_timeout = 1
idle = 60
probes = 3
interval = 3
ldap_debug = 0x0028
}
tls {
}
pool {
start = ${thread[pool].start_servers}
min = ${thread[pool].min_spare_servers}
max = ${thread[pool].max_servers}
spare = ${thread[pool].max_spare_servers}
uses = 0
retry_delay = 30
lifetime = 0
idle_timeout = 60
}
}
|
修改好ldap配置文件后需要软连接到mods-enabled目录下
1
2
|
sudo bash -c "cd /etc/freeradius/3.0/mods-enabled/ && \
ln -sv ../mods-available/ldap ldap"
|
ldap站点配置
ldap配置修改好后,还需要新建一个ldap站点配置,用这个站点配置暴露出的端口对外服务。
(freeradius默认使用1812和1812两个UDP端口对外服务。)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
sudo bash -c "cat <<EOF > /etc/freeradius/3.0/sites-available/site_ldap
server site_ldap {
listen {
ipaddr = 0.0.0.0
port = 1833
type = auth
}
authorize {
update {
control:Auth-Type := ldap
}
}
authenticate {
Auth-Type ldap {
ldap
}
}
post-auth {
Post-Auth-Type Reject {
}
}
}
EOF"
|
然后软链接到sites-enabled目录下
1
2
|
sudo bash -c "cd /etc/freeradius/3.0/sites-enabled/ && \
ln -sv ../sites-available/site_ldap site_ldap"
|
Radius clients.conf配置修改
freeradius的默认client配置文件如下,需要修改处进行了注释解释。
(默认配置允许客户端从127.0.0.1发起认证,目前环境不做修改。)
⚠️如果radius和ocserv部署在不同的服务器或者radius还需要给其他服务提供认证,此处应该要添加一个client,具体可以看此配置文件,里面有很多示例!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
sudo cat /etc/freeradius/3.0/clients.conf | grep -Ev '#|^$'
client localhost {
ipaddr = 127.0.0.1 #被认证可以访问的ip地址
proto = *
secret = testing123
require_message_authenticator = no
limit {
max_connections = 16
lifetime = 0
idle_timeout = 30
}
}
client localhost_ipv6 {
ipv6addr = ::1
secret = testing123
}
|
Radius 测试认证账户配置修改
此处配置一个测试账户密码,以验证Radius配置无误。在第88行处有一个bob用户,取消注释即可打开bob账户认证。
1
2
3
4
5
6
7
8
9
10
11
|
sudo cat /etc/freeradius/3.0/users | grep -Ev '#|^$'
bob Cleartext-Password := "hello" # 取消注释
Reply-Message := "Hello, %{User-Name}" # 取消注释
DEFAULT Framed-Protocol == PPP
Framed-Protocol = PPP,
Framed-Compression = Van-Jacobson-TCP-IP
DEFAULT Hint == "CSLIP"
Framed-Protocol = SLIP,
Framed-Compression = Van-Jacobson-TCP-IP
DEFAULT Hint == "SLIP"
Framed-Protocol = SLIP
|
测试认证功能
到此为止,已经配置好了freeradius
,建议先将freeradius
服务停掉,开一个tmux
来进行测试Debug。
1
2
3
4
|
#freeradius服务debug模式开启
sudo systemctl stop freeradius
sudo freeradius -X
radtest bob hello localhost 0 testing123
|
可以看到bob账户是认证通过✅的,返回了Received Access-Accept Id 226 from 127.0.0.1:1812 to 127.0.0.1:52726 length 32
。
如果是认证失败返回的则是Received Access-Reject Id 154 from 127.0.0.1:1812 to 127.0.0.1:43777 length 32
。
同理再使用AD账户密码做测试认证。
1
2
3
4
5
6
7
8
9
|
radtest kay.li Password 127.0.0.1:1833 0 testing123
Sent Access-Request Id 26 from 0.0.0.0:41861 to 127.0.0.1:1833 length 76
User-Name = "kay.li"
User-Password = "Password"
NAS-IP-Address = 127.0.1.1
NAS-Port = 0
Message-Authenticator = 0x00
Cleartext-Password = "Password"
Received Access-Accept Id 26 from 127.0.0.1:1833 to 127.0.0.1:41861 length 20
|
测试通过的话代表以上的安装以及配置都是没有问题的。
ocserv使用radius认证配置
以上步骤顺利结束后,来到了本文的重头戏ocserv
配置使用radius服务。
主要分为两个部分,一个是ocserv
本身的配置文件配置(包含内核转发以及防火墙设置)以及radiusclient
的配置。
ocserv配置文件
默认你还处于编译安装的路径,可以在以下路径复制demo配置文件(根据具体情况进行调优,比如更换为自己的证书。)
1
2
3
4
5
|
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
sudo cp ./doc/sample.config /etc/ocserv/ocserv.conf
|
关键配置,依据自身情况进行配置。
1
|
auth = "radius[config=/etc/radcli/radiusclient.conf,groupconfig=true]"
|
1
2
3
|
server-cert = ../tests/certs/server-cert.pem
server-key = ../tests/certs/server-key.pem
ca-cert = ../tests/certs/ca.pem
|
1
2
3
4
5
|
route = 10.10.10.0/255.255.255.0
route = 192.168.0.0/255.255.0.0
#route = fef4:db8:1000:1001::/64
#route = default
no-route = 192.168.5.0/255.255.255.0
|
ocserv systemd配置
开机自启动
(注意⚠️,ocserv.service
内部的ocserv路径需要修改成与安装位置一致)
1
2
|
sudo cp ./doc/systemd/standalone/ocserv.service /lib/systemd/system/
sudo systemctl enable ocserv
|
内核与防火墙设置
打开IPv4的转发(其他内核优化不在这里说了)以及防火墙规则设定,防火墙规则请注意更换为自身配置的端口以及网卡。
1
2
3
4
5
6
|
sudo sed -i '/net.ipv4.ip_forward.*/d;$a\net.ipv4.ip_forward = 1' /etc/sysctl.conf
sudo sysctl -p
sudo iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
sudo iptables -t nat -A POSTROUTING -o ens160 -j MASQUERADE
sudo iptables -I INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -I INPUT -p udp --dport 443 -j ACCEPT
|
radiusclient配置修改
修改authserver
的端口,为上面配置的ldap_site
端口。
1
2
3
4
5
6
7
8
9
|
cat /etc/radcli/radiusclient.conf | grep -Ev '#|^$'
authserver 127.0.0.1:1833
acctserver 127.0.0.1
servers /etc/radcli/servers
dictionary /etc/radcli/dictionary
default_realm
radius_timeout 10
radius_retries 3
bindaddr *
|
ocserv Debug测试
配置完成之后,进行Debug测试一遍,向上使用tmux
过程相似。
1
|
sudo ocserv -c /etc/ocserv/ocserv.conf -f -d 1
|
Anyconnect
客户端配置当前服务器的信息后,使用AD账户密码进行验证即可。
验证通过后,即可关闭Debug模式。
开启服务
到这一步,可以开启freeradius和ocserv正式对外服务了。
1
2
|
sudo systemctl start freeradius
sudo systemctl start ocserv
|
本次记录完毕!