在 CentOS 7 安装 ocserv 使用 freeradius mysql daloRADIUS 实现通过web界面和数据库管理vpn用户

一、设置网卡IP

手动设置网卡静态ip

vi /etc/sysconfig/network-scripts/ifcfg-ens33
#修改下面的内容,没有的添加
BOOTPROTO=static
ONBOOT=on
IPADDR=192.168.238.241
NETMASK=255.255.255.0
GATEWAY=192.168.238.2
DNS1=114.114.114.114

二、安装 ocserv (OpenConnect server)

ocserv 是一个 OpenConnect SSL VPN 协议服务端,0.3.0 版后兼容使用 cisco AnyConnect SSL VPN 协议的终端。
官方主页:http://www.infradead.org/ocserv/

1、ocserv 已经在 epel 仓库中提供了,所以可以直接通过 yum 安装

yum install epel-release
yum install ocserv

2. 生成证书

这里你需要先仔细阅读官方文档,简单的来说,如下几步
1) 创建工作文件夹
mkdir anyconnect
cd anyconnect
2 生成 CA 证书
$ certtool --generate-privkey --outfile ca-key.pem
$ cat >ca.tmpl <<EOF
cn = "TJYL VPN CA"
organization = "TJYL"
serial = 1
expiration_days = 3650
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

把生成的 ca-cert.pem 放到 /etc/ocserv/ 中

cp ca-cert.pem  /etc/ocserv/
3) 生成本地服务器证书(后面有通过合法机构签发正式证书的步骤)
$ certtool --generate-privkey --outfile server-key.pem
$ cat >server.tmpl <<EOF
cn = "testvpn.xinmeow.com"
organization = "TJYL"
serial = 2
expiration_days = 3650
encryption_key
signing_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

把生成的 server-cert.pem 和 server-key.pem 放到 /etc/ocserv/ 中

