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.4, “網路自動組態漫遊使用者”)。允許每個使用者以圖形介面組態 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     *