問題
就在最近,許多人還不知道在家工作是什麼感覺。 這場流行病極大地改變了世界局勢;每個人都開始適應當前的情況,即離開家變得根本不安全。 許多人不得不迅速為員工安排在家工作。
然而,缺乏有效的方法來選擇遠端工作解決方案可能會導致不可挽回的損失。 使用者密碼可能被竊取,這將使攻擊者能夠不受控制地連接到企業的網路和 IT 資源。
這就是為什麼現在對創建可靠的企業 VPN 網路的需求不斷增加。 我會告訴你關於 可靠的, 安全的 и 簡單 使用 VPN 網路時。
它根據 IPsec/L2TP 方案運作,該方案使用儲存在令牌上的不可檢索的金鑰和憑證來驗證客戶端,並以加密形式透過網路傳輸資料。
使用 CentOS 7 的伺服器(位址:centos.vpn.server.ad)和 Ubuntu 20.04 的用戶端以及 Windows 10 的用戶端作為設定演示台。
系統描述
VPN 將依照 IPSec + L2TP + PPP 方案運作。 協定 點對點協議 (PPP)運行在 OSI 模型的資料鏈路層,提供用戶身份驗證和傳輸資料的加密。 其資料封裝在L2TP協定的資料中,實際上保證了VPN網路中連接的創建,但不提供認證和加密。
L2TP資料封裝在IPSec中,IPSec也提供身份驗證和加密,但與PPP不同的是,身份驗證和加密發生在設備級別,而不是用戶級別。
此功能可讓您僅從某些裝置對使用者進行身份驗證。 我們將按原樣使用 IPSec 協議,並允許從任何裝置進行使用者身份驗證。
使用智慧卡的使用者驗證將使用 EAP-TLS 協定在 PPP 協定層級執行。
有關該電路操作的更多詳細資訊可以在
為什麼這個方案能夠滿足良好VPN網路的所有三個要求?
- 此方案的可靠性經過了時間的檢驗。 自 2000 年以來,它一直用於部署 VPN 網路。
- PPP 協定提供安全的使用者身份驗證。
Paul Mackerras 開發的 PPP 協議的標準實現 不能提供足夠的安全級別,因為對於身份驗證,在最好的情況下,使用使用登入名稱和密碼的身份驗證。 我們都知道登入密碼可能被監視、猜測或竊取。 然而,長期以來,開發商珍·賈斯特·凱瑟 в其實施 此協定修正了此問題,並新增了使用基於非對稱加密的協定(例如 EAP-TLS)進行身份驗證的功能。 此外,他還添加了使用智慧卡進行身份驗證的功能,這使得系統更加安全。
目前,關於合併這兩個項目的積極談判正在進行中,您可以確定,無論如何,這遲早都會發生。 例如,PPP 的修補程式版本已經在 Fedora 儲存庫中存在很長時間了,它使用安全協定進行身份驗證。 - 直到最近,這個網路只能由 Windows 用戶使用,但我們來自莫斯科國立大學的 Vasily Shokov 和 Alexander Smirnov 發現
適用於 Linux 的舊 L2TP 用戶端項目 並對其進行了修改。 我們一起修復了客戶工作中的許多錯誤和缺點,簡化了系統的安裝和配置,即使是從原始碼建置時也是如此。 其中最重要的是:- 修正舊客戶端與新版本openssl、qt介面的相容性問題。
- 刪除了 pppd 透過暫存檔案傳遞令牌 PIN 的功能。
- 修正了透過圖形介面錯誤啟動密碼請求程式的問題。 這是透過為 xl2tpd 服務安裝正確的環境來完成的。
- L2tpIpsecVpn 守護程式的建置現在與客戶端本身的建置一起進行,這簡化了建置和設定過程。
- 為了方便開發,連接了Azure Pipelines系統來測試建置的正確性。
- 新增強制降級功能
安全級別 在 openssl 的上下文中。 這對於正確支援標準安全等級設定為 2 的新作業系統以及使用不符合該等級安全要求的憑證的 VPN 網路非常有用。 此選項對於使用現有的舊 VPN 網路非常有用。
更正後的版本可以在
該用戶端支援使用智慧卡進行身份驗證,同時也盡可能隱藏了在Linux下設定方案的所有艱辛,讓用戶端設定盡可能簡單、快速。
當然,為了 PPP 和客戶端 GUI 之間的方便連接,如果不對每個項目進行額外的編輯是不可能的,但儘管如此,它們還是被最小化並減少到最低限度:
- 固定的
錯誤地將令牌 PIN 碼從 PPP 轉送到 openssl 上下文 - 固定的
載入配置和初始化 openssl 上下文的順序錯誤 。 此錯誤不允許我們從本地/etc/ppp/openssl.cnf 設定檔載入任何內容,除了有關用於智慧卡的openssl 引擎的資訊之外,這會帶來嚴重的不便,例如,除了有關引擎的資訊之外,我們想設定一些別的東西。 例如,在建立連線時固定安全等級。
現在您可以開始設定了。
服務器調整
讓我們安裝所有必需的軟體包。
安裝strongswan(IPsec)
首先,讓我們設定防火牆以使用 ipsec
sudo firewall-cmd --permanent --add-port=1701/{tcp,udp}
sudo firewall-cmd --permanent --add-service=ipsec
sudo firewall-cmd --reload
然後我們開始安裝
sudo yum install epel-release ipsec-tools dnf
sudo dnf install strongswan
安裝後,您需要設定strongswan(IPSec實作之一)。 為此,請編輯文件 /etc/strongswan/ipsec.conf :
config setup
nat_traversal=yes
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
oe=off
protostack=netkey
conn L2TP-PSK-NAT
rightsubnet=vhost:%priv
also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
authby=secret
pfs=no
auto=add
keyingtries=3
rekey=no
ikelifetime=8h
keylife=1h
type=transport
left=%any
leftprotoport=udp/1701
right=%any
rightprotoport=udp/%any
ike=aes128-sha1-modp1536,aes128-sha1-modp1024,aes128-md5-modp1536,aes128-md5-modp1024,3des-sha1-modp1536,3des-sha1-modp1024,3des-md5-modp1536,3des-md5-modp1024
esp=aes128-sha1-modp1536,aes128-sha1-modp1024,aes128-md5-modp1536,aes128-md5-modp1024,3des-sha1-modp1536,3des-sha1-modp1024,3des-md5-modp1536,3des-md5-modp1024
我們還將設定一個通用的登入密碼。 所有網路參與者都必須知道共享密碼才能進行身份驗證。 這種方法顯然是不可靠的,因為這個密碼很容易被我們不希望提供網路存取權限的個人知曉。
然而,即使這個事實也不會影響網路的安全,因為基本的資料加密和使用者認證是透過PPP協定進行的。 但公平地說,值得注意的是,strongswan 支援更安全的身份驗證技術,例如使用私鑰。 Strongswan 也能夠使用智慧卡提供身份驗證,但到目前為止僅支援有限範圍的設備,因此使用 Rutoken 令牌和智慧卡進行身份驗證仍然很困難。 讓我們透過檔案設定一個通用密碼 /etc/strongswan/ipsec.secrets:
# ipsec.secrets - strongSwan IPsec secrets file
%any %any : PSK "SECRET_PASSPHRASE"
讓我們重新啟動strongswan:
sudo systemctl enable strongswan
sudo systemctl restart strongswan
安裝 xl2tp
sudo dnf install xl2tpd
讓我們透過文件來配置它 /etc/xl2tpd/xl2tpd.conf:
[global]
force userspace = yes
listen-addr = 0.0.0.0
ipsec saref = yes
[lns default]
exclusive = no
; определяет статический адрес сервера в виртуальной сети
local ip = 100.10.10.1
; задает диапазон виртуальных адресов
ip range = 100.10.10.1-100.10.10.254
assign ip = yes
refuse pap = yes
require authentication = yes
; данную опцию можно отключить после успешной настройки сети
ppp debug = yes
length bit = yes
pppoptfile = /etc/ppp/options.xl2tpd
; указывает адрес сервера в сети
name = centos.vpn.server.ad
讓我們重新啟動服務:
sudo systemctl enable xl2tpd
sudo systemctl restart xl2tpd
PPP 設定
建議安裝最新版本的 pppd。 為此,請執行以下命令序列:
sudo yum install git make gcc openssl-devel
git clone "https://github.com/jjkeijser/ppp"
cd ppp
./configure --prefix /usr
make -j4
sudo make install
寫入文件 /etc/ppp/options.xl2tpd 以下內容(如果有任何值,您可以刪除它們):
ipcp-accept-local
ipcp-accept-remote
ms-dns 8.8.8.8
ms-dns 1.1.1.1
noccp
auth
crtscts
idle 1800
mtu 1410
mru 1410
nodefaultroute
debug
lock
proxyarp
connect-delay 5000
我們頒發根憑證和伺服器憑證:
#директория с сертификатами пользователей, УЦ и сервера
sudo mkdir /etc/ppp/certs
#директория с закрытыми ключами сервера и УЦ
sudo mkdir /etc/ppp/keys
#запрещаем любой доступ к этой дирректории кроме администатора
sudo chmod 0600 /etc/ppp/keys/
#генерируем ключ и выписываем сертификат УЦ
sudo openssl genrsa -out /etc/ppp/keys/ca.pem 2048
sudo openssl req -key /etc/ppp/keys/ca.pem -new -x509 -out /etc/ppp/certs/ca.pem -subj "/C=RU/CN=L2TP CA"
#генерируем ключ и выписываем сертификат сервера
sudo openssl genrsa -out /etc/ppp/keys/server.pem 2048
sudo openssl req -new -out server.req -key /etc/ppp/keys/server.pem -subj "/C=RU/CN=centos.vpn.server.ad"
sudo openssl x509 -req -in server.req -CAkey /etc/ppp/keys/ca.pem -CA /etc/ppp/certs/ca.pem -out /etc/ppp/certs/server.pem -CAcreateserial
這樣,我們就完成了基本的伺服器設定。 伺服器配置的其餘部分涉及新增客戶端。
新增客戶
若要將新用戶端新增至網絡,您必須將其憑證新增至該用戶端的可信任憑證清單中。
如果使用者想要成為 VPN 網路的成員,他會為此用戶端建立金鑰對和憑證申請。 如果使用者是可信任的,則可以對該應用程式進行簽名,並且可以將產生的憑證寫入憑證目錄:
sudo openssl x509 -req -in client.req -CAkey /etc/ppp/keys/ca.pem -CA /etc/ppp/certs/ca.pem -out /etc/ppp/certs/client.pem -CAcreateserial
讓我們在 /etc/ppp/eaptls-server 檔案中新增一行以符合客戶端名稱及其憑證:
"client" * /etc/ppp/certs/client.pem /etc/ppp/certs/server.pem /etc/ppp/certs/ca.pem /etc/ppp/keys/server.pem *
注意
為了避免混淆,最好: 通用名稱、憑證檔案名稱和使用者名稱是唯一的。
另外值得檢查的是,我們新增的使用者名稱沒有出現在其他身份驗證檔案中的任何位置,否則使用者的身份驗證方式將會出現問題。
必須將相同的憑證傳回使用者。
產生密鑰對和證書
為了成功進行身份驗證,客戶端必須:
- 產生密鑰對;
- 擁有CA根憑證;
- 擁有由根 CA 簽署的金鑰對憑證。
對於 Linux 上的客戶端
首先,讓我們在令牌上產生密鑰對並為證書建立應用程式:
#идентификатор ключа (параметр --id) можно заменить на любой другой.
pkcs11-tool --module /usr/lib/librtpkcs11ecp.so --keypairgen --key-type rsa:2048 -l --id 45
openssl
OpenSSL> engine dynamic -pre SO_PATH:/usr/lib/x86_64-linux-gnu/engines-1.1/pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:librtpkcs11ecp.so
...
OpenSSL> req -engine pkcs11 -new -key 45 -keyform engine -out client.req -subj "/C=RU/CN=client"
將出現的 client.req 應用程式傳送給 CA。 收到密鑰對的憑證後,將其寫入與密鑰具有相同 id 的令牌:
pkcs11-tool --module /usr/lib/librtpkcs11ecp.so -l -y cert -w ./client.pem --id 45
適用於 Windows 和 Linux 用戶端(更通用的方法)
這種方法比較通用,因為允許您產生 Windows 和 Linux 使用者可以成功識別的金鑰和證書,但它需要 Windows 電腦來執行金鑰產生過程。
在產生請求和匯入憑證之前,您必須將 VPN 網路的根憑證新增至可信任清單。 為此,請打開它,然後在打開的視窗中選擇“安裝證書”選項:
在開啟的視窗中,選擇為本機使用者安裝憑證:
讓我們在 CA 的受信任根憑證儲存中安裝憑證:
經過所有這些行動,我們同意所有進一步的觀點。 系統現已配置完畢。
讓我們建立一個包含以下內容的檔案 cert.tmp:
[NewRequest]
Subject = "CN=client"
KeyLength = 2048
KeySpec = "AT_KEYEXCHANGE"
ProviderName = "Microsoft Base Smart Card Crypto Provider"
KeyUsage = "CERT_KEY_ENCIPHERMENT_KEY_USAGE"
KeyUsageProperty = "NCRYPT_ALLOW_DECRYPT_FLAG"
RequestType = PKCS10
SMIME = FALSE
之後,我們將產生密鑰對並建立證書應用程式。 為此,請開啟 powershell 並輸入以下命令:
certreq.exe -new -pin $PIN .cert.tmp .client.req
將建立的應用程式 client.req 傳送到您的 CA 並等待接收 client.pem 憑證。 可以使用以下命令將其寫入令牌並新增至 Windows 憑證儲存空間:
certreq.exe -accept .client.pem
值得注意的是,可以使用mmc程式的圖形介面來重現類似的動作,但這種方法更耗時且可程式性較差。
設定 Ubuntu 客戶端
注意
目前在 Linux 上設定客戶端相當耗時,因為... 需要從原始碼建立單獨的程式。 我們將盡力確保所有變更在不久的將來都包含在官方儲存庫中。
為了確保 IPSec 等級與伺服器的連接,使用了 Strongswan 軟體包和 xl2tp 守護程序。 為了簡化使用智慧卡連接到網路的過程,我們將使用 l2tp-ipsec-vpn 軟體包,它提供了一個圖形 shell 來簡化連接設定。
讓我們開始逐步組裝各個元素,但在此之前我們將安裝 VPN 直接運行所需的所有軟體包:
sudo apt-get install xl2tpd strongswan libp11-3
安裝用於處理令牌的軟體
安裝最新的 librtpkcs11ecp.so 函式庫
sudo apt-get install pcscd pcsc-tools opensc libengine-pkcs11-openssl
連接Rutoken並檢查系統是否識別它:
pkcs11-tool --module /usr/lib/librtpkcs11ecp.so -O -l
安裝打補丁的 ppp
sudo apt-get -y install git make gcc libssl-dev
git clone "https://github.com/jjkeijser/ppp"
cd ppp
./configure --prefix /usr
make -j4
sudo make install
安裝 L2tpIpsecVpn 客戶端
目前,客戶端還需要從原始碼編譯。 這是使用以下命令序列完成的:
sudo apt-get -y install git qt5-qmake qt5-default build-essential libctemplate-dev libltdl-dev
git clone "https://github.com/Sander80/l2tp-ipsec-vpn"
cd l2tp-ipsec-vpn
make -j4
sudo make install
設定 L2tpIpsecVpn 客戶端
啟動已安裝的客戶端:
啟動後,L2tpIpsecVPN 小程式應該會打開。 右鍵單擊它並配置連接:
要使用令牌,首先,我們指示 OpenSSL 的 opensc 引擎和 PKCS#11 函式庫的路徑。 為此,請開啟「首選項」標籤來配置 openssl 參數:
.
讓我們關閉 OpenSSL 設定視窗並繼續設定網路。 讓我們透過點擊設定面板中的「新增...」按鈕來新增網絡,然後輸入網路名稱:
此後,該網路將在設定面板中變為可用。 雙擊新網路進行配置。 在第一個選項卡上,您需要進行 IPsec 設定。 讓我們設定伺服器位址和公鑰:
之後,轉到 PPP 設定標籤並在其中指示我們要存取網路的使用者名稱:
之後,開啟「屬性」標籤並指定金鑰、用戶端憑證和 CA 的路徑:
讓我們關閉此標籤並執行最終設定;為此,請開啟「IP 設定」標籤並勾選「自動取得 DNS 伺服器位址」選項旁邊的方塊:
此選項將允許用戶端從伺服器接收網路內的個人 IP 位址。
完成所有設定後,關閉所有選項卡並重新啟動客戶端:
網絡連接
設定完成後就可以連接網路了。 為此,請打開小程式標籤並選擇我們要連接的網路:
在連線建立過程中,客戶端會要求我們輸入Rutoken PIN碼:
如果狀態列中出現連線已成功建立的通知,則表示設定成功:
否則,有必要弄清楚為什麼未建立連線。 為此,您應該透過在小程式中選擇「連線資訊」命令來查看程式日誌:
設定 Windows 用戶端
在 Windows 上設定客戶端比在 Linux 上設定客戶端容易得多,因為... 所有必要的軟體均已內建於系統中。
系統設定
我們將安裝使用 Rutokens 所需的所有驅動程序,方法是從
導入根憑證進行驗證
下載伺服器根憑證並將其安裝在系統上。 為此,請打開它,然後在打開的視窗中選擇“安裝證書”選項:
在開啟的視窗中,選擇為本機使用者安裝憑證。 如果您希望電腦上的所有使用者都可以使用證書,那麼您應該選擇在本機電腦上安裝證書:
讓我們在 CA 的受信任根憑證儲存中安裝憑證:
經過所有這些行動,我們同意所有進一步的觀點。 系統現已配置完畢。
設定 VPN 連接
若要設定 VPN 連接,請前往控制面板並選擇建立新連接的選項。
在彈出視窗中,選擇建立連線以連接到您的工作場所的選項:
在下一個視窗中,選擇 VPN 連線:
並輸入 VPN 連線詳細信息,並指定使用智慧卡的選項:
設定尚未完成。 剩下的就是指定 IPsec 協定的共用金鑰;為此,請前往「網路連線設定」選項卡,然後前往「此連線的屬性」標籤:
在開啟的視窗中,前往「安全性」標籤,指定「L2TP/IPsec網路」作為網路類型,然後選擇「進階設定」:
在開啟的視窗中,指定共用 IPsec 金鑰:
Подключение
設定完成後,您可以嘗試連接網路:
在連接過程中,我們將需要輸入令牌 PIN 碼:
我們已經建立了安全的VPN網路並確保這並不困難。
致謝
我要再次感謝我們的同事 Vasily Shokov 和 Alexander Smirnov 為簡化 Linux 用戶端 VPN 連線的建立而共同完成的工作。
來源: www.habr.com