在安全要求比較高的企業中,服務放內網是很基本的需求。在 Azure 的世界裡,我們可以透過 Private Endpoint 來完成。
不過在 Service Bus 的定價層中,只有 Premium 以上才支援 Private Endpoint 的功能,不過它的價格相當不斐,如果不是正式環境使用,真的是很難下手。
既然這樣,有沒有其他「俗擱大碗」的方式可以幫助我們達到目的呢?如果你有相同的疑問,你要找的,很可能就是 IP Rule 這個功能!
Service Bus 定價簡介
前言提到,只有 Premium 的 Service Bus 才支援 Private Endpoint,其他 Basic / Standard 都不支援。
但它們的價格真的有差這麼多嗎?這邊我以 Standard 跟 Premium 一個月的定價為例
Standard 一個月的售價為 NT$303.15:

Premium 一個月的售價為 NT$20,918.91:

可以看到只是跳了一個級距,價格就足足差了69 倍之多。
在正式環境或許還下的了手,畢竟 Premium tier 有自帶 Multi-AZ 功能,不過以測試環境的預算來說可能就真的要想一下了。
IP Rule 簡介
如果不能使用 Private Endpoint,其實等同於我們把服務暴露到外網上,以資安的角度是非常要不得的。
幸好,Service Bus 有額外提供了一個 IP Rule 的方式,讓我們可以針對要 Access 的 IP 進行白名單的設定。
這個功能沒有定價層限制,Basic / Standard 的都能夠使用,可說是相當經濟實惠的作法。
雖然它的安全性不及 Private Endpoint 來的好,但透過白名單限制的方式,其實也已經是非常夠用了。
不過請注意,在 Basic / Standard 的定價層中,這個功能在 Azure Portal 是找不到的,因此我們需要透過 Azure CLI 等方式來設定。
實機演練
建立 Service Bus 並測試發送訊息
這邊我們直接來實機演練一下,首先我從 Azure Portal 建立一個 Basic tier 的 Service Bus。

接著在設定 IP Rule 之前,先建立一個 Queue,並使用 Service Bus Explorer 送一個訊息。

你可以看到訊息一下就送出成功了。

新增 IP Rule
接著重頭戲來了,在這邊我使用 Azure CLI 來新增一條 IP Rule,我希望讓我的電腦 IP不能夠被存取。
請注意,IP Rule 沒有黑名單概念,所以我們只能以設定白名單的方式來操作。
這邊我希望限制 Service Bus 只允許 8.8.8.8 的 IP 存取,ip 的格式要以 CIDR 的格式提供,指令如下:
az servicebus namespace network-rule-set ip-rule add `
--namespace-name "{NAME_OF_SB}" `
--resource-group "{NAME_OF_RG}" `
--ip-rule ip-address=8.8.8.8/32 action=Allow
執行結果如下,你可以看到 ipRules 裡面已經有我們剛才設定的 IP。

基本上只要你的 ClientIP 不是 8.8.8.8 這個 IP,預設送訊息時就會被阻擋下來。
溫馨提醒:在實際的狀況中,請指定允許打到 Service Bus 的伺服器 IP而非 8.8.8.8,它可以是單一伺服器的 IP,也可以是整個網段。
修改 defaultAction
但...這樣就設定完成了嗎?
如果你再從 Service Bus Explorer 送一次訊息,你會發現結果還是會成功,訊息沒有如預期地被阻擋。
這個原因是微軟在某一次更新中修改了 API 的預設值。
在 API 版本 2021-01-01-preview 之前的版本,defaultAction
的預設值會是 Deny
。
不過在 2021-06-01-preview 之後的版本,defaultAction
的預設值就變成 Allow
了。
這邊一樣使用 Azure CLI 設定,語法也相當簡單:
az servicebus namespace network-rule-set update `
--namespace-name "{NAME_OF_SB}" `
--resource-group "{NAME_OF_RG}" `
--default-action "Deny"
從執行結果中你可以看到 defaultAction
已經成功被修改為 Deny
了,這樣就修改完成了。

測試訊息是否被阻擋
接著讓我們回到 Service Bus Explorer 再送一次訊息

送出後會卡一陣子,最後看到錯誤訊息就表示測試完成啦!

結語
一直以來,成本跟安全都是互相對立的面向。
透過 Service Bus 的 IP Rule ,得以讓我們在夾縫中繼續求生存,我認為是相當經濟實惠的小功能。
最後最後,還是希望在未來微軟能夠在 Premium 以外的 tier 也可以都支援 Private Endpoint 啦!