《Linux系统安全:纵深防御、安全扫描与入侵检测 》 —3.4 使用OpenVPN创建远程访问的虚拟专用网络
3.4 使用OpenVPN创建远程访问的虚拟专用网络
在上个实践中,我们创建了两台具有公网IP的服务器之间的虚拟专用网络,进行安全的数据传输。在本案例中,我们将创建远程访问(Remote Access)模式的虚拟专用网络。
在某些文档中,远程访问被称为Road Warrior(可以翻译为“移动办公”),是指为经常不在办公室的驻场人员或者远程办公的人员提供访问服务器资源或者办公网络资源的通道。在这些场景中,远程访问者一般没有公网IP,他们使用内网地址通过防火墙设备进行网络地址转换后连接互联网。
在本例中,我们使用的物理网络结构图如图3-5所示。
图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所示。
图3-6 OpenVPN安装确认界面
请勾选“始终信任来自‘OpenVPN Technologies,Inc.’的软件(A)”。
安装完成后,在目录C:\Program Files\OpenVPN\config下面部署如下文件,如图3-7所示。
图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所示。
图3-8 客户端获得的隧道IP地址
由此可见,它获得的隧道IP地址和服务器端配置文件/etc/openvpn/ccd/vpnclient2.xufeng.info中使用ifconfig-push指令配置的完全一致。
它获得的路由如图3-9所示。
图3-9 客户端获得的路由
在远程访问模式下,从虚拟专用网络客户端192.168.20.96使用ICMP ping服务器Host:a.b.c.239所在局域网中的一台服务器10.168.103.171的虚拟网络数据流图如图3-10所示。
图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
- 点赞
- 收藏
- 关注作者
评论(0)