OpenVPN最常用的部署模型是具有多个远程客户端的单个服务器,能够路由IP流量。我们将此部署模型称为具有tun设备的clinet/server模式。
在本章中,我们从基本的客户端/服务器设置开始。我们将继续添加更多功能,本章末尾给出了一些关于如何在客户端/服务器tun模式下设置OpenVPN的高级示例。在下一章中,我们将解释如何将基于客户端/服务器tun的设置集成到现有的网络设置中,包括Windows文件共享和基于策略的路由等主题。
本章将涵盖以下主题:
客户端/服务器模式最初是在OpenVPN2.0中引入的。在这种模式下,服务器是一个单一的OpenVPN进程,多个客户端可以连接到该进程。每个经过身份验证和授权的客户端都会从OpenVPN服务器管理的IP地址池中分配一个IP地址。客户端不能直接互相通信。所有流量都通过服务器流动,这既是优点也是缺点。
优点如下:
client-to-client
或使用巧妙地防护墙和路由规则,可以允许客户端相互通信。缺点如下:
此模式最常见的部署场景是各种VPN客户端连接到的公司网站上的OpenVPN服务器。客户端可能包括分公司、流动工作者、在家工作的人,以及智能手机和平板电脑用户。
这种部署模型涵盖了VPN 95%的典型要求,并且比使用桥接等高级功能的更复杂的设置更可取。只有当路由非IP流量(例如,传统IPX流量)有特殊需求,或者需要形成一个单一的网络广播时,这种部署模型才是不够的。
在客户端/服务器模式下,OpenVPN使用带有X.509证书和私钥的公钥基础设施(Public Key Infrastructure——PKI)进行设置。在设置客户端/服务器VPN之前,我们需要先设置此PKI。PKI由CA、私钥和客户端和服务器的证书(公钥)组成。在第三章PKI和证书中,我们曾详细讨论了如何建立这样的PKI。本章以该章中生成的证书和密钥为基础。
首先,我们将证书和密钥复制到一个单独的位置。一般来说,将PKI文件保存在单独的位置时一种良好的安全做法,如果可能的话,甚至在单独的计算机上。应特别注意保护好ca.key文件,因为PKI的整个安全性都依赖于此文件。如果ca.key文件以任何方式被泄露,整个PKI将变得不安全,应该被放弃。在以下命令中,假设PKI文件是使用 ssladmin
生成的,并存储在目录 <PKI_DIR>
中,其中 <PKI_DIR>
表示系统上的真实目录。执行以下命令以复制服务器所需的PKI文件:
xxxxxxxxxx
[root@server] # mkdir -p /etc/openvpn/movpn
[root@server] # chmod 700 /etc/openvpn/movpn
[root@server] # cd /etc/openvpn/movpn
[root@server] # PKI=<PKI_DIR>/ssladmin/active
[root@server] # cp -a $PKI/ca.crt movpn-ca.crt
[root@server] # cp -a $PKI/Mastering_OpenVPN_Server.crt server.crt
[root@server] # cp -a $PKI/Mastering_OpenVPN_Server.key server.key
我们还需要生成VPN会话密钥所需的DH(Diffie-Hellman)参数文件。会话密钥是临时密钥,在首次建立客户端和服务器之间的连接时生成。为了确保最佳安全性,在会话期间以固定间隔重新生成临时密钥。OpenVPN的默认密钥间隔为一小时,但可以使用各种OpenVPN选项进行调整。本章稍后将在 Session key renegotiation (会话密钥重新协商)一节中对此进行解释。
要生成DH参数文件,请执行以下命令:
xxxxxxxxxx
[root@server] # cd /etc/openvpn/movpn
[root@server] # openssl dhparam -out dh2048.pem 2048
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
........+................................................................
..................................................................+......
此例中,我们选择2048位的DH密钥大小,这是推荐的大小。DH过大会使每个OpenVPN客户端的初始连接变慢。我们现在已经准备好设置和启动OpenVPN服务器。
为了设置基本的OpenVPN服务器,我们首先使用以下步骤创建服务器配置文件:
1、创建以下文件(各条目内容含义详见下一节):
xxxxxxxxxx
proto udp
port 1194
dev tun
server 10.200.0.0 255.255.255.0
topology subnet
persist-key
persist-tun
keepalive 10 60
dh /etc/openvpn/movpn/dh2048.pem
ca /etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/server.crt
key /etc/openvpn/movpn/server.key
user nobody
group nobody # use ‘group nogroup’ on Debian/Ubuntu
verb 3
daemon
log-append /var/log/openvpn.log
2、将此文件保存为 movpn-04-01-server.conf
。稍后将给出每条配置线的详细说明。
3、启动OpenVPN服务:
xxxxxxxxxx
[root@server] # openvpn --config movpn-04-01-server.conf
4、该命令不会在命令行上产生任何输出,因为所有输出都被重定向到日志文件 /var/log/openvpn.log
。检查此文件以了解OpenVPN的启动消息详细信息:
xxxxxxxxxx
OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Sep 12 2013
Enter Private Key Password:
WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
TUN/TAP device tun0 opened
do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 10.200.0.1/24 broadcast 10.200.0.255
GID set to nobody
UID set to nobody
UDPv4 link local (bound): [undef]
UDPv4 link remote: [undef]
Initialization Sequence Completed
5、注意,通常每个日志文件条目都以时间戳开头。为清楚起见,此时间戳已被删除。
6、接下来,创建客户端配置文件(各条目内容含义详见下一节):
xxxxxxxxxx
client
proto udp
remote openvpnserver.example.com
port 1194
dev tun
nobind
ca /etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/client1.crt
key /etc/openvpn/movpn/client1.key
将其保存为 movpn-04-01-client.conf
。
7、使用安全通道(例如scp
命令)将PKI文件传输到客户端:
xxxxxxxxxx
[root@client]# mkdir -p /etc/openvpn/movpn
[root@client]# chmod 700 /etc/openvpn/movpn
[root@client]# cd /etc/openvpn/movpn
[root@client]# PKI_HOST=openvpnserver.example.com
[root@client]# PKI=<PKI_DIR>/ssladmin/active
[root@client]# scp root@$PKI_HOST:$PKI/ca.crt movpn-ca.crt
[root@client]# scp root@$PKI_HOST:$PKI/client1.crt client1.crt
[root@client]# scp root@$PKI_HOST:$PKI/client1.key client1.key
8、启动OpenVPN客户端:
xxxxxxxxxx
[root@client]# openvpn --config movpn-04-01-client.conf --suppress-timestamps
OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Sep 12 2013
WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info.
UDPv4 link local: [undef]
UDPv4 link remote: [AF_INET]openvpnserver:1194
[Mastering OpenVPN Server] Peer Connection Initiated with [AF_INET]openvpnserver:1194
TUN/TAP device tun0 opened
do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 10.200.0.2/24 broadcast 10.200.0.255
Initialization Sequence Completed
9、时间戳再次丢失,但这次使用OpenVPN选项 suppress-timestamps
来抑制它们,如以上命令行上指定的。
10、连接启动后,检查以上信息中有以下一句:
xxxxxxxxxx
Initialization Sequence Completed
11、你可以通过ping服务器的VPN地址来验证连接是否正常运行。
proto udp
虽然这是默认协议,但明智的做法是在配置文件中明确列出它,以避免混淆。
port 1194
OpenVPN将要监听的本地端口号。默认值为1194,但可以设置为任何可用端口号。
dev tun
指定将用于服务器的tun设备的名称。tun
后面没有数字,表示OpenVPN将打开一个新的tun设备。这个新设备将被分配系统内核中的第一个可用编号,从0开始(如:tun0、tun1、tun2等)。对于Windows服务器,建议保持此行不变。如果需要使用特定的Windows设备,则需要选项 dev-node
。
server 10.200.0.0 255.255.255.0
server
语句将OpenVPN置于服务器模式。IP子网和子网掩码指定用于VPN服务器和客户端的子网和掩码。VPN服务器被分配了第一个地址,在本例中是10.200.0.1。第一个客户端会被分配地址10.200.0.2(因为我们使用的是 topology subnet
)。此配置的服务器语句内部扩展如下:
xxxxxxxxxx
mode server
tls-server
push “topology subnet”
ifconfig 10.200.0.1 255.255.255.0
ifconfig-pool 10.200.0.2 10.200.0.254 255.255.255.0
push “route-gateway 10.200.0.1”
以上取自于OpenVPN手册页(https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage)。如果使用这些配置行,而不是宏服务器,则使用相同配置。
以上扩展中包括 push "topology subnet"
因为我们还在配置文件中指定了topology subnet
(拓扑子网)。如果没有这一行,扩展就不会发生。
topology subnet
这指定了VPN的拓扑结构。当前的默认拓扑是 net30
,其中服务器和每个客户端都被分配了一个单独的微型 /30
子网空间。下一节将详细介绍拓扑子网与拓扑 net30 的使用情况。
persist-tun
和 persist-key
指示OpenVPN既不重新打开tun设备,也不在隧道重新启动时生成新的密钥材料。这些选项与 user nobody
结合使用时特别有用,因为 user nobody
通常没有打开新tun接口的访问权限。
keepalive 10 60
这用于确保VPN连接保持正常,即使隧道中没有流量。keeplive
语句是 ping
和 ping-restart
命令的宏。服务器配置中的 keeplive 10 60
语句扩展为:
xxxxxxxxxx
ping 10 #每10秒向每个客户端发送ping信息
ping-restart 120 #如果客户端在120秒内没有响应,则重新启动连接
push “ping 10” #将此两个语句推送到每个客户端
push “ping-restart 60”
dh <path to Diffie Hellman file>
指定OpenVPN服务器所需的DH文件的路径。如果没有此文件,服务器无法与客户端建立安全的TLS连接。
建议为此文件(以及其他证书和私钥文件)使用绝对路径。
ca <path to CA file>
指定CA文件的路径。CA文件需要包含用于对客户端证书进行签名的CA证书(甚至证书集)。它不一定必须与用于签署服务器证书的CA相同,尽管在我们的PKI设置中我们使用了相同的CA。
建议为此文件使用绝对路径。
cert <path to X.509 certificate file>
指定服务器x.509公共证书文件的路径。OpenVPN服务器需要此证书,即使客户端连接时没有使用证书。
建议为此文件使用绝对路径。
key <path to private key file>
指定服务器私钥文件的路径。OpenVPN服务器需要此私钥文件,即使客户端在连接时没有使用证书或私钥。此文件需要仅由root(或管理员)用户读取,因为任何具有私钥读取权限的人都可以解密OpenVPN流量。请注意,OpenVPN将在删除用户权限之前读取此文件。
建议为此文件使用绝对路径。
user nobody
和 group nobody
指定OpenVPN在连接建立后,不向Unix用户发送任何消息,也不向任何组发送任何消息。这进一步增强了安全性,因为对隧道的攻击不太可能导致根漏洞利用。
注意,在Debian/Ubuntu上使用组 nogroup
。
verb 3
将详细程度(verbosity level)设置为默认3。增加此数字可查看OpenVPN过程的更详细输出。如果设置为0,则几乎不会产生任何日志输出,不建议这样做。
daemon
daemon模式。这意味着即使在启动OpenVPN的终端窗口关闭后,OpenVPN进程也将继续运行。
log-append <path to log file>
这指定了服务器日志文件的路径。通过使用 log-append
而不是 log <path to file>
,我们可以防止OpenVPN每次启动时覆盖已有日志内容。
建议为此文件使用绝对路径。
指定OpenVPN进入客户端模式。
它指示OpenVPN连接到远程服务器,并在成功连接后从服务器中提取和处理配置参数。
客户端声明内部扩展如下:
xxxxxxxxxx
tls-client
pull
指定要使用的协议。虽然默认是tun,但强烈建议在配置文件中明确指出,以避免混淆。
指定要连接的VPN服务器的名称。该名称可以是FQDN或IPv4地址。在本章后面,我们将介绍如何连接到基于IPv6的VPN服务器。
指定OpenVPN客户端使用哪个端口连接服务器。默认值为1194,但可以使用任何有效的可用端口号(取决于服务器的设置)。
也是使用以下方式组合remote
和port
:
xxxxxxxxxx
remote openvpnserver.example.com:1194
指定用于服务器的tun设备的名称。tun后面不添加数字,意味着OpenVPN连接时打开一个新的tun设备。这个新设备将被分配系统内核中的第一个可用编号。编号从0开始。
对于Windows服务器,建议保持此行不变。如果需要使用特定的Windows设备,则需要选项dev-node
。
指示OpenVPN客户端不要绑定(也不要监听)使用port
指定的端口。
相反,OpenVPN客户端将使用匿名端口范围内的端口,通常是1024-65535。
指定CA文件的路径。此CA文件需要包含用于对服务器证书进行签名的CA证书(甚至证书集)。它不一定必须与用于签署客户端证书的CA相同,尽管我们在PKI设置中使用了相同的CA。
在linux/Unix上,建议为此文件(以及其他证书和私钥的路径)使用绝对路径。
指定此客户端X.509公共证书的路径。可以将OpenVPN配置为使用用户名/密码身份验证而不是证书,但这样不安全。
在linux/Unix上,建议为此文件(以及其他证书和私钥的路径)使用绝对路径。
指定客户端私钥文件路径。此文件需要仅由root(或管理员)用户读取,因为OpenVPN将在删除用户权限之前读取此文件。
在linux/Unix上,建议为此文件(以及其他证书和私钥的路径)使用绝对路径。
注意,我们没有为客户端配置指定 daemon
或 log-append
,因为在大多数情况下,包装器应用程序将启动 openvpn
进程。然后,此包装器应用程序将控制OpenVPN的日志记录。最常见的包装应用程序有:
操作系统 | 包装应用程序 |
---|---|
Windows | OpenVPN-GUI.exe(OpenVPN 安装包的一部分) |
Mac OS X | Tunnelblick 或 Viscosity |
Linux | NetworkManager(含OpenVPN插件) |
OpenVPN在tun模式下支持多种拓扑结构:
拓扑net30是当前默认值。在此模式下,OpenVPN为每个客户端(以及服务器)设置一个点对点网络接口,并为每个客户端分配一个/30
子网。这意味着服务器和客户端都被分配了一个由四个IP地址组成的块。在服务器配置文件种,指定了服务器10.200.0.0 255.255.255.0。对于拓扑net30,这会导致OpenVPN分配以下IP块:
OpenVPN服务器的分配范围为:从10.200.0.0 到 10.200.0.3。
第一个客户端被分配的范围为:从10.200.0.4 到10.200.0.7。
第二个客户端被分配的范围为:从10.200.0.8 到10.200.0.11。 每个/30子网由四个地址组成;对于第一个客户端,这些地址如下:
如你所见,这不是一种非常有效的分配IP地址的方法——对于每个VPN客户端,分配四个IP地址。对于小型VPN设置,这种方法可以很好地工作,但这种方法不适用于连接了100多个客户端的服务器。
为了克服这个问题,引入了topology subnet
(拓扑子网模)式。它允许OpenVPN为所有客户端分配一个IP地址,这使得管理大规模VPN变得更容易。服务器端路由存在一些问题(详细信息可参阅本章少受的路由和服务器端路由部分),这些问题阻止了此拓扑模式成为默认拓扑模式,但预计从2.4版本开始,这将是默认拓扑模式。
初始配置文件集是客户端/服务器部署的良好起点。然而,对于生产级系统,我们希望增加更多的安全性。可以通过两种方式增强安全性:
tls-auth
密钥在C/S模式下,OpenVPN将尝试为每个尝试连接的客户端建立TLS控制通道。设置TLS控制通道会消耗资源,这使得OpenVPN容易受到拒绝服务攻击:攻击者可以启动大量配置错误的客户端,这些客户端都试图连接到OpenVPN服务器。对于每种情况,OpenVPN服务器都会尝试建立TLS连接,这将有效地导致配置良好的客户端拒绝服务。当OpenVPN使用proto udp
(推荐的默认值)运行时尤其如此。UDP流量是无连接的,这意味着对于服务器接收到每个新UDP数据包,它都必须验证对方是否是有效的OpenVPN数据包。
为了解决这个可能的漏洞,OpenVPN使用 tls-auth
选项在TLS控制通道中引入了一个额外的身份验证层。此TSL身份验证必须使用预共享密钥完成,因为服务器尚不知道是否有有效的客户端正在尝试连接。用于此目的的预共享密钥与点对点模式中使用的密钥完全相同,可参阅第二章所述。
与第二章一样,可以使用以下命令生成tls-auth密钥:
xxxxxxxxxx
[root@server]# openvpn --genkey --secret /etc/openvpn/movpn/ta.key
就像客户端的私钥文件一样,此文件需要使用安全通道复制到每个客户端,或者需要包含在安全客户端配置包中:
xxxxxxxxxx
[root@client]# cd /etc/openvpn/movpn
[root@client]# scp root@openvpnserver:/etc/openvpn/movpn/ta.key .
生成X.509证书时,可以将特殊的扩展密钥使用(Extended Key Usage——EKU)属性添加到证书中。这允许我们指定证书的用途,例如仅作为服务器证书或仅作为客户端证书。安全网站使用的证书使用相同的EKU属性。
在生成服务器证书或非服务器(客户端)证书时,easy-rsa
脚本和 ssladmin
工具默认设置EKU属性。要检查证书的EKU属性,请使用以下命令:
xxxxxxxxxx
$ openssl x509 -text -noout -in server.crt | \
grep -C 1 “Key Usage”
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Key Usage:
Digital Signature, Key Encipherment
以上信息表明,server.crt
证书只能用于服务器身份验证。
旧证书可能没有设置这些EKU属性,而是使用(已弃用的) Netscape Cert Type
属性。easy-rsa
脚本和 ssladmin
工具也设置了此属性:
xxxxxxxxxx
$ openssl x509 -text -noout -in server.crt | \
grep -C 1 “Netscape Cert”
Netscape Cert Type:
SSL Server
但是,此证书只能设置为服务器端证书。
通过检查这些属性可以提高OpenVPN的安全性。为此,我们使用选项 remote-cert-tls
。
remote-cert-tls client
选项指示OpenVPN服务器只允许来自具有X.509 EKU属性设置为 TLS Web Client Authentication
的证书的VPN客户端连接。
这可以防止黑客使用客户端证书设置流氓(rogue)OpenVPN服务器。
同样,对于客户端,remote-cert-tls server
选项指示OpenVPN客户端只允许连接到具有X.509 EKU属性设置为 TLS Web Server Authentication
的证书的VPN服务器。
这可以防止恶意客户端设置流氓OpenVPN服务器来吸引其他VPN用户的连接。
还可以检查 Netscape Cert Type
属性。由于这是服务器证书的属性,OpenVPN客户端在连接时需要检查此服务器。为此,可以使用 ns-cert-type server
选项。最好使用 remote-cert-tls
选项。
我们扩展了之前的客户端和服务器配置文件,以使用新创建的 tls-auth
密钥。我们通过在配置文件 movpn-04-01-server.conf
中添加一行以及第二个安全增强选项来实现这一点:
xxxxxxxxxx
proto udp
port 1194
dev tun
server 10.200.0.0 255.255.255.0
topology subnet
persist-key
persist-tun
keepalive 10 60
remote-cert-tls client
tls-auth /etc/openvpn/movpn/ta.key 0
dh /etc/openvpn/movpn/dh2048.pem
ca /etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/server.crt
key /etc/openvpn/movpn/server.key
user nobody
group nobody
verb 3
daemon
log-append /var/log/openvpn.log
注意,此配置文件中语句的顺序是随机的。可以在文件中任意位置添加remote-cert-tls
和 tls-auth
行。
此服务器配置文件是一个基本的服务器配置文件,我们将在本章和其他章节中重复使用。将其另存为 basic-udp-server.conf
,以便我们以后可以重用它。
我们在客户端配置文件 movpn-04-01-client.conf
中添加了两行类似的代码:
xxxxxxxxxx
client
proto udp
remote openvpnserver.example.com
port 1194
dev tun
nobind
remote-cert-tls server
tls-auth /etc/openvpn/movpn/ta.key 1
ca /etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/client1.crt
key /etc/openvpn/movpn/client1.key
将以上文件保存为 basic-udp-client.conf
。
tls-auth
选项的第二个参数是所谓的密钥方向。OpenVPN支持使用方向密钥(directional keys),也就是说,传入和传出数据使用不同的密钥。这进一步增强了安全性。方向标志需要在一端为0,在另一端为1。在C/S模式下,这意味着服务器的方向参数为0,所有客户端的方向参数都设置为1。
当我们启动OpenVPN服务器时,我们可以看到TLS控制通道现在使用静态密钥进行保护:
xxxxxxxxxx
[root@server]# openvpn --config basic-udp-server.conf --suppress-timestamps
OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Sep 12 2013
Enter Private Key Password:
WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
Control Channel Authentication: using ‘/etc/openvpn/movpn/ta.key’ as a OpenVPN static key file
TUN/TAP device tun0 opened
do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 10.200.0.1/24 broadcast 10.200.0.255
GID set to nobody
UID set to nobody
UDPv4 link local (bound): [undef]
UDPv4 link remote: [undef]
Initialization Sequence Completed
同样的,当我们启动OpenVPN客户端,可以看到:
xxxxxxxxxx
[root@client]# openvpn --config basic-udp-client.conf --suppress-timestamps
OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Sep 12 2013
Control Channel Authentication: using ‘/etc/openvpn/movpn/ta.key’ as a OpenVPN static key file
UDPv4 link local: [undef]
UDPv4 link remote: [AF_INET]openvpnserver:1194
[Mastering OpenVPN Server] Peer Connection Initiated with [AF_INET]openvpnserver:1194
TUN/TAP device tun0 opened
do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 10.200.0.2/24 broadcast 10.200.0.255
Initialization Sequence Completed
OpenVPN使用的默认协议是UDP。根据之前创建的配置文件创建基于TCP的版本非常简单。在客户端和服务器配置文件中,将 proto udp
改为 proto tcp
。下面列出了整个基于TCP的服务器的配置文件:
xxxxxxxxxx
proto tcp
port 1194
dev tun
server 10.200.0.0 255.255.255.0
topology subnet
persist-key
persist-tun
keepalive 10 60
remote-cert-tls client
tls-auth /etc/openvpn/movpn/ta.key 0
dh /etc/openvpn/movpn/dh2048.pem
ca /etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/server.crt
key /etc/openvpn/movpn/server.key
user nobody
group nobody
verb 3
daemon
log-append /var/log/openvpn.log
将此文件保存为 basic-tcp-server.conf
。
同样的,修改客户端配置文件:
xxxxxxxxxx
client
proto tcp
remote openvpnserver.example.com
port 1194
dev tun
nobind
remote-cert-tls server
tls-auth /etc/openvpn/movpn/ta.key 1
ca /etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/client1.crt
key /etc/openvpn/movpn/client1.key
将其保存为 basic-tcp-client.conf
。
Windows平台的基本配置文件与Linux/Unix或Mac OS平台的配置文件略有不同。在Windows平台上,使用 Openvpn-GUI.exe
包装器,它要求所有配置文件都存储在目录 c:\Program Files\OpenVPN\config
或其子目录中。
其他语言的Windows版中 Program Files
目录可能不同,在所有语言中,Windows的环境变量 %PRIGRAMFILES%
将指向正确的位置。
因此,基本的UDP和TCP配置文件实际上略短。创建UDP客户端配置文件:
xxxxxxxxxx
client
proto udp
remote openvpnserver.example.com
port 1194
dev tun
nobind
remote-cert-tls server
tls-auth ta.key 1
ca movpn-ca.crt
cert client1.crt
key client1.key
将其另存为basic-udp-client.ovpn
,以便我们可以在本书后面重复使用。
同样,创建客户端配置:
xxxxxxxxxx
client
proto tcp
remote openvpnserver.example.com
port 1194
dev tun
nobind
remote-cert-tls server
tls-auth ta.key 1
ca movpn-ca.crt
cert client1.crt
key client1.key
保存为 basic-tcp-client.ovpn
。
只有当VPN客户端可以访问服务器端资源时,VPN才真正有用。为了访问这些资源,在大多数情况下需要路由。OpenVPN有很多选项,可以在客户端连接或断开时自动设置和删除额外的路由。
应该指出的是,大多数OpenVPN故障排除问题都与路由有关。设置VPN连接是一回事,让网络流量正常流动是另外一回事。这通常与OpenVPN本身关系不大,但更多地与客户端和服务器的路由表和防火墙规则有关。
这里描述了访问服务器端网络上资源的最常见布局:
【有图,略】
服务器端的LAN是192.168.122.0/24。VPN客户端需要访问的资源位于此子网上。因此服务器需要指示VPN客户端需要设置额外的路由。这是使用 push
选项完成的,其中路由配置被推送到客户端。也可以通过将路由添加到客户端配置文件本身来实现,但这并不能很好地扩展。这是因为对于每个新的服务器端网络路由,都需要更新所有客户端配置文件。
我们从 basic-udp-server.conf
开始,添加一行:
xxxxxxxxxx
proto udp
port 1194
dev tun
server 10.200.0.0 255.255.255.0
topology subnet
persist-key
persist-tun
keepalive 10 60
remote-cert-tls client
tls-auth /etc/openvpn/movpn/ta.key 0
dh /etc/openvpn/movpn/dh2048.pem
ca /etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/server.crt
key /etc/openvpn/movpn/server.key
user nobody
group nobody
verb 3
daemon
log-append /var/log/openvpn.log
push “route 192.168.122.0 255.255.255.0”
将其保存为 movpn-04-03-server.conf
然后用这个配置文件启动OpenVPN服务器。此次,我们使用Windows7 64-bit专业版作为OpenVPN客户端,此客户端电脑安装了X86_64版的OpenVPN 2.3.4-I004。将以下文件复制到Windows电脑:
将它们放在 %PROGRAMFILES%\config
中。
启动OpenVPN GUI应用,选择设置 basic-udp-client
然后按 Connect。
【有图。略】
成功建立连接后,OpenVPN GUI图标变为绿色,悬停在图标上时显示连接信息。
我们现在可以通过打开命令shell并ping服务器来验证到服务器的VPN连接是否正常工作。
在我们验证我们可以访问OpenVPN服务器后,我们需要确保OpenVPN服务器正在转发IP流量,我们需要在服务器端网关上添加一条额外的路由,以确保VPN流量通过VPN服务器正确路由回来。如果没有此路由,服务器端网络上的机器现在将知道IP地址为10.200.0.0/24
的VPN流量来自哪里,并且很可能会错误地路由或丢弃数据包:
xxxxxxxxxx
[root@server]# sysctl -w net.ipv4.ip_forward=1
[router]# ip route add 10.200.0.0/24 via 192.168.122.1
现在,我们检查客户端的路由表,并验证我们可以访问服务器端局域网上的机器。
【有图,略】
输出的第一部分显示,VPN子网10.200.0.0/24的多条路由已添加到路由表中,包括pushed
网络192.168.122.0/24
的路由。注意输出中的最后一列,它显示了路由度量。Windows计算一个度量(在这种情况下为286),但可以使用正确的route
语句来推翻它。使用push route 192.168.122.0 255.255.255.0
添加的路由具有较低的度量,因为指定了OpenVPN默认度量30。
与第二章点对点模式中的解释类似,配置语句 push route <network> <netmaks> [vpn_gateway] [metric]
在此设置中至关重要。route
选项最多接受四个参数,其中两个是必需的,另外两个是可选的。这是在该设置中其重要作用的第三个参数。vpn_gateway
是一个特殊的OpenVPN关键字,它指定了VPN远程端点地址。通常,不必指定此关键字,除非还需要为此路由指定度量(metric)。
route
语句的完整语法是 route <network> <netmask> [gateway] [metirc]
,其中gateway
可以显式设置为IPv4地址,也可以使用特殊关键字 vpn_gateway
或 net_gateway
中的任何一个。如果没有指定网关和度量,则使用 vpn_gateway
。
关键字 net_gateway
可用于指定不应通过VPN明确路由的子网。对于 net_gateway
,将替换建立VPN连接之前的默认网关。
该度量有一个默度量,可以使用 route-metric m
,然后应用于所有路由。如果你想推翻特定路由的度量(就像我们在这个例子中所做的那样),那么需要指定网关(在我们的例子中是 vpn_gateway
),然后指定该特定路由的metric。
有时,无法添加服务器端路由将所有VPN流量重定向回OpenVPN服务器。在这种情况下,一种快速而肮脏的方法是使用伪装(masquerading)。在Linux上,你可以使用iptables
命令在服务器上设置伪装:
xxxxxxxxxx
[root@server]# iptables -t nat -I POSTROUTING -o eth0 \
-s 10.200.0.0/24 -j MASQUERADE
此 iptables
语句指示Linux内核重写来自VPN子网10.200.0.0/24并离开以太网接口eth0的所有流量。离开eth0接口的流量会重写其源地址,使其看起来像是来自OpenVPN服务器本身,而不是来自OpenVPN客户端。这是使路由正常工作的一个简单快捷方式,但缺点是不再可能区分此流量是来自OpenVPN服务器本身,还是来自连接的客户端之一。
VPN的一个非常常见的用途是通过安全隧道路由所有流量。这使得人们可以再恶劣的环境中(例如,保护不力的网吧)安全地访问网络,甚至互联网本身。
重定向默认网关是通过在服务器配置文件中添加 push "redirect-gateway [def1 local bypass-dhcp bypass-dns]"
来实现的。
前面列出的 redirect-gateway
的参数是可选的,但它们可以发挥非常重要的作用:
def1
OpenVPN将添加两条新路由0.0.0.0/1和128.0.0.0/1,而不是替换现有的默认网关。这些路由一起也覆盖了所有IPv4空间,并且比常规网关(/0)更具体(/1)。路由总是通过更具体的路由进行,因此所有流量都是通过VPN发送的。这种技巧的优点是默认网关保持不变。如果VPN连接停止,则可以恢复原始网关。
注意,在这种情况下,OpenVPN将向OpenVPN服务器本身添加一条显式路由,因此加密流量本身不会通过隧道发送。bypass-dhcp
有时,向客户端局域网上的本地DHCP服务器添加显式路由时有用的。这避免了DHCP续订也通过VPN进行隧道传输,尽管在大多数网络设置中不会发生这种情况,因为通常有一条更具体的路由到本地DHCP服务器所在的网段。bypass-dns
有时,可能需要向本地DNS服务器添加显式路由,否则DNS解析会失败。只有当你想使用客户端DNS服务器,但又想通过隧道路由所有流量时,才会发生这种情况。除了选项 redirect-gateway
之外,我们还可以指定选项 push "redirect-private [def1 local bypass-dhcp bypass-dns]"
到服务器配置文件。此选项采用于 redirect-gateway
相同的参数,但它根本不会更改现有的默认网关。这对于推送私有子网非常有用。
现在,我们将 push "redirect-gateway def1"
添加到 basic-udp-server.conf
配置文件中。将其另存为 movpn-04-06-server.conf
,启动OpenVPN服务器,并使用默认配置文件重新连接客户端。
连接建立后,我们使用 traceroute
命令(在Windows上的命令是 tracert -d
)验证所有流量现在都通过VPN流动。
traceroute
输出的第一跳(hop
)是10.200.0.1,这是OpenVPN服务器的IP地址。这证明默认情况下流量是通过VPN流动的。
配置选项 redirect-gateway def1
告诉OpenVPN客户端向客户端操作系统添加三条路由:
xxxxxxxxxx
10.198.1.1 via 192.168.4.254 dev eth0
0.0.0.0/1 via 10.200.0.1 dev tun0
128.0.0.0/1 via 10.200.0.1 dev tun0
第一条路由是通过LAN接口从客户端到OpenVPN服务器的显式路由。需要此路由,否则OpenVPN服务器本身的所有流量都将通过隧道。
另外两条路由是一个巧妙地技巧,可以推翻默认路由,使所有流量都通过隧道发送,而不是发送到默认地局域网网关。
这种方法地优点是原始默认网关保持不变。当VPN断开连接时,原始网关地址会自动再次接管。如果我们只是使用 redirect-gateway
,当VPN断开连接时,默认网关可能会丢失,从而导致网络连接完全丢失。
这种方法的缺点是Windows7及更高版本的客户端。Windows有时会拒绝信任没有默认路由的TAP-Win适配器,因此将其标记为公共适配器。在Windows7中,无法使用公共适配器进行文件或打印机共享。我们将在下一章了解如何解决这一特殊问题。
在单个服务器可以处理多个客户端的设置中,有时需要设置每个客户端的选项来推翻全局选项,或者为特定客户端添加额外的选项。client-config-dir
选项对此非常有用。它允许VPN管理员为客户端分配特定的IP地址,以便将DNS服务器等特定选项推送到特定客户端,或暂时完全禁用客户端。如果你想将子网从客户端路由到服务器端,此选项也很重要,我们稍后将看到。
client-config-dir
或CCD文件可以包含以下选项:
push
: 用于推送DNS和WINS服务器、路由等push-reset
: 这有助于推翻全局推送选项iroute
: 用于将IPv4客户端子网路由到服务器iroute-ipv6
: 用于将IPv6客户端子网路由到服务器ifconfig-push
: 用于为客户端分配特定的IPv4地址ifconfig-ipv6-push
: 用于为客户端分配特定的IPv6地址disable
: 用于暂时完全禁用客户端config
: 用于包含另一个CCD配置文件为了使用 CCD文件,我们在 basic-udp-server.conf
配置文件中添加一行:
xxxxxxxxxx
client-config-dir /etc/openvpn/movpn/clients
将其保存为 movpn-04-04-server.conf
。接下来创建CCD目录并在其中创建CCD文件,令客户端使用证书 client1.crt
:
xxxxxxxxxx
[root@server]# mkdir -p /etc/openvpn/movpn/clients
[root@server]# echo “ifconfig-push 10.200.0.99 255.255.255.0” \
> /etc/openvpn/movpn/clients/client1
[root@server]# chmod 755 /etc/openvpn/movpn/clients
[root@server]# chmod 644 /etc/openvpn/movpn/clients/client1
CCD文件的名称基于证书主体的通用名称("/CN="部分),如client1.crt文件中所示:
xxxxxxxxxx
$ openssl x509 -subject -noout -in client1.crt
subject= /C=ZA/ST=Enlightenment/O=Mastering OpenVPN/CN=client1/emailAddress=root@example.org
在这种情况下,文件名需要只是 client1
,没有扩展名,即使在Windows上也是如此。如果公共名称中存在空格,则需要将其转换为下划线(_)。如果Windows资源管理器配置为隐藏常见文件类型的扩展名,则最简单的方法是打开命令shell(cmd.exe)窗口,并使用以下命令删除扩展名:
xxxxxxxxxx
C:\> cd %PROGRAMFILES%\openvpn\config\clients
C:\> rename client1.txt client1,145.102.134.201:35519
接下来,我们使用此配置文件启动OpenVPN服务器,并连接VPN客户端。连接日志显示,客户端被分配了地址10.200.0.99:
xxxxxxxxxx
[root@client]# openvpn --config basic-udp-client.conf
OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Sep 12 2013
Control Channel Authentication: using ‘/etc/openvpn/movpn/ta.key’ as a OpenVPN static key file
UDPv4 link local: [undef]
UDPv4 link remote: [AF_INET]openvpnserver:1194
[Mastering OpenVPN Server] Peer Connection Initiated with [AF_INET]openvpnserver:1194
TUN/TAP device tun0 opened
do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 10.200.0.99/24 broadcast 10.200.0.255
Initialization Sequence Completed
使用默认详细度(verbosity)设置时,服务器端日志不显示任何关于拾取CCD文件的消息。将详细度设置增加到5或更多,以查看是否处理了CCD文件:
xxxxxxxxxx
<client-ip>:49299 [client1] Peer Connection Initiated with [AF_INET]<client-ip>:49299
client1/<client-ip>:49299 OPTIONS IMPORT: reading client specific options from: /etc/openvpn/movpn/clients/client1client1/<client-ip>:49299 MULTI: Learn: 10.200.0.99 -> client1/<client-ip>:49299
CCD文件是否正确处理的故障排除可能有点棘手。以下指南将有助于调试CCD文件问题:
client-config-dir
选项指定完整路径nobody
或 openvpn
,在本书的例子中,使用 user nobody
)。ccd-exclusive
选项添加到服务器配置文件中。这指示OpenVPN仅在客户端有特定CCD文件的情况下才允许客户端连接。如果读取特定客户端的CCD文件时出现问题,则客户端也将被拒绝访问。这样,你将知道你的client-config-dir
设置配置错误。如果你使用的是(默认)拓扑设置(topology net30
),那么 ifconfig-push
语句略有不同。由于现在为每个客户端分配了一个 /30
子网。以下规则适用:
例如,VPN客户端的有效IP地址为10.200.0.50:
CCD文件现在应包含以下内容:
xxxxxxxxxx
ifconfig-push 10.200.0.50 10.200.0.49
有时候,需要服务器(或其他VPN客户端)访问客户端所在的网络。这被称为客户端侧(client-side)路由。OpenVPN中的客户端侧路由要求该客户端的CCD文件包含iroute
语句。
以下网络布局:
服务器端的LAN和服务器端子网192.168.122.0/24需要通过客户端侧LAN访问客户端子网192.168.4.0/24。通过以下方式实现此功能:
1、在 basic-udp-server.conf
配置文件中添加以下两行:
xxxxxxxxxx
client-config-dir /etc/openvpn/movpn/clients
route 192.168.4.0 255.255.255.0 10.200.0.1
将文件保存为 movpn-04-05-server.conf
。
2、在目录 /etc/openvpn/movpn/clients
中创建 client1
CCD文件,包含以下内容:
xxxxxxxxxx
ifconfig-push 10.200.0.99 255.255.255.0
iroute 192.168.4.0 255.255.255.0
push “route 192.168.122.0 255.255.255.0”
3、在服务器和客户端分别确认IP流量转发已经启用(enabled)并被允许(allowed):
xxxxxxxxxx
[root@client]# sysctl -w net.ipv4.ip_forward=1
[root@server]# sysctl -w net.ipv4.ip_forward=1
4、用以下配置文件启动OpenVPN服务器:
xxxxxxxxxx
movpn-04-05-server.conf
5、客户端使用以下配置文件连接:
xxxxxxxxxx
basic-udp-client.conf
6、连接建立后,我们验证两个子网是否可以使用ping互相连通:
xxxxxxxxxx
[root@client]# ping -c 3 192.168.122.184
PING 192.168.122.184 (192.168.122.184) 56(84) bytes of data.
64 bytes from 192.168.122.184: icmp_seq=1 ttl=63 time=3.29 ms
64 bytes from 192.168.122.184: icmp_seq=2 ttl=63 time=3.27 ms
64 bytes from 192.168.122.184: icmp_seq=3 ttl=63 time=3.31 ms
--- 192.168.122.184 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2006ms
rtt min/avg/max/mdev = 3.277/3.296/3.317/0.016 ms
[root@server]# ping -c 3 192.168.4.10
PING 192.168.4.10 (192.168.4.10) 56(84) bytes of data.
64 bytes from 192.168.4.10: icmp_seq=1 ttl=63 time=6.31 ms
64 bytes from 192.168.4.10: icmp_seq=2 ttl=63 time=5.07 ms
64 bytes from 192.168.4.10: icmp_seq=3 ttl=63 time=5.14 ms
--- 192.168.4.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2007ms
rtt min/avg/max/mdev = 5.073/5.512/6.317/0.575 ms
client-config-dir
配置在以上例子的第一步,我们在服务器配置文件中添加了两行。这些行设置 client-config-dir
,它们指导OpenVPN为子网段192.168.4.0/24添加一个网络路由。由于OpenVPN中的一个小错误,我们需要在这里明确指定网关地址10.200.0.1。这个缺点预计在2.4版中得到解决,之后你可以再次指定 route 192.168.4.0 255.255.255.0
。
CCD文件的内容指示OpenVPN,当具有通用名称 client1
的客户端连接时,此客户端的IP地址应设置为 10.200.0.99
。此外,OpenVPN需要为此客户端设置一个内部路由( iroute
),以便OpenVPN本身知道子网192.168.4.0/24位于此特定客户端之后。
最后,push route
语句指示OpenVPN将此特定子网的路由推送到客户端 client1
。这样,OpenVPN服务器可以以透明的(transparent)方式将不同的路由推送到不同的客户端。
注意,有选择地将路由推送到特定客户端可能很方便,但它不能防止被篡改。单独向此子网添加路由的流氓VPN客户端也可以访问它。如果你需要控制对特定子网的访问,请使用防火墙解决方案,如 iptables
或 ipfw
。
此示例显示了OpenVPN配置选项的灵活性。无需更改客户端配置文件中的任何一行,就可以分配不同的IP地址,将特定子网路由到客户端,或将特定子网络从客户端网络路由到服务器端局域网。
OpenVPN还允许你设置客户端到客户端的流量。默认情况下,不允许VPN客户端直接互相通信。这是一种很好的安全措施,但有时需要允许客户端之间的流量。请注意,所有VPN客户端到客户端的流量都将通过OpenVPN服务器流动:从client1
到VPN服务器,然后再从VPN服务器到client2
,反之亦然。这很容易导致性能问题。
在tun模式下,可以使用 iptables
或使用OpenVPN选项 client-to-client
来实现客户端到客户的连接。client-to-client
选项的优点是速度更快:从一个客户端到达服务器的流量会自动转发到第二个客户端,而无需通过系统路由表或防火墙规则。缺点是很难监控流量,也不可能应用访问控制。
如果没有 client-to-client
选项,来自一个客户端的流量将由OpenVPN服务器接收、转发到系统路由和防火墙表,并(如果配置正确)再次反弹回OpenVPN服务器。然后,服务器将其转发给第二个客户端。
如果其它VPN客户端需要访问前一个示例中指定的子网192.168.4.0/24,则服务器配置需要扩展一行:
xxxxxxxxxx
push “192.168.4.0 255.255.255.0”
这指示OpenVPN服务器向所有客户端推送一条路由,即子网192.168.4.0/24可以通过VPN隧道访问,但客户端 client1
除外。由于匹配的 iroute
条目,客户端 client1
本身被排除在外。
OpenVPN提供了多种选项来监控连接到服务器的客户端。最常见的方法是使用状态文件。OpenVPN状态文件由OpenVPN进程不断更新,包含以下信息:
我们通过在服务器配置中添加一行来修改 client-side routing
服务器配置文件 movpn-04-05-server.conf
:
xxxxxxxxxx
proto udp
port 1194
dev tun
server 10.200.0.0 255.255.255.0
topology subnet
persist-key
persist-tun
keepalive 10 60
remote-cert-tls client
tls-auth /etc/openvpn/movpn/ta.key 0
dh /etc/openvpn/movpn/dh2048.pem
ca /etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/server.crt
key /etc/openvpn/movpn/server.key
user nobody
group nobody
verb 3
daemon
log-append /var/log/openvpn.log
client-config-dir /etc/openvpn/movpn/clients
route 192.168.4.0 255.255.255.0 10.200.0.1
status /var/run/openvpn.status 3
将其保存为 movpn-04-07-server.conf
。重新连接VPN后,在VPN客户端 client1
连接并传输了一些数据后,我们可以在状态文件中看到以下内容:
xxxxxxxxxx
OpenVPN CLIENT LIST
Updated,Tue Oct 21 15:45:27 2014
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
client1,<client-IP>:35519,7730,9342,Tue Oct 21 15:44:35 2014
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
192.168.4.0/24,client1,145.102.134.201:35519,Tue Oct 21 15:44:35 2014
10.200.0.99,client1,145.102.134.201:35519,Tue Oct 21 15:44:35 2014
GLOBAL STATS
Max bcast/mcast queue length,0
END
CLIENT LIST
显示了连接的客户端列表,包括有关接收到的字节数和发送的字节数的信息。
ROUTING TABLE
显示OpenVPN内部路由列表:
iroute
语句,子网 192.168.4.0/24被路由到 client1
client1
的CCD文件中明确设置的 client1
的IP地址当客户端断开连接时,状态文件将在3秒后更新,连接的客户端将不再列出。
注:当客户端断开连接时,所有信息都将从状态文件中删除,所有统计信息都将重置。如果客户端稍后再次连接,则接收和发送的字节数将再次从零开始。当客户端断开连接时,客户端断开脚本会受到所有状态信息。
status
选项的第二个参数是状态文件更新(重写)的间隔。默认值为60秒。
OpenVPN服务器在使用UDP协议时无法立即检测到客户端断开连接,无论是故意还是由于互联网连接不良。这允许客户端在连接不良的情况下重新连接到VPN服务器,而不会丢失所有隧道连接。缺点是OpenVPN服务器需要一些时间才能意识到客户端已经消失。
OpenVPN客户端可以使用 explicit-exit-notify
选项显式通知服务器它正在断开连接。此选项接受一个参数,该参数指定客户端尝试发送到服务器的显式消息的数量。默认值为1,如果底层网络连接本身不稳定,则无法正常工作。在这种情况下,建议将此值增加到3。
当使用 explicit-exit-notify
时,当客户端断开连接时,OpenVPN服务器会立即收到远程退出消息,如服务器日志文件所示:
xxxxxxxxxx
SIGTERM[soft,remote-exit] received, client-instance exiting
注意,使用 proto tcp
时不会出现此问题,因为服务器会立即注意到TCP连接的终止。
OpenVPN最强大但最不太知名的选项之一是管理界面。管理界面在服务器端和客户端都可用。在服务器端,它可用于收集统计数据、监视和控制连接的客户端,以及执行其他与管理相关的任务。在客户端,它可用于查询密码、输入与VPN服务器建立连接的代理信息、与PKCS#11设备交互以及收集客户端统计数据。
Linux NetworkManager的OpenVPN插件广泛使用管理界面来控制VPN连接的启动和关闭。
要使用管理界面,请在客户端或服务器配置文件中添加行 management 127.0.0.1 23000 stdin
。此选项指示OpenVPN在IP地址127.0.0.1、端口23000上设置管理接口,并使用stdin
指定管理员密码。
如果我们将此添加到 basic-udp-server.conf
配置文件中并启动OpenVPN服务器,则OpenVPN将首先向我们查询要使用的管理密码。
我们可以使用 telnet
登录到管理界面(用户输入以黑体列出):
xxxxxxxxxx
[root#server]# telnet 127.0.01 23000
Trying 127.0.0.1...
Connected to 127.0.01.
Escape character is ‘^]’.
ENTER PASSWORD:[password]
SUCCESS: password is correct
>INFO:OpenVPN Management Interface Version 1 -- type ‘help’ for more info
help
Management Interface for OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)]
[LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Sep 12 2013
Commands:
auth-retry t : Auth failure retry mode
(none,interact,nointeract).
bytecount n : Show bytes in/out, update every n secs
(0=off).
echo [on|off] [N|all] : Like log, but only show messages in echo
buffer.
exit|quit : Close management session.
forget-passwords : Forget passwords entered so far.
help : Print this message.
[...]
END
这个原始telnet接口可用于查看服务器的状态,提供与前一个示例中的选项状态相同的输出。它还可以使用以下命令立即终止客户端连接:
xxxxxxxxxx
kill client1
这将导致客户端 client1
断开连接。注意,在大多数情况下,客户端会自动尝试重新连接。现在,键入 exit
结束telnet会话。
管理界面可用于以多种不同的方式控制OpenVPN(详见OpenVPN手册页 https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage ):
management IP port [pw-file]
在IP:port上启用TCP服务器以处理守护进程管理功能。pw-file
(如果指定)是一个密码文件(密码在第一行)或 stdin
,用于从标准输入进行提示。提供的密码将设置TCP客户端访问管理功能所需提供的密码。
如果支持,管理界面还可以监听Unix域套接字。要使用域套接字,请指定Unix套接字路径名替代IP,并将端口设置为 unix
。
管理界面提供了一种特殊模式,TCP管理链路可以在隧道本身上运行。要启用此模式,请设置 IP = "tunnel"
。隧道模式将导致管理接口在TUN/TAP接口的本地VPN地址上侦听TCP连接。management-client
管理界面将作为TCP/Unix域客户端连接到 --management
指定的 IP:port,而不是作为TCP服务器或Unix域套接字进行监听。如果客户端连接失败或断开,将生成SIGTERM信号,并导致OpenVPN退出。management-query-passwords
这是私钥密码和 --auth-user-pass
用户名/密码的查询管理通道。management-hold
在休眠状态下启动OpenVPN,直到管理界面的客户端使用hold release命令明确启动它。management-signal
如果管理会话断开连接,则向OpenVPN发送SIGUSR1信号。当您希望在用户注销时断开OpenVPN会话时,这很有用。management-client-auth
这赋予了管理接口客户端在验证客户端证书后对客户端进行身份验证的责任。为了确保每个OpenVPN连接的安全性,服务器会定期与每个客户端重新协商数据通道的密钥。这可以使用三个选项进行控制:
reneg-sec N
: N秒后重新协商数据通道密钥 (default is 3600)reneg-bytes N
: N字节后重新协商数据通道密钥 (default=0=off)reneg-pkts N
: N个数据包后重新协商数据通道密钥 (default=0=off)如果VPN客户端在连接到服务器时遇到周期性超时,则更改这些参数通常很有用。但是,如果以非常短的间隔设置 reneg-sec
参数,VPN的性能将严重下降。
reneg
选项可以在客户端或服务器端指定,也可以在两者上指定。在任何一侧运行最频繁的reneg
选项将重置两端的计数器。如果服务器指定了 reneg-sec 500
,但客户端指定了 reneg-sec 60
,则数据通道重新协商将大约每60秒发生一次。
我们通过在 basic-udp-server.conf
配置文件中添加三行来创建一个示例:
xxxxxxxxxx
reneg-sec 10
reneg-pkts 1000
reneg-bytes 1000000
我们将配置保存为 movpn-04-09-server.conf
,并重新建立VPN连接。服务器日志现在将包含许多以 TLS: soft reset
开头的行:
xxxxxxxxxx
Tue Oct 21 16:53:29 2014 <IP>:41679 [client1] Peer Connection Initiated with [AF_INET]<IP>:41679
[...]
Tue Oct 21 16:53:39 2014 client1/<IP>:41679 TLS: soft reset sec=0 bytes=0/100000 pkts=0/100
[...]
Tue Oct 21 16:53:49 2014 client1/<IP>:41679 TLS: soft reset sec=0 bytes=53/100000 pkts=1/100
[...]
Tue Oct 21 16:53:59 2014 client1/<IP>:41679 TLS: soft reset sec=0 bytes=105/100000 pkts=2/100
设置了选项 reneg-sec 10
后,我们从服务器日志时间戳中看到,数据通道密钥每10秒重新协商一次。
在客户端侧,我们还可以看到密钥重新协商对VPN连接性能的影响。通过在连接建立后运行一个简单的ping命令,我们可以根据ping响应时间的峰值看到密钥重新协商何时发生:
xxxxxxxxxx
[client]$ ping 10.200.0.1
PING 10.200.0.1 (10.200.0.1) 56(84) bytes of data.
64 bytes from 10.200.0.1: icmp_seq=1 ttl=64 time=3.29 ms
64 bytes from 10.200.0.1: icmp_seq=2 ttl=64 time=3.55 ms
64 bytes from 10.200.0.1: icmp_seq=3 ttl=64 time=61.6 ms
64 bytes from 10.200.0.1: icmp_seq=4 ttl=64 time=16.6 ms
64 bytes from 10.200.0.1: icmp_seq=5 ttl=64 time=3.23 ms
64 bytes from 10.200.0.1: icmp_seq=6 ttl=64 time=3.22 ms
64 bytes from 10.200.0.1: icmp_seq=7 ttl=64 time=3.74 ms
64 bytes from 10.200.0.1: icmp_seq=8 ttl=64 time=3.25 ms
64 bytes from 10.200.0.1: icmp_seq=9 ttl=64 time=3.21 ms
64 bytes from 10.200.0.1: icmp_seq=10 ttl=64 time=3.26 ms
64 bytes from 10.200.0.1: icmp_seq=11 ttl=64 time=3.26 ms
64 bytes from 10.200.0.1: icmp_seq=12 ttl=64 time=3.55 ms
64 bytes from 10.200.0.1: icmp_seq=13 ttl=64 time=3.27 ms
64 bytes from 10.200.0.1: icmp_seq=14 ttl=64 time=3.26 ms
64 bytes from 10.200.0.1: icmp_seq=15 ttl=64 time=3.31 ms
64 bytes from 10.200.0.1: icmp_seq=16 ttl=64 time=3.28 ms
64 bytes from 10.200.0.1: icmp_seq=17 ttl=64 time=77.1 ms
...
当数据包或字节边界 (boundary)被跨越时,也会发生同样的事情,此时数据通道密钥也将被重新协商。
特别是在使用PKCS#11设备时,密钥重新协商可能很麻烦。一些PKCS#11设备对密钥重新协商施加了沉重的惩罚,导致重新协商过程需要几秒钟。在此期间,VPN没有响应。
将 reneg-sec
值设置为0将有效地禁用密钥重新协商,但这会使VPN本身容易受到中间人和定时攻击,从而使使用硬件安全设备的额外安全性变得毫无用处。
OpenVPN2.3为IPv6提供了坚实的支持,包括在OpenVPN隧道内以及隧道本身的传输。OpenVPN一直到1.x都对IPv6有基本的支持,但IPv6在很大程度上被重写了。总体而言,在OpenVPN隧道内,管理员可以选择支持以太网(第2层)、IPv4(第3层)和IPv6(第3级)。
只需要使用一种传输方法,单个OpenVPN配置可以包含IPv4和IPv6 --remote
条目。所有交通,无论类型如何,都将在隧道内受到保护。拥有一个全IPv6隧道是完全可以接受的,将IPv6用于传输和受保护的流量。通过额外的路由和代理,甚至可以使用OpenVPN来帮助IPv6到IPv4的转换。
基于上一节的示例,我们可以像客户端提供IPv6地址,并保护隧道内的流量。为此,我们在服务器配置中添加了 --server-ipv6
选项。这与 --server
指令的操作类似,仅适用于IPv6而不是IPv4,并采用IPv6网络地址和网络掩码作为参数。与 --server
一样,--server-ipv6
是一个宏,用于单独传递其他选项:--ifconfig-ipv6
、 --ifconfig-ipv6-pool
、--tun-ipv6
和 -push tun-ipv6
。
与IPv4一样,IPv6路由可以从主服务器配置或 client-config
目录中的每个客户端配置文件中推送。然而,在这个例子中,我们将所有IPv6流量推送一个默认路由。
目前,IPv6的OpenVPN中没有 redirect-gateway
选项。添加路由类似于IPv6,关键字为 route-ipv6
,而不是 route
。
现在,编辑 movpn-04-01-server.conf
文件,添加 --server-ipv6
指示:
xxxxxxxxxx
proto udp
port 1194
dev tun
server 10.200.0.0 255.255.255.0
server-ipv6 2001:DB8:100::/64
push “route-ipv6 ::/0”
topology subnet
persist-key
persist-tun
keepalive 10 60
dh /etc/openvpn/movpn/dh2048.pem
ca /etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/server.crt
key /etc/openvpn/movpn/server.key
user nobody
group nobody
verb 3
daemon
log-append /var/log/openvpn.log
文件保存后,需要重新启动OpenVPN服务器进程。如果使用新选项正确启动了该过程,你应该在日志文件中看到类似这样的内容:
xxxxxxxxxx
IFCONFIG POOL IPv6: (IPv4) size=252, size_ipv6=65536, netbits=64, base_ipv6=2001:db8:100::1000
此时,客户端能够在隧道内使用IPv6传递流量,服务器正在向客户端推送IPv6的默认路由。添加服务器配置选项不需要客户端配置中的其他相应选项。
连接的客户端将在 tunX
接口上显示IPv4和IPv6地址。
下面是一个FreeBSD例子:
xxxxxxxxxx
utun1: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1331
inet 10.200.0.2 --> 10.200.0.2 netmask 0xffffff00
inet6 fe80::5ab0:35ff:fef5:811f%utun1 prefixlen 64 scopeid 0x9
inet6 2001:db8:100::1001 prefixlen 64
nd6 options=1<PERFORMNUD>
OpenVPN目前无法同时监听IPv4和IPv6地址,但大多数现代内核都可以通过IPv6映射地址为你处理。这所做的是获取一个版本4的IP,如192.168.200.4,并将其映射为IPv6地址 ::ffff:192:168.:200:.:4。此外,客户端和服务器上的协议将是udp6
,而不是原型的udp
。
在更改了示例配置中的proto
语句后,client2
被初始化,我们可以看到地址被分配了。OpenVPN服务器v4和v6地址都可以被ping到,我们可以通过tcpdump
确认隧道上的传输是通过IPv6进行的。
下面是客户端tun接口:
xxxxxxxxxx
ecrist@phillip:~-> ifconfig tun4
tun4: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500
options=80000<LINKSTATE>
inet6 fe80::216:3eff:fe09:5d4e%tun4 prefixlen 64 scopeid 0x9
inet 10.200.0.2 --> 10.200.0.2 netmask 0xffffff00
inet6 2001:db8:100::1000 prefixlen 64
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
Opened by PID 45391
下面是隧道 ping 中的IPv4:
xxxxxxxxxx
ecrist@phillip:~-> ping -c 1 10.200.0.1
PING 10.200.0.1 (10.200.0.1): 56 data bytes
64 bytes from 10.200.0.1: icmp_seq=0 ttl=64 time=0.490 ms
--- 10.200.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.490/0.490/0.490/0.000 ms
下面是隧道 ping 中的IPv6:
xxxxxxxxxx
ecrist@phillip:~-> ping6 -c 1 2001:db8:100::1
PING6(56=40+8+8 bytes) 2001:db8:100::1000 --> 2001:db8:100::1
16 bytes from 2001:db8:100::1, icmp_seq=0 hlim=64 time=0.591 ms
--- 2001:db8:100::1 ping6 statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.591/0.591/0.591/0.000 ms
下面是 tcpdump
输出(注意输出中的IPv6关键字):
xxxxxxxxxx
root@terrance:/usr/local/etc/openvpn-> tcpdump -i xn0 host 2001:db8:5555:5555::1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on xn0, link-type EN10MB (Ethernet), capture size 65535 bytes
19:14:05.449553 IP6 phillip.1194 > terrance.1194: UDP, length 53
19:14:05.449692 IP6 terrance.1194 > phillip.1194: UDP, length 53
19:14:08.389222 IP6 phillip.1194 > terrance.1194: UDP, length 93
19:14:08.389394 IP6 terrance.1194 > phillip.1194: UDP, length 93
19:14:09.389858 IP6 phillip.1194 > terrance.1194: UDP, length 93
接下来的几节将说明一些高级配置选项。建议你在将其部署到生产环境中之前,充分了解其对网络的影响。这些选项很少使用,但在适当的情况下可能非常有益。
通常希望VPN客户端看起来像是服务器端网络的一部分。这使得浏览文件夹、共享文件和打印机更容易。为了实现这一目的,许多设置都采用以太网桥接(见第六章 带tap设备的C/S模式),这有其自身的缺点。于非桥接设置相比,桥接配置的性能可能要低得多。
当OpenVPN服务器在Linux或Unix上运行时,有一种替代解决方案:大多数Unix内核都具有代理ARP功能,可用于在服务器局域网上为OpenVPN客户端分配IP地址,并使其看起来像是该局域网的一部分。请注意,这仅适用于IPv4网络,因为IPv6网络不使用ARP。
考虑以下网络布局:
客户端tun0地址为192.168.3.34
服务器端tun0地址为192.168.3.33,服务器端网段为192.168.3.0/24
此布局中,无法使用标准的VPN子网10.200.0.0/24,因为我们必须将VPN客户端集成到现有子网中,在本例中为192.168.3.0/24。此子网中的当前计算机在192.168.3.10-192.168.3.24范围内,因此我们将VPN地址放置在此范围之外。确保服务器端局域网上的DHCP服务器不应公布VPN地址,因为我们希望OpenVPN为VPN客户端分配地址。
对于这个例子,我们利用OpenVPN功能在客户端连接或断开连接时运行脚本。OpenVPN的脚本功能在第七章 脚本和插件 中有更详细的解释。
1、我们从以下服务器配置文件开始:
xxxxxxxxxx
proto udp
port 1194
dev tun
server 192.168.3.32 255.255.255.224
push “route 192.168.3.0 255.255.255.0”
topology subnet
persist-key
persist-tun
keepalive 10 60
tls-auth /etc/openvpn/movpn/ta.key 0
dh /etc/openvpn/movpn/dh2048.pem
ca /etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/server.crt
key /etc/openvpn/movpn/server.key
verb 3
daemon
log-append /var/log/openvpn.log
script-security 2
client-connect /etc/openvpn/movpn/proxyarp-connect.sh
client-disconnect /etc/openvpn/movpn/proxyarp-disconnect.sh
注意,我们添加了三条语句来设置脚本的安全级别,并在客户端连接或断开连接时运行自定义脚本。
2、将以上文件保存为 movpn-04-01-server.conf
。
3、接下来,创建每次VPN客户端连接时执行的 proxyarp-connect.sh
脚本:
xxxxxxxxxx
/sbin/arp -i eth0 -Ds ${ifconfig_pool_remote_ip} eth0 pub
/sbin/ip route add ${ifconfig_pool_remote_ip}/32 dev tun0
4、将以上脚本保存为 /etc/openvpn/movpn/proxyarp-connect.sh
。脚本位置必须与 movpn-04-10-server.conf
文件中指定的绝对路径匹配。
5、然后,创建 proxyarp-disconnect.sh
脚本,该脚本在客户端断开连接时执行:
xxxxxxxxxx
/sbin/arp -i eth0 -d ${ifconfig_pool_remote_ip}
/sbin/ip route del ${ifconfig_pool_remote_ip}/32 dev tun0
6、将以上脚本保存为 /etc/openvpn/movpn/proxyarp-disconnect.sh
。
注意,设备名称 eth0
和 tun0
被硬编码到脚本中。这是必要的,因为OpenVPN不知道需要发布额外ARP地址的设备。通过在两个脚本中复制 /sbin/arp
行,也可以在多个接口(eth0、eth1、wlan0等)上发布额外的ARP地址。
使这两个脚本都可执行,并使用以下命令启动OpenVPN服务器:
xxxxxxxxxx
[root@server]# chmod a+x /etc/openvpn/movpn/proxyarp-connect.sh
[root@server]# openvpn --config movpn-04-10-server.conf
7、与往常一样,使用 basic-udp-client.conf
(或者 basic-udp-client.ovpn
)配置文件连接到服务器。VPN客户端成功连接后,我们会验证局域网上的其他设备是否可以看到该客户端。
【原文有安卓收集界面的图,略】
安卓设备上没有添加额外的网络路由。VPN客户端真正集成到现有子网中。
8、我们还可以验证OpenVPN服务器现在是否在其ARP表中发布了额外的IP地址:
xxxxxxxxxx
[server]$ /sbin/arp -an | grep PERM
? (192.168.3.34) at * PERM PUP on eth0
代理ARP是大多数Unix和Linux内核支持的功能。它最常用于将拨入客户端连接到局域网,现在也被ADSL和有线互联网提供商使用。
当客户端连接时,OpenVPN服务器从其本地局域网范围借用IP地址。然后将此IP地址分配给此OpenVPN客户端。服务器还在系统的ARP表中创建了一个特殊条目,告诉站点B的局域网的其余部分,OpenVPN服务器充当IP 192.168.3.34的代理。这意味着,当服务器端局域网上的另一台机器想知道在哪里找到IP为192.168.3.34的主机时,OpenVPN服务器将使用其自己的代理ARP地址发布的接口的MAC地址进行响应。
服务器配置文件包含一些需要解释的语句:
xxxxxxxxxx
server 192.168.3.32 255.255.255.224
push “route 192.168.3.0 255.255.255.0”
前面的行导致OpenVPN服务器将地址192.168.3.33分配给服务器VPN IP地址,网络掩码为255.255.255.224(或/27)。第一个VPN客户端被分配了地址192.168.3.34/27。但是,这意味着VPN客户端本身无法访问此范围之外的任何IP地址。需要推送路由声明来告诉OpenVPN客户端可以通过VPN访问整个子网192.168.3.0/24。
到目前为止,服务器配置文件通常包括以下行:
xxxxxxxxxx
user nobody
group nobody
在此配置文件中,它们不存在,因为 client-connect
和 client-disconnect
脚本需要以 root
用户身份运行。另一种方法是设置 sudo
权限,以便允许 user nobody
以root权限执行/sbin/arp命令。
最后,以下行:
xxxxxxxxxx
script-security 2
client-connect /etc/openvpn/movpn/proxyarp-connect.sh
client-disconnect /etc/openvpn/movpn/proxyarp-disconnect.sh
设置OpenVPN的脚本功能。第一行将脚本的安全级别设置为2,这意味着某些环境变量对脚本可用。
client-connect
和 client-disconnect
行都指定了要执行的脚本的绝对路径。
作为代理ARP示例的后续,我们现在将研究如何将公共IPv4地址分发给OpenVPN客户端。让我们假设以下一组(仅作为示例)公共IPv4地址对我们可用:
我们的公网IPv4网络是192.0.2.160/28,这给了我们16个地址,这些地址的使用方式如下:
IP地址 | 用处 |
---|---|
192.0.2.160 | 子网的网络地址 |
192.0.2.161 | 服务器的VPN IP地址 |
192.0.2.162 | 未使用 |
192.0.2.163 | 未使用 |
192.0.2.163-192.0.2.170 | 用于VPN客户端 |
192.0.2.171 | OpenVPN服务器本身的局域网地址 |
192.0.2.172 | 未使用 |
192.0.2.173 | 未使用 |
192.0.2.174 | 远程局域网上的路由器 |
192.0.2.175 | 网络广播地址 |
我们现在想设置一个OpenVPN服务器,能够分发地址192.0.2.164到192.0.2.170,OpenVPN服务器本身位于地址192.0.2.161:
1、创建服务器配置文件:
xxxxxxxxxx
proto udp
port 1194
dev tun
mode server
tls-server
ifconfig 192.0.2.161 255.255.255.240
ifconfig-pool 192.0.2.164 192.0.2.170
push “route 192.0.2.171 255.255.255.255 net_gateway”
push “route-gateway 192.0.2.174”
push “redirect-gateway def1”
push “topology subnet”
topology subnet
persist-key
persist-tun
keepalive 10 60
tls-auth /etc/openvpn/movpn/ta.key 0
dh /etc/openvpn/movpn/dh2048.pem
ca /etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/server.crt
key /etc/openvpn/movpn/server.key
verb 3
daemon
log-append /var/log/openvpn.log
script-security 2
client-connect /etc/openvpn/movpn/proxyarp-connect.sh
client-disconnect /etc/openvpn/movpn/proxyarp-disconnect.sh
2、将此文件另存为 movpn-04-11-server.conf
。我们将重用前面示例中的 proxyarp-connect.sh
和 proxyarp-disconnect.sh
脚本。创建每次VPN客户端连接时执行的 proxyarp-connect.sh
:
xxxxxxxxxx
/sbin/arp -i eth0 -Ds ${ifconfig_pool_remote_ip} eth0 pub
/sbin/ip route add ${ifconfig_pool_remote_ip}/32 dev tun0
3、将以上内容保存为 /etc/openvpn/movpn/proxyarp-connect.sh
。
4、然后,创建 proxyarp-disconnect.sh
脚本,该脚本在客户端断开连接时执行:
xxxxxxxxxx
/sbin/arp -i eth0 -d ${ifconfig_pool_remote_ip}
/sbin/ip route del ${ifconfig_pool_remote_ip}/32 dev tun0
5、将以上内容保存为 /etc/openvpn/movpn/proxyarp-disconnect.sh
。使这两个脚本都可执行并启动OpenVPN服务器:
xxxxxxxxxx
[root@server]# chmod a+x /etc/openvpn/movpn/proxyarp-connect.sh[
[root@server]# openvpn --config movpn-04-11-server.conf
6、使用基本配置文件将OpenVPN客户端连接到服务器。第一个客户端将被分配地址192.0.2.164。
服务器配置文件类似于文件movpn-04-10-server.conf
,除了以下块:
xxxxxxxxxx
mode server
tls-server
ifconfig 192.0.2.161 255.255.255.240
ifconfig-pool 192.0.2.164 192.0.2.170
push “route 192.0.2.171 255.255.255.255 net_gateway”
push “route-gateway 192.0.2.174”
push “redirect-gateway def1”
push “topology subnet”
本章前面解释了宏 server 10.200.0.0 255.255.255.0
的扩展如下:
xxxxxxxxxx
mode server
tls-server
push “topology subnet”
ifconfig 10.200.0.1 255.255.255.0
ifconfig-pool 10.200.0.2 10.200.0.254 255.255.255.0
push “route-gateway 10.200.0.1”
在分发公共IP地址时,我们通常不会浪费IPv4地址。OpenVPN 2.1中引入的选项 topology subnet
在这里非常有用。
在检查了我们的公共IPv4空间后,我们放弃了server
语句,并包含了我们自己版本的ifconfig
和ifconfig-pool
选项:
ifconfig 192.0.2.161 255.255.255.240
: 指定服务器VPN IP地址为192.0.2.161/28。ifconfig-pool 192.0.2.164 192.0.2.170
: 指定了VPN客户端的可用IP地址池范围为192.0.2.164到192.0.2.170,总共七个地址。请注意,ifconfig-pool
范围需要是连续的。
如果一个范围内有“漏洞”,那么使用脚本分配IP地址通常更容易,正如我们将在第7章“脚本和插件”中学习的那样。push “route 192.0.2.171 255.255.255.255 net_gateway”
: 此到VPN服务器LAN地址的路由需要明确推送到客户端。通常,此路由由OpenVPN客户端自动添加,以确保用于OpenVPN服务器本身的流量不会再次注入隧道,从而导致数据包循环。使用我们特殊的ifconfig
和ifconfig-pool
设置,建议向OpenVPN服务器的LAN地址添加一个显式路由。push “route-gateway 192.0.2.174”
: route-gateway
指定用于将所有隧道流量定向到的网关地址。通常,route-gateway
等于VPN服务器IP地址。在这种情况下,它只会导致路由跳变,因为VPN服务器会立即将其转发到同一子网上的真实网关192.0.2.174。因此,我们指定LAN网关的IP地址。push “redirect-gateway def1”
: 为了使OpenVPN客户端将公共地址用于其所有流量,它必须通过VPN隧道路由所有流量。push “topology subnet”
: 通常,服务器宏会为我们处理这个push
,但由于我们在这里没有使用服务器宏,我们必须显式地推送这个选项。如果省略此选项,则服务器将分配线性地址(因为它的配置中有一条线topology subnet
),但VPN客户端将假设它们被分配了topology net30
地址,这是当前的默认值。明确的push
避免了这种潜在的配置错误。本章介绍了具有tun设备的客户端/服务器模式的各种功能和选项。我们为OpenVPN服务器和客户端、作为传输手段的UDP和TCP协议以及Windows和Linux/Unix客户端建立了一组基本的配置文件。这组基本配置文件将在本书的其余部分中使用。
我们讨论了如何设置一个同时提供IPv4地址和IPv6地址的OpenVPN服务器。我们介绍了服务器端和客户端路由,包括通过VPN隧道重定向所有流量。我们还看到了如何使用OpenVPN分发公共IPv4地址。
在下一章中,我们将探讨OpenVPN提供的高级功能。此外,在第6章“带抽头设备的客户端/服务器模式”中,将解释几个对tun模式也有用的选项和示例。