上班基本功: SSH 混搭 Azure Firewall
本篇分享一下我個人上班常用 SSH 混搭 Azure Firewall 服用的跳板基本功
人在江湖,想連回 Azure,有何選擇?
正常管控狀況下,你的服務都放在 Azure Virtual Network 內,你人在外面想要連進去,這時候有幾種做法
- 優選 - Azure Bastion: 原生跳板服務,不用自己維護,可以
az network bastion ssh
或az network bastion rdp
用 Native Client 連到內網主機 - 中選 - Azure VPN Gateway: 無論透過 S2S VPN 或 P2S VPN,都可以連到內網主機,常見都是看到 S2S,而後者需要在電腦安裝 Azure VPN Client,不知道為什麼比較少出現在選項中,不然其實這個選擇蠻安全
- 普選 - 把玩 SSH: 今天文章就是要講這個,回歸到網路基本功,如何搭配既有的 Azure Firewall、一台具有 SSH Server 的虛擬機和網路知識來做到各種常規的開發測試
常見架構
- 你的個人電腦: 基本上就是一台有 SSH Client 的電腦,可以是 Windows、Mac、Linux,然後這邊你可以先決定一個 Port 來作為待會的
Dynamic Port Forwarding
的使用,個人常用是1080
- Azure Firewall: 這邊假設你已經有一個 Azure Firewall,無論是 Basic、Standard、Premium 都可以,三個都支援 SNAT + DNAT 的能力,然後你對外的 Public IP 會綁在 Azure Firewall 上,最多可以在 1 台 Azure Firewall 上綁 250 個 Public IP
- Azure Firewall Policy: 這邊會需要撰寫 DNAT Policy 和 Network Policy (for SNAT),第一次寫應該都會被欄位搞混和 Azure Virtual Network Transit 的處理方式搞混,譬如說 3 Virtual Network 連再一起的時候,是路由不過去的之類議題
- Azure Virtual Machine: 這台角色就是內網跳板機,只要有 SSH Server 即可,這邊有一些防禦機制,但會離題就不在這邊詳述了
- Web Service: 毫無懸念,就是一台在內網的 Web Server,我自己會遇到的狀況是 Azure Red Hat OpenShift 有自己的 Web Console,所以得要特別用這個文章的做法跳 SOCKS5 出來
- Azure Route Table 給 Spoke VNET: 路由表,如果在裡面撰寫特定的路由,這個行為又稱 UDR (User Defined Routes),他綁定的單位是基於
Subnet
,不是Virtual Network
.如果想要讓從 Internet 進去的路由能夠正確地回去,這邊就需要撰寫 UDR 將路由指回去 Azure Firewall,意旨 0.0.0.0/0 的下一跳為 Network Virtual Appliances (Azure Firewall) 的 Private IP10.99.99.4
- Azure Route Table 給 Azure Firewall: 這邊主要就是要設定讓 Azure Firewall 可以連 Internet 的能力
我個人蠻推薦第一次接觸這個架構的人可以看 The Azure🌍 hub-and-spoke-playground 圖文相當詳細,極推薦!
Case 1: 從外面安全地透過 SSH 跳進去內網主機
核心技術: DNAT
在開始設定 DNAT 之前,你得要先確定 Spoke to Spoke 可以互相透過 Azure Firewall 傳輸,詳細可參考 SOLUTION: Allows machines in ANY spoke to communicate with ANY machine in ANY other spoke (Azure Firewall),這邊就不贅述
下面就是實際上的 DNAT 規則,相當經典
priority | collection name | rule name | src | port | protocol | destination | translated address | translated port | action |
---|---|---|---|---|---|---|---|---|---|
1000 | coll01 | ssh-restrict-to-rhel9 | 4.5.6.7 | 5566 | TCP | 1.2.3.4 | 10.0.0.4 | 22 | Dnat |
上面的規則白話就是: 限制 IP 來源 4.5.6.7 連線到 Firewall Public IP 的 5566 Port 上,做 DNAT 到 10.0.0.4 的 22 Port
假設有設定好的話,你就可以在你的電腦上執行下面的指令,只要是在 4.5.6.7 以內,就可以正確的連線到你的內網主機了
ssh [email protected] -p 5566
如果你不知道你的電腦的對外 IP 為何,可以用下列指令查詢
若你不想每次登入都要打一大串,建議可以寫 ~/.ssh/config
來讓你更方便的連線
這樣就可以用 ssh azhome
來連線了
Case 2: 我想要看到 Web 頁面 https://web.pichuang.infra,但我內網機器都沒有瀏覽器,該怎麼辦?
核心技術: DNAT + SOCKS5
ssh 其實有內建 SOCKS5 Proxy 的能力,只是要上參數 -D
給他,意旨 Dynamic Port Forwarding
,這邊我們就用 1080
這個 Port 來當作 Proxy 的 Port
ssh -D 1080 [email protected] -p 5566
# or
# ssh -D localhost:1080 [email protected] -p 5566
# or
# ssh -D 0.0.0.0:1080 [email protected] -p 5566
登入進去後,你需要開啟你的瀏覽器,修改 Proxy 設定,我個人歷年都是用 SwitchyOmega
這個 Chrome Extension,他可以讓你在瀏覽器上快速切換 Proxy,同時也適用於 Edge,這邊就用 socks5://127.0.0.1:1080
來當作 Proxy 的設定,設定畫面如下
這樣你就可以在你本地的瀏覽器可以看到 https://web.pichuang.infra
的頁面了
當然也可以把設定寫到 ~/.ssh/config
囉,多一行 DynamicForward 1080
即可
另外,總是有些服務他預設就是不走 IP 為主的,而是以 HTTP 為主,因為 SOCKS5 並不會幫忙做 DNS 解析和導流,倘若你有需要在本機做 DNS 解析的話,你得要自己在 /etc/hosts
把對應的 IP 和 FQDN 寫進去是一個比較簡易務實的做法,如下圖的對照
Case 3: 我想要透過 Azure Firewall 的 Public IP 來連線到外面
核心技術: DNAT + SOCKS5 + SNAT
倘若你透過這個方式去訪問 https://ifconfig.me
的話,因為出 Internet 會受 Azure Firewall SNAT 的影響,故會獲得到 Azure Firewall 的 Public IP: 1.2.3.4,如下圖
如果你有開 Azure Firewall IDPS 的功能的話,流量都會被檢查到
Case 4: SSH 多段跳躍
核心技術: DNAT + SSH ProxyCommand
這個會用到 ssh 內建的 ProxyCommand
的功能,也算實用技巧,個人建議是好好寫 ~/.ssh/config
來管理,不然跳到後面會很亂
Host azhome
HostName 1.2.3.4
Port 5566
User pichuang
IdentityFile ~/.ssh/id_rsa
DynamicForward 1080
Host target-vm
HostName 10.0.0.5
User pichuang
Port 22
ProxyCommand ssh -W %h:%p azhome
如果你是 Ansible 的愛用者,也可以基於此文,多新增 ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q [email protected]"'
來跳
文後廢言
因為近期眼睛酸通,昨日去看眼科,醫生說我眼睛都充滿著血絲,是不是壓力太大了?
OS: 沒想到連眼科醫生都看得出來 (?)
References
- Azure Bastion SKU
- The Azure🌍 hub-and-spoke-playground
- Ansible - How do I configure a jump host to access servers that I have no direct access to?