《Linux系统安全:纵深防御、安全扫描与入侵检测 》 —3.4 使用OpenVPN创建远程访问的虚拟专用网络

华章计算机 发表于 2019/11/14 12:25:45 2019/11/14
【摘要】 本节书摘来自华章计算机《Linux系统安全:纵深防御、安全扫描与入侵检测》一书中第3章,第3.4节,作者是胥峰。

3.4 使用OpenVPN创建远程访问的虚拟专用网络

在上个实践中,我们创建了两台具有公网IP的服务器之间的虚拟专用网络,进行安全的数据传输。在本案例中,我们将创建远程访问(Remote Access)模式的虚拟专用网络。

在某些文档中,远程访问被称为Road Warrior(可以翻译为“移动办公”),是指为经常不在办公室的驻场人员或者远程办公的人员提供访问服务器资源或者办公网络资源的通道。在这些场景中,远程访问者一般没有公网IP,他们使用内网地址通过防火墙设备进行网络地址转换后连接互联网。

在本例中,我们使用的物理网络结构图如图3-5所示。

 image.png

图3-5 远程访问模式虚拟专用网络物理网络结构图

创建远程访问模式的虚拟专用网络的操作步骤如下。

1)在服务器a.b.c.239上生成CA证书、服务器证书、客户端证书。

在OpenVPN 2.0.9的源码包中有相关的脚本可以辅助我们进行证书的生成和管理。

我们首先从http://build.openvpn.net/downloads/releases/openvpn-2.0.9.tar.gz下载该代码。使用如下命令:

wget http://build.openvpn.net/downloads/releases/openvpn-2.0.9.tar.gz

解压缩后,进入以下目录:

[root@localhost easy-rsa]# cd openvpn-2.0.9/easy-rsa

[root@localhost easy-rsa]# ls

2.0       build-dh     build-key       build-key-pkcs12  build-req       clean-all  make-crl     README      revoke-full  vars

build-ca  build-inter  build-key-pass  build-key-server  build-req-pass  list-crl   openssl.cnf  revoke-crt  sign-req     Windows

生成如下CA证书:

[root@localhost easy-rsa]# . vars #初始化环境变量

NOTE: when you run ./clean-all, I will be doing a rm -rf on /root/openvpn/openvpn-2.0.9/easy-rsa/keys

[root@localhost easy-rsa]# ./clean-all #删除旧的文件

[root@localhost easy-rsa]# ./build-ca #创建root CA

Generating a 1024 bit RSA private key

...........................++++++

....++++++

writing new private key to 'ca.key'

-----

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country Name (2 letter code) [KG]:CN #填写国家代码

State or Province Name (full name) [NA]:SH #填写省份

Locality Name (eg, city) [BISHKEK]:SH #填写城市

Organization Name (eg, company) [OpenVPN-TEST]:XUFENG-INFO #填写组织名

Organizational Unit Name (eg, section) []:DEVOPS #填写部门名称

