Skip to content

上班基本功: SSH 混搭 Azure Firewall

本篇分享一下我個人上班常用 SSH 混搭 Azure Firewall 服用的跳板基本功

人在江湖,想連回 Azure,有何選擇?

正常管控狀況下,你的服務都放在 Azure Virtual Network 內,你人在外面想要連進去,這時候有幾種做法

  1. 優選 - Azure Bastion: 原生跳板服務,不用自己維護,可以 az network bastion sshaz network bastion rdp 用 Native Client 連到內網主機
  2. 中選 - Azure VPN Gateway: 無論透過 S2S VPN 或 P2S VPN,都可以連到內網主機,常見都是看到 S2S,而後者需要在電腦安裝 Azure VPN Client,不知道為什麼比較少出現在選項中,不然其實這個選擇蠻安全
  3. 普選 - 把玩 SSH: 今天文章就是要講這個,回歸到網路基本功,如何搭配既有的 Azure Firewall、一台具有 SSH Server 的虛擬機和網路知識來做到各種常規的開發測試

常見架構

  1. 你的個人電腦: 基本上就是一台有 SSH Client 的電腦,可以是 Windows、Mac、Linux,然後這邊你可以先決定一個 Port 來作為待會的 Dynamic Port Forwarding 的使用,個人常用是 1080
  2. Azure Firewall: 這邊假設你已經有一個 Azure Firewall,無論是 Basic、Standard、Premium 都可以,三個都支援 SNAT + DNAT 的能力,然後你對外的 Public IP 會綁在 Azure Firewall 上,最多可以在 1 台 Azure Firewall 上綁 250 個 Public IP
  3. Azure Firewall Policy: 這邊會需要撰寫 DNAT Policy 和 Network Policy (for SNAT),第一次寫應該都會被欄位搞混和 Azure Virtual Network Transit 的處理方式搞混,譬如說 3 Virtual Network 連再一起的時候,是路由不過去的之類議題
  4. Azure Virtual Machine: 這台角色就是內網跳板機,只要有 SSH Server 即可,這邊有一些防禦機制,但會離題就不在這邊詳述了
  5. Web Service: 毫無懸念,就是一台在內網的 Web Server,我自己會遇到的狀況是 Azure Red Hat OpenShift 有自己的 Web Console,所以得要特別用這個文章的做法跳 SOCKS5 出來
  6. 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 IP 10.99.99.4
  7. 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 為何,可以用下列指令查詢

$ curl ifconfig.me
4.5.6.7

若你不想每次登入都要打一大串,建議可以寫 ~/.ssh/config 來讓你更方便的連線

~/.ssh/config
Host azhome
    HostName 1.2.3.4
    Port 5566
    User pichuang
    IdentityFile ~/.ssh/id_rsa

這樣就可以用 ssh azhome 來連線了

Case 2: 我想要看到 Web 頁面 https://web.pichuang.infra,但我內網機器都沒有瀏覽器,該怎麼辦?

核心技術: DNAT + SOCKS5

ssh 其實有內建 SOCKS5 Proxy 的能力,只是要上參數 -D 給他,意旨 Dynamic Port Forwarding,這邊我們就用 1080 這個 Port 來當作 Proxy 的 Port

socks5-command-using-ssh
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 即可

Host azhome
    HostName 1.2.3.4
    Port 5566
    User pichuang
    IdentityFile ~/.ssh/id_rsa
    DynamicForward 1080

另外,總是有些服務他預設就是不走 IP 為主的,而是以 HTTP 為主,因為 SOCKS5 並不會幫忙做 DNS 解析和導流,倘若你有需要在本機做 DNS 解析的話,你得要自己在 /etc/hosts 把對應的 IP 和 FQDN 寫進去是一個比較簡易務實的做法,如下圖的對照

/etc/hosts
10.252.12.62     console-openshift-console.apps.dr.aro.divecode.intranet

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

Comments