cp server-cert.pem server-key.pem  /etc/ocserv/
4) 生成客户端证书(用freeradius管理用户这步不需要执行

创建 gen-client-cert.sh

$ 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 = "users"
serial = "$SERIAL"
expiration_days = 9999
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

保存退出

创建用户文件夹并调用 gen-client-cert.sh 生成证书

$ mkdir user
$ cd user

user 指的是用户名,.. 指的是 ca 证书所在的目录

$ sh ../gen-client-cert.sh user ..

按提示设置证书使用密码,或直接回车不设密码

最后,通过 http 服务器或其他方式将 user.p12 传输给客户端导入即可

3. 配置 ocserv

$ vi /etc/ocserv/ocserv.conf

主要修改以下部分

#ocserv支持多种认证方式,这是自带的密码认证,使用ocpasswd创建密码文件
#ocserv还支持证书认证,可以通过Pluggable Authentication Modules (PAM)使用radius等认证方式
#密码认证,选择这个就可以通过后面的创建用户命令直接创建用户来登录,简单。我这次使用radius来管理用户,所以不选这个
auth = "plain[passwd=/etc/ocserv/ocpasswd]"

#通过radius认证
auth = "radius[config=/usr/local/etc/radiusclient/radiusclient.conf,groupconfig=true]"

#通过radius审计

acct = "radius[config=/usr/local/etc/radiusclient/radiusclient.conf,groupconfig=true]"

#指定替代的登录方式,这里使用证书登录作为第二种登录方式,对应上面的创建用户证书的步骤,这次不用这个,这个也不需要打开。
enable-auth = "certificate"

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

#ca路径
ca-cert = /etc/ocserv/ca-cert.pem

#从证书中提取用户名的方式,这里提取的是证书中的 CN 字段作为用户名
cert-user-oid = 2.5.4.3

#最大用户数量
max-clients = 16

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

#tcp和udp端口
tcp-port = 4433
udp-port = 4433

#运行用户和组
run-as-user = ocserv
run-as-group = ocserv

#虚拟设备名称
device = vpns

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

注释掉route的字段,这样表示所有流量都通过 VPN 发送

 

4. 创建用户

#username为你要添加的用户名
$ ocpasswd -c /etc/ocserv/ocpasswd username

5. 配置系统设置

开启内核转发

#新增
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf 
#如果已经加过了,则修改
sed -i 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf
#生效配置
sysctl -p
#检查转发已经开启
cat /proc/sys/net/ipv4/ip_forward
#应该为1

配置 iptables 规则

你可以参考Linode 的文章来配置 iptables,注意要修改第一行的ip地址为你ocserv配置中的ipv4地址段,然后ens33改为你的网卡名称

#IP段和eth0接口和vpns类接口要根据自己的情况修改
iptables -t nat -A POSTROUTING -s 10.12.0.0/24 -o ens33 -j MASQUERADE
iptables -A FORWARD -i vpns+ -j ACCEPT
iptables -A FORWARD -o vpns+ -j ACCEPT
iptables-save >> /etc/sysconfig/iptables

6. 测试

现在我们可以开启服务器试试了

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

拿起你的 iOS 设备,下载思科的 AnyConnect 客户端,连接你的服务器。

出现问题可以看debug的返回信息,如果信息不详细,可以把 1 改成 10。

如果没有问题,那么就可以配置成开机运行了。

$ systemctl enable ocserv
$ systemctl start ocserv

a. 下发路由

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

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

所以我们只能保证下某几个常用的服务是可用的,比如 Google Facebook 以及 Twitter

编辑配置文件

$ sudo vim /etc/ocserv/ocserv.conf

添加 route = 的字段即可

B. windows客户端的配置

参考

https://ifreedom.one/2015/04/20/Setup-Cisco-AnyConnect-VPN-on-CentOS7/

 

二、安装 freeradius

1.首先我们在freeradius服务器安装freeradius服务端

yum install freeradius

安装完毕后使用

radiusd -v

若看到版本号信息说明安装成功。
由于我们之后需要使用mysql来存储用户信息,我们还需要安装freeradius的mysql扩展

yum install freeradius-mysql

2.配置freeradius并测试

我们首先使用freeradius的默认设置,即文本形式记录用户的用户名和密码。测试freeradius的工作是否正常,再测试ocserv调用freeradius是否正常,最后再设置freeradius使用mysql来读取用户记录。

freeradius的保存用户的文本在 /etc/raddb/user 其他设置也在这个目录,我们等会会改动这个目录下的设置。user文件是一个link,我们直接编辑其实际路径(vim似乎不能编辑link)

vi /etc/raddb/mods-config/files/authorize

在第一行插入如下内容后保存

opscaff001 Cleartext-Password := "123456"

这里,我们新建了一个用户,用户名为 opscaff001 ,密码为 123456 。之后我们新建一个screen并以调试模式运行radiusd

radiusd -X

好,现在我们可以看到我们的freeradius服务端已经处于运行状态了
我们退出screen,然后使用freeradius的调试工具进行测试,首先安装它

yum install freeradius-utils

执行以下命令

radtest opscaff001 123456 localhost 0 testing123

ps:如果修改了主机名,一定要当心出错。

如果看到 Received Access-Accept 字样说明验证成功。如果看到 Received Access-Reject 说明验证失败,你需要检查使用的命令。

当我们确认freeradius工作正常之后我们用freeradius客户端来访问freeradius服务端。不过在那之前我们需要先设置freeradius服务端设置。

首先打开设置文件(服务端上的客户端配置)

vi /etc/raddb/clients.conf

我们在这份文件可以对每个客户端进行设置(以ip区分),以及所有客户端的一些全局设置。内容很多,我们不一一详谈了。
我们直接找到第30行的 client localhost,我们刚才测试工具之所以能正确访问freeradius服务端,是因为默认设置下,localhost已被加入这份设置,即localhost可以访问freeradius服务端。

而我们之前在测试命令中使用的 testing123在这份文件的第100行,这个设置用来指定客户端发送请求时带的密钥,若密钥错误将导致服务端返回验证失败的信息。这个设置很重要,我们这里不去修改他,但是真正的生产环境需要修改这个设置。

生产环境修改freeradius客户端访问服务端的密钥(由于我这个是本机访问,所以暂时没有修改)

secret = testing123

为了方便起见,我们不另外再开一个客户端设置了,我们直接修改现有的客户端设置即 client localhost 的设置中的客户端ip设置。

找到第42行,修改为
#ipaddr = 127.0.0.1

找到第46行,修改为ipv4addr = * # any. 127.0.0.1 == localhost
保存这个文件。现在我们允许任何ipv4地址访问freeradius服务端(这在实际生产环境中是不安全的,生产环境中请仔细配置每一个客户端设置)。

由于我目前的配置都装在一台机器上,默认就有,所以也不需要修改

client localhost {

ipaddr = 127.0.0.1

3.安装freeradius客户端

我们现在在ocserv服务器上安装freeradius客户端

1)下载freeradius-client源码包

这里我们使用的包为:freeradius-client-1.1.7.tar.gz

wget ftp://ftp.freeradius.org/pub/freeradius/freeradius-client-*
tar -zxvf freeradius-client-1.1.7.tar.gz
cd freeradius-client-1.1.7
 2)安装依赖包、编译安装:
yum install -y  gcc gcc-c++
./configure
make -j2 && make install 


为了测试freeradius服务端在这台服务器上也可以访问,我们可以在这台服务器上也安装测试工具并进行测试(假设freeradius服务器地址为localhost)

yum install freeradius-utils
radtest opscaff001 123456 localhost 0 testing123

确认无误后我们进行接下来的设置。

3)配置freeradius客户端要访问的服务端地址
vi /usr/local/etc/radiusclient/radiusclient.conf

第37行改为(客户端配置文件的默认认证服务器地址就是localhost,不需要修改)

authserver localhost

第42行改为(这个默认也是localhost不需要改)

acctserver localhost

保存

4)打开freeradius客户端的服务器设置, 添加允许访问的客户端
vi /usr/local/etc/radiusclient/servers

(打开localhost 密钥为testing123行的注释就可以了,不需要添加东西)

localhost testing123

保存这份文件。自此,我们已经设置好了freeradius客户端需要做的设置。

5)设置ocserv使用freeradius作为验证模块

打开ocserv配置文件

vim /etc/ocserv/ocserv.conf

修改第39行的验证方式设置,改为

auth = "radius[config=/usr/local/etc/radiusclient/radiusclient.conf,groupconfig=true]"

这样,我们就使得ocserv使用freeradius来进行用户验证。

重启ocserv

systemctl restart ocserv.service

但是使用文本保存密码不是我们最终需要的,我们到此仅仅是确认了ocserv调用freeradius正常,接下去我们完成freeradius服务端的mysql设置

 

三、配置mysql数据库

1、安装数据库

#RHEL 7 開始, MariaDB 會取代 MySQL 成為預設的資料庫系統, 以下是安裝方法:
yum install mariadb-server mariadb
#启动数据库
systemctl start mariadb.service
#设置开机自启动
systemctl enable mariadb.service
#查看状态
systemctl status mariadb
systemctl is-enabled mariadb.service

MariaDB Server 預設 root 密碼為空密碼, 要重設 root 密碼有兩種方法, 一種是傳統的方法, 登入 mysql 後修改密碼, 另一種是用 mysql_secure_installation, 這個方法只要在指令模式輸入 mysql_secure_installation, 跟著步驟回答問題就可以, 以下會看看登入 mysql 修改密碼:

初始化数据库安全设置:

# mysql_secure_installation

推荐选项:(默认密码先设置为root)

Set root password? [Y/n] Y
Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] Y
Remove test database and access to it? [Y/n] Y
Reload privilege tables now? [Y/n] Y

2、创建freeradius数据库和数据表

mysql -u root -p
create database radius;
use radius;
source /etc/raddb/mods-config/sql/main/mysql/setup.sql;
source /etc/raddb/mods-config/sql/main/mysql/schema.sql;
GRANT ALL on radius.* TO 'radius'@'localhost';
flush privileges;

3.配置FreeRadius使用mysql

启用sql模块:

# ln -s /etc/raddb/mods-available/sql /etc/raddb/mods-enabled/
# chgrp -h radiusd /etc/raddb/mods-enabled/sql

配置mysql数据库连接信息:

# vi /etc/raddb/mods-available/sql

主要修改内容:

sql {
    (...省略...)
        
    driver = "rlm_sql_mysql"
    dialect = "mysql"
        
    # Connection info:
    #取消下面的注释:
    server = "localhost"
    port = 3306
    login = "radius"
    password = "radpass"
    radius_db = "radius"
    (...省略...)
}

4.调整FreeRadius与MariaDB的启动顺序

添加FreeRadius启动服务:

# systemctl enable radiusd.service

FreeRadius服务必须在数据库正常启动后才能正常启动,否则会出错。为了确保这一点,按照以下方法强制指定radius服务启动的顺序

# vi /etc/systemd/system/multi-user.target.wants/radiusd.service

在[Unit]部分,增加After=mariadb.service,如下所示:

[Unit]
Description=FreeRADIUS high performance RADIUS server.
After=syslog.target network.target
After=mariadb.service

启动服务

# systemctl start radiusd.service
# systemctl status radiusd.service

5.测试radius通过数据库读取用户信息

创建一个测试用户

#连接mysql命令行
mysql -uroot -p radius #使用sql添加一条测试记录: INSERT INTO radcheck (id, username, attribute, op, value) VALUES (1,'testuser','Cleartext-Password',':=','mypass');

使用radtest命令测试:radtest [用户名] [密码] [radius服务器host/ip] 0 [对客户端设置的共享秘钥],例如:

