如何使用 openconnect 和 vpn-slice 連線到 Linux 中的企業 VPN

您想在工作中使用 Linux,但您的公司 VPN 不允許嗎? 那麼這篇文章可能會有所幫助,儘管這還不確定。 我想提前警告您,我不太了解網路管理問題,因此有可能我做錯了一切。 另一方面,我也有可能寫出一個普通人可以理解的指南,所以我建議你試試看。

這篇文章包含許多不必要的信息,但如果沒有這些知識,我將無法解決設定 VPN 時意外出現的問題。 我認為任何嘗試使用本指南的人都會遇到我沒有遇到的問題,我希望這些額外的資訊將有助於他們自己解決這些問題。

本指南中使用的大多數命令都需要透過 sudo 運行,為簡潔起見,已將其刪除。 記住。

大多數IP位址都被嚴重混淆了,所以如果您看到像435.435.435.435這樣的位址,那麼那裡一定有一些正常的IP,特定於您的情況。

我有 Ubuntu 18.04,但我認為只需稍加修改,該指南就可以應用於其他發行版。 然而,在本文中,Linux == Ubuntu。

思科連線

使用 Windows 或 MacOS 的使用者可以透過 Cisco Connect 連接到我們的企業 VPN,需要指定網關位址,並且每次連線時輸入由固定部分和 Google Authenticator 產生的程式碼組成的密碼。

就 Linux 而言,我無法運行 Cisco Connect,但我設法在 google 上搜尋了使用 openconnect 的建議,該建議是專門用來替代 Cisco Connect 的。

打開連接

理論上,Ubuntu有一個專門的openconnect圖形介面,但它對我不起作用。 也許是為了更好。

在 Ubuntu 上,openconnect 是從套件管理器安裝的。

apt install openconnect

安裝後,您可以立即嘗試連線VPN

openconnect --user poxvuibr vpn.evilcorp.com

vpn.evilcorp.com 是虛構 VPN 的位址
poxvuibr - 虛構的用戶名

openconnect 會要求您輸入密碼,我提醒您,該密碼由固定部分和來自 Google Authenticator 的程式碼組成,然後它將嘗試連接到 VPN。 如果它有效,那麼恭喜你,你可以安全地跳過中間的過程,這很痛苦,然後繼續討論 openconnect 在後台運行的問題。 如果不起作用,那麼您可以繼續。 雖然如果它在連接時有效,例如,透過工作時的訪客 Wi-Fi 連接,那麼現在高興可能還為時過早;您應該嘗試在家中重複該過程。

證書

很可能什麼都不會啟動,並且 openconnect 輸出將如下所示:

POST https://vpn.evilcorp.com/
Connected to 777.777.777.777:443
SSL negotiation with vpn.evilcorp.com
Server certificate verify failed: signer not found

Certificate from VPN server "vpn.evilcorp.com" failed verification.
Reason: signer not found
To trust this server in future, perhaps add this to your command line:
    --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444
Enter 'yes' to accept, 'no' to abort; anything else to view: fgets (stdin): Operation now in progress

一方面,這是令人不快的,因為沒有連接到 VPN,但另一方面,原則上如何解決這個問題是明確的。

在這裡,伺服器向我們發送了一個證書,透過該證書,我們可以確定連接是與我們本地公司的伺服器建立的,而不是與邪惡的詐欺者建立的,並且該證書對於系統來說是未知的。 因此她無法檢查伺服器是否真實。 因此,為了以防萬一,它會停止工作。

為了讓 openconnect 連接到伺服器,您需要使用 —servercert key 明確告訴它哪個憑證應該來自 VPN 伺服器

您可以從 openconnect 列印的內容中找到伺服器直接傳送給我們的憑證。 這是這篇文章的內容:

To trust this server in future, perhaps add this to your command line:
    --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444
Enter 'yes' to accept, 'no' to abort; anything else to view: fgets (stdin): Operation now in progress

使用此命令您可以嘗試再次連接

openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 --user poxvuibr vpn.evilcorp.com

也許現在它正在發揮作用,那麼你就可以繼續進行到底了。 但就我個人而言,烏本塔向我展示了這種形式的無花果

POST https://vpn.evilcorp.com/
Connected to 777.777.777.777:443
SSL negotiation with vpn.evilcorp.com
Server certificate verify failed: signer not found
Connected to HTTPS on vpn.evilcorp.com
XML POST enabled
Please enter your username and password.
POST https://vpn.evilcorp.com/
Got CONNECT response: HTTP/1.1 200 OK
CSTP connected. DPD 300, Keepalive 30
Set up DTLS failed; using SSL instead
Connected as 192.168.333.222, using SSL
NOSSSSSHHHHHHHDDDDD
3
NOSSSSSHHHHHHHDDDDD
3
RTNETLINK answers: File exists
/etc/resolvconf/update.d/libc: Warning: /etc/resolv.conf is not a symbolic link to /run/resolvconf/resolv.conf

