Iptables

如何在保持 8080 對 Internet 關閉的同時將埠 80 重定向到 8080?

  • May 29, 2020

我有一個執行 CentOS 的虛擬機和一個用於託管我在那裡部署的隨機服務的 Web 伺服器,所以為了使它可以從 Internet 訪問,我使用iptables. 由於 Web 伺服器本身在非root的專用使用者下作為服務執行,因此無法直接使用埠 80。因此,在閱讀完文件後,我添加了從埠 80 到 8080 的重定向,以便 Web 伺服器可以綁定到該埠(我確實計劃稍後添加對 HTTPS 的支持,也許我會購買一個合適的域,然後使用 Let’s加密什麼的)。

到目前為止它工作正常,但最近我注意到埠 8080 也保持開放狀態,因此任何針對埠 80 或 8080 的請求都會得到相同的響應。問題是,我只需要從外部訪問埠 80,因為我的提供商以某種方式考慮讓埠 8080 開放某種潛在的濫用?無論哪種方式,我都不希望定向到埠 8080 的外部請求得到響應,只有那些以埠 80 為目標的請求才能得到響應。

到目前為止,這就是我的配置文件的iptables樣子:

*nat
:PREROUTING ACCEPT [89:7936]
:INPUT ACCEPT [70:3812]
:OUTPUT ACCEPT [41:2756]
:POSTROUTING ACCEPT [41:2756]
-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
COMMIT
*filter
:INPUT ACCEPT [916:134290]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [819:117300]
:f2b-sshd - [0:0]
-A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd
-A INPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

我嘗試刪除打開埠 8080 的規則,但重新載入後iptables伺服器也不會響應來自埠 80 的請求。最近,我一直在考慮添加另一個重定向規則,將源 IP 更改為特定的東西以在埠 8080 中接受,但我不確定這是否可行。我需要這裡的指導。

**注意:**我對這個工具不太熟悉,這是我懷疑的主要來源。另外,也許我遺漏了一些可能有用的規則,因此我們將不勝感激下面評論中對新規則的任何建議。

示意圖應該可以幫助您了解如何完成數據包處理:

Netfilter 和通用網路中的數據包流

filter/INPUT 規則只看到在 nat/PREROUTING 中 NAT 後的數據包,因此預設情況下無法區分在埠 8080 上接收數據包(因為客戶端直接發送它)與在埠 8080 上接收數據包之間的區別,因為客戶端在埠 80 上發送它,然後重定向到埠 8080。在這兩種情況下,他們都會看到一個數據包到達埠 8080。因此,您需要額外的資訊才能區分這兩種情況。

首先第一件事:這個規則應該被刪除,因為它沒用:

   -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT

因為正如解釋的那樣,過濾器/輸入不會在埠 80 上看到數據包:它現在到達埠 8080。在這裡不要tcpdump盲目相信:如示意圖所示,tcpdump(AF_PACKET)在這一切之前看到數據包,所以會看到埠 80 .


  • 您可以使用 iptables 的conntrackmatch 查詢 netfilter 的連接跟踪系統,從而訪問失去的資訊:對於這種情況,目前傳入的數據包是否是經歷 DNAT 轉換的連接的一部分,使用--ctstate DNAT(REDIRECT 是 DNAT 的一個特例,就像 MASQUERADE 是 SNAT 的一個特例一樣)。此匹配還有其他選項,例如--ctorigdstport等,可能會達到類似的結果。

我將僅列出有關此案例的重要規則,而不是全部,以說明解釋。只需在需要時在正確的地方使用它們。

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

可能就在通用... ESTABLISHED,RELATED -j ACCEPT行之後:

iptables -A INPUT -p tcp --dport 8080 -m conntrack --ctstate DNAT -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j DROP

(或者如果以後有一個包羅萬象的刪除規則,則不要添加最後一個 DROP 規則)。

第一個 INPUT 規則將匹配到達埠 8080 的流量(這裡是從最初到達埠 80),而第二個規則將丟棄剩餘到達埠 8080 的流量:直接連接嘗試。

注意:如果你想知道為什麼statematch 和conntrackmatch 看起來很相似,那state已經被conntrack. 實際上,核心模組在內部xt_conntrack.ko處理state除了匹配之外的conntrack匹配,以實現向後兼容性。

  • 傳輸此資訊的另一種方法是使用數據包標記,這是一種更通用的方法,可以應用於許多其他情況。它是一個任意數字,將標記數據包(僅在核心中,不在網路上)並且可以在一些地方使用,包括 iptablesmark匹配以更改決策。由於MARK目標不是終止規則,因此可以在實際使用之前使用REDIRECT規則。由於它們以十六進制顯示,因此我也將它們設置為十六進制。價值是你選擇它的意思。這裡的 0x80(即十進制 128)將自己傳達“命中埠 80 並被重定向到埠 8080”的資訊,因此無需稍後重新檢查埠,檢查標記驗證所有。像往常一樣,它是連接的第一個數據包:此連接的每個其他數據包都由通用 conntrack stateful rule 處理... ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 0x80
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

在通用... ESTABLISHED,RELATED -j ACCEPT行之後:

iptables -A INPUT -m mark --mark 0x80 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j DROP

我還必須警告您不要先丟棄(而不是拒絕)無效狀態數據包就使用 REJECT 規則的危險。當 TCP 數據包以錯誤的順序到達時,這可能會在某些罕見的擁塞情況下為您帶來隨機連接重置問題。目前正在考慮添加此問題的相關文件:

所以,而不是:

-A INPUT ... -j REJECT

考慮使用:

-A INPUT ... -m conntrack --ctstate INVALID -j DROP
-A INPUT ... -j REJECT

引用自:https://serverfault.com/questions/1019115