在OpenVPN上组织远程工作SMB组织

问题的提法


本文介绍了开放源产品上员工的远程访问组织,既可以用于构建完全自治的系统,又可以在现有商业系统中缺少许可证或性能不足时用于扩展。

本文的目的是介绍一个用于提供对组织的远程访问的完整系统,这比“在10分钟内安装OpenVPN”要略多。

结果,我们得到一个系统,其中证书和(可选)Active Directory公司目录将用于用户身份验证。至。我们得到一个具有两个验证因素的系统-我拥有的(证书)和我知道的(密码)。

允许用户连接的标志是他在myVPNUsr组中的成员身份。证书颁发机构将独立使用。

实施该解决方案的成本只有很小的硬件资源,并且需要系统管理员花费1个小时的时间。

我们将在CetntOS 7上使用带有OpenVPN和Easy-RSA 3rd版本的虚拟机,该虚拟机基于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,并且为VPN客户端分配了子网172.16.20.0/23。 。

要从外部进行连接,请在端口1194 / udp上使用连接,并在我们服务器的DNS中创建一个A记录gw.abc.ru。

强烈建议不要禁用SELinux!OpenVPN可以在不禁用安全策略的情况下工作。

内容


  1. 操作系统和应用程序软件安装
  2. 密码学设置
  3. 配置OpenVPN
  4. AD中的身份验证
  5. 启动和诊断
  6. 证书的签发和撤销
  7. 网络配置
  8. 下一步是什么


操作系统和应用程序软件安装


我们使用分发套件CentOS 7.8.2003。我们需要以最小配置安装操作系统。使用kickstart,克隆先前安装的OS映像和其他方法可以很方便地进行此操作

安装后,为网络接口分配地址(根据任务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="admin@abc.ru"
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 leap年)。在颁发用户证书之前,需要调整此值。

接下来,建立一个独立的证书颁发机构。

配置包括导出变量,初始化CA,颁发根密钥和CA证书,Diffie-Hellman密钥,TLS密钥以及服务器密钥和证书。证书颁发机构密钥必须小心保护并保密!默认情况下,可以保留请求中的所有参数。

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


为了支持第二个因素,我们将在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 =用户,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.ru \ myGrp中的组myVPNUsr);
  • SearchFilter“(cn = myVPNUsr)”是解析组的名称。


启动和诊断


现在,我们可以尝试打开并启动服务器:

$ sudo systemctl enable openvpn@server.service
$ sudo systemctl start openvpn@server.service

启动检查:

systemctl status openvpn@server.service
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(有效)-有效;
    • 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

应用设置-常用的firewalld命令重新读取设置:

$ sudo firewall-cmd --reload

丢弃的报文可以如下查看:

grep forward_fw /var/log/messages


下一步是什么


设置完成!

它仍然保留在客户端上,以安装客户端软件,导入配置文件并进行连接。对于Windows之类的操作系统,可以在开发人员的站点上找到该发行版

总之,我们将新服务器连接到监视和归档系统,并且不要忘记定期安装更新。

连接稳定!

All Articles