Product SiteDocumentation Site

10.2. 虚拟专用网络

虚拟专用网络 (VPN) 是以信道方式,经由互联网链接两个局域网路的方式;通常以加密方式在信道内发送信息。VPN 通常用于集成公司内部远程机器。
好几个工具提供这种服务。OpenVPN 是个有效率解决方案,基于 SSL/TLS,容易布署与维护。以 IPsec 加密两部机器的 IP 流量;这是透明的编码,在该等主机运行应用程序时不需修改 VPN。SSH 在传统的功能外,也能提供 VPN。最后,可以用微软的 PPTP 协议创建 VPN。其他的解决方案,就留给读者自行探索。

10.2.1. OpenVPN

OpenVPN 用于创建虚拟专用网络的一个软件。在 VPN 服务器及客户端创建虚拟专用网络;支持 tun (IP 层面的信道) 和 tap (Ethernet 层面的信道) 接口。实务上,常用的是 tun 接口,除非 VPN 客户端难以经由 Ethernet 桥接器集成入服务器的局域网路。
OpenVPN 所有的 SSL/TLS 加密与其他功能 (机密性、认证、完整性、不可否认性),均有赖于 OpenSSL。可以用公钥基础设施的共享私钥或使用 X.509 认证的方式配置它。建议使用后者的方式配置,以漫游方式近用 VPN 的用户可享有更多的弹性。

10.2.1.1. 公钥基础设施:easy-rsa

