制定问题
文章介绍了开源产品上员工远程访问的组织方式,既可以用来构建完全自治的系统,也可以在现有商业系统许可证不足或性能不足时进行扩展。
本文的目标是实现一个完整的系统,为组织提供远程访问,这只不过是“在 10 分钟内安装 OpenVPN”。
因此,我们将获得一个系统,其中将使用证书和(可选)企业 Active Directory 对用户进行身份验证。 那。 我们将得到一个具有两个验证因素的系统 - 我所拥有的(证书)和我所知道的(密码)。
用户被允许连接的标志是他们在 myVPNUsr 组中的成员身份。 证书颁发机构将离线使用。
实施该解决方案的成本仅为少量的硬件资源和系统管理员1小时的工作。
我们将在 CetntOS 3 上使用具有 OpenVPN 和 Easy-RSA 版本 7 的虚拟机,为每 100 个连接分配 4 个 vCPU 和 4 GiB RAM。
在示例中,我们组织的网络为 172.16.0.0/16,其中地址为 172.16.19.123 的 VPN 服务器位于网段 172.16.19.0/24,DNS 服务器为 172.16.16.16 和 172.16.17.17,子网为 172.16.20.0 .23/XNUMX 分配给 VPN 客户端。
要从外部连接,请使用通过端口 1194/udp 的连接,并且已在我们服务器的 DNS 中创建了一条 A 记录 gw.abc.ru。
严格不建议禁用 SELinux! OpenVPN 无需禁用安全策略即可工作。
内容
操作系统和应用软件的安装
我们使用 CentOS 7.8.2003 发行版。 我们需要以最低配置安装操作系统。 使用以下命令可以方便地执行此操作
安装后,为网络接口分配一个地址(根据任务172.16.19.123的条款),我们更新操作系统:
$ sudo yum update -y && reboot
我们还需要确保我们的机器上执行时间同步。
要安装应用程序软件,您需要 openvpn、openvpn-auth-ldap、easy-rsa 和 vim 软件包作为主编辑器(您将需要 EPEL 存储库)。
$ sudo yum install epel-release
$ sudo yum install openvpn openvpn-auth-ldap easy-rsa vim
为虚拟机安装访客代理非常有用:
$ sudo yum install open-vm-tools
对于 VMware ESXi 主机或 oVirt
$ sudo yum install ovirt-guest-agent
设置密码学
进入easy-rsa目录:
$ cd /usr/share/easy-rsa/3/
创建变量文件:
$ sudo vim vars
以下内容:
export KEY_COUNTRY="RU"
export KEY_PROVINCE="MyRegion"
export KEY_CITY="MyCity"
export KEY_ORG="ABC LLC"
export KEY_EMAIL="[email protected]"
export KEY_CN="allUsers"
export KEY_OU="allUsers"
export KEY_NAME="gw.abc.ru"
export KEY_ALTNAMES="abc-openvpn-server"
export EASYRSA_CERT_EXPIRE=3652
此处描述了条件组织 ABC LLC 的参数;您可以将它们更正为实际参数或将它们保留在示例中。 参数中最重要的是最后一行,它决定了证书的有效期(以天为单位)。 该示例使用值 10 年(365*10+2 闰年)。 在颁发用户证书之前需要调整该值。
接下来,我们配置一个自治的证书颁发机构。
设置包括导出变量、初始化 CA、颁发 CA 根密钥和证书、Diffie-Hellman 密钥、TLS 密钥以及服务器密钥和证书。 CA 密钥必须小心保护并保密! 所有查询参数都可以保留为默认值。
cd /usr/share/easy-rsa/3/
. ./vars
./easyrsa init-pki
./easyrsa build-ca nopass
./easyrsa gen-dh
./easyrsa gen-req myvpngw nopass
./easyrsa sign-req server myvpngw
./easyrsa gen-crl
openvpn --genkey --secret pki/ta.key
设置 OpenVPN
进入 OpenVPN 目录,创建服务目录并添加 easy-rsa 链接:
cd /etc/openvpn/
mkdir /var/log/openvpn/ /etc/openvpn/ccd /usr/share/easy-rsa/3/client
ln -s /usr/share/easy-rsa/3/pki/ /etc/openvpn/
创建主 OpenVPN 配置文件:
$ sudo vim server.conf
以下内容
port 1194
proto udp
dev tun
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/myvpngw.crt
key /etc/openvpn/pki/private/myvpngw.key
crl-verify /etc/openvpn/pki/crl.pem
dh /etc/openvpn/pki/dh.pem
server 172.16.20.0 255.255.254.0
ifconfig-pool-persist ipp.txt
push "route 172.16.0.0 255.255.255.0"
push "route 172.17.0.0 255.255.255.0"
client-config-dir ccd
push "dhcp-option DNS 172.16.16.16"
push "dhcp-option DNS 172.16.17.17"
keepalive 10 120
cipher AES-256-CBC
user nobody
group nobody
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
explicit-exit-notify 1
username-as-common-name
plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-ldap.so /etc/openvpn/ldap.conf
关于参数的一些注释:
- 如果在颁发证书时指定了不同的名称,请注明;
- 指定适合您任务的地址池*;
- 可以有一个或多个路由和DNS服务器;
- 最后两行是在 AD** 中实现身份验证所必需的。
*示例中选择的地址范围最多允许 127 个客户端同时连接,因为选择 /23 网络,OpenVPN 使用 /30 掩码为每个客户端创建一个子网。
如果特别有必要,可以更改端口和协议,但是应该记住,更改端口端口号将需要配置 SELinux,并且使用 tcp 协议会增加开销,因为TCP 数据包传送控制已在封装在隧道中的数据包级别执行。
**如果不需要在AD中进行身份验证,请将其注释掉,跳过下一节,并在模板中 删除 auth-user-pass 行.
广告认证
为了支持第二个因素,我们将在 AD 中使用帐户验证。
我们需要在域中拥有一个具有普通用户和组权限的帐户,其中的成员资格将决定连接的能力。
创建配置文件:
/etc/openvpn/ldap.conf
以下内容
<LDAP>
URL "ldap://ldap.abc.ru"
BindDN "CN=bindUsr,CN=Users,DC=abc,DC=ru"
Password b1ndP@SS
Timeout 15
TLSEnable no
FollowReferrals yes
</LDAP>
<Authorization>
BaseDN "OU=allUsr,DC=abc,DC=ru"
SearchFilter "(sAMAccountName=%u)"
RequireGroup true
<Group>
BaseDN "OU=myGrp,DC=abc,DC=ru"
SearchFilter "(cn=myVPNUsr)"
MemberAttribute "member"
</Group>
</Authorization>
主要参数:
- URL“ldap://ldap.abc.ru”-域控制器地址;
- BindDN “CN=bindUsr,CN=Users,DC=abc,DC=ru” - 绑定到 LDAP 的规范名称(UZ - abc.ru/Users 容器中的 bindUsr);
- 密码b1ndP@SS——绑定的用户密码;
- BaseDN “OU=allUsr,DC=abc,DC=ru” — 开始搜索用户的路径;
- BaseDN “OU=myGrp,DC=abc,DC=ru” – 允许组的容器(容器 abc.rumyGrp 中的组 myVPNUsr);
- SearchFilter“(cn=myVPNUsr)”是允许组的名称。
启动和诊断
现在我们可以尝试启用并启动我们的服务器:
$ sudo systemctl enable [email protected]
$ sudo systemctl start [email protected]
启动检查:
systemctl status [email protected]
journalctl -xe
cat /var/log/messages
cat /var/log/openvpn/*log
证书颁发和撤销
因为除了证书本身之外,您还需要密钥和其他设置;将所有这些内容包装在一个配置文件中非常方便。 然后,该文件会传输给用户,并且配置文件会导入到 OpenVPN 客户端上。 为此,我们将创建一个设置模板和一个生成配置文件的脚本。
您需要将根证书 (ca.crt) 和 TLS 密钥 (ta.key) 文件的内容添加到配置文件中。
颁发用户证书之前 不要忘记设置证书所需的有效期 在参数文件中。 您不应该安排太长的时间;我建议您最多限制在 180 天。
vim /usr/share/easy-rsa/3/vars
...
export EASYRSA_CERT_EXPIRE=180
vim /usr/share/easy-rsa/3/client/template.ovpn
client
dev tun
proto udp
remote gw.abc.ru 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
verb 3
auth-user-pass
<ca>
-----BEGIN CERTIFICATE-----
PUT YOUR CA CERT (ca.crt) HERE
-----END CERTIFICATE-----
</ca>
key-direction 1
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
PUT YOUR TA KEY (ta.key) HERE
-----END OpenVPN Static key V1-----
</tls-auth>
注:
- 线 把你的... 更改内容 他们的 证书;
- 在远程指令中,指定网关的名称/地址;
- auth-user-pass 指令用于额外的外部身份验证。
在主目录(或其他方便的位置)中,我们创建一个用于请求证书和创建配置文件的脚本:
vim ~/make.profile.sh
#!/bin/bash
if [ -z "$1" ] ; then
echo Missing mandatory client name. Usage: $0 vpn-username
exit 1
fi
#Set variables
basepath=/usr/share/easy-rsa/3
clntpath=$basepath/client
privpath=$basepath/pki/private
certpath=$basepath/pki/issued
profile=$clntpath/$1.ovpn
#Get current year and lowercase client name
year=`date +%F`
client=${1,,}
echo Processing $year year cert for user/device $client
cd $basepath
if [ -f client/$client* ]; then
echo "*** ERROR! ***"
echo "Certificate $client already issued!"
echo "*** ERROR! ***"
exit 1
fi
. ./vars
./easyrsa --batch --req-cn=$client gen-req $client nopass
./easyrsa --batch sign-req client $client
#Make profile
cp $clntpath/template.ovpn $profile
echo "<key>" >> $profile
cat $privpath/$1.key >> $profile
echo "</key>" >> $profile
echo -e "n" >> $profile
openssl x509 -in $certpath/$1.crt -out $basepath/$1.crt
echo "<cert>" >> $profile
cat $basepath/$1.crt >> $profile
echo "</cert>" >> $profile
echo -e "n" >> $profile
#remove tmp file
rm -f $basepath/$1.crt
echo Complete. See $profile file.
cd ~
使文件可执行:
chmod a+x ~/make.profile.sh
我们可以颁发我们的第一个证书。
~/make.profile.sh my-first-user
召回
如果证书遭到泄露(丢失、被盗),则需要吊销该证书:
cd /usr/share/easy-rsa/3/
./easyrsa revoke my-first-user
./easyrsa gen-crl
查看已颁发和吊销的证书
要查看已颁发和已吊销的证书,只需查看索引文件:
cd /usr/share/easy-rsa/3/
cat pki/index.txt
说明:
- 第一行是服务器证书;
- 第一个字符
- V(Valid)——有效;
- R(撤销)- 召回。
网络设置
最后一步是配置传输网络 - 路由和防火墙。
允许本地防火墙中的连接:
$ sudo firewall-cmd --add-service=openvpn
$ sudo firewall-cmd --add-service=openvpn --permanent
接下来,启用 IP 流量路由:
$ sudo sysctl net.ipv4.ip_forward=1
$ sudo echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/50-sysctl.conf
在企业环境中,可能存在子网划分,我们需要告诉路由器如何发送发往 VPN 客户端的数据包。 在命令行上我们以如下方式执行命令(取决于所使用的设备):
# ip route 172.16.20.0 255.255.254.0 172.16.19.123
并保存配置。
另外,在提供外部地址gw.abc.ru的边界路由器接口上,需要允许udp/1194数据包通过。
如果组织有严格的安全规则,则还必须在我们的 VPN 服务器上配置防火墙。 在我看来,最大的灵活性是通过设置 iptables FORWARD 链来提供的,尽管设置它们不太方便。 关于设置它们的更多信息。 为此,最方便的是使用“直接规则”——直接规则,存储在文件中 /etc/firewalld/direct.xml。 目前的规则配置如下:
$ sudo firewall-cmd --direct --get-all-rule
在更改文件之前,请先对其进行备份:
cp /etc/firewalld/direct.xml /etc/firewalld/direct.xml.`date +%F.%T`.bak
该文件的大概内容是:
<?xml version="1.0" encoding="utf-8"?>
<direct>
<!--Common Remote Services-->
<!--DNS-->
<rule priority="0" table="filter" ipv="ipv4" chain="FORWARD">-i tun0 -o ens192 -p udp --dport 53 -j ACCEPT</rule>
<!--web-->
<rule priority="0" table="filter" ipv="ipv4" chain="FORWARD">-i tun0 -o eth0 -p tcp -d 172.16.19.200 --dport 80 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT</rule>
<rule priority="0" table="filter" ipv="ipv4" chain="FORWARD">-i tun0 -o eth0 -p tcp -d 172.16.19.201 --dport 443 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT</rule>
<!--Some Other Systems-->
<rule priority="0" table="filter" ipv="ipv4" chain="FORWARD">-i tun0 -o eth0 -p udp -d 172.16.19.100 --dport 7000 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT</rule>
<!--just logging-->
<rule priority="1" table="filter" ipv="ipv4" chain="FORWARD">-i tun0 -o eth0 -j LOG --log-prefix 'forward_fw '</rule>
</direct>
说明
这些本质上是常规的 iptables 规则,在 Firewalld 出现后被打包。
默认设置的目的接口为tun0,隧道的外部接口可能会有所不同,例如ens192,具体取决于所使用的平台。
最后一行用于记录丢弃的数据包。 为了使日志记录正常工作,您需要更改firewalld配置中的调试级别:
vim /etc/sysconfig/firewalld
FIREWALLD_ARGS=--debug=2
应用设置是重新读取设置的常用防火墙命令:
$ sudo firewall-cmd --reload
您可以像这样查看丢弃的数据包:
grep forward_fw /var/log/messages
接下来是什么
这样就完成了设置!
剩下的就是在客户端安装客户端软件、导入配置文件并连接。 对于 Windows 操作系统,分发工具包位于
最后,我们将新服务器连接到监控和归档系统,并且不要忘记定期安装更新。
连接稳定!
来源: habr.com