Common Name (eg, your name or your server's hostname) []:cert.xufeng.info

Email Address [me@myhost.mydomain]:xufengnju@163.com #填写管理员邮箱地址

Common Name (eg, your name or your server's hostname) []:cert.xufeng.info是最重要的字段,相当于发证机关root CA的组织代码。务必保持唯一。

生成OpenVPN服务器证书和私钥如下:

[root@localhost easy-rsa]# ./build-key-server vpnserver #extension = server

Generating a 1024 bit RSA private key

...........++++++

..........................................++++++

writing new private key to 'vpnserver.key'

-----

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country Name (2 letter code) [KG]:CN

State or Province Name (full name) [NA]:SH

Locality Name (eg, city) [BISHKEK]:SH

Organization Name (eg, company) [OpenVPN-TEST]:XUFENG-INFO

Organizational Unit Name (eg, section) []:VPN

Common Name (eg, your name or your server's hostname) []:vpnserver.xufeng.info

Email Address [me@myhost.mydomain]:xufengnju@163.com

Please enter the following 'extra' attributes

to be sent with your certificate request

A challenge password []:

An optional company name []:

Using configuration from /root/openvpn/openvpn-2.0.9/easy-rsa/openssl.cnf

Check that the request matches the signature

Signature ok

The Subject's Distinguished Name is as follows

countryName           :PRINTABLE:'CN'

stateOrProvinceName   :PRINTABLE:'SH'

localityName          :PRINTABLE:'SH'

organizationName      :PRINTABLE:'XUFENG-INFO'

organizationalUnitName:PRINTABLE:'VPN'

commonName            :PRINTABLE:'vpnserver.xufeng.info'

emailAddress          :IA5STRING:'xufengnju@163.com'

Certificate is to be certified until Dec  8 06:56:36 2025 GMT (3650 days)

Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y

Write out database with 1 new entries

Data Base Updated

Common Name (eg, your name or your server's hostname) []:vpnserver.xufeng.info是最重要的字段,相当于虚拟专用网络服务器的标识。建议使用虚拟专用网络服务器的完整域名(Fully Qualified Domain Name,FQDN),例如vpnserver.xufeng.info。

生成客户端需要的证书和私钥如下:

[root@localhost easy-rsa]# ./build-key vpnclient2

Generating a 1024 bit RSA private key

........................++++++

......++++++

writing new private key to 'vpnclient1.key'

-----

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country Name (2 letter code) [KG]:CN

State or Province Name (full name) [NA]:SH

Locality Name (eg, city) [BISHKEK]:SH

Organization Name (eg, company) [OpenVPN-TEST]:XUFENG-INFO

Organizational Unit Name (eg, section) []:VPN

Common Name (eg, your name or your server's hostname) []:vpnclient2.xufeng.info

Email Address [me@myhost.mydomain]:xufengnju@163.com

 

Please enter the following 'extra' attributes

to be sent with your certificate request

A challenge password []:

An optional company name []:

Using configuration from /root/openvpn/openvpn-2.0.9/easy-rsa/openssl.cnf

Check that the request matches the signature

Signature ok

The Subject's Distinguished Name is as follows

countryName           :PRINTABLE:'CN'

stateOrProvinceName   :PRINTABLE:'SH'

localityName          :PRINTABLE:'SH'

organizationName      :PRINTABLE:'XUFENG-INFO'

organizationalUnitName:PRINTABLE:'VPN'

commonName            :PRINTABLE:'vpnclient2.xufeng.info'

emailAddress          :IA5STRING:'xufengnju@163.com'

Certificate is to be certified until Dec  8 06:57:53 2025 GMT (3650 days)

Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y

Write out database with 1 new entries

Data Base Updated

Common Name (eg, your name or your server's hostname) []:vpnclient2.xufeng.info是最重要的字段,相当于虚拟专用网络客户端的标识。建议使用虚拟专用网络客户端的完整域名或用户的邮箱名加域名。

2)在服务器a.b.c.239配置OpenVPN,配置文件是server.conf。配置文件的内容如下:

port 1194 #使用1194端口进行监听

proto udp #使用UDP协议

dev tun #使用IP路由模式

ca      /etc/openvpn/ca.crt #指定CA证书位置

cert    /etc/openvpn/vpnserver.crt #指定服务器端证书位置

key     /etc/openvpn/vpnserver.key #指定服务器端私钥位置

dh      /etc/openvpn/dh1024.pem #使用Diffie-Hellman算法进行加密密钥计算

server 172.16.100.0 255.255.255.0 #客户端连接上虚拟专用网络后从此网段分配隧道IP

client-config-dir /etc/openvpn/ccd #使用此目录对各个虚拟专用网络客户端进行细粒度控制

route 192.168.20.0 255.255.255.0 #配置服务器增加一条到客户端网络的路由

client-to-client #允许不同的客户端进行互相访问,使用OpenVPN内部路由

keepalive 10 120 #每10s发送保活,120s内未收到保活信息时向OpenVPN进程发送SIGUSR1信号

#在TLS控制通道的通信协议上增加一层HMAC(Hash-based Message Authentication Code)防止dos攻击

tls-auth    /etc/openvpn/ta.key 0

comp-lzo #启用压缩

max-clients 100 #最大用户数

user nobody #执行OpenVPN进程的用户

group nobody #执行OpenVPN进程的组

persist-key #收到信号SIGUSR1时不重新读取key文件

persist-tun #收到信号SIGUSR1时不关闭tun虚拟网口和重新打开

#创建并修改权限,使nobody可以读写 /var/log/openvpn

status /var/log/openvpn/status.log  #指定状态日志位置

log-append  /var/log/openvpn/openvpn.log #指定运行日志位置

verb 4 #设置日志级别为一般级别,会记录正常连接信息和报错

我们来看看/etc/openvpn/ccd下文件vpnclient2.xufeng.info中的内容:

ifconfig-push 172.16.100.9 172.16.100.10 #指定客户端的IP为172.16.100.9

iroute 10.192.168.20.0 255.255.255.0 #加一条内部路由

push "route 10.168.103.0 255.255.255.0" #把该路由推送到客户端执行

1)ccd目录下的文件必须以客户端证书的Common Name为文件名。

2)ccd目录可以对每个不同的客户端进行细粒度控制。

3)iroute是必需的。在server.conf中的--route指令把包从内核路由到OpenVPN,进入OpenVPN以后,--iroute指令把包路由到该指定的客户端。

启动OpenVPN服务器进程。使用如下的命令:

openvpn --daemon --config /etc/openvpn/server.conf

3)在192.168.20.96上安装OpenVPN GUI,并部署配置文件。

在https://openvpn.net/index.php/download/community-downloads.html页面进行下载。

在32位Windows 7 系统上,我们通过以下链接进行下载并安装:

https://swupdate.openvpn.org/community/releases/openvpn-install-2.3.9-I601-i686.exe

在安装过程中,可能会出现确认界面,如图3-6所示。

 image.png

图3-6 OpenVPN安装确认界面

请勾选“始终信任来自‘OpenVPN Technologies,Inc.’的软件(A)”。

安装完成后,在目录C:\Program Files\OpenVPN\config下面部署如下文件,如图3-7所示。

 image.png

图3-7 客户端文件部署

vpnclient.ovpn内容如下:

client #指定角色为客户端

dev tun #和服务器端一致

proto udp #和服务器端一致

remote a.b.c.239 1194 #指定服务器端IP和端口

resolv-retry infinite #连接失败时重复尝试

nobind #不指定本地端口

persist-key #收到信号SIGUSR1时不重新读取key文件

persist-tun #收到信号SIGUSR1时不关闭tun虚拟网口和重新打开

ca ca.crt #指定CA证书位置

cert    vpnclient2.crt #指定客户端证书位置

key     vpnclient2.key #指定客户端私钥位置

ns-cert-type server #要求服务器端的证书的扩展属性为server

#在TLS控制通道的通信协议上增加一层HMAC(Hash-based Message Authentication Code)防止dos攻击

tls-auth ta.key 1

comp-lzo #启用压缩

verb 4 #设置日志级别为一般级别,会记录正常连接信息和报错

keepalive 10 120 #每10s发送保活,120s内未收到保活信息时向OpenVPN进程发送SIGUSR1信号

log-append openvpn.log #指定log位置

经过以上3个步骤后,客户端192.168.20.96可以使用虚拟隧道和虚拟专用网络服务器进行通信。但此时无法与10.168.103.171通信。为了实现客户端192.168.20.96可以与10.168.103.171通信,必须在a.b.c.239这个虚拟专用网络服务器上执行以下的操作:

#启用ip_forward

sed -e 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf

sysctl -p

#增加iptables对tun0的转发支持

iptables -A FORWARD -i tun0 -j ACCEPT

#加入网络地址转换的转发

iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE #eth1为服务器内网端口

iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE #tun0为虚拟隧道端口

同时在10.168.103.171服务器上执行以下的操作:

route add -net 192.168.20.0/24 gw 10.168.103.239

4)在192.168.20.96上,连接OpenVPN服务器并进行网络测试。

