轻松构建一套企业级 VPN 解决方案

home

Author:rab



前言

说到 VPN,我们可能会想到 OpenVPN,但今天的主角并不是它,而是 Ocserv + FreeIPA + LDAP Tool Box Self Service Password 的完整方案。那 Ocserv、FreeIPA、LDAP Tool Box Self Service Password 这三个组件又是什么呢?简单解释一下。

  1. Ocserv:VPN 统一入口(即 VPN 服务);
  2. FreeIPA:LDAP 工具,可与 Ocserv 集成,统一创建、管理 Ocserv 登录用户;
  3. LDAP Tool Box Self Service Password:开源的自助式密码重置和账户管理工具,专为 LDAP 目录服务设计,允许 LDAP 用户通过 Web 界面自主更改其密码。

这一套下来其实就完全可以作为企业级 VPN 来落地实现。

一、Ocserv

官网:https://ocserv.openconnect-vpn.net/index.html

官网部署文档:https://ocserv.openconnect-vpn.net/recipes-ocserv-installation-CentOS-RHEL-Fedora.html

1.1 场景

也许你听说过 OpenVPN,但 Ocserv 也许你听起来就比较陌生,实际上它是一种 VPN 解决方案,基于 OpenConnect 协议。它是一个开源的 SSL VPN 服务器,用于建立安全的远程访问连接。Ocserv VPN允许用户通过加密的隧道连接到远程网络,从而可以安全地访问远程资源,就像身处本地网络一样。

那 Ocserv VPN 与 OpenVPN 有什么区别、优缺点、应用场景呢?

1、Ocserv VPN

优点

兼容性安全性性能
基于 OpenConnect 协议,与 Cisco AnyConnect 兼容,这使得它在与一些商业 VPN 解决方案集成时更加容易。使用 GnuTLS 和 GNUTLS-DTLS等现代加密技术,提供良好的安全性。使用了现代技术实现,在性能方面有所提升,特别是在处理大量连接时。

缺点

灵活性知名度
在配置上不如 OpenVPN 灵活,因此定制化程度较低。相对于 OpenVPN,Ocserv 的知名度可能较低,可能不如 OpenVPN 在社区支持和资源方面丰富。

适用场景

企业环境需要高性能的情景
由于其与商业 VPN 解决方案的兼容性,Ocserv 通常在企业环境中得到广泛应用。对于需要处理大量连接并且对性能要求较高的场景,Ocserv 可能是一个更好的选择。

2、OpenVPN

优点

灵活性跨平台支持社区支持
具有很高的灵活性和可定制性,可以根据需要进行各种配置。在多个平台上都有支持,包括Windows、Linux和macOS等。拥有庞大的用户社区和资源库,可获得丰富的支持和资源。

缺点

性能配置复杂
由于其用户空间的解决方案,OpenVPN可能在处理大量连接时性能稍逊一筹。OpenVPN的配置相对复杂,可能需要一些技术知识来正确配置和管理。

适用场景

个人用户定制化需求
对于个人用户来说,是一种广泛使用且灵活的解决方案,适用于许多不同的使用场景。需要根据具体需求定制VPN解决方案的情况下,OpenVPN可能更适合,因为它具有更高的可定制性。

总的来说,企业级可选择 Ocserv VPN,用户级可选择 OpenVPN。

1.2 部署

1.2.1 环境

1、服务器

HostVersion配置备注
CentOS/10.206.0.77.9.20092C/4G 20G云服务器

2、软件(服务)

ServiceVersion备注
Ocserv1.2.2VPN 服务

3、其它

域名DNS证书备注
ocserv.vpnarsen.fun10.206.0.7 的公网 IPocserv.vpnarsen.fun.key
ocserv.vpnarsen.fun.pem
加密传输

4、客户端下载

任选其一下载即可

1.2.2 部署

官方部署文档:https://ocserv.openconnect-vpn.net/recipes.html

1、修改主机名

hostnamectl set-hostname ocserv.vpnarsen.fun

2、安装 EPEL 存储库

对于 CentOS 和 RHEL 用户,ocserv 和 radcli 软件包仅在 EPEL 存储库上可用。

yum install -y epel-release

image-20240225154613884

3、检查 EPEL 存储库是否启用

yum repolist enabled

image-20240225154734610

4、检查 ocserv 是否可以安装

yum info ocserv

image-20240225154857797

或查看可安装的软件版本:

yum list ocserv --showduplicates

image-20240225155210144

5、安装 ocserv

yum install -y ocserv

6、验证安装版本

ocserv --version

image-20240225160403750

7、开启路由转发

# 添加内核参数
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf

# 立即生效
sysctl -p

8、iptables 配置

# 对指定的表 table 进行操作,添加一个规则,把172.26.1.0的流量指定到eth0出去
# 172.26.1.0这个IP是我们分配给客户端的IP池,在配置文件中设置
iptables -t nat -A POSTROUTING -s 172.26.1.0 -o eth0 -j MASQUERADE
iptables -A FORWARD -i vpns+ -j ACCEPT
iptables -A FORWARD -o vpns+ -j ACCEPT

# 保存路由表
iptables-save > /etc/sysconfig/iptables

