一、Ocserv简介
Openconnect VPN服务端简称ocserv(Openconnect VPN Server),ocserv是一款开源的,兼容Cisco Anyconnect VPN的VPN服务端软件。目前状况下通讯较为稳定,干扰较小。主要优势是多平台的支持,Windows、Android、iOS都能找到它的客户端。
二、方案概述
2-1、方案拓扑图
2-2、部署目标
实现PC(Windows)、苹果电脑(Mac OS)、苹果手机(iOS)、安卓手机(Android)通过AnyConnect或者OpenConnect客户端拨通VPN后,获取到内网IPv4及IPv6地址,且通过内网三层路由网络,实现校园网内部互访及图书馆数据库资源访问。
2-3、部署内容
部署操作系统环境为CentOS7.4,双网口,ocserv版本为0.11.8,两个网卡分别连接内网及外网;其后安装ocserv并做个性化配置,调整系统参数,实现IPv4及IPv6数据转发,添加策略路由,将ocserv中客户端流量转发至内网,其后调整内部路由实现互访,内网访问策略可实现与其它内网用户业务地址一致。
三、部署过程
3-1、安装ocserv
查看系统版本
cat /etc/redhat-release |
ocserv已经在epel源提供,直接yum安装对应软件包。
yum install epel-release -y yum install ocserv -y |
安装完毕后使用命令检查安装。
ocserv -v |
设置开机自动启动
chkconfig ocserv on |
3-2、证书配置
anyconnect使用ssl证书来进行加密,ocserv也使用此方法。除了ca证书之外,还有服务端证书和客户端登陆用的证书,这里使用密码验证来完成客户端登陆。而ca证书和服务端证书使用自签方式(由于ca证书自签,客户端登陆时将提示不受信任的服务器。如果需要合法的ca证书,请需寻找信誉良好的ca证书颁发机构进行签发)。
仔细阅读官方文档,简单的来说,如下几步:
创建文件夹
[root@openconnect ~]# mkdir anyconnect [root@openconnect ~]# cd anyconnect |
生成 CA 证书
[root@openconnect anyconnect]# certtool --generate-privkey --outfile ca-key.pem Generating a 2048 bit RSA private key... [root@openconnect anyconnect]# cat >ca.tmpl <<EOF > cn ="VPN CA" > organization = "SUN YAT-SEN UNIVERSITY" > serial = 1 > expiration_days = 3650 > ca > signing_key > cert_signing_key > crl_signing_key > EOF [root@openconnect anyconnect]# certtool --generate-self-signed --load-privkey ca-key.pem --template ca.tmpl --outfile ca-cert.pem |
把生成的 ca-cert.pem 复制放到 /etc/ocserv/ 中。
生成本地服务器证书
[root@openconnect anyconnect]# certtool --generate-privkey --outfile server-key.pem Generating a 2048 bit RSA private key... [root@openconnect anyconnect]# cat >server.tmpl <<EOF > cn = "202.116.99.6" //cn为ocserv服务器 > organization = "SUN YAT-SEN UNIVERSITY" > serial = 2 > expiration_days = 3650 > encryption_key > signing_key > tls_www_server > EOF [root@openconnect anyconnect]# 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 |
把生成的 server-cert.pem 和 server-key.pem 复制放到 /etc/ocserv/ 中。
生成客户端证书
创建 gen-client-cert.sh
[root@openconnect anyconnect]# vi gen-client-cert.sh #!/bin/bash USER=$1 CA_DIR=$2 SERIAL=`date +%s` certtool --generate-privkey --outfile $USER-key.pem cat << _EOF_ >user.tmpl cn = "$USER" unit = "admins" serial = "$SERIAL" expiration_days = 365 signing_key tls_www_client _EOF_ certtool --generate-certificate --load-privkey $USER-key.pem --load-ca-certificate $CA_DIR/ca-cert.pem --load-ca-privkey $CA_DIR/ca-key.pem --template user.tmpl --outfile $USER-cert.pem openssl pkcs12 -export -inkey $USER-key.pem -in $USER-cert.pem -name "$USER VPN Client Cert" -certfile $CA_DIR/ca-cert.pem -out $USER.p12 [root@openconnect anyconnect]# chmod +x gen-client-cert.sh |
创建用户文件夹并调用 gen-client-cert.sh 生成证书。
[root@openconnect anyconnect]# mkdir user [root@openconnect anyconnect]# cd user [root@openconnect user]# ../gen-client-cert.sh user001 .. |
按提示设置证书使用密码,或直接回车不设密码。
3-3、配置ocserv
vim /etc/ocserv/ocserv.conf |
以下是需要修改的部分
这里的auth即指使用何种方式进行用户登陆验证,其中plain为ocserv自带的密码验证,需要通过ocserv的相关命令来添加用户(其实是按一定格式保存到文件里,是一种纯文本的用户记录方式)。radius方式即需要使用的方式,在此先使用plain方式,通过分步测试来确保每一步都可以检查是否正确。
auth = "plain[passwd=/etc/ocserv/ocpasswd]" |
对外服务端口配置,这里采用默认的TCP及UDP 443端口。
tcp-port = 443 udp-port = 443 |
证书颁发机构,将被用来验证客户端证书(公钥)如果证书身份验证设置。
ca-cert = /etc/ocserv/ca-cert.pem |
服务端证书路径,这两个路径推荐如下所示,这样便于集中管理ocserv有关文件。如果你之前生成证书后拷贝到了其他位置,请使用证书的实际位置作为设置。
server-cert = /etc/ocserv/server-cert.pem server-key = /etc/ocserv/server-key.pem |
该选项指定本服务端最大可以同时接入的连接数量,设置为0表示无限制(依然会受到linux最大用户可打开文件数限制)。推荐值1024。
max-clients = 1024 |
相同的账户可同时连接上限。这个选项可以限制同一个用户可同时使用的设备数量。设置为0表示无限制。
max-same-clients = 2 |
以下是虚拟网卡设置。包括虚拟网卡名和IPv4/v6地址池以及子网掩码,接下来将会在其他设置中用到。
IPv4:
device = vpns ipv4-network = 192.168.174.0 ipv4-netmask = 255.255.255.0 |
IPv6:
ipv6-network = 2001:250:3002:02c0::/64 |
配置所有DNS解析通过VPN隧道。
tunnel-all-dns = true |
配置分配给客户端的DNS。
dns = 114.114.114.114 |
打开 PMTUD(自动优化VPN的网络性能)。
try-mtu-discovery = true |
注释掉所有的 route,让服务器成为 gateway。
#route = 192.168.1.0/255.255.255.0 |
针对用户个性化配置目录,取消注释可在该目录下添加用户个性化配置文件,以用户名为文件名保存,可添加dns、nbns、ipv4/v6-network、ipv4-netmask、rx/tx-per-sec、iroute、route、no-route、explicit-ipv4、explicit-ipv6、net-priority、deny-roaming、no-udp、user-profile、cgroup、stats-report-time、session-timeout等参数格式同主配置文件。
config-per-user = /etc/ocserv/config-per-user/ |
保存设置文件,接下来执行bash命令添加ocserv本地用户。
ocpasswd -c /etc/ocserv/ocpasswd user002 |
其中 -c 参数后面是密码文件的路径。后面的user002是用户名。回车后输入两次密码以完成添加。添加完成后将在指定的目录出现ocpasswd文件,这就是保存密码用的文件。
其它参数调优。
max-clients = 250 keepalive = 32400 dpd = 45 mobile-dpd = 60 auth-timeout = 180 min-reauth-time = 10 ban-reset-time = 100 cookie-timeout = 3600 persistent-cookies = true |
3-4、系统配置
3-4-1、内核配置
关于涉及数据包转发(在此次配置不采用nat方式),在linux上使用内核转发效率是最高的,因此ocserv也采用此方案。为此我们需要确认当前操作系统已开启内核转发功能。
vim /etc/sysctl.conf |
打开该文件后检查是否存在以下两行,使系统支持IPv4/v6数据转发。
net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding=1 |
若没有,添加到文件末尾。保存。然后重载配置文件。
sysctl -p |
确认ipv4内核转发已开启
cat /proc/sys/net/ipv4/ip_forward cat /proc/sys/net/ipv6/conf/all/forwarding |
若值为1,表示内核转发已开启。接下来不使用service来执行ocserv,而直接运行ocserv以查看实时输出。
3-4-2、IP配置
添加IPv4/v6网络支持修改/etc/sysconfig/network文件(默认支持)。
NETWORKING=yes NETWORKING_IPV6=yes |
修改IP地址,这里两个网络端口配置文件名分别为ens160及ens192。
修改用于外网端口的配置文件/etc/sysconfig/network-scripts/ifcfg-ens160。
NAME=ens160 GATEWAY=202.116.99.1 DNS1=114.114.114.114 DOMAIN=sysu.edu.cn DEVICE=ens160 ONBOOT=yes USERCTL=no BOOTPROTO=static NETMASK=255.255.255.0 IPADDR=202.116.99.6 PEERDNS=no |
修改用于内网端口的配置文件/etc/sysconfig/network-scripts/ifcfg-ens192,这里添加与内网三层设备IPv4/v6互联地址。
TYPE=Ethernet BOOTPROTO=none DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6ADDR=fd00:102c::ff02/126 IPV6_DEFAULTGW=fd00:102c::ff01 IPV6_AUTOCONF=no #IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=ens192 DEVICE=ens192 ONBOOT=yes IPADDR=10.00.44.202 PREFIX=30 IPV6_PRIVACY=no PROXY_METHOD=none BROWSER_ONLY=no ZONE=trusted |
重启网络服务使配置文件生效。
systemctl restart network |
3-4-3、策略路由配置
将所有源地址为192.168.174.0/24及2001:250:3002:02c0::/64的网段下一跳指向内网端口10.00.44.201及fd00:102c::ff01。
手动在终端输入以下命令使路由生效,并在etc/rc.d/rc.local添加以下命令试其开机自动执行。
ip rule add from 192.168.174.0/24 table 100 ip route add 0.0.0.0/0 via 10.0.44.201 table 100
ip rule add from 10.0.44.202/32 table 101 ip route add 0.0.0.0/0 via 10.0.44.201 table 101
ip -6 rule add from 2001:250:3002:02c0::/64 table 200 ip -6 route add ::/0 via fd00:102c::ff01 table 200
ip link set em1 txqueuelen 10000 |
修改etc/rc.d/rc.local文件权限使其可执行
chmod 754 /etc/rc.d/rc.local |
在对端网络设备做回指路由,试VPN客户端获取到的地址段可以正常访问内部网络。
4-4、防火墙配置
创建一个ocserv服务防火墙配置文件
vim /etc/firewalld/services/ocserv.xml <?xml version="1.0" encoding="utf-8"?> <service> <short>ocserv</short> <description>Cisco AnyConnect</description> <port protocol="tcp" port="443"/> <port protocol="udp" port="443"/> </service> |
启动firewalld
systemctl start firewalld firewall-cmd --permanent --add-service=ocserv firewall-cmd --permanent --add-rich-rule 'rule family=ipv4 source address=202.116.98.0/24 service name=ssh log prefix="ssh" level=info accept' --zone=public //配置允许SSH连接服务器的IP段,减小安全风险。 firewall-cmd --permanent --remove-service=ssh --zone=public //删除允许所有网段SSH远程。 firewall-cmd --permanent --zone=trusted --add-interface=ens192 //将内网口ens192口加入可信区域。 firewall-cmd --set-default-zone=trusted //将默认区域改为trusted区域,这样客户端拨通VPN在服务器建立的虚拟网卡vpn0、vpn1、vpn2……区域属于“no zone”,使用默认区域trusted区域规则,否则DNS无法通过VPN隧道进行解析。 firewall-cmd --reload firewall-cmd --get-default-zone //查看默认区域 firewall-cmd --get-active-zones //查看活动区域 |
假如采用NAT模式需要执行firewall-cmd --permanent --add-masquerade --zone=public,这里不需要。
查看所有打开端口
firewall-cmd --list-all --zone=public firewall-cmd --list-all --zone=trusted firewall-cmd --get-zone-of-interface=vpns0 //当拨通VPN后可查看虚拟网卡所在区域 |
4-5、调试ocserv
ocserv -f -d 1 |
其中 -f 参数表示前台运行,-d 参数表示debug等级。通过这种方式,如果设置有错误将立即看到错误输出。之所以放到screen里,是因为接下来还需要做其他事情,而为了不中断ocserv,因此在screen中运行。一般情况下ocserv应该已经成功运行并有输出了。
启动ocserv服务,并加入开机启动。
systemctl start ocserv systemctl enable ocserv systemctl is-enabled ocserv //查看是否假如开机启动 |
4-6、对接freeradius
4-6-1、配置freeradius服务器
在另外一台centos服务器上搭建radius服务,这里采用开源的freeradius
freeradius用来提供用户验证功能,搭建freeradius然后调整ocserv设置以使其使用radius作为用户身份验证模块。freeradius分为两部分,客户端和服务端。ocserv通过调用freeradius客户端对连接者进行身份验证。
freeradius服务端与ocserv不需要在同一台服务器上。freeradius客户端必须在ocserv服务器上。同样的,mysql数据库也不需要和freeradius在同一台服务器上。下面的示例中,采取的网络架构是三台服务器 ocserv服务器(安装有ocserv,freeradius client)、freeradius服务器(安装有freeradius server)、mysql服务器(安装有mysql)。
在freeradius服务器安装freeradius服务端。
yum install freeradius |
安装完毕后使用
radiusd -v |
若看到版本号信息说明安装成功。
配置freeradius并测试
首先使用freeradius的默认设置,即文本形式记录用户的用户名和密码。测试freeradius的工作是否正常,再测试ocserv调用freeradius是否正常,最后再设置freeradius使用mysql来读取用户记录。
freeradius的保存用户的文本在 /etc/raddb/users文件
在第一行插入如下内容后保存
[用户名] Cleartext-Password := "[密码为用户密码]"
这里,新建了一个用户,用户名为user003,密码为user003mima。新建一个screen并以调试模式运行radiusd
radiusd -X |
退出screen,然后使用freeradius的调试工具进行测试,首先安装它
yum install freeradius-utils |
执行以下命令
radtest [用户名] [密码为用户密码] [radius服务器地址] [服务器端口] [服务器对应密钥]
如:radtest user003 mima localhost 0 secret
如果看到 Received Access-Accept 字样说明验证成功。如果看到 Received Access-Reject 说明验证失败。
首先打开设置文件
vim /etc/raddb/clients.conf |
找到client localhost,测试工具之所以能正确访问freeradius服务端,是因为默认设置下,localhost已被加入这份设置,即localhost可以访问freeradius服务端。
#ipaddr = 127.0.0.1 |
修改为
ipv4addr = * # any. 127.0.0.1 == localhost |
允许任何ipv4地址访问freeradius服务端(这在实际生产环境中是不安全的,生产环境中请仔细配置每一个客户端设置)。
添加将要到freeradius认证的客户端(即ocserv)信息。
client ocserv { ipaddr = 202.116.99.6 require_message_authenticator = no shortname = ocserv secret = secret123 } |
4-6-2、配置freeradius客户端
在ocserv服务器上安装freeradius客户端
下载freeradius-client源码包
这里我们使用的包为:freeradius-client-1.1.7.tar.gz
tar -zxvf freeradius-client-1.1.7.tar.gz cd freeradius-client-1.1.7 |
安装依赖包:
yum install gcc gcc-c++ -y ./configure make -j2 && make install |
现在在ocserv服务器上安装freeradius客户端
yum install freeradius-client |
为了测试freeradius服务端在这台服务器上也可以访问,在这台服务器上也安装测试工具并进行测试(假设freeradius服务器地址为202.116.97.116)
yum install freeradius-utils radtest user004 user004mima 202.116.97.116 secret123 |
打开freeradius客户端设置文件
vim /usr/local/etc/radiusclient/radiusclient.conf |
将认证及计费服务器更换为202.116.97.116。
authserver 202.116.97.116 acctserver 202.116.97.116 |
打开freeradius客户端的服务器设置
vim /usr/local/etc/radiusclient/servers |
添加以下内容至最后一行
202.116.97.116 secret123 |
保存这份文件。自此, freeradius客户端需要做的设置。接下来让ocserv使用freeradius作为验证模块
修改ocserv配置文件
vim /etc/ocserv/ocserv.conf |
修改验证方式设置,注释原来的认证方式,修改为radius认证。
#auth = "plain[passwd=/etc/ocserv/ocpasswd]" auth = "radius[config=/usr/local/etc/radiusclient/radiusclient.conf,groupconfig=true]" |
使ocserv使用freeradius来进行用户验证。
4-6-3、配置freeradius数据库
安装mariadb
yum intsall mariadb |
freeradius与mariadb的对接
安装freeradius-mysql组件
yum install freeradius-mysql |
激活和启动mariadb服务
systemctl enable mariadb systemctl start mariadb systemctl status mariadb |
创建数据库
mysql -u root -p |
要求输入密码时,直接回车即可。
mysql>create database radius; mysql>grant all on radius.* to radius@localhost identified by "radpass"; mysql>exit; 导入表结构 mysql -u root radius < /etc/raddb/mods-config/sql/main/mysql/scheama.sql |
上面的指令,共导入了7个表,分别是:
radcheck 用户检查信息表
radreply 用户回复信息表
radgroupcheck 用户组检查信息表
radgroupreply 用户组检查信息表
radusergroup 用户和组关系表
radacct 计费情况表
radpostauth 认证后处理信息,可以包括认证请求成功和拒绝的记录。
建立组信息和用户信息
输入mysql -u root radius,打开数据库,在 mysql> 提示符下,执行如下命令:
建立组信息:(在此新建组名称为user)
insert into radgroupreply (groupname,attribute,op,value) values ('user','Auth-Type',':=','Local'); insert into radgroupreply (groupname,attribute,op,value) values ('user','Service-Type',':=','Framed-User'); insert into radgroupreply (groupname,attribute,op,value) values ('user','Framed-IP-Address',':=','255.255.255.255'); insert into radgroupreply (groupname,attribute,op,value) values ('user','Framed-IP-Netmask',':=','255.255.255.0'); |
建立用户信息:(在此新建用户名为user005,密码为user005mima)
insert into radcheck (username,attribute,op,value) values ('user005','Cleartext-Password',':=',' user005mima'); |
将用户加入组中:
insert into radusergroup (username,groupname) values ('user005','user005'); |
修改 Freeradius中的mysql 认证配置
cd /etc/raddb/mods-enabled ln -s ../mods-available/sql |
修改 Freeradius中的mysql 配置文件
该配置文件位于/etc/raddb/mods-available目录,名称为sql
vi /etc/raddb/mods-available/sql |
找到driver = “rlm_sql_null”这一行,修改为driver = “rlm_sql_mysql”。保持并退出。
测试通过数据库做用户认证
重新以调试方式运行freeradius:
radiusd -X |
再打开一个新的终端,运行测试工具命令:
radtest user005 user005mima localhost 1812 secret123 |
五、客户端使用
5-1、Windows客户端
Windows使用Cisco的Anyconnect客户端,这里使用具体版本为(anyconnect-win-4.2.02075-pre-deploy-k9.msi),打开软件,如下图:
假如服务器段使用自签证书,点击左下角齿轮状图标修改配置。
需要将“Block connections to untrusted servers”前面的勾去掉然后关闭该窗口,点击Connect连接。
输入帐号密码后即可正常连接。
在cmd命令行窗口输入“route print -4”可以查看到已经增加了指向内网的路由。
注:Windows下也有Openconnect客户端但是会出现默认路由无法下发的情况,再次推荐使用Anyconnect客户端。
下载链接:http://pan.baidu.com/s/1dFvUz1B 密码:77br
5-2、Mac OS客户端
Mac OS使用Cisco的Anyconnect客户端,这里使用具体版本为(anyconnect-macosx-i386-4.2.02075-k9.dmg),打开软件,如下图:
假如服务器段使用自签证书,点击左下角齿轮状图标修改配置。
需要将VPN及System Scan下的“Block connections to untrusted servers”前面的勾去掉然后关闭该窗口,点击Connect连接。
输入帐号密码后即可正常连接。
下载链接:http://pan.baidu.com/s/1c2jfnwO 密码:hpx8
5-3、iOS客户端
iOS使用Cisco的Anyconnect客户端,需要在App Store,打开软件,如下图:
假如服务器段使用自签证书,点击左下角齿轮状图标修改配置。
需要将“阻止不信任的服务器”拨至关闭,返回主页,点击添加VPN连接,在服务器地址栏输入服务器对外服务地址,保存。
选择VPN服务器,提示不信任的服务器,点击继续,输入帐号密码后即可正常连接。
5-4、安卓客户端
安卓使用OpenConnect客户端及Cisco的Anyconnect客户端,OpenConnect具体版本为(OpenConnectV1.11.apk),,Anyconnect具体版本为(AnyConnectV4.0.09039.apk)。
打开OpenConnect,如下图:
点击右上角的加号添加配置,输入VPN服务地址,出现编辑页面返回即可。
点击刚添加VPN服务器,点击始终保持连接,输入帐号密码后即可正常连接。
打开Anyconnect,如下图:
假如服务器段使用自签证书,点击右上角三个点,点击添加Settings,将阻止不信任的服务器勾去掉,返回首页点击连接,添加新的VPN连接,输入VPN服务地址,确定。
拨开AnyConnect VPN的开关,提示证书不可信,点击继续。
输入帐号密码后即可正常连接。
下载链接:http://pan.baidu.com/s/1eRPyxCu 密码:f3xx
六、高可用方案(设想)
方案1:通过域名加DNS轮询的方式实现负载均衡(由DNS自动分配vpn)。
方案2:使用Nginx负载均衡软件实现的解决方案。
求打赏!!!!
百度文库链接:https://wenku.baidu.com/view/6c9537301fb91a37f111f18583d049649a660e62
豆丁链接:http://www.docin.com/p-2033064607.html
CSDN链接:http://download.csdn.net/download/spy_123/10025455
转载请注明原文链接:https://my.oschina.net/caiyuanbo/blog/1551226
可能有些纰漏,如果有问题可以跟我一起研究。
QQ:384152164
E-mail:caiyb@vip.qq.com
来源:oschina
链接:https://my.oschina.net/u/1168635/blog/1551226