私はVM私がそこに展開するランダムサービスをホストするために使用するWebサーバーでCentOSを実行しているため、インターネットから到達可能にするために、iptables
を使用してポート80を開きました。サーバー自体はrootではない専用ユーザーの下でサービスとして実行されているため、ポート80を直接使用することはできません。読み取り、ポート80から8080へのリダイレクトを追加して、Webサーバーをそのポートにバインドできるようにしました(後でHTTPSのサポートを追加する予定です。適切なドメインを購入して、Let's Encryptなどを使用します)。
これまでのところ問題なく機能していますが、最近ではポート8080も開いたままになっているため、ポート80または8080のいずれかをターゲットとするリクエストが同じ応答を受け取ることに気づきました。問題は、外部から到達できるようにするために必要なのは、ポート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で受け入れるように特定のものに変更する別のリダイレクトルールを追加することを考えていますが、それが機能するかどうかはわかりません。ここでガイダンスが必要です。
注:私はこのツールをあまり経験していません。それが私の疑問の主な原因です。また、おそらく役立ついくつかのルールが欠けているので、以下のコメントで新しいルールの提案をいただければ幸いです。
これ schematic は、パケット処理がどのように行われるかを理解するのに役立ちます:
フィルター/ INPUTルールは、nat/PREROUTINGでNATされた後のパケットのみを表示するため、デフォルトではポートでのパケット受信の違いを認識できません8080は、クライアントがポート8080でパケットを受信してから直接そこに送信したためです。これは、クライアントがポート80でパケットを送信し、ポート8080にリダイレクトされたためです。どちらの場合でも、パケットはポート8080に到着します。したがって、追加のこれらの2つのケースを区別できるようにするための情報。
まず最初に:このルールは役に立たないので削除する必要があります:
-A INPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
説明したように、filter/INPUTはポート80でパケットを認識しないため、ポート8080に到達します。ここではtcpdump
を盲目的に信頼しないでください:回路図で見られるように、tcpdump
(AF_PACKET )この前にパケットを確認するため、ポート80を確認します。
Iptablesの conntrack
を使用して、netfilterの接続追跡システムにクエリを実行し、不足している情報にアクセスできます。この場合、現在の着信パケットがDNATを受けた接続の一部であるかどうか変換の有無にかかわらず、--ctstate DNAT
を使用します(REASは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ルールは、DNATされたポート8080に到着するトラフィック(ここでは最初にポート80に到着したもの)に一致しますが、2番目のルールは、ポート8080に到着した残りのものをドロップします:直接接続試行。
注: state
の一致と conntrack
の一致が似ている理由を知りたくない場合、state
はconntrack
に置き換えられました。実際、カーネルモジュールxt_conntrack.ko
は、下位互換性のために、state
一致に加えてconntrack
一致も内部的に処理します。
この情報を送信するもう1つの方法は、パケット mark を使用する方法です。これはより一般的な方法であり、他の多くの場合に適用できます。これは、パケットをマークする任意の数値であり(カーネル内のみで、ワイヤー上ではありません)、iptables mark
を含むいくつかの場所で使用して、決定を変更できます。 MARK
ターゲットはterminationルールではないため、実際のREDIRECT
ルール。 16進数で表示されるため、16進数でも設定しました。値は、それが何を意味するかを選択することです。ここで、0x80(10進数の128)は、「ポート80にヒットし、ポート8080にリダイレクトされました」という情報を単独で伝達するため、後でポートを再確認する必要がなく、マークを確認することですべてが検証されます。いつものように、それは数える接続の最初のパケットです:この接続の他の各パケットは一般的なconntrackステートフルルール... 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
INVALID状態のパケットを(拒否するのではなく)最初にドロップせずにREJECTルールを使用する危険性についても警告する必要があります。 TCPパケットが間違った順序で到着する場合、特定のまれな輻輳ケースでこれによりランダムな接続リセットの問題が発生する可能性があります。関連性がある この問題のドキュメント は現在追加のために熟考されています:
したがって、代わりに:
-A INPUT ... -j REJECT
使用を検討してください:
-A INPUT ... -m conntrack --ctstate INVALID -j DROP -A INPUT ... -j REJECT
REDIRECTはポート番号を変更するだけなので、接続が次の場合:
client -> public_addres:80
あれは。。。になる
client -> public_address:8080
したがって、自分がしていることを実行することによって、同時にブロックしたり受け入れたりすることはできません。
まず、このルールを削除します。
-A INPUT -p tcp -m tcp --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT
そして、次のようなREDIRECTの代わりにDNATを使用します。
-A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j DNAT --to 127.0.0.1:8080
うまくいくかもしれません。
127.0.0.1:8080(0.0.0.0:8080ではなく)でのみリッスンすることもできます。
私の経験では、通常は8080サービスのバインドを変更します。
IEは0.0.0.0:8080にバインドするのではなく、サービスを127.0.0.1:8080にバインドします。これは、アプリケーションがパブリックインターフェイスをリッスンしないことを意味します。
この場合、ポート80/443からポート8080へのリバースプロキシ(nginx)をセットアップします。これにより、httpポート80からhttpsポート443へのリダイレクトを構成でき、アプリケーションはポート8080で実行できます。 SSLについて知る。
私はiptablesの専門家ではないので、上記の問題を解決するための解決策は試しません。