使用 UFW 限制 Vultr 上的 RDP 反向代理端口,只允許自己的出口 IP 連入

| Linux | 2 Reads

最近我遇到一個問題:
Windows 遠端桌面帳號突然被鎖定,提示「登入失敗次數過多」。一開始以為是自己密碼輸錯,但後來在 Linux 伺服器上查看連線後發現,Vultr 上開放的反向代理端口已經被外部掃描到了。

我的架構大概是這樣:

本地電腦 mstsc
    ↓
Vultr Linux 公網 IP:5555
    ↓
反向代理 / SSH Tunnel
    ↓
遠端 Windows RDP 3389

也就是說,雖然 Windows 的 3389 沒有直接暴露在公網上,但 Vultr 的 5555 實際上就是 RDP 的入口。如果這個端口對全世界開放,外部掃描器一旦發現它,就可能不斷嘗試登入,最終導致 Windows 帳號被鎖。

所以比較安全的做法是:

只允許自己的出口 IP 連 Vultr:5555
其他所有 IP 全部拒絕

1. 在本地 Windows 查詢自己的出口 IP

在正在使用 mstsc 的那台 Windows 電腦上打開 PowerShell,執行:

curl.exe https://api.ipify.org

假設返回結果是:

203.0.113.25

那麼 203.0.113.25 就是目前這個辦公地點 / 網路環境的出口 IP。

後面要把它加入 Vultr Linux 的 UFW 白名單。


2. 在 Vultr Linux 上允許自己的 IP 連 5555

SSH 登入 Vultr Linux 後,先加入允許規則:

sudo ufw allow from 203.0.113.25 to any port 5555 proto tcp

這條規則的意思是:

允許 203.0.113.25 連入本機 TCP 5555 端口

也就是允許我自己目前的辦公地點連進來。


3. 拒絕其他所有 IP 連 5555

接著加上拒絕規則:

sudo ufw deny 5555/tcp

這條規則的意思是:

拒絕其他所有來源 IP 連入 TCP 5555

注意順序很重要。
應該是:

先 allow 自己的 IP
再 deny 全部

如果先寫了 deny 5555/tcp,再寫 allow 自己的 IP,有可能因為規則順序問題,白名單規則吃不到。


4. 啟用或重載 UFW

如果 UFW 還沒啟用:

sudo ufw enable

如果已經啟用,只需要重載:

sudo ufw reload

5. 確認 UFW 規則順序

執行:

sudo ufw status numbered

理想狀態應該類似這樣:

Status: active

     To                         Action      From
     --                         ------      ----
[1]  22/tcp                     ALLOW IN    Anywhere
[2]  80/tcp                     ALLOW IN    Anywhere
[3]  443/tcp                    ALLOW IN    Anywhere
[4]  5555/tcp                   ALLOW IN    203.0.113.25
[5]  5555/tcp                   DENY IN     Anywhere
[6]  22/tcp (v6)                ALLOW IN    Anywhere (v6)
[7]  80/tcp (v6)                ALLOW IN    Anywhere (v6)
[8]  443/tcp (v6)               ALLOW IN    Anywhere (v6)
[9]  5555/tcp (v6)              DENY IN     Anywhere (v6)

關鍵是這兩條:

5555/tcp ALLOW IN 203.0.113.25
5555/tcp DENY  IN Anywhere

而且 ALLOW 必須排在 DENY 前面。


6. 如果順序錯了,要重新插入規則

假設現在規則順序變成這樣:

[4] 5555/tcp DENY IN Anywhere
[5] 5555/tcp ALLOW IN 203.0.113.25

這樣是不對的。因為 DENY Anywhere 先匹配,後面的 ALLOW 可能不會生效。

可以先刪除錯誤位置的 allow:

sudo ufw delete allow from 203.0.113.25 to any port 5555 proto tcp

然後把 allow 插入到 deny 前面。
假設 DENY Anywhere 是第 4 條,就插入到第 4 條:

sudo ufw insert 4 allow from 203.0.113.25 to any port 5555 proto tcp

再確認一次:

sudo ufw status numbered

7. 如果辦公地點變了,需要重寫 5555 的白名單

這一點很重要。

如果換了辦公地點、換了網路、改用手機熱點,出口 IP 很可能會變。
這時候原本的白名單 IP 就不再適用,mstsc 可能會突然連不上 Vultr:5555。

處理流程如下。

7.1 在新辦公地點重新查出口 IP

在本地 Windows PowerShell 執行:

curl.exe https://api.ipify.org

假設新 IP 是:

198.51.100.77

7.2 刪除舊的白名單規則

舊 IP 假設是:

203.0.113.25

在 Vultr Linux 執行:

sudo ufw delete allow from 203.0.113.25 to any port 5555 proto tcp

7.3 加入新的白名單規則

sudo ufw insert 4 allow from 198.51.100.77 to any port 5555 proto tcp

這裡的 insert 4 要根據你自己的規則順序調整。
原則只有一個:

新的 allow 規則要放在 5555 deny Anywhere 前面

7.4 確認規則

sudo ufw status numbered

應該看到類似:

[4] 5555/tcp ALLOW IN 198.51.100.77
[5] 5555/tcp DENY  IN Anywhere

8. 如果想清理已經沒用的單獨封鎖 IP

有時候一開始可能會手動封鎖某個可疑 IP,例如:

5555/tcp DENY IN 192.0.2.123

但如果後面已經有:

5555/tcp DENY IN Anywhere

那單獨封鎖某個 IP 的規則其實就沒必要了,因為 Deny Anywhere 已經包含它。

可以用:

sudo ufw status numbered

找到該規則的編號,例如:

[6] 5555/tcp DENY IN 192.0.2.123

然後刪除:

sudo ufw delete 6

刪除後再確認:

sudo ufw status numbered

9. 查看目前誰正在連 5555

可以用:

sudo ss -tnp | grep ':5555'

如果看到類似:

ESTAB 0 0 203.0.113.10:5555 198.51.100.77:52341 users:(("sshd",pid=1234,fd=8))

可以理解為:

203.0.113.10:5555      Vultr Linux 的 5555 端口
198.51.100.77:52341    連進來的客戶端 IP

如果客戶端 IP 不是自己的出口 IP,那就很可疑。

不過要注意,ss 只能看到當前還活著的連線。
如果攻擊者只是短暫掃描、連一下就斷開,可能不一定剛好被看到。


10. 如果還有陌生連線殘留

UFW 新規則通常會阻止新的連線,但已經建立的連線不一定會立刻消失。
如果想快速踢掉既有連線,可以重啟 sshd:

sudo systemctl restart sshd

然後再查看:

sudo ss -tnp | grep ':5555'

正常情況下,應該只剩自己的 IP,或者沒有任何陌生 IP。


總結

這次問題的本質是:

沒有直接公開 Windows 3389
不代表 RDP 沒有暴露

如果 Vultr 上的 5555 反向代理到了 Windows RDP,那麼:

Vultr:5555 = 實際上的 RDP 公網入口

所以只改端口是不夠的。更安全的做法是:

1. 查詢自己目前的出口 IP
2. UFW 允許該 IP 連 5555
3. UFW 拒絕其他所有 IP 連 5555
4. 換辦公地點後重新更新白名單

最終規則應該保持這種結構:

5555/tcp ALLOW IN 自己目前的出口 IP
5555/tcp DENY  IN Anywhere
5555/tcp (v6) DENY IN Anywhere (v6)

這樣可以避免 RDP 反向代理口被全網掃描器亂撞,也能降低 Windows 帳號被暴力嘗試導致鎖定的風險。

This article was last edited at