/ etc / resolv.conf中

# Generated by NetworkManager
search gst.evilcorpguest.com
nameserver 127.0.0.53

/run/resolvconf/resolv.conf

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.

nameserver 192.168.430.534
nameserver 127.0.0.53
search evilcorp.com gst.publicevilcorp.com

habr.com 將會解決,但您將無法前往那裡。 像 jira.evilcorp.com 這樣的位址根本無法解析。

我不清楚這裡發生了什麼事。 但實驗表明,如果您將這一行添加到 /etc/resolv.conf

nameserver 192.168.430.534

然後 VPN 內的位址將開始神奇地解析,您可以瀏覽它們,也就是說,DNS 正在尋找的解析位址專門在 /etc/resolv.conf 中查找,而不是在其他地方。

您可以驗證是否存在與VPN 的連接並且它可以正常工作,而無需對/etc/resolv.conf 進行任何更改;為此,只需在瀏覽器中輸入其IP 位址,而不是來自VPN 的資源的符號名稱

這樣一來,就有兩個問題

  • 連接到 VPN 時,未取得其 dns
  • 所有流量都透過VPN,不允許上網

我會告訴你現在該怎麼做,但首先是一點自動化。

自動輸入密碼的固定部分

到目前為止,您很可能已經輸入了至少五次密碼,而這個過程已經讓您疲憊不堪。 一是因為密碼長,二是因為輸入時需要契合固定的時間段

該問題的最終解決方案並未包含在文章中,但您可以確保密碼的固定部分不必輸入多次。

假設密碼的固定部分是fixedPassword,來自Google Authenticator的部分是567。整個密碼可以使用--passwd-on-stdin參數透過標準輸入傳遞給openconnect。

echo "fixedPassword567987" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 --user poxvuibr vpn.evilcorp.com --passwd-on-stdin

現在,您可以不斷返回到最後輸入的命令,並僅更改其中的部分 Google 驗證器。

企業 VPN 不允許您上網。

一般來說,當你必須使用單獨的計算機去哈布爾時,這並不是很不方便。 無法從 stackoverfow 進行複製貼上通常會導致工作癱瘓,因此需要採取一些措施。

我們需要以某種方式組織它,以便當您需要從內部網路存取資源時,Linux 會轉到 VPN,而當您需要存取 Habr 時,它會轉到 Internet。

openconnect 在啟動並與 vpn 建立連線後,會執行一個特殊的腳本,該腳本位於 /usr/share/vpnc-scripts/vpnc-script 中。 一些變數作為輸入傳遞給腳本,並配置 VPN。 不幸的是,我無法弄清楚如何使用本機腳本在企業 VPN 和互聯網其他部分之間分配流量。

顯然,vpn-slice 實用程式是專門為像我這樣的人開發的,它允許您透過兩個通道發送流量,而無需手鼓跳舞。 嗯,也就是說,你必須跳舞,但你不必成為薩滿。

使用 vpn-slice 進行流量分離

首先,你必須安裝 vpn-slice,你必須自己解決這個問題。 如果評論裡有問題,我會單獨寫一篇文章討論這個問題。 但這是一個常規的Python程序,所以應該不會有任何困難。 我使用 virtualenv 安裝。

然後必須使用 -script 開關應用該實用程序,指示 openconnect 需要使用 vpn-slice,而不是標準腳本

echo "fixedPassword567987" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 --user poxvuibr --passwd-on-stdin 
--script "./bin/vpn-slice 192.168.430.0/24  " vpn.evilcorp.com 

--script 傳遞一個字串,其中包含需要呼叫的命令而不是腳本。 ./bin/vpn-slice - vpn-slice 執行檔的路徑 192.168.430.0/24 - vpn 中要存取的位址遮罩。 這裡,我們的意思是,如果位址以192.168.430開頭,那麼就需要在VPN內部搜尋該位址的資源

現在的情況應該差不多正常了。 幾乎。 現在你去Habr可以透過ip去企業內部資源,但不能透過符號名稱去企業內部資源。 如果您在主機中指定符號名稱和位址之間的匹配,則一切都應該有效。 並一直工作直到ip改變。 Linux 現在可以存取 Internet 或 Intranet,具體取決於 IP。 但仍使用非企業 DNS 來決定位址。

