[後端] 如何讓 Heroku 上的專案使用固定 IP 連接 MongoDB Atlas 服務?
前言
在閱讀以下內容前,請先確認你有一張信用卡
可以註冊到 Heroku 的帳戶內,如果沒有,請嘗試使用其他免費網路空間服務。
基礎概念
隨著硬體技術越來越強,儲存空間的單位成本越來越低,於是有各種雲端空間服務可以使用,但是網路 IP 是有限的共享資源,由各地區的 ISP 業者分配使用(以台灣來說,需要申請中華電信線路,再申請固定 IP),雲端空間業者不會持有大量的 IP 讓用戶使用,通常是以內部固定 IP 加上動態分配外部 IP 來連線。
資料庫用來儲存網站的各種資料,通常也會包含大量的客戶資訊(姓名、手機、信箱…等),這些個資或商業機密一旦外洩就會造成公司和客戶的嚴重損失,最基礎的第一道防線就是網路防火牆,只能允許網頁(App)伺服器對資料庫(DB)伺服器連線(設置白名單規則)。
設置 Heroku 連線 IP 的三種方法
MongoDB 的文件 Configuring Heroku IP Addresses in MongoDB Atlas 有介紹幾個方法讓 Heroku 使用固定 IP 連線:
- 使用插件(add-on)來提供固定的對外 IP,也就是這篇文章要介紹的方法。
- 使用 Heroku Private Spaces 來設置固定 IP,雖然不需要安裝插件(add-on),但是需要
$$$
,無課仔表示:下面一位! - 直接把所有 Heroku 會使用的動態 IP 加到白名單中,文章中沒有提供到底是哪些 IP,表示要自己找,而且這個方法非常不保險,萬一動態 IP 清單變了,服務突然就掛了。
Heroku Addons 說明
我們可以到 Heroku 的 Network Services Addons 中看到有許多網路服務的插件可以選擇,這些插件並不是直接提供固定 IP,而是以代理的方式來達到固定 IP 的效果。
了解 Addons 的運作方式,事情並沒有因此豁然開朗,這麼多的 Addons 根本不知道要選哪個!先講結論:我使用的是QuotaGuard Static IP's
每個 Addons 提供的應用不太一樣,有些使用他的函式庫來取代 Axios(或 fetch),透過 Addons 函式庫的方法設置好代理參數後發出 GET 請求,但這種方式提供的是 HTTP 代理,僅適用 HTTP/HTTPS 的連線,MongoDB 的連線就無法使用了(網路層級不同)。
QuotaGuard Static IP’s 提供了 SOCKS 代理,他可以監聽 Heroku App 的連線請求,並且把對 MongoDB 的連線導向自己,再由 Addons 把請求送給 MongoDB,所以對 MongoDB 來說,收到的請求來源都會是 QuotaGuard Static IP’s 提供的固定 IP。
原始連線模式
Heroku(IP: ??.??.??.??) -> MongoDB Atlas(無法限制來源)
代理連線模式
Heroku(IP: ??.??.??.??) -> Proxy(某個固定 IP) -> MongoDB Atlas(只接受 Proxy 的固定 IP)
實作開始
整個實作過程,都是參考 QuotaGuard 的 How to Connect to MongoDB using QuotaGuard 文件進行,雖然他寫的蠻詳細的,但是要弄清楚還是得費一番功夫。
馬上進入實作步驟:
請到 Heroku 的 Network Services Addons 選擇 QuotaGuard Static IP’s。
選擇 Addons 之後建議還是先往下拉看一下價錢,確認有免費的,才能為荷包把關。
價錢確認後,可以回到最上方的右邊點選 install 按鈕安裝。
進入提交頁面後,請先確認收費方式,接著在下方輸入要設置代理的專案名稱(專案名稱可以到自己的 Heroku 頁面查看),選取好專案後就可以點擊按鈕進入下一步。
如果帳號沒有綁定信用卡,就會跳出警告,不讓你安裝,請完成綁定才能進行下一步。
裝完後會進入 資源列表(Resources)畫面,點擊「QuotaGuard Static IP’s」進入,首次進入會出現一些條款需要拉到最底下點擊同意(後續再點擊就會導向操作面板了)。
接下來請回到 VScode,開啟佈署到這個 Heroku 專案的資料夾,接著在終端機輸入以下指令來安裝 QuotaGuard 的相關檔案,執行完成後會多出一個 vender 資料夾和一些檔案。
1 | curl https://s3.amazonaws.com/quotaguard/qgtunnel-latest.tar.gz | tar xz |
- 接著再開啟瀏覽器進入操作面板網址 https://www.quotaguard.com/dashboard,或是在終端機輸入以下指令,會開啟瀏覽器進入相同頁面。
1 | heroku addons:open quotaguardstatic |
點選操作面板右上方的「齒輪」圖案,再點選「QGTunnel Configuration」
點擊右上方的綠色「+」按鈕來新增 Tunnel。
請開啟一個網頁分頁,並登入 MongoDB Atlas,點選你的 cluster 名稱進入詳細資訊頁面。
REGION 區塊有好幾個 cluster,請每個都點進去,然後把完整的名稱複製下來。
回到步驟 10 的 新增 Tunnel 頁面,把剛才 mongoDB 複製下來的字串建立起來,有幾個就建幾筆(通常會有三筆,有關 cluster 的連線字串在 QuotaGuard 的文件也有說明),設定資訊如下:
- Remote Destination:MongoDB Atlas 內 cluster region 的完整名稱,建立完成後系統會在前面自動加上 “tcp://“,這是正常的。
(名稱範例:xxxxxx-xxxx-00-00.xxxxx.mongodb.net:27017) - Local Port:27017(MongoDB 的 Port)
- Transparent:透通模式請開啟
- Encrypted:加密模式可以不用開
- Optional Name:可以為這個 Tunnel 設定名稱,也可以空著。
- 回到 VScode,在專案的根目錄新增一個檔案,檔案名稱是 Procfile (請不要加入任何副檔名,txt 也不行),這個檔名是 Heroku 的設定檔,在裡面撰寫導入 addons 的啟動指令,撰寫格式如下:
1 | web: bin/qgtunnel 啟動程式名稱 啟動指令和參數 |
以 node.js 為例,啟動指令是 npm start
,Procfile 內撰寫的就是
1 | web: bin/qgtunnel npm start |
接下來就可以執行 git add & commit 把修改好的專案 push 到 Heroku 上,在 commit 前請用 git status 確認 vender 資料夾內的檔案和 Procfile 都有加入,一個都不能少!
推送完後先確認一下 app 會不會 crash,如果正常運行就可以回到 QuotaGuard 的操作面板 https://www.quotaguard.com/dashboard,把左上方的兩個 IP 設定到 MongoDB Atlas 裡面的 Network Access,
IP 後面請加上 /32
,這個遮罩表示單一 IP,如果後面是 /0,不管前面打什麼 IP,任何人都可以連的到!設定完之後就可以測試,在本地用 Compass 連和從 Heroku 主機連線是否一個不能連、一個能連,測試沒問題就大功告成啦!
補充
- 官方文件有建議把 Tunnel 的設定備份下來,可以自行考量需不需要。
- Heroku 安裝 QuotaGuard Static IP’s 時會自動為該專案建立一條名稱為
QUOTAGUARDSTATIC_URL
的環境變數,如果連線失敗可以查看一下這個環境變數有沒有建立起來。 - 正常狀況下加入 QuotaGuard Static IP’s 不會影響原始 App 的運作,因為他只是個封包傳輸的代理程式。