# radtest testuser mypass localhost 0 testing123

认证成功的输出如下:

Sent Access-Request Id 84 from 0.0.0.0:44961 to 127.0.0.1:1812 length 78
 User-Name = "testuser"
 User-Password = "mypass"
 NAS-IP-Address = 127.0.0.1
 NAS-Port = 0
 Message-Authenticator = 0x00
 Cleartext-Password = "mypass"
Received Access-Accept Id 84 from 127.0.0.1:1812 to 0.0.0.0:0 length 20

radius调试

如果radius启动出现问题,可以将radius进程停止,然后以参数-X的方式临时启动调试模式。

# pkill radius   
# radiusd -X

6.防火墙配置radius相关规则(本机访问,暂时不需要配置

  1. 配置防火墙,打开radius服务端口
    # (如果已经打开firewalld的话,可以跳过该步骤)
    # systemctl enable firewalld
    # systemctl start firewalld
    # systemctl status firewalld
  2. 添加radius服务
    cat /usr/lib/firewalld/services/radius.xml
    firewall-cmd --add-service=radius --permanent
    firewall-cmd --reload
    firewall-cmd --list-services

    ※ [特殊化定制]:如果不想让raidus端口暴漏在公网上,可以只允许特定IP地址访问radius服务

    firewall-cmd --permanent --new-zone=radius
    firewall-cmd --reload
    
    firewall-cmd --permanent --zone=radius --set-target=ACCEPT
    firewall-cmd --permanent --zone=radius --add-service= radius
    firewall-cmd --permanent --zone=radius --add-source=192.168.111.222/32
    firewall-cmd --permanent --zone=radius --add-source=192.168.111.223/32
    firewall-cmd --reload
    firewall-cmd --get-active-zones

到此为止基本的Radius服务就可以正常工作了。如果没有更好的Radius管理软件,那么推荐安装daloRADIUS

 

7.打开防火墙ocserv监听端口

vi /usr/lib/firewalld/services/ocserv.xml
<service>
 <short>ocserv</short>
 <description>ocserv listen port.</description>
 <port protocol="tcp" port="4433"/>
 <port protocol="udp" port="4433"/>
</service>

firewall-cmd --add-service=ocserv --permanent
firewall-cmd --reload
firewall-cmd --list-services

到此位置理论上oserv就可以正常访问了,可以用

cisco anonyconnect 连接 用 testuser 密码 mypass来测试连接 服务器的4433端口

测试结束后别忘了使用sql命令清除测试用户:

delete from radcheck where username = 'testuser';

8.其他说明

1)如果可以连接vpn,但无法访问vpn连接的内部网络,可能需要检查iptables的规则

目前防火墙启用中,手动家的规则可能会掉,需要重新配

iptables -t nat -A POSTROUTING -s 10.12.0.0/24 -o ens33 -j MASQUERADE
iptables -A FORWARD -i vpns+ -j ACCEPT
iptables -A FORWARD -o vpns+ -j ACCEPT
iptables-save >> /etc/sysconfig/iptables
2)cisco anonyconnect报错,AnyConnect cannot confirm it is connected to your secure gateway. The local network may not be trustworthy. Please try another network.)

可能是客户端安装过证书登录或到如果其他vpn的ca证书,与本VPN的ca证书的CN名相同了,因此报服务器不可靠,可能被中间人攻击。将本VPN的ca证书名字改了,重新制作一套ca和server证书重启ocserv即可。

 

四、(可选) 安装配置Radius管理软件:daloRADIUS

daloRADIUS的官网:http://www.daloradius.com/GitHub

1.配置好PHP及Web服务器,CentOS7下推荐使用php7+nginx。

#安装httpd
yum install httpd -y
#安装php及组件
yum install php php-mysql php-gd -y
# 安装php组间
yum install php-pear-DB -y
yum -y install php php-fpm
#nginx开机自启动
systemctl enable nginx