問題還可以透過這種形式表現出來——在工作中一切都很好,但在家裡你只能透過IP存取公司內部資源。 這是因為當您連接到公司 Wi-Fi 時,也會使用公司 DNS,並在其中解析來自 VPN 的符號位址,儘管事實上不使用 VPN 仍然無法存取此類位址。

自動修改hosts文件

如果禮貌地詢問 vpn-slice,則在啟動 VPN 後,它可以轉到其 DNS,透過符號名稱找到必要資源的 IP 位址,並將其輸入到主機中。 關閉 VPN 後,這些位址將從主機中刪除。 為此,您需要將符號名稱作為參數傳遞給 vpn-slice。 像這樣。

echo "fixedPassword567987" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 --user poxvuibr --passwd-on-stdin
--script "./bin/vpn-slice 192.168.430.0/24  jira.vpn.evilcorp.com git.vpn.evilcorp.com " vpn.evilcorp.com 

現在一切都應該在辦公室和海灘上都能正常運作。

在VPN給出的DNS中搜尋所有子網域的位址

如果網路內的位址很少,那麼自動修改hosts檔案的方法就很有效。 但如果網路上有很多資源,那麼您將不斷需要在腳本中添加像 zoidberg.test.evilcorp.com 這樣的行,zoidberg 是其中一個測試平台的名稱。

但現在我們已經了解為什麼可以消除這種需求了。

如果在啟動 VPN 後,您查看 /etc/hosts,您可以看到這一行

192.168.430.534 dns0.tun0 # vpn-slice-tun0 自動建立

並在 resolv.conf 中加入了新行。 簡而言之,vpn-slice 以某種方式確定了 vpn 的 dns 伺服器所在的位置。

現在我們需要確保,為了找到以evillcorp.com 結尾的網域的IP 位址,Linux 會存取公司DNS,如果需要其他內容,則存取預設DNS。

我在 Google 上搜尋了一段時間,發現 Ubuntu 中已經提供了這樣的功能。 這意味著能夠使用本機 DNS 伺服器 dnsmasq 來解析名稱。

也就是說,您可以確保Linux始終向本機DNS伺服器尋找IP位址,而本機DNS伺服器又會根據網域名稱在對應的外部DNS伺服器上尋找IP。

為了管理與網路和網路連線相關的所有內容,Ubuntu 使用 NetworkManager,而用於選擇(例如 Wi-Fi 連線)的圖形介面只是它的前端。

我們需要爬升它的配置。

  1. 在 /etc/NetworkManager/dnsmasq.d/evilcorp 中建立文件

地址=/.evilcorp.com/192.168.430.534

注意evilcorp前面的點。 它向 dnsmasq 發出信號,應在公司 dns 中搜尋 evilcorp.com 的所有子網域。

  1. 告訴 NetworkManager 使用 dnsmasq 進行名稱解析

網路管理器設定位於 /etc/NetworkManager/NetworkManager.conf 您需要在那裡新增:

[主] dns=dnsmasq

  1. 重新啟動網路管理員

service network-manager restart

現在,使用 openconnect 和 vpn-slice 連接到 VPN 後,即使您沒有將符號位址新增至 vpnslice 的參數中,也會正常確定 IP。

如何透過VPN存取個人服務

成功連接VPN後,我高興了兩天,然後發現,如果我從辦公室網路外連接VPN,那麼郵件就不能用了。 這個症狀很熟悉,不是嗎?

我們的郵件位於mail.publicevilcorp.com,這意味著它不屬於dnsmasq的規則,並且郵件伺服器位址是透過公共DNS搜尋的。

嗯,辦公室仍然使用 DNS,其中包含這個地址。 跟我想的一樣。 事實上,將行加入 dnsmasq 後

地址=/mail.publicevilcorp.com/192.168.430.534

情況根本沒有改變。 ip保持不變。 我必須去上班。

後來,當我深入了解情況並稍微了解了問題後,一位聰明的人告訴我如何解決。 不但需要這樣連接郵件伺服器,還需要透過VPN

我使用 vpn-slice 透過 VPN 存取以 192.168.430 開頭的位址。 而且郵件伺服器不只有一個不是evilcorp子網域的符號位址,而且也沒有以192.168.430開頭的IP位址。 當然,他也不允許總網的人來找他。

為了讓 Linux 透過 VPN 到達郵件伺服器,您還需要將其新增至 vpn-slice。 假設郵寄者的地址是 555.555.555.555

echo "fixedPassword567987" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 --user poxvuibr --passwd-on-stdin
--script "./bin/vpn-slice 555.555.555.555 192.168.430.0/24" vpn.evilcorp.com 

