在 OpenVPN 上组织中小企业组织的远程工作

制定问题

文章介绍了开源产品上员工远程访问的组织方式,既可以用来构建完全自治的系统,也可以在现有商业系统许可证不足或性能不足时进行扩展。

本文的目标是实现一个完整的系统,为组织提供远程访问,这只不过是“在 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 无需禁用安全策略即可工作。

内容

  1. 操作系统和应用软件的安装
  2. 设置密码学
  3. 设置 OpenVPN
  4. 广告认证
  5. 启动和诊断
  6. 证书颁发和撤销
  7. 网络设置
  8. 接下来是什么

操作系统和应用软件的安装

我们使用 CentOS 7.8.2003 发行版。 我们需要以最低配置安装操作系统。 使用以下命令可以方便地执行此操作 Kickstart中、克隆以前安装的操作系统映像等方式。

安装后,为网络接口分配一个地址(根据任务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

添加评论