本文讨论了具有其他功能的OpenVPN的配置:
- 用于主要身份验证的令牌证书(以Rutoken为例)
- 用于辅助身份验证的LDAP后端(以ActiveDirectory为例)
- 过滤用户可用的内部资源(通过iptables)
它还描述了如何为Linux,Windows和MacOS配置客户端。
服务器设置
安装OpenVPN
以脚本
Nyr / openvpn-install ,从根目录运行。
git clone https://github.com/Nyr/openvpn-install.git cd openvpn-install
启动过程将询问一些问题。
- udp协议
- 1194端口
- DNS服务器-本地
- 外部ip-Internet上的网关地址,通过该网关可以使用vpn服务器
原始脚本还有一个增强安全性的版本
-github.com/Angristan/OpenVPN-install 。 它具有更多的加密设置以及原因说明。
用户管理
新增中如果不使用令牌,则通过相同的脚本添加用户。 该脚本实质上会生成一个自定义的ovpn配置,并在其中插入由根证书签名的证书。
如果使用了令牌(请参阅下面的令牌部分),那么将根据对令牌生成的证书请求,手动将证书写出。 用户配置必须从现有模板(从生成配置脚本的模板)中手动完成。 模板在这里
/etc/openvpn/client-common.txt
。 它不包含在openvpn软件包中,而是由脚本在配置过程中生成的。
删掉删除用户是通过相同的安装脚本完成的。 证书被添加到
CRL ,新的CRL被推送到vpn服务器。 服务器认为CRL中的所有证书均无效,并拒绝接受。
如何手动吊销证书:
cd /etc/openvpn/easyrsa # ./easyrsa revoke $CLIENT # crl ./easyrsa gen-crl # crl rm -rf /etc/openvpn/crl.pem # cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem # openvpn crl, nobody chown nobody:nobody /etc/openvpn/crl.pem
筛选客户端可用的主机
客户端需要受它们连接到openvpn时可以在网络上访问的主机的限制。
手动地这个想法是即使在
tun0
接口上也要捕获数据包,这些数据包来自客户端,并在进入NAT之前对其进行过滤。 进行NAT之后,将没有理由对其进行过滤-它们在内部网络上都将具有openvpn服务器ip地址。 在进入NAT之前,每个用户的数据包都有自己唯一的ip地址(有关ip地址和用户的对应关系,请参见文件
/etc/openvpn/ipp.txt
)。
穿过系统的数据包(不是直接来自系统,也不是传入的,也就是说,实际上是由系统路由)由FORWARD表处理。 iptables中的表是从上到下处理的,如果表中的任何规则都没有导致有关数据包命运的决定,那么将触发默认规则。
准备FORWARD表:
# iptables -F FORWARD # FORWARD - iptables -P FORWARD DROP # iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
特定客户的示例规则。 由于该表的默认规则是DROP,因此仅保留它允许的主机+端口对。 允许访问主机上的端口+ ping主机本身:
iptables -I FORWARD -s 10.8.0.3 -i tun0 -d 10.0.2.3 -p tcp --dport 443 -j ACCEPT iptables -I FORWARD -s 10.8.0.3 -i tun0 -d 10.0.2.3 -p icmp --icmp-type echo-request -j ACCEPT
在上面的示例中,主机10.8.0.3被允许访问主机10.0.2.3的端口443。
如何关闭访问权限:
# iptables -L FORWARD --line-numbers # iptables -D FORWARD { }
然后,您需要找到特定客户端的所有规则并将其删除。
在调试过程中,可以方便地查看哪些规则有效。 每个规则都有一个已处理数据包的计数器。
# , watch iptables -nvL FORWARD # iptables -Z FORWARD
自动地OpenVPN服务器可以执行某些动作的脚本。 特别是在连接和断开客户端时。 只要脚本是可执行的,脚本就可以写在任何东西上。 在脚本内部,环境变量将各种参数传递给当前连接。 我们对变量感兴趣:
common_name
(证书所有者的名称;创建证书时驱动到“通用名称”字段的内容)ifconfig_pool_remote_ip
(tun0上的客户端IP地址)script_type
(发生了哪个事件-连接或断开连接)。
您需要root特权才能管理iptables。 连接后的Openvpn会将权限重置为无人,并从中运行脚本。 不允许任何人从sudo下做某事是很不好的,最好不要在规则中使用星号,但是您需要以某种方式允许用户控制iptables。
在服务器配置中,您需要添加权限以执行第三方文件,并启用两个负责连接和断开用户连接的钩子。
script-security 2 client-connect /etc/openvpn/bin/hosts.rb client-disconnect /etc/openvpn/bin/hosts.rb
该脚本本身读取配置并为iptables应用规则。 该脚本的工作原理与上一节中所述的相同。
规则存储在与
/etc/openvpn/hosts
文件夹中的证书的通用名称相对应的文件中。 它们准确地指定了特定客户端可以使用的IP地址。 分隔符-任意数量的空格。 IP地址,端口和协议(tcp或udp)通过分隔符写入。
10.0.0.24 53 udp 10.0.0.25 53 udp 10.0.2.3 443 tcp
结果,以下结构应
/etc/openvpn
在
/etc/openvpn
文件夹中
├──箱
│└──hosts.rb
├──房东
│├──用户1
│├──user2
│└──大家
├──server.conf
└──...
User1
和
user2
是上述格式的文件。 它们描述了具有相应公共名称的用户可以访问的主机。
还有另一个附加的
everybody
文件,它包含适用于所有客户端的规则,前提是这些客户端有单独的配置文件。 也就是说,如果用户有一个可以访问的主机列表,则将应用此列表以及
everybody
人中列出的那些主机。 如果没有,那么
everybody
都不适用。 例如,将DNS服务器放置在此文件中非常方便。
记录中安装脚本仅包括当前连接的日志记录(
status)
参数
status)
。 为了显示常规日志,您需要在服务器配置(
/etc/openvpn/server.conf
)中添加
/etc/openvpn/server.conf
:
log-append /var/log/openvpn.log
LDAP有一个
openvpn-auth-ldap插件,可让您通过LDAP再次验证用户身份。
交付包裹:
sudo yum install openvpn-auth-ldap
添加到server.conf:
plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-ldap.so "/etc/openvpn/ldap.conf"
在
/etc/openvpn/ldap.conf
为ldap创建一个配置:
<LDAP> URL ldaps://{LDAP_DOMAIN_HERE} Timeout 15 TLSEnable no FollowReferrals yes BindDN "BIND_DN_HERE" Password "BIND_PASSWORD_HERE" </LDAP> <Authorization> BaseDN "{BASE_DN_HERE}" SearchFilter "(&(sAMAccountName=%u)(objectClass=organizationalPerson)(objectCategory=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))" RequireGroup false </Authorization>
将行添加到自定义ovpn配置中:
auth-user-pass
因此,首先将要求用户从域中输入用户名和密码,然后是来自令牌的PIN。 如果这些步骤之一失败,将不会建立连接。
ldap.conf的选项描述
在插件存储库中 。 它支持通过组成员身份进行身份验证,但我尚未对其进行测试。
速度
速度的最大提高使udp模式成为可能。 在所有手册中都建议这样做。 关键是,在TCP通道中启动TCP客户端连接没有任何意义。 客户端一个TCP就足以正确发送数据包。 如果数据包在udp通道中丢失,则客户端tcp连接将控制传递调整。
速度至少会提高,因为不需要等待确认通道中每个数据包的传递。 TCP存在第二个问题-一个客户端tcp数据包很可能不适合vpn通道的一个数据包。 MTU相同,但是需要将标头添加到客户端程序包。 结果,您必须在每个用户数据包的vpn通道内发送两个数据包。
如果无法通过其他方式使用TCP,则可以使用。 例如,当vpn通过ssh通道工作时。
完整服务器配置的示例
example-server.conf port 1194 proto tcp dev tun sndbuf 0 rcvbuf 0 ca ca.crt cert server.crt key server.key dh dh.pem tls-auth ta.key 0 topology subnet server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 10.0.0.25" push "dhcp-option DNS 10.0.0.24" keepalive 10 120 cipher AES-256-CBC comp-lzo user nobody group nobody persist-key persist-tun status openvpn-status.log verb 3 crl-verify crl.pem log-append /var/log/openvpn.log script-security 2 client-connect /etc/openvpn/bin/hosts.rb client-disconnect /etc/openvpn/bin/hosts.rb
代币设置
PKCS#11库
要使用令牌,您需要一个特殊的库。 创建密钥对和实际连接都需要该库。
通过链接下载所有平台 。
以后无论在哪里找到librtpkcs11ecp.so,这都是一个需要下载的库,并将其放在方便的地方。
在令牌上创建证书
在令牌上生成密钥对。 这里的id参数是密钥对适合的令牌上插槽的序列号。
pkcs11-tool --module /usr/lib64/librtpkcs11ecp.so --keypairgen --key-type rsa:2048 -l --id 01
提出公共密钥证书请求。 在创建证书请求的过程中,将设置证书的生存期和通用名称,该名称和名称用于过滤网络中的可用ip地址。 公用名必须与ActiveDirectory中的登录名匹配,以免造成混淆。
openssl openssl> engine -t dynamic -pre SO_PATH:/usr/lib64/openssl/engines/pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/lib64/librtpkcs11ecp.so openssl> req -engine pkcs11 -new -key slot_0-id_01 -keyform engine -out /home/john/good.req
收到的请求必须移至
/etc/openvpn/easy-rsa/pki/reqs/
。 文件扩展名必须为
req
。
将请求转换为证书:
cd /etc/openvpn/easy-rsa/ ./easyrsa sign-req client good
之后,具有相同名称但扩展名为
crt
的证书将出现在
/etc/openvpn/easy-rsa/pki/issued/
文件夹中。
在记录之前,必须将证书转换为DER:
openssl x509 -in /home/user/user-cert.pem -out /home/user/user-cert.crt -outform DER
为令牌编写证书:
pkcs11-tool --module /usr/lib/librtpkcs11ecp.so -l -y cert -w /home/user/user-cert.crt --id 45 --label TEST
它是根据
“将Rutoken EDS与OpenSSL(RSA)结合使用”一文编写的。
使用令牌进行身份验证
找到要提供给服务器的证书的ID:
$ openvpn --show-pkcs11-ids /usr/lib64/librtpkcs11ecp.so The following objects are available for use. Each object shown below may be used as parameter to --pkcs11-id option please remember to use single quote mark. Certificate DN: /CN=User1 Serial: 490B82C4000000000075 Serialized id: aaaa/bbb/41545F5349474E415455524581D2A1A1B23C4AA4CB17FAF7A4600
我们对这里的序列化ID感兴趣。
必须在ovpn配置中输入的选项,以便令牌可以使用:
pkcs11-providers /usr/lib64/librtpkcs11ecp.so pkcs11-id 'aaaa/bbb/41545F5349474E415455524581D2A1A1B23C4AA4CB17FAF7A4600'
pkcs11-id
选项
必须用单引号引起来。本手册适用于所有平台。 您需要在标记上指定库的路径和证书ID。 该库的名称可能有所不同,即
.dll
而不是
.so
,但含义相同。
在这种情况下,您需要从ovpn文件中删除
cert
和
key
部分,因为证书和私钥将从令牌中获取。
完整的客户端配置(对于Windows)如下所示:
客户程序client
dev tun
proto tcp
sndbuf 0
rcvbuf 0
remote 78.47.37.247 22222
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
comp-lzo
setenv opt block-outside-dns
key-direction 1
verb 3
pkcs11-providers "c://Windows//System32//rtPKCS11ECP.dll"
pkcs11-id 'Aktiv\x20Co\x2E/Rutoken\x20ECP/342b871d/Rutoken/01'
-----BEGIN CERTIFICATE-----
{CERT_HERE}
-----END CERTIFICATE-----
<tls-auth>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
{KEY_HERE}
-----END OpenVPN Static key V1-----
</tls-auth>
基于
“如何使用客户端智能卡向OpenVPN配置添加双因素身份验证”撰写。
客户设置
的Linux
Openvpn有一个错误,如果该程序包是在systemd支持下构建的,则阻止用户从令牌中输入PIN码。 由于systemd最近无处不在,因此存储库中所有可用的软件包都将在其支持下进行编译。 Linux上的客户端需要自行收集软件包。 这是在Arch Linux上为我工作的示例配置:
./configure \ --prefix=/usr \ --sbindir=/usr/bin \ --enable-iproute2 \ --enable-pkcs11 \ --enable-plugins \ --enable-x509-alt-username
您可以使用以下命令验证openvpn是使用systemd或不使用systemd构建的:
openvpn --version | grep --color enable_systemd
马索斯
在Mac OS下,只有一个免费客户端
-Tunnelblink 。
他不知道如何从gui令牌输入密码。 该错误的描述示例如下:
https: //groups.google.com/forum/#!
topic/ tunnelblick-discuss/f_Rp_2nV-x8从控制台启动openvpn可以绕过此错误。 鉴于Windows的官方客户端也不知道这一点,因此这并不奇怪。
同样在Mac OS(不同于Windows)下,还需要其他脚本来配置网络。 如果仅从控制台运行openvpn,则DNS将不起作用(也许其他原因,仅DNS将出现)。
TunnelBlick具有这些网络配置脚本,仅在建立和断开连接时才需要调用它们。 您需要添加到ovpn配置的内容:
script-security 2 up "/Applications/Tunnelblick.app/Contents/Resources/client.up.tunnelblick.sh -9 -d -f -m -w -ptADGNWradsgnw" down "/Applications/Tunnelblick.app/Contents/Resources/client.down.tunnelblick.sh -9 -d -f -m -w -ptADGNWradsgnw"
用于启动openvpn连接的示例脚本,可以将其放在桌面上并用鼠标戳一下:
#!/bin/bash tunnelblick=/Applications/Tunnelblick.app/Contents/Resources/openvpn/openvpn-2.4.2-openssl-1.0.2k sudo $tunnelblick/openvpn --config $tunnelblick/user.ovpn
窗户
在Windows下,一切似乎正常。 官方客户端不知道如何从令牌输入PIN码,而是设法从控制台手动打开vpn。
最重要的事情是从管理员那里做所有事情。 以管理员身份运行客户端安装程序。 启动同时具有管理员权限的openvpn启动终端,否则它将无法控制网络接口。
在Windows下,用于处理令牌的库的路径应通过双斜杠记录。 这适用于命令行上的ovpn配置和
--show-pkcs11-ids
选项。
pkcs11-providers "c://Windows//System32//rtPKCS11ECP.dll" pkcs11-id 'Aktiv\x20Co\x2E/Rutoken\x20ECP/342b871d/Rutoken/01'