连接后,我们在192.168.20.96上可以看到它获得的隧道IP地址,如图3-8所示。

 image.png

图3-8 客户端获得的隧道IP地址

由此可见,它获得的隧道IP地址和服务器端配置文件/etc/openvpn/ccd/vpnclient2.xufeng.info中使用ifconfig-push指令配置的完全一致。

它获得的路由如图3-9所示。

 image.png

图3-9 客户端获得的路由

在远程访问模式下,从虚拟专用网络客户端192.168.20.96使用ICMP ping服务器Host:a.b.c.239所在局域网中的一台服务器10.168.103.171的虚拟网络数据流图如图3-10所示。

 image.png

图3-10 远程访问模式下虚拟网络数据流图

可以看到,OpenVPN起到虚拟路由器的作用,使用net30的模式,建立起远程访问者和虚拟专用网络服务器之间的虚拟专用网络。方框中的IP包标示出了在虚拟专用网络客户端发出的包到达虚拟专用网络服务器时经过网络地址转换的情况。此时,在服务器10.168.103.171上看到的ICMP的来源IP地址是虚拟专用网络服务器(Host:a.b.c.239)的内网IP地址10.168.103.239。

在服务器10.168.103.171使用tcpdump抓取ICMP网络通信的结果如下:

# tcpdump -vvv -nnn -i em1 -c 3 icmp

tcpdump: listening on em1, link-type EN10MB (Ethernet), capture size 65535 bytes

10:38:35.015495 IP (tos 0x0, ttl 127, id 654, offset 0, flags [none], proto ICMP (1), length 60)

10.168.103.239 > 10.168.103.171: ICMP echo request, id 1, seq 9923, length 40 #源地址已经被转换成VPN服务器的内网地址

10:38:35.016139 IP (tos 0x0, ttl 64, id 64964, offset 0, flags [none], proto ICMP (1), length 60)

10.168.103.171 > 10.168.103.239: ICMP echo reply, id 1, seq 9923, length 40

10:38:36.017624 IP (tos 0x0, ttl 127, id 655, offset 0, flags [none], proto ICMP (1), length 60)

10.168.103.239 > 10.168.103.171: ICMP echo request, id 1, seq 9924, length 40 #源地址已经被转换成虚拟专用网络服务器的内网地址

3 packets captured

4 packets received by filter

0 packets dropped by kernel


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。