9、firewalld(必须配置)

firewall-cmd --zone=public --add-port=22/tcp --permanent   # ssh远程连接
firewall-cmd --zone=public --add-port=443/tcp --permanent  # ocserv ssl tcp
firewall-cmd --zone=public --add-port=443/udp --permanent  # ocserv ssl udp
firewall-cmd --add-masquerade --permanent
firewall-cmd --reload
1.2.3 配置

1、配置文件路径

安装完成后,从启动脚本中就可看见其配置文件在 /etc/ocserv/

image-20240225155442294

配置文件备份:

cp /etc/ocserv/ocserv.conf /etc/ocserv/ocserv.conf.bak

2、配置文件详解

默认参数详解

# 用户认证,指定认证方式为PAM,意味着 OpenConnect 服务器将使用系统中的 PAM 配置来验证用户身份。
auth = "pam"
# 指定 OpenConnect 服务器监听的 TCP 和 UDP 端口号。
tcp-port = 443
udp-port = 443
# 指定服务器在运行时所使用的用户和用户组,有助于提高安全性,限制了服务器的权限。
run-as-user = ocserv
run-as-group = ocserv
# 指定一个 Unix 套接字文件,用于与服务器进行通信。
socket-file = ocserv.sock
# 指定服务器在运行时所使用的 chroot 环境的根目录。
chroot-dir = /var/lib/ocserv
# 指定服务器使用的 SSL 证书和私钥,用于加密通信。
server-cert = /etc/pki/ocserv/public/server.crt
server-key = /etc/pki/ocserv/private/server.key
# 在多个工作线程之间启用隔离,增强安全性。
isolate-workers = true
# 分别指定允许连接到服务器的最大客户端数量以及相同用户同时连接的最大数量。
max-clients = 16
max-same-clients = 2
# 设置连接速率限制,以防止恶意行为或滥用。
rate-limit-ms = 100
# 指定服务器统计信息重置的时间间隔,以秒为单位。
server-stats-reset-time = 604800
# 设置保持连接的时间(以秒为单位)和死亡对等检测时间(以秒为单位)。
keepalive = 32400
dpd = 90
# 移动设备的死亡对等检测时间。
mobile-dpd = 1800
# 当 UDP 连接失败时,切换到 TCP 的超时时间(以秒为单位)。
switch-to-tcp-timeout = 25
# 禁用 MTU 发现。
try-mtu-discovery = false
# 指定客户端证书中用于用户标识的 OID。
cert-user-oid = 0.9.2342.19200300.100.1.1
# 设置 TLS 优先级。
tls-priorities = "NORMAL:%SERVER_PRECEDENCE"
# 认证超时时间(以秒为单位)。
auth-timeout = 240
# 最小重新认证时间(以秒为单位)。
min-reauth-time = 300
# 于防止暴力攻击的参数。
max-ban-score = 80
ban-reset-time = 1200
# Cookie 超时时间(以秒为单位)。
cookie-timeout = 300
# 是否禁止用户漫游。
deny-roaming = false
# 重新协商密钥的时间间隔和方法。
rekey-time = 172800
rekey-method = ssl
# 是否使用occtl来管理客户端。
use-occtl = true
# 保存服务器进程ID的文件路径。
pid-file = /var/run/ocserv.pid
# 设置日志级别。
log-level = 1
# 指定设备名称。
device = vpns
# 是否为客户端分配可预测的IP地址。
predictable-ips = true
# 默认域名。
default-domain = example.com
# 是否启用租约的定期ping。
ping-leases = false
# 不允许访问的路由。
no-route = 192.168.5.0/255.255.255.0
# Cisco AnyConnect 客户端兼容性设置,启用 DTLS 旧版支持。
cisco-client-compat = true
dtls-legacy = true
cisco-svc-client-compat = false
# 客户端绕过协议。
client-bypass-protocol = false
# 用于欺骗检测的参数。
camouflage = false
camouflage_secret = "mysecretkey"
camouflage_realm = "Restricted Content"
# 指定要包含在 HTTP 响应中的标头,这些标头可以帮助增强安全性。
included-http-headers = Strict-Transport-Security: max-age=31536000 ; includeSubDomains
included-http-headers = X-Frame-Options: deny
included-http-headers = X-Content-Type-Options: nosniff
included-http-headers = Content-Security-Policy: default-src 'none'
included-http-headers = X-Permitted-Cross-Domain-Policies: none
included-http-headers = Referrer-Policy: no-referrer
included-http-headers = Clear-Site-Data: "cache","cookies","storage"
included-http-headers = Cross-Origin-Embedder-Policy: require-corp
included-http-headers = Cross-Origin-Opener-Policy: same-origin
included-http-headers = Cross-Origin-Resource-Policy: same-origin
included-http-headers = X-XSS-Protection: 0
included-http-headers = Pragma: no-cache
included-http-headers = Cache-control: no-store, no-cache

企业内部使用(直接复制去使用-已验证)

# 用户认证,指定认证方式为PAM,意味着 OpenConnect 服务器将使用系统中的 PAM 配置来验证用户身份。
auth = "pam"
# 指定 OpenConnect 服务器监听的 TCP 和 UDP 端口号。
tcp-port = 443
udp-port = 443
# 指定服务器在运行时所使用的用户和用户组,有助于提高安全性,限制了服务器的权限。
run-as-user = ocserv
run-as-group = ocserv
# 指定一个 Unix 套接字文件,用于与服务器进行通信。
socket-file = ocserv.sock
# 指定服务器在运行时所使用的 chroot 环境的根目录。
chroot-dir = /var/lib/ocserv
# 指定服务器使用的 SSL 证书和私钥,用于加密通信。
server-cert = /etc/ocserv/cert/ocserv.vpnarsen.fun.pem
server-key = /etc/ocserv/cert/ocserv.vpnarsen.fun.key
# 在多个工作线程之间启用隔离,增强安全性。
isolate-workers = true
# 分别指定允许连接到服务器的最大客户端数量以及相同用户同时连接的最大数量。
max-clients = 16
max-same-clients = 2
# 设置连接速率限制,以防止恶意行为或滥用。
rate-limit-ms = 100
# 指定服务器统计信息重置的时间间隔,以秒为单位。
server-stats-reset-time = 604800
# 设置保持连接的时间(以秒为单位)和死亡对等检测时间(以秒为单位)。
keepalive = 32400
dpd = 90
# 移动设备的死亡对等检测时间。
mobile-dpd = 1800
# 当 UDP 连接失败时,切换到 TCP 的超时时间(以秒为单位)。
switch-to-tcp-timeout = 25
# 禁用 MTU 发现。
try-mtu-discovery = false
# 指定客户端证书中用于用户标识的 OID。
#cert-user-oid = 0.9.2342.19200300.100.1.1
# 启用压缩协商(LZS、LZ4)
compression = true
# 据包不会被压缩的最小大小(字节)
no-compress-limit = 256
# 设置 TLS 优先级。
#tls-priorities = "NORMAL:%SERVER_PRECEDENCE"
tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0"
# 认证超时时间(以秒为单位)。
auth-timeout = 240
# 空闲超时时间,如果客户端连接在10小时内没有任何活动,服务器将自动断开该连接,单位为秒
idle-timeout = 36000
# 这个参数指定了两次重新认证之间的最小时间间隔,单位为秒。
# 当用户在一段时间内进行了重新认证(例如更改了密码),系统将在此时间间隔内阻止用户再次进行重新认证,以防止滥用。
min-reauth-time = 10
# 这个参数指定了触发防暴力攻击保护机制的最大失败次数。
# 当某个用户在一段时间内连续失败的认证尝试达到或超过此阈值时,系统将认为这是一次暴力攻击,并采取相应的措施。
max-ban-score = 10
# 这个参数指定了防暴力攻击保护机制的重置时间,单位为秒。
# 在用户达到最大失败次数后,系统将在此时间间隔内重置用户的失败次数,以允许用户重新尝试认证。
ban-reset-time = 300
# 客户端 Cookie 超时时间(以秒为单位)。
cookie-timeout = 300
# 是否禁止用户漫游,漫游是指用户在连接到 VPN 后从一个网络切换到另一个网络的过程,而不中断 VPN 连接。
# 1)当 deny-roaming 设置为 false 时,表示不拒绝用户的漫游功能。
# 在这种情况下,用户可以在不断开 VPN 连接的情况下从一个网络切换到另一个网络,保持与 VPN 服务器的持续连接。
# 2)当 deny-roaming 设置为 true,则表示禁止用户的漫游功能。
# 在这种情况下,如果用户从一个网络切换到另一个网络,可能会导致 VPN 连接断开,需要用户手动重新连接 VPN。
deny-roaming = false
# 指定了重新协商密钥的时间间隔,单位为秒。
# 在指定的时间间隔内,服务器和客户端将重新协商密钥,以更新加密通信所使用的密钥。
# 在这个例子中,rekey-time = 172800 表示每隔 172800 秒(即两天)重新协商一次密钥。
rekey-time = 172800
# 指定了重新协商密钥的方法。
# 在这个配置中,ssl 表示使用 SSL/TLS 协议进行重新协商密钥。
# 它可以确保通信的安全性,并提供密钥更新的机制。
# 启用的目的:通过定期重新协商密钥,可以降低密钥被破解的风险,并确保加密通信的持续安全性。
rekey-method = ssl
# 指定了用户在连接建立和断开时要运行的脚本(安装时默认配置了,但此处未启用)。
# 默认的脚本的作用是根据连接的状态向防火墙添加或移除特定的接口,以允许或禁止通过该接口的流量。
# 这对于管理连接时的网络访问权限非常有用。
# connect-script = /usr/bin/ocserv-script
# disconnect-script = /usr/bin/ocserv-script
# 在实际中,我们可以根据需求来自定义脚本(如记录每个用户的登录登出日志)
connect-script = /etc/ocserv/ocserv-script
disconnect-script = /etc/ocserv/ocserv-script
# 是否使用occtl来管理客户端。
use-occtl = true
# 保存服务器进程ID的文件路径。
pid-file = /var/run/ocserv.pid
# 设置日志级别。
#log-level = 1
# 指定设备名称。
device = vpns
# 是否为客户端分配可预测的IP地址。
predictable-ips = true
# 默认域名。
default-domain = ocserv.vpnarsen.fun
# 用于配置 VPN 服务器分配给客户端的 IPv4 地址池,以便为连接到 VPN 的客户端分配虚拟 IP 地址。
ipv4-network = 172.26.1.0/24
# 是否启用租约的定期ping。
ping-leases = false
# 不允许访问的路由(全局配置)。
#no-route = 192.168.5.0/255.255.255.0
# 用于指定在连接建立时用户应该选择的用户组,可写多个,供用户选择。
select-group = ops
select-group = dev
select-group = test
select-group = alluser
select-group = tmp
select-group = devtest
# 用于指定在用户连接到服务器时默认选择的用户组,如果用户没有显式选择用户组,系统将默认选择指定的用户组。
default-select-group = alluser
# 用于配置自动选择用户组的条件(注释掉或修改为false,因为打开后会过滤出 ocserv 服务器上的所有用户,反而无法获取到你上面配置的这些组名)。
#auto-select-group = true
# 用于指定是否为每个用户配置个性化的配置(相当于指定用户所在的目录,需手动创建)。因为后面要集成FreeIPA,所以这里注释,创建用户由FreeIPA完成。
#config-per-user = /etc/ocserv/config-per-user/
# 用于指定是否为每个用户组配置特定的配置(相当于指定用户组所在的目录,需手动创建)。
config-per-group = /etc/ocserv/config-per-group/
# 用于指定默认的用户配置,可写多个。因为后面要集成FreeIPA,所以这里注释,创建用户由FreeIPA完成。
#default-user-config = /etc/ocserv/config-per-user/user1.conf
#default-user-config = /etc/ocserv/config-per-user/user2.conf
#default-user-config = /etc/ocserv/config-per-user/user3.conf
# 用于指定默认的用户组配置,可写多个,可与每个select-group对应起来。
default-group-config = /etc/ocserv/config-per-group/ops.conf
default-group-config = /etc/ocserv/config-per-group/dev.conf
default-group-config = /etc/ocserv/config-per-group/test.conf
default-group-config = /etc/ocserv/config-per-group/alluser.conf
default-group-config = /etc/ocserv/config-per-group/tmp.conf
default-group-config = /etc/ocserv/config-per-group/devtest.conf
# Cisco AnyConnect 客户端兼容性设置,启用 DTLS 旧版支持。
cisco-client-compat = true
dtls-legacy = true
#cisco-svc-client-compat = false
# 客户端绕过协议。
#client-bypass-protocol = false
# 用于欺骗检测的参数。
# 这些参数的作用是为连接添加一层伪装,使其看起来像是在与受限内容领域进行通信。
# 伪装功能可以用于隐藏真实通信的目的地或内容,以增强连接的隐私性和安全性。
# 但需要注意的是,伪装功能的效果取决于实际的使用情况和配置方式,可能对性能和安全性产生影响。
# 当设置为 false 时,表示不启用伪装功能。
#camouflage = false
## 用于配置伪装功能的密钥。
#camouflage_secret = "mysecretkey"
## 用于指定伪装功能的领域(realm)。
#camouflage_realm = "Restricted Content"
# 指定要包含在 HTTP 响应中的标头,这些标头可以帮助增强安全性。
#included-http-headers = Strict-Transport-Security: max-age=31536000 ; includeSubDomains
#included-http-headers = X-Frame-Options: deny
#included-http-headers = X-Content-Type-Options: nosniff
#included-http-headers = Content-Security-Policy: default-src 'none'
#included-http-headers = X-Permitted-Cross-Domain-Policies: none
#included-http-headers = Referrer-Policy: no-referrer
#included-http-headers = Clear-Site-Data: "cache","cookies","storage"
#included-http-headers = Cross-Origin-Embedder-Policy: require-corp
#included-http-headers = Cross-Origin-Opener-Policy: same-origin
#included-http-headers = Cross-Origin-Resource-Policy: same-origin
#included-http-headers = X-XSS-Protection: 0
#included-http-headers = Pragma: no-cache
#included-http-headers = Cache-control: no-store, no-cache

需要提前准备的额外文件

1)登录登出执行脚本

默认登录登出的执行脚本:

cat /usr/bin/ocserv-script
#!/bin/sh

if [ "$REASON" = "connect" ];then
	# add the user's interface into the internal zone
	firewall-cmd --zone=internal --add-interface=$DEVICE
else
	firewall-cmd --zone=internal --remove-interface=$DEVICE
fi

exit 0

修改后的登录登出执行脚本:

vim /etc/ocserv/ocserv-script
#!/bin/bash
 
export LOGFILE=/etc/ocserv/login.log

case "$REASON" in
  connect)
echo `date` $USERNAME "connected" >> $LOGFILE
echo `date` $REASON $USERNAME $DEVICE $IP_LOCAL $IP_REMOTE $IP_REAL >> $LOGFILE
    ;;
  disconnect)
echo `date` $USERNAME "disconnected" >> $LOGFILE
    ;;
esac
exit 0
chmo +x /etc/ocserv/ocserv-script

2)SSL 证书

mkdir /etc/ocserv/cert
# 将你的证书上传至该目录下

image-20240330160347782

3)创建用户组配置目录及配置

mkdir /etc/ocserv/config-per-group/
touch /etc/ocserv/config-per-group/ops.conf
touch /etc/ocserv/config-per-group/dev.conf
touch /etc/ocserv/config-per-group/test.conf
touch /etc/ocserv/config-per-group/alluser.conf

举例子

vim /etc/ocserv/config-per-group/ops.conf

# 就是客户端连接vpn后,允许你通此vpn去访问以下主机
route = 10.206.0.15/32           # 内网
route = 119.45.140.59/32,eth0    # 外网
1.2.4 启动
systemctl restart ocserv.service
systemctl enable ocserv.service
systemctl status ocserv.service

image-20240330193412827

注意!!!ocserv 服务器安全组放通 443 端口(对外-所有),便于用户来连接你的 VPN。

1.3 常用命令

1、查看当前服务运行状态

occtl -n show status

image-20240330182224829

2、查看当前在线用户详情

occtl -n show users

3、踢掉当前在线用户

# 法1
occtl disconnect user <用户名>

# 法2
occtl disconnect id <id号>

二、FreeIPA

官网:https://www.freeipa.org/

官网部署文档:https://www.freeipa.org/page/Quick_Start_Guide

2.1 场景

那 Freeipa 又是什么呢?其实是一个开源的身份管理解决方案,旨在简化组织内部的身份验证、授权、策略和账户管理

主要使用了以下技术:

  1. LDAP(轻型目录访问协议):用于存储和管理用户、组、计算机等对象的目录服务。
  2. Kerberos:用于提供强大的身份验证和单点登录功能,确保用户可以安全地访问资源而无需多次身份验证。
  3. DNS(域名系统):用于管理网络上的域名和 IP 地址,以便识别网络资源。
  4. 证书颁发机构(CA):用于颁发和管理数字证书,用于安全通信和身份验证。

在实际应用中,Ocserv 和 FreeIPA 可以配合使用,以提供更完整的远程访问解决方案,如:

  1. 使用 FreeIPA 中存储的用户凭据进行身份验证。
  2. 使用 FreeIPA 作为身份验证源,可以实现单点登录和集中式用户管理。
  3. 这种集成可以提高安全性和管理效率,同时简化用户的远程访问体验。

2.2 部署

2.2.1 环境

1、服务器

HostVersion配置备注
CentOS/172.19.0.157.9.20092C/4G 20G云服务器 - 香港区,大陆请求 80/443 端口需要备案

2、软件(服务)

ServiceVersion备注
FreeIPA4.6.8LDAP 服务

3、其它

域名DNS证书备注
freeipa.vpnarsen.fun172.19.0.15 的公网 IP--
2.2.2 部署

1、修改主机名

Kerberos 身份验证依赖于静态主机名,如果主机名发生更改,Kerberos 身份验证可能会中断。

hostnamectl set-hostname freeipa.vpnarsen.fun

2、关闭防火墙

systemctl stop firewalld && systemctl disable firewalld

3、修改主机 hosts

echo '172.19.0.15 freeipa.vpnarsen.fun' >> /etc/hosts

4、从官方 CentOS 存储库安装 FreeIPA 软件包

yum install -y ipa-server bind-dyndb-ldap ipa-server-dns

5、设置 FreeIPA 服务器

ipa-server-install

我们这里暂时先不配置 DNS

image-20240331010522791

1)配置服务器主机名 - Server host name

image-20240331001355868

2)配置域名 - domain name

image-20240330221848748

3)配置领域名 - realm name

image-20240330221947123

那 domain name 和 realm name 区别?- - 交给 GPT 来解答

image-20240330212753977

4)配置目录管理员密码 - Directory Manager password

某些目录服务器操作需要管理用户,此用户称为目录管理员,具有完全访问权限。添加到系统管理任务的目录中,并将添加到。为IPA创建的目录服务器实例,密码长度必须至少为 8 个字符。

image-20240330214931319

5)设置 IPA 管理员密码 - IPA admin password

IPA服务器需要名为‘admin’的管理用户,此用户是用于 IPA 服务器管理的常规系统帐户。

image-20240330215103959

6)是否配置 DNS 转发器?- - no

这里先不配置,不是我们的目标

image-20240330223730424

7)是否要搜索缺少的反向区域?- - no

image-20240330223959621

8)是否继续使用这些值配置系统?- - yes

image-20240330224259180

这里需要等待 3~5 分钟,耐心等待 …

image-20240330224721826

在此阶段,我们已经在 CentOS 7 服务器上设置了 FreeIPA,接下来要验证我们的配置。

9)验证管理员

kinit admin

image-20240330225245447

10)验证管理员用户在 FreeIPA 数据库上是否可用

ipa user-find admin

image-20240330225526156

如何卸载重装?

ipa-server-install --uninstall

# 卸载完成之后再次 ipa-server-install 即可

如何重启?

systemctl restart ipa.service

6、放通安全组入站白名单

TCP:80,443,389,636,88,464,53
UDP:88,464,53,123
2.2.3 验证

输入 http://freeipa.vpnarsen.fun 后会 301 重定向到 https://freeipa.vpnarsen.fun/ipa/ui/

image-20240331011619819

image-20240331012302627

2.2.4 ssl 配置

1、安装ssl证书模块

yum install mod_ssl -y

装好mod_ssl模块后,在我们的/etc/httpd/conf.d目录下会生成一个ssl.conf

image-20240331101432257

2、创建证书的存放目录

mkdir /etc/httpd/ssl

3、配置 ssl 证书

2.3 集成 Ocserv

2.3.1 Ocserv 注册

这里的话就非常简单了,vpn 服务器安装 ipa 客户端,然后通过 ipa 客户端注册到 freeipa 上。

1、安装客户端

yum install -y ipa-client   # 或 yum install -y ipa-server 都是没问题的

2、添加 hosts

echo '<公网/内网IP> freeipa.vpnarsen.fun' >> /etc/hosts

3、注册到 freeipa

ipa-client-install
  • FreeIPA 域:VPNARSEN.FUN
  • FreeIPA 服务:freeipa.vpnarsen.fun
  • 输入:yes
  • 输入:yes
  • FreeIPA 的登录用户:admin
  • FreeIPA 的登录密码:xxxxxx

image-20240331015817043

如何重新注册?

ipa-client-install --uninstall

# 卸载完成之后再次 ipa-client-install 即可

3、验证

image-20240331013211798

2.3.2 FreeIPA 创建用户与用户组

1、创建用户组

这个用户组创建好后,需要在 ocserv 上对应创建,因为在连接 vpn 的时候需要选择用户组,而且 ocserv 中也要对组进行相关路由配置。

image-20240402131544673

image-20240402131712060

2、创建用户

这里只需要 freeipa 创建即可,因为 ocserv 已经集成到了 freeipa。

image-20240402132102708

image-20240402132312966

3、设置密码过期时间

这里一定要设置,因为 freeipa 创建的用户密码过期时间就是当前,因此我们需要设置更长的过期时间

在 freeipa 服务器上执行

# 1)先鉴权freeipa身份
kinit admin    # 回车后输入你安装freeipa时设置的admin管理员的密码

# 2)鉴权成功后修改用户密码过期时间
ipa user-mod opsuser --password-expiration=20240702120001Z

image-20240402133020845

你也可以到 freeipa 的 web 端去验证是否修改成功。

image-20240402133125599

4、将用户添加到组

创建的用户默认加入了 ipausers 组,我们可以放入指定的组,便于管理

image-20240402134133722

image-20240402134201823

image-20240402134240262

image-20240402134308630

image-20240402134326164

5、设置 OTP 二次验证

在一些公司的等保安全评审中,这往往是必须的一项,其作用就是,输入我们的登录密码后,还需要输入二次动态验证码。

image-20240402140956824

启用【双因素认证(密码+OTP)】

image-20240402141033661

然后点击【保存】

image-20240402141131388

继续点击【操作】,并【添加OTP令牌】

image-20240402141219097

点击【添加】

image-20240402141333632

截图保存生成的 OTP 令牌二维码,并点击【OK】

image-20240402141523566

此时就完成了 opsuser 用户的双因素认证!

2.3.3 Ocserv 配置

1、配置组

vim /etc/ocserv/ocserv.conf

image-20240402134536099

2、创建组配置文件

touch /etc/ocserv/config-per-group/ops.conf
vim /etc/ocserv/config-per-group/ops.conf
# 1)内网IP格式
# i.具体IP
route = 10.206.0.7/32   # 即连接vpn后可通过vpn路由到该目标IP
route = 10.206.0.17/32  # 同理
# ii.IP段
# route = 10.206.0.7/20
# 2)外网IP格式
# i.具体IP
# route = 119.45.218.115/32,eth0

3、重启 ocserv

systemctl restart ocserv.service

# 如果你只修改了配置文件,执行加载一下即可,因为重启会导致已经连接vpn的用户掉线
# systemctl reload ocserv.service
2.3.4 案例1 - 访问内网应用

连接 vpn 后访问夜莺监控

上面配置的 route = 10.206.0.17/32,该目标服务器是我用来部署夜莺监控的,且 0.17 服务器的安全组入站规则只允许 0.7(vpn 服务器)来访问,如下图:

image-20240402135609446

在实际中我们也会这样配置,我们公司内部所有的 web 应用的入站规则都必须通过 vpn 统一入口,这样就更安全,只有连接我们 vpn 的用户才能访问部署的一些 web 应用。

1、这里我使用的是 CISCO AnyConnect 客户端工具:

image-20240402140507751

2、输入登录信息:

image-20240402140635888

3、输入 opsuser 用户密码

image-20240402141955601

4、输入谷歌二次验证码

如何获取?

1、手机下载 Google 身份验证器 APP

2、打开 APP 并扫描你刚截图保存的二维码

3、扫描后即可获取 6 位动态验证码

image-20240402142146268

5、登录成功

image-20240402142221145

6、访问验证

http://10.206.0.17:17000/

如下图,此时我就可以通过私网地址直接访问。

image-20240402142525415

image-20240402143246680

2.3.5 案例2 - LDAP 应用

1、LDAP 配置

前面说了,freeipa 除了可以集成 ocserv,也是强大的 LDAP 管理服务,因此我们也借用夜莺上的 LDAP 功能来实现。

注意 389 安全组端口放通,freeipa 的入站需要允许目标 web 的请求。

当然,你也可以在目标服务器(如本次的 n9e 服务器)使用 LDAP 客户端工具测试一下是否可以连接到 LDAP 服务:

ldapsearch -x -H ldap://freeipa.vpnarsen.fun -b "cn=users,cn=accounts,dc=vpnarsen,dc=fun" -D "uid=adminldap,cn=users,cn=accounts,dc=vpnarsen,dc=fun" -W

# 如果没有ldapsearch命令,安装即可
# yum install -y openldap-clients

成功后输出如下:

image-20240403205300460

测试无误后,即可在 n9e web 端配置 LDAP 了,如下图:

image-20240403161203313

Enable = true                  # 启用LDAP
Host = 'freeipa.vpnarsen.fun'  # LDAP主机地址
Port = 389                     # 服务端口(非加密)
BaseDn = 'cn=users,cn=accounts,dc=vpnarsen,dc=fun'                   # 搜索操作的起始点,它定义了搜索操作的范围
BindUser = 'uid=adminldap,cn=users,cn=accounts,dc=vpnarsen,dc=fun'   # 用于绑定身份验证的用户
BindPass = 'xxxxx'           # 用户密码
AuthFilter = '(&(uid=%s))'   # 默认
CoverAttributes = true       # 默认
TLS = false                  # 改为false
StartTLS = false             # 设置为false
DefaultRoles = ['Standard']  # 默认

[Attributes]     # 默认
Nickname = 'cn'  # 默认
Phone = 'mobile' # 默认
Email = 'mail'   # 默认

配置后保存,然后退出当前的登录用户(无需重启 n9e 服务),用 freeipa 上的用户进行登录测试。

2、验证

我们就用 freeipa 已有的用户 opsuser 来测试即可。

需要注意的是,因为我们 freeipa 的用户采用了 OTP 双因素认证,因此,用户登录密码也是:密码 + 6位动态验证码,企业级别中我们推荐这样做。

image-20240403163450834

image-20240403163510487

没问题,freeipa 的 LDAP 的功能是可用的,只要支持 LDAP 的 web 应用都可使用 freeipa 的 LDAP 功能。

其它应用 LDAP 配置,如 jenkins,可参考 https://computingforgeeks.com/how-to-configure-jenkins-freeipa-ldap-authentication/

三、LDAP Tool Box Self Service Password

官网:https://self-service-password.readthedocs.io

官网部署文档:https://self-service-password.readthedocs.io/en/latest/installation.html#centos-redhat

3.1 场景

LDAP Tool Box Self Service Password(简称LTB Self Service Password)是一个开源的自助式密码重置和账户管理工具,专为LDAP目录服务设计。它允许LDAP用户通过Web界面自主更改其密码,解放了管理员的工作负担,并提高了用户的体验。

在实际应用场景中,我们 freeipa 的用户的密码过期时间一般会控制在 3~6 月,密码即将到期时,可以邮件的形式通知用户,用户就可以及时更新自己的密码,这样就不需要我们 freeipa 管理员集中操作,大大提升了工作效率。

3.2 部署

3.2.1 环境

1、服务器

HostVersion配置备注
CentOS/172.19.0.147.9.20092C/4G 20G云服务器 - 香港区,大陆请求 80/443 端口需要备案

2、软件(服务)

ServiceVersion备注
LDAP Tool Box Self Service Password1.5.4密码自助

3、其它

域名DNS证书备注
selfpd.vpnarsen.fun172.19.0.14 的公网 IP--

4、要求

Apache or another web server
php (>=7.4)
php-curl (haveibeenpwned api)
php-filter
php-gd (captcha)
php-ldap
php-mbstring (reset mail)
php-openssl (token crypt, probably built-in)
Smarty (version >=3) (php-smarty)
3.2.2 部署

部署参考:https://blog.csdn.net/qq_39438868/article/details/131702143

1、关闭 firewalld

systemctl stop firewalld.service
systemctl disable firewalld.service

2、修改主机名

hostnamectl set-hostname selfpd.vpnarsen.fun

3、配置 hosts

echo '172.19.0.14 selfpd.vpnarsen.fun' >> /etc/hosts

4、安装 nginx

yum install -y nginx
systemctl start nginx
systemctl enable nginx

验证:

image-20240403172843817

5、安装 PHP

yum install -y yum-utils && sudo yum install -y epel-release
rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
yum-config-manager --enable remi-php74
yum install -y php php-gd php-fpm php-mbstring php-ldap php-filter php-curl php-Smarty
3.2.3 配置

1、php 配置

1)修改启动用户为nginx

vim /etc/php-fpm.d/www.conf

image-20240403182049196

2)启动 php-fpm

systemctl start php-fpm
systemctl enable php-fpm

3)下载 self-service-password 代码包

地址:https://ltb-project.org/download.html

下载并上传至服务器

image-20240403173711293

tar -zxvf ltb-project-self-service-password-1.5.4.tar.gz 
mv ltb-project-self-service-password-1.5.4.tar.gz /usr/share/self-service-password
mv /usr/share/php/Smarty/ /usr/share/php/smarty3/
chown nginx.nginx -R /usr/share/self-service-password/
chown nginx.nginx -R /var/log/php-fpm

4)php 配置

vim /etc/php.ini
...
session.save_path = "/tmp"
upload_max_filesize = 10M
post_max_size = 16M
max_execution_time = 600
expose_php = Off
output_buffering = 4096
...
# 重载
systemctl reload php-fpm.service

5)修改时区

默认是 UTC 时间,我们需要修改一下:

vim /etc/php.ini

image-20240404121000681

2、nginx 配置

vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    log_format http_log_access '$remote_addr - $remote_user [$time_local] '
                               '"$request" $status $body_bytes_sent '
                               '"$http_referer" "$http_user_agent"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;
    server {
        listen 80;
        server_name selfpd.vpnarsen.fun;
        sendfile off;
        gzip on;
        gzip_comp_level 6;
        gzip_min_length 1000;
        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js;
        gzip_vary on;
        gzip_proxied any;
        gzip_disable "MSIE [1-6]\.(?!.*SV1)";
        access_log /data/logs/selfpd/http_access.log http_log_access;
        location / {
            root /usr/share/self-service-password/htdocs;
            index index.php index.html index.htm;
        }
        location ~ \.php {
            root /usr/share/self-service-password/htdocs;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_split_path_info       ^(.+\.php)(/.+)$;
            fastcgi_param PATH_INFO       $fastcgi_path_info;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_index index.php;
            try_files $fastcgi_script_name =404;
            fastcgi_read_timeout 600;
            include fastcgi_params;
        }
        error_page 404 /404.html;
        location = /404.html {
            root /usr/share/nginx/html;
            internal;
        }
        location ~ /\. {
            log_not_found off;
            deny all;
        }
        location ~ /scripts {
            log_not_found off;
            deny all;
        }
    }
}
mkdir -p /data/logs/selfpd

3、验证

http://selfpd.vpnarsen.fun/

image-20240403202056988

如何解决报红问题?根据提示修改即可

vim /usr/share/self-service-password/conf/config.inc.php  # 随便设置个随机字符串即可

image-20240403230710053

再次刷新页面:

image-20240403203916161

如何自定义上图中的文字内容?

vim /usr/share/self-service-password/lang/zh-CN.inc.php

image-20240403231519948

修改完成后,刷新一下页面你会发现内容已经更新了。

image-20240403231431576

3.3 集成 FreeIPA

vim /usr/share/self-service-password/conf/config.inc.php
# Base
$use_captcha = true;      # 开启验证码
$use_sms = false;         # 关闭短信重置
$use_questions = false;   # 关闭问题重置

# LDAP
$ldap_url = "ldap://freeipa.vpnarsen.fun:389";
$ldap_starttls = false;
$ldap_binddn = "uid=adminldap,cn=users,cn=accounts,dc=vpnarsen,dc=fun";
$ldap_bindpw = '********';
$ldap_base = "cn=users,cn=accounts,dc=vpnarsen,dc=fun";
$ldap_login_attribute = "uid";
$ldap_fullname_attribute = "cn";
$ldap_filter = "(&(objectClass=person)($ldap_login_attribute={login}))";
$ldap_use_exop_passwd = false;
$ldap_use_ppolicy_control = false;
$who_change_password = "adminldap";

# Mail
$token_lifetime = "300";         # Token lifetime in secondst 重置密码链接的有效时间
$mail_attributes = array( "mail", "gosaMailAlternateAddress", "proxyAddresses" );
$mail_address_use_ldap = true;   # 密码找回不需要输入邮箱
$mail_from = "xxxxx@163.com";
$mail_from_name = "密码即将过期,请及时修改密码!";
$mail_signature = "本邮件为自助修改LDAP账号密码,无需回复,此链接有效时间为5分钟,如有问题,请联系运维团队!";
$notify_on_change = true;
$mail_sendmailpath = '/usr/sbin/sendmail';
$mail_protocol = 'smtp';
$mail_smtp_debug = 0;
$mail_debug_format = 'html';
$mail_smtp_host = 'smtp.163.com';
$mail_smtp_auth = true;
$mail_smtp_user = 'xxxxx@163.com';
$mail_smtp_pass = '授权码';
$mail_smtp_port = 465;
$mail_smtp_timeout = 30;
$mail_smtp_keepalive = false;
$mail_smtp_secure = 'tls';
$mail_smtp_autotls = true;
$mail_smtp_options = array();
$mail_contenttype = 'text/plain';
$mail_wordwrap = 0;
$mail_charset = 'utf-8';
$mail_priority = 3;

再次刷新页面,只剩下【邮件】模块了:

image-20240403232952862

开始修改密码:

image-20240404123826552

image-20240404123534986

密码修改成功,接下来验证修改的密码是否生效,以夜莺为例(因为我已经在夜莺集成了 LDAP):

image-20240404125944266

image-20240404125957934

没问题!

FAQ

Ocserv 启动报错

image-20240330175522419

该错误可暂时不用管,不影响使用。

—END

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云计算-Security

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值