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
They then store the required parameters into the vars file, which can be uncommented and edited:
$ vim vars
$ grep EASYRSA 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"
$ 
接著新增 CA 密鑰配對本身 (在此階段把兩組鑰匙儲存在 keys/ca.crtkeys/ca.key):
The next step is the creation of the CA's key pair itself (the two parts of the key pair will be stored under pki/ca.crt and pki/private/ca.key during this step). We can add the option nopass to avoid entering a password each time the private key is used:
$ ./easyrsa build-ca nopass

Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1b  26 Feb 2019
Generating RSA private key, 2048 bit long modulus (2 primes)
......................................................................................+++++
......................+++++
e is 65537 (0x010001)
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.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/home/roland/pki-falcot/pki/ca.crt

現在 VPN 伺服器的認證完成,Diffie-Hellman 參數供伺服器的 SSL/TLS 連結亦完成。VPN 伺服器以其 DNS 名稱 vpn.falcot.com 識別;此名稱再次使用於新增鑰匙檔案 (keys/vpn.falcot.com.crt 供公鑰,keys/vpn.falcot.com.key 供私鑰):
$ ./easyrsa gen-req vpn.falcot.com nopass
Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1b  26 Feb 2019
Generating a RSA private key
.................................................................................+++++
........+++++
writing new private key to '/home/roland/pki-falcot/pki/private/vpn.falcot.com.key.E5c3RGJBUd'
-----
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.
-----
Common Name (eg: your user, host, or server name) [vpn.falcot.com]:

Keypair and certificate request completed. Your files are:
req: /home/roland/pki-falcot/pki/reqs/vpn.falcot.com.req
key: /home/roland/pki-falcot/pki/private/vpn.falcot.com.key

$ ./easyrsa sign-req server vpn.falcot.com

Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1b  26 Feb 2019


You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.

Request subject, to be signed as a server certificate for 1080 days:

subject=
    commonName                = vpn.falcot.com


Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes
Using configuration from /home/roland/pki-falcot/pki/safessl-easyrsa.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'vpn.falcot.com'
Certificate is to be certified until Jun 14 10:44:44 2022 GMT (1080 days)

Write out database with 1 new entries
Data Base Updated

Certificate created at: /home/roland/pki-falcot/pki/issued/vpn.falcot.com.crt

$ ./easyrsa gen-dh

Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1b  26 Feb 2019
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
[…]
DH parameters of size 2048 created at /home/roland/pki-falcot/pki/dh.pem

以上的步驟新增 VPN 客戶;每個使用 VPN 的電腦或使用者都需有個認證:
$ ./build-key JoeSmith

Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1b  26 Feb 2019
Generating a RSA private key
....+++++
..............................+++++
writing new private key to '/home/roland/pki-falcot/pki/private/JoeSmith.key.mY21iP8ysv'
-----
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.
-----
Common Name (eg: your user, host, or server name) [JoeSmith]:

Keypair and certificate request completed. Your files are:
req: /home/roland/pki-falcot/pki/reqs/JoeSmith.req
key: /home/roland/pki-falcot/pki/private/JoeSmith.key
Now all certificates have been created, they need to be copied where appropriate: the root certificate's public key (pki/ca.crt) will be stored on all machines (both server and clients) as /etc/ssl/certs/Falcot_CA.crt. The server's certificate is installed only on the server (pki/issued/vpn.falcot.com.crt goes to /etc/ssl/vpn.falcot.com.crt, and pki/private/vpn.falcot.com.key goes to /etc/ssl/private/vpn.falcot.com.key with restricted permissions so that only the administrator can read it), with the corresponding Diffie-Hellman parameters (pki/dh.pem) installed to /etc/openvpn/dh.pem. Client certificates are installed on the corresponding VPN client in a similar fashion.

10.2.1.2. 組態 OpenVPN 伺服器

By default, the OpenVPN initialization script tries starting all virtual private networks defined in /etc/openvpn/*.conf. Setting up a VPN server is therefore a matter of storing a corresponding configuration file in this directory. A good starting point is /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz, which leads to a rather standard server. Of course, some parameters need to be adapted: ca, cert, key and dh need to describe the selected locations (respectively, /etc/ssl/certs/Falcot_CA.crt, /etc/ssl/vpn.falcot.com.crt, /etc/ssl/private/vpn.falcot.com.key and /etc/openvpn/dh.pem). The server 10.8.0.0 255.255.255.0 directive defines the subnet to be used by the VPN; the server uses the first IP address in that range (10.8.0.1) and the rest of the addresses are allocated to clients.
在這種組態下,通常以 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
If the VPN should not be started automatically on boot, set the AUTOSTART directive to none in the /etc/default/openvpn file. Starting or stopping a given VPN connection is always possible with the commands systemctl start openvpn@name and systemctl stop openvpn@name (where the connection name matches the one defined in /etc/openvpn/name.conf).
network-manager-openvpn-gnome 套件包括允許管理 OpenVPN 虛擬專屬網路的延伸網路管理者 (見 節 8.2.5, “網路自動組態漫遊使用者”)。允許每個使用者以圖形介面組態 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
  ip route add 192.168.0.0/24 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
  ip route del 192.168.0.0/24 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     *