RSA 算法是使用广泛的公钥加密法。以 “密钥配对” 法比对私钥与公钥。两钥密切连在一起,以公钥演算加密的消息,只能被知道私钥的人解开,以保障其安全。反之亦然,以私钥加密的消息,只能被公钥解开,也就是让拥有私钥的人,可以向指定的社区发出消息。以数字哈希 (MD5、SHA1、或其他) 方式演算,适用于任何签名机制的消息。
任何人都可以添加密钥配对。采用 授权认证 (CA),即 X.509 标准。此术语指的是拥有信任密钥配对做为 root 认证。此认证只用于签署另个认证 (密钥配对),经过适当的进程,检查保存在密钥配对的内容。使用 X.509 可以检查其中的认证。
OpenVPN 遵守此法则。因为公共 CA 放出的认证系用于交换 (巨大) 的费用,可以在公司内部生成专用的认证机制。easy-rsa 软件包可做为 X.509 认证基础建设,应用于 openssl 命令的脚本内。
Falcot 公司的管理者以此工具添加必要的服务器与客户端认证。可以把所有的客户端配置成类似的状态,因为他们只需信件 Falcot 本地 CA 的认证。此 CA 是率先认证的;为此工作,管理者在适当的地方创建新的文件夹,供 CA 的文件使用,最好放在脱机的地方,杜绝私钥被窃的危险。
$ make-cadir pki-falcot
$ cd pki-falcot
把必要的参数保存在 vars 文件内,特别是以 KEY_ 开头的部分;这些变量集成入环境:
$ vim vars
$ grep KEY_ vars
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
export KEY_DIR="$EASY_RSA/keys"
echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
export KEY_SIZE=2048
export KEY_EXPIRE=3650
export KEY_COUNTRY="FR"
export KEY_PROVINCE="Loire"
export KEY_CITY="Saint-Étienne"
export KEY_ORG="Falcot Corp"
export KEY_EMAIL="admin@falcot.com"
export KEY_OU="Certificate authority"
export KEY_NAME="Certificate authority for Falcot Corp"
# If you'd like to sign all keys with the same Common Name, uncomment the KEY_CN export below
# export KEY_CN="CommonName"
$ . ./vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/roland/pki-falcot/keys
$ ./clean-all
接着添加 CA 密钥配对本身 (在此阶段把两组钥匙保存在 keys/ca.crtkeys/ca.key):
$ ./build-ca
Generating a 2048 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) [FR]:
State or Province Name (full name) [Loire]:
Locality Name (eg, city) [Saint-Étienne]:
Organization Name (eg, company) [Falcot Corp]:
Organizational Unit Name (eg, section) [Certificate authority]:
Common Name (eg, your name or your server's hostname) [Falcot Corp CA]:
Name [Certificate authority for Falcot Corp]:
Email Address [admin@falcot.com]:
现在 VPN 服务器的认证完成,Diffie-Hellman 参数供服务器的 SSL/TLS 链接亦完成。VPN 服务器以其 DNS 名称 vpn.falcot.com 识别;此名称再次使用于添加钥匙文件 (keys/vpn.falcot.com.crt 供公钥,keys/vpn.falcot.com.key 供私钥):
$ ./build-key-server vpn.falcot.com
Generating a 2048 bit RSA private key
.....................................................................................................................+++
...........+++
writing new private key to 'vpn.falcot.com.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) [FR]:
State or Province Name (full name) [Loire]:
Locality Name (eg, city) [Saint-Étienne]:
Organization Name (eg, company) [Falcot Corp]:
Organizational Unit Name (eg, section) [Certificate authority]:
Common Name (eg, your name or your server's hostname) [vpn.falcot.com]:
Name [Certificate authority for Falcot Corp]:
Email Address [admin@falcot.com]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /home/roland/pki-falcot/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'FR'
stateOrProvinceName   :PRINTABLE:'Loire'
localityName          :T61STRING:'Saint-\0xFFFFFFC3\0xFFFFFF89tienne'
organizationName      :PRINTABLE:'Falcot Corp'
organizationalUnitName:PRINTABLE:'Certificate authority'
commonName            :PRINTABLE:'vpn.falcot.com'
name                  :PRINTABLE:'Certificate authority for Falcot Corp'
emailAddress          :IA5STRING:'admin@falcot.com'
Certificate is to be certified until Mar  6 14:54:56 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
$ ./build-dh
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
[…]
以上的步骤添加 VPN 客户;每个使用 VPN 的电脑或用户都需有个认证:
$ ./build-key JoeSmith
Generating a 2048 bit RSA private key
................................+++
..............................................+++
writing new private key to 'JoeSmith.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) [FR]:
State or Province Name (full name) [Loire]:
Locality Name (eg, city) [Saint-Étienne]:
Organization Name (eg, company) [Falcot Corp]:
Organizational Unit Name (eg, section) [Certificate authority]:Development unit
Common Name (eg, your name or your server's hostname) [JoeSmith]:Joe Smith
[…]
新的认证建好后,需复制至适当的地方:超级用户公钥 (keys/ca.crt) 保存在所有机器 (服务器与客户端) 的 /etc/ssl/certs/Falcot_CA.crt。服务器的认证仅安装在服务器 (keys/vpn.falcot.com.crt/etc/ssl/vpn.falcot.com.crt,以及 keys/vpn.falcot.com.key/etc/ssl/private/vpn.falcot.com.key 限制其权限为管理者才能读取),对应至 Diffie-Hellman 参数 (keys/dh2048.pem) 安装在 /etc/openvpn/dh2048.pem。客户端认证则类似的方式,安装在对应的 VPN 各户端。

10.2.1.2. 配置 OpenVPN 服务器

缺省,OpenVPN 初始化的脚本在 /etc/openvpn/*.conf 启动所有虚拟专用网络。设置 VPN 服务器就是在此文件夹保存对应的配置档。/usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz 是个好的起点,创建相当标准服务器。当然,还有若干参数需要调整:cacertkeydh 需指定其地点 (分别是 /etc/ssl/certs/Falcot_CA.crt/etc/ssl/vpn.falcot.com.crt/etc/ssl/private/vpn.falcot.com.key/etc/openvpn/dh2048.pem)。server 10.8.0.0 255.255.255.0 设置 VPN 的次网络;此服务器使用此范围内的第一个 IP 地址 (10.8.0.1) 然后把其他的地址保留给客户端。
在这种配置下,通常以 tun0 之名,添加 OpenVPN 的虚拟网络接口。然而,有时在启动 OpenVPN 前,把防火墙配置成真实的网络接口。最好固定添加的虚拟网络接口,OpenVPN 使用预存的接口。进一步选择接口的名称。到了这个阶段,openvpn --mktun --dev vpn --dev-type tun 添加一个虚拟网络接口名称为 vpn 型态为 tun;这个命令可以集成入防火墙配置脚本,或 up 指向 /etc/network/interfaces 文件。OpenVPN 配置档必须跟着更新,直接使用 dev vpndev-type tun
禁止进一步的行动,VPN 客户端只能经由 10.8.0.1 地址近用 VPN 服务器。为了授权客户近用本地网络 (192.168.0.0/24),需在 OpenVPN 配置中加入 推送路径 192.168.0.0 255.255.255.0,让 VPN 客户端自动取得网络路由,使其明了经由 VPN 可以进入该网络。此外,本地网络的机器也需被告知,经由 VPN 服务器 (在闸道安装 VPN 服务器即自动启用) 进入VPN。另外,VPN 服务器可以配置后运行伪装 IP 的工作,让来自 VPN 客户端的消息显示成来自 VPN 服务器 (见 第 10.1 节 “网关”)。

10.2.1.3. 配置 OpenVPN 客户端

需配置 /etc/openvpn/ 内的文件才能设置 OpenVPN 客户端。标准的配置方法可从使用 /usr/share/doc/openvpn/examples/sample-config-files/client.conf 这个文件开始。remote vpn.falcot.com 1194 介绍 OpenVPN 服务器的地址及端口号;描述密钥文档地址时,需参考 cacertkey
若开机时无法自动进入 VPN,则需设置 AUTOSTARTnone/etc/default/openvpn 文件内。以命令 service openvpn@name startservice openvpn@name stop (其中的 name 就是在 /etc/openvpn/name.conf 中设置的名称) 就能启用或停用指定的 VPN 链接。
network-manager-openvpn-gnome 软件包包括允许管理 OpenVPN 虚拟专属网络的延伸网络管理者 (见 第 8.2.5 节 “Automatic Network Configuration for Roaming Users”)。允许每个用户以图形接口配置 OpenVPN 且从网络管理图标控制它们。

10.2.2. SSH 下的虚拟专属网络

实际上有两种方法以 SSH 添加虚拟专属网络。较旧的是以 SSH 创建 PPP 层链接。此方法在 HOWTO 文档详细说明:
第二个方法较新,适用于 OpenSSH 4.3;可以在 OpenSSH 之下创建虚拟网络接口 (tun*) 于 SSH 链接的两端,且可以精准地配置这些虚拟接口,就像在实体接口环境下。必须先设置 PermitTunnel 为 “yes” 于 SSH 服务器配置档 (/etc/ssh/sshd_config),才能启用此隧道系统。启用 SSH 链接后,添加的隧道必须以 -w any:any 选项 (any 可以用期望的 tun 设备名称取代) 请求链接。两端的用户需有管理者权限,才能添加网络设备 (换句话说,必须以超级用户的身份才能创建链接)。
以 SSH 创建虚拟专属网络的两种方法都很直接。然而,它们提供的 VPN 不是最有效的;特别是,无法有效处理高端的流量。
当 TCP/IP 堆栈封装在 TCP/IP 链接 (供 SSH 使用) 时,TCP 协议用了两次,一次给 SSH 链接用,另一次使用于信道。问题就在这里,尤其是 TCP 改变网络延迟时间的状态。详情见: 所以在 SSH 环境下的 VPN 应限制于无性能限制的一次性信道。

10.2.3. 互联网安全协议

仅管 IPsec 已是 IP VPN 的标准,不过在应用层面仍有待加强。IPsec 引擎本身已经集成入 Linux 核心;控制与配置工具等必备的用户部分,已由 ipsec-tools 软件包提供。具体来说,每个主机的 /etc/ipsec-tools.conf 包括给 IPsec tunnels (或 Security Associations,以 IPsec 术语来说) 使用的参数,让主机连进来;/etc/init.d/setkey 脚本提供启用与停止信道的方法 (每个信道是安全链接至另个主机虚拟私有网络)。可以参考 setkey(8) 手册提供的文档,以人工方式创建此文件。然而,撰写供所有主机使用的参数,并不轻松反而极为烦琐,因为信道的数量急剧增加。安装 IKE 调度 (如 IPsec Key Exchange) 就像 racoonstrongswan 把管理带入中央的点,就可简化此进程,而且定期更换密钥,显得更安全。
仅管其状态为参照,IPsec 的设置限制其用途。必备的信道不多也不是动态时,OpenVPN-based 解决方案较受用。

10.2.4. PPTP

PPTP (𪅈原文是 Point-to-Point Tunneling Protocol) 用到两种通信闸道,一个控制数据另个酬载数据;后者使用 GRE 协议 (Generic Routing Encapsulation)。标准的 PPP 链接创建在数据交换闸道。

10.2.4.1. 设置客户端

pptp-linux 封包含有易于配置的 Linux 客户端 PPTP。以下说明取自官方文档:
Falcot 管理者添加若干文件:/etc/ppp/options.pptp/etc/ppp/peers/falcot/etc/ppp/ip-up.d/falcot、与 /etc/ppp/ip-down.d/falcot

例 10.2. /etc/ppp/options.pptp 文件

# PPP options used for a PPTP connection
lock
noauth
nobsdcomp
nodeflate

例 10.3. /etc/ppp/peers/falcot 文件

# vpn.falcot.com is the PPTP server
pty "pptp vpn.falcot.com --nolaunchpppd"
# the connection will identify as the "vpn" user
user vpn
remotename pptp
# encryption is needed
require-mppe-128
file /etc/ppp/options.pptp
ipparam falcot

例 10.4. /etc/ppp/ip-up.d/falcot 文件

# Create the route to the Falcot network
if [ "$6" = "falcot" ]; then
  # 192.168.0.0/24 is the (remote) Falcot network
  route add -net 192.168.0.0 netmask 255.255.255.0 dev $1
fi

例 10.5. /etc/ppp/ip-down.d/falcot 文件

# Delete the route to the Falcot network
if [ "$6" = "falcot" ]; then
  # 192.168.0.0/24 is the (remote) Falcot network
  route del -net 192.168.0.0 netmask 255.255.255.0 dev $1
fi

10.2.4.2. 配置服务器

pptpd 是 Linux 的 PPTP 服务器。它的主要配置档是,/etc/pptpd.conf,应做若干改变:localip (内网 IP 地址) 与 remoteip (外网 IP 地址)。在下例中,PPTP 服务器总是使用 192.168.0.199 地址,以及从 192.168.0.200192.168.0.250 之间接收 PPTP 客户端的 IP 地址。

例 10.6. /etc/pptpd.conf 文件

# TAG: speed
#
#       Specifies the speed for the PPP daemon to talk at.
#
speed 115200

# TAG: option
#
#       Specifies the location of the PPP options file.
#       By default PPP looks in '/etc/ppp/options'
#
option /etc/ppp/pptpd-options

# TAG: debug
#
#       Turns on (more) debugging to syslog
#
# debug

# TAG: localip
# TAG: remoteip
#
#       Specifies the local and remote IP address ranges.
#
#       You can specify single IP addresses separated by commas or you can
#       specify ranges, or both. For example:
#
#               192.168.0.234,192.168.0.245-249,192.168.0.254
#
#       IMPORTANT RESTRICTIONS:
#
#       1. No spaces are permitted between commas or within addresses.
#
#       2. If you give more IP addresses than MAX_CONNECTIONS, it will
#          start at the beginning of the list and go until it gets
#          MAX_CONNECTIONS IPs. Others will be ignored.
#
#       3. No shortcuts in ranges! ie. 234-8 does not mean 234 to 238,
#          you must type 234-238 if you mean this.
#
#       4. If you give a single localIP, that's ok - all local IPs will
#          be set to the given one. You MUST still give at least one remote
#          IP for each simultaneous client.
#
#localip 192.168.0.234-238,192.168.0.245
#remoteip 192.168.1.234-238,192.168.1.245
#localip 10.0.1.1
#remoteip 10.0.1.2-100
localip 192.168.0.199
remoteip 192.168.0.200-250
PPP 采用 PPTP 服务器配置时也需在 /etc/ppp/pptpd-options 做若干改变。 重要的参数有服务器名称 (pptp)、网域名称 (falcot.com)、以及 DNS 与 WINS 服务器的 IP 地址。

例 10.7. /etc/ppp/pptpd-options 文件

## turn pppd syslog debugging on
#debug

## change 'servername' to whatever you specify as your server name in chap-secrets
name pptp
## change the domainname to your local domain
domain falcot.com

## these are reasonable defaults for WinXXXX clients
## for the security related settings
# The Debian pppd package now supports both MSCHAP and MPPE, so enable them
# here. Please note that the kernel support for MPPE must also be present!
auth
require-chap
require-mschap
require-mschap-v2
require-mppe-128

## Fill in your addresses
ms-dns 192.168.0.1
ms-wins 192.168.0.1

## Fill in your netmask
netmask 255.255.255.0

## some defaults
nodefaultroute
proxyarp
lock
登录 vpn 用户 (及其密码) 于 /etc/ppp/chap-secrets 文件的最后一个步骤。其他的作为里,星号 (*) 是有作用的,在此的服务器名称必须明示出来。而且,Windows PPTP 客户端以 DOMAIN\\USER 形式辨识,不是以用户名区别。这就说明了在 FALCOT\\vpn 用户必须提及的文件。也可以指定用户使用特定的 IP 地址;此字段内的星号用于指定动态的地址。

例 10.8. 该 /etc/ppp/chap-secrets 文件

# Secrets for authentication using CHAP
# client        server  secret      IP addresses
vpn             pptp    f@Lc3au     *
FALCOT\\vpn     pptp    f@Lc3au     *