2.配置php-fpm服务

  1. 修改php-fpm的默认设置上一步安装的php-fpm,默认设置里运行用户都是apache,需要先修改成nginx
    vi /etc/php-fpm.d/www.conf

    需要修改的内容:

    user = nginx
    group = nginx
    listen.owner = nginx
    listen.group = nginx
        
    ;如果不需要外部主机访问该php-fpm的话,推荐改为监听unix socket.
    listen = /var/run/php-fpm/php-fpm.sock
  2. 启动php-fpm服务
    # systemctl start php-fpm
    # systemctl enable php-fpm
  1. 下载并解压daloRADIUS
    # mkdir -p /opt/www
    # cd /opt/www
    # wget https://github.com/lirantal/daloradius/archive/master.zip
    # unzip master.zip
    # mv daloradius-master/ daloradius
    # chown -R nginx:nginx daloradius
  2. 导入daloRADIUS扩展表由于daloRADIUS除了用到了基本的FreeRadius表,例如radcheck, radreply等,还扩展了很多附件表,例如billing_history,userinfo等,因此首先需要导入这些扩展表。
    # cd /opt/www/daloradius
    # mysql -u root -p radius < contrib/db/mysql-daloradius.sql
  3. 配置数据库连接
    # chmod 664 /opt/www/daloradius/library/daloradius.conf.php
    # vi /opt/www/daloradius/library/daloradius.conf.php

    主要需要修改的是数据库的连接信息:

    $configValues['CONFIG_DB_HOST'] = 'localhost';
    $configValues['CONFIG_DB_PORT'] = '3306';
    $configValues['CONFIG_DB_USER'] = 'radius';
    $configValues['CONFIG_DB_PASS'] = 'radpass';
    $configValues['CONFIG_DB_NAME'] = 'radius';
  4. 配置网站这里只列出了配置普通http网站的内容。生产环境下推荐使用https。vi /etc/nginx/nginx.conf
    server_name配置为匹配所有ip地址访问

    server {
        listen 80;
        server_name ~^\d+\.\d+\.\d+\.\d+$;
        root /opt/www/daloradius;
        index index.php;
             
        charset utf-8;
             
        try_files $uri $uri/ /index.php?q=$uri&$args;
                
        location ~ \.php$ {
            fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }
  5. 重启服务
    # systemctl restart mariadb.service 
    # systemctl restart radiusd.service 
    # systemctl restart nginx
  6. 重新启动php-fpm服务
    # systemctl restart php-fpm
    # systemctl enable php-fpm
  7. 修改php-fpm的unix目录的用户及组
    chown nginx:nginx /var/run/php-fpm/ -R
    chown nginx:nginx /var/lib/php/ -R
  8. 打开防火墙http及https端口
    firewall-cmd --permanent --add-service=http 
    firewall-cmd --permanent --add-service=https
    firewall-cmd --reload
  9. 登陆daloradiusdns更改生效后,访问dalo.mysite.com即可配置FreeRadius。默认的管理员的用户名是administrator,密码是radius。如果无法登陆,有一个可能的原因就是nginx无权限访问php的session目录。可以修改目录的属性或者将拥有者改为nginx用户, 例如:
    chown nginx:nginx /var/run/php-fpm/ -R
    chown nginx:nginx /var/lib/php/ -R

五、申请证书服务器证书,让登录时不报证书错误

用的腾讯云的免费证书

ssl证书管理

选申请证书

选免费的

输入要申请证书的域名

选手动添加dns记录方式验证

根据详情中的提示去添加一条dns解析记录

加好以后点自助诊断旁边的查询,验证过了就会签发证书。

下载证书,找nginx目录里的公钥文件和私钥文件

传到ocserv服务器的/etc/ocserv/目录下

修改配置文件

vi /etc/ocserv/ocserv.conf

把服务器证书改成刚刚下载的证书

server-cert = /etc/ocserv/1_xxxx.xinmeow.com_bundle.crt
server-key = /etc/ocserv/2_xxxx.xinmeow.com.key​

保存,重启ocserv服务

service ocserv restart

好了

 

客户端下载

国外很多高校自建的vpn都是用这个协议的,都有win、linux和mac的客户端下载比如下面的
http://web.unbc.ca/~getvpn/

参考资料:

http://www.opscaff.com/2017/03/01/ocserv-radius-%E8%AE%A4%E8%AF%81%E6%90%AD%E5%BB%BA-freeradius-mysql/

CentOS 7 安装FreeRadius mysql daloRADIUS web管理端
http://www.racksam.com/2017/03/02/centos7-install-freeradius/

使用daloRADIUS Web程序管理FreeRADIUS服务
http://blog.51cto.com/wzlinux/1736744

http://blog.51cto.com/wzlinux/1737044
FreeRADIUS+DaloRADIUS实现PPTP VPN高级用户控制+流量控制

CentOS 7 下使用 Firewall

http://havee.me/linux/2015-01/using-firewalls-on-centos-7.html

ocserv + Let's Encrypt + 证书认证

http://blog.dazzyd.org/blog/ocserv-letsencrypt-certificate/

 

aa

© 2017 - 2018, 新之助meow. 原创文章转载请注明: 转载自http://www.xinmeow.com

5.00 avg. rating (95% score) - 1 vote
点赞