透過一個參數提升 VPN 的腳本

當然,這一切並不是很方便。 是的,您可以將文字儲存到文件中並將其複製並貼上到控制台中,而不是手動輸入,但這仍然不是很愉快。 為了使過程更容易,您可以將該命令包裝在位於 PATH 中的腳本中。 然後您只需要輸入從 Google Authenticator 收到的代碼

#!/bin/sh  
echo "fixedPassword$1" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 --user poxvuibr --passwd-on-stdin 
--script "./bin/vpn-slice 192.168.430.0/24  jira.vpn.evilcorp.com git.vpn.evilcorp.com " vpn.evilcorp.com 

如果你把腳本放在 connect~evilcorp~ 中,你可以簡單地在控制台中編寫

connect_evil_corp 567987

但現在由於某種原因你仍然必須保持運行 openconnect 的控制台打開

在背景執行 openconnect

幸運的是,openconnect的作者很照顧我們,為程式添加了一個特殊的按鍵——background,使得程式啟動後在背景工作。 如果你像這樣運行它,你可以在啟動後關閉控制台

#!/bin/sh  
echo "fixedPassword$1" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 
--user poxvuibr 
--passwd-on-stdin 
--background 
--script "./bin/vpn-slice 192.168.430.0/24  jira.vpn.evilcorp.com git.vpn.evilcorp.com " vpn.evilcorp.com  

現在還不清楚日誌跑到哪裡去了。 一般來說,我們其實並不需要日誌,但你永遠不知道。 openconnect 可以將它們重定向到 syslog,在那裡它們將保持安全。 您需要將 –syslog 開關新增到命令中

#!/bin/sh  
echo "fixedPassword$1" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 
--user poxvuibr 
--passwd-on-stdin 
--background 
--syslog 
--script "./bin/vpn-slice 192.168.430.0/24  jira.vpn.evilcorp.com git.vpn.evilcorp.com " vpn.evilcorp.com  

因此,事實證明 openconnect 正在後台某個地方工作,並且不會打擾任何人,但尚不清楚如何阻止它。 也就是說,您當然可以使用 grep 過濾 ps 輸出並尋找名稱包含 openconnect 的進程,但這在某種程度上很乏味。 感謝也思考過這個問題的作者。 Openconnect 有一個關鍵的 -pid-file,使用它可以指示 openconnect 將其進程標識符寫入檔案。

#!/bin/sh  
echo "fixedPassword$1" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 
--user poxvuibr 
--passwd-on-stdin 
--background  
--syslog 
--script "./bin/vpn-slice 192.168.430.0/24  jira.vpn.evilcorp.com git.vpn.evilcorp.com " vpn.evilcorp.com  
--pid-file ~/vpn-pid

現在您可以隨時使用命令終止進程

kill $(cat ~/vpn-pid)

如果沒有進程,kill會詛咒,但不會拋出錯誤。 如果該檔案不存在,那麼也不會發生任何不良情況,因此您可以安全地終止腳本第一行中的進程。

kill $(cat ~/vpn-pid)
#!/bin/sh  
echo "fixedPassword$1" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 
--user poxvuibr 
--passwd-on-stdin 
--background 
--syslog 
--script "./bin/vpn-slice 192.168.430.0/24  jira.vpn.evilcorp.com git.vpn.evilcorp.com " vpn.evilcorp.com  
--pid-file ~/vpn-pid

現在您可以打開計算機,打開控制台並運行命令,並向其傳遞來自 Google Authenticator 的程式碼。 然後就可以固定控制台了。

沒有 VPN 切片。 而不是後記

事實證明,很難理解如何在沒有 VPN 切片的情況下生活。 我必須大量閱讀和谷歌。 幸運的是,在花了這麼多時間解決一個問題之後,技術手冊甚至 man openconnect 讀起來就像令人興奮的小說一樣。

結果,我發現 vpn-slice 和原生腳本一樣,修改了路由表以分離網路。

路由表

簡單來說,這是一個表,第一列包含Linux要經過的位址應該從什麼開始,第二列包含該位址要經過哪個網路介面卡。 其實發言者還多了,但這並沒有改變本質。

為了查看路由表,需要執行 ip route 指令

default via 192.168.1.1 dev wlp3s0 proto dhcp metric 600 
192.168.430.0/24 dev tun0 scope link 
192.168.1.0/24 dev wlp3s0 proto kernel scope link src 192.168.1.534 metric 600 
192.168.430.534 dev tun0 scope link 

在這裡,每一行負責您需要去哪裡才能將訊息發送到某個地址。 第一個是地址應該從哪裡開始的描述。 為了了解如何確定 192.168.0.0/16 意味著該位址應該以 192.168 開頭,您需要 google 什麼是 IP 位址遮罩。 dev 之後是訊息應發送到的適配器的名稱。

對於VPN,Linux製作了一個虛擬適配器-tun0。 該線路確保以 192.168 開頭的所有位址的流量都經過它

192.168.0.0/16 dev tun0 scope link 

您也可以使用以下命令查看路由表的目前狀態 路線-n (IP 位址被巧妙地匿名化)該命令以不同的形式產生結果,並且通常已被棄用,但其輸出通常可以在 Internet 上的手冊中找到,並且您需要能夠閱讀它。

路由的 IP 位址應該從哪裡開始可以透過 Destination 和 Genmask 欄位的組合來了解。 IP 位址中與 Genmask 中的數字 255 相對應的部分會被考慮在內,但 0 的部分則不會被考慮在內。 也就是說,Destination 192.168.0.0 和 Genmask 255.255.255.0 的組合意味著,如果地址以 192.168.0 開頭,那麼對其的請求將沿著這條路線進行。 如果目標位址為 192.168.0.0 但 Genmask 為 255.255.0.0,則以 192.168 開頭的位址的請求將沿著此路線進行

為了弄清楚 vpn-slice 實際上做了什麼,我決定查看前後表的狀態

沒開啟VPN之前是這樣的

route -n 

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         222.222.222.1   0.0.0.0         UG    600    0        0 wlp3s0
222.222.222.0   0.0.0.0         255.255.255.0   U     600    0        0 wlp3s0
333.333.333.333 222.222.222.1   255.255.255.255 UGH   0      0        0 wlp3s0

在沒有 vpn-slice 的情況下呼叫 openconnect 後,它變成了這樣

route -n

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         0.0.0.0         0.0.0.0         U     0      0        0 tun0
0.0.0.0         222.222.222.1   0.0.0.0         UG    600    0        0 wlp3s0
222.222.222.0   0.0.0.0         255.255.255.0   U     600    0        0 wlp3s0
333.333.333.333 222.222.222.1   255.255.255.255 UGH   0      0        0 wlp3s0
192.168.430.0   0.0.0.0         255.255.255.0   U     0      0        0 tun0
192.168.430.534 0.0.0.0         255.255.255.255 UH    0      0        0 tun0

像這樣與 vpn-slice 結合呼叫 openconnect 之後

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         222.222.222.1   0.0.0.0         UG    600    0        0 wlp3s0
222.222.222.0   0.0.0.0         255.255.255.0   U     600    0        0 wlp3s0
333.333.333.333 222.222.222.1   255.255.255.255 UGH   0      0        0 wlp3s0
192.168.430.0   0.0.0.0         255.255.255.0   U     0      0        0 tun0
192.168.430.534 0.0.0.0         255.255.255.255 UH    0      0        0 tun0

可以看到,如果不使用vpn-slice,那麼openconnect明確寫了所有地址,除了特別指明的,都必須透過vpn存取。

就在這裡:

0.0.0.0         0.0.0.0         0.0.0.0         U     0      0        0 tun0

在它旁邊,立即指示另一條路徑,如果 Linux 嘗試通過的位址與表中的任何遮罩都不匹配,則必須使用該路徑。

0.0.0.0         222.222.222.1   0.0.0.0         UG    600    0        0 wlp3s0

這裡已經寫到,在這種情況下您需要使用標準的 Wi-Fi 轉接器。

我相信使用了 VPN 路徑,因為它是路由表中的第一個路徑。

而且理論上,如果從路由表中刪除這條預設路徑,那麼結合 dnsmasq openconnect 應該可以保證正常運作。

我試過

route del default

一切順利。

將請求路由到沒有 VPN 切片的郵件伺服器

但我還有一個位址為555.555.555.555的郵件伺服器,也需要透過VPN存取。 到它的路由也需要手動添加。

ip route add 555.555.555.555 via dev tun0

現在一切都很好。 所以你可以不用 vpn-slice,但你需要清楚知道你在做什麼。 我現在正在考慮在本機 openconnect 腳本的最後一行中添加刪除預設路由的功能,並在連接到 VPN 後為郵件程式添加一條路由,這樣我的自行車中的移動部件就會更少。

也許,這篇後記足以讓人們了解如何設定 VPN。 但是,當我試圖了解做什麼以及如何做時,我閱讀了很多對作者有用的此類指南,但由於某種原因對我不起作用,我決定在這裡添加我找到的所有內容。 我會對這樣的事情感到非常高興。

來源: www.habr.com

添加評論