443

私以外のユーザーがいないときに、私の開発ボックスにこの制限があるのは非常に面倒です。

私は標準的な回避策を知っていますが、どれも私が望むことを正確に行うものではありません:

  1. authbind (Debian テスト中のバージョン 1.0 は IPv4 のみをサポートします)
  2. iptables REDIRECT ターゲットを使用して、低いポートを高いポートにリダイレクトします(「nat」テーブルは、iptables の IPv6 バージョンである ip6tables にはまだ実装されていません)。
  3. sudo (ルートとして実行することは避けようとしています)
  4. SELinux (または類似)。(これは単なる私の開発ボックスです。余分な複雑さを導入したくありません。)

sysctl非ルート プロセスが Linux の「特権」ポート (1024 未満のポート) にバインドできるようにする簡単な変数はありますか?

編集:場合によっては、機能を使用してこれを行うことができます。

4

25 に答える 25

445

さて、能力システムと能力を指摘してくれた人々に感謝しCAP_NET_BIND_SERVICEます。最近のカーネルを使用している場合、これを使用してサービスを非ルートとして開始し、低ポートをバインドすることが実際に可能です。簡単な答えは、あなたがすることです:

setcap 'cap_net_bind_service=+ep' /path/to/program

そして、その後いつでもprogram実行され、それは機能を持ちCAP_NET_BIND_SERVICEます。setcapdebian パッケージに含まれていますlibcap2-bin

ここで、注意事項について説明します。

  1. 少なくとも 2.6.24 カーネルが必要です
  2. ファイルがスクリプトの場合、これは機能しません。(つまり、#! 行を使用してインタープリターを起動します)。この場合、私が理解している限り、インタープリター実行可能ファイル自体に機能を適用する必要があります。これは、もちろん、そのインタープリターを使用するすべてのプログラムに機能があるため、セキュリティ上の悪夢です。この問題を回避するためのクリーンで簡単な方法を見つけることができませんでした。
  3. Linux は、や などprogramの昇格された権限を持つすべての LD_LIBRARY_PATH を無効にします。したがって、独自の を使用している場合は、ポート転送などの別のオプションを検討する必要がある場合があります。setcapsuidprogram.../lib/

資力:

注: RHEL はこれを v6 で初めて追加しました

于 2009-01-05T19:46:44.693 に答える
46

ポートリダイレクトを行うことができます。これは、Linuxボックスで実行されているSilverlightポリシーサーバーに対して行うことです。

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300
于 2009-11-19T11:57:18.030 に答える
33

更新 2017:

[authbind][1] を使用


*免責事項 (2021 年ごとに更新): authbind は LD_PRELOAD を介して機能することに注意してください。これは、プログラムが LIBC を使用する場合にのみ使用されます。これは、プログラムが GO でコンパイルされている場合、または C を回避する他のコンパイラーの場合には当てはまらない (またはそうでない可能性があります)。 go を使用する場合は、保護されたポート範囲のカーネル パラメータを設定します。投稿の下部を参照してください。</EndUpdate>

Authbind は、CAP_NET_BIND_SERVICE やカスタム カーネルよりもはるかに優れています。

  • CAP_NET_BIND_SERVICE は、バイナリに信頼を付与しますが、ポートごとのアクセスを制御しません。
  • Authbind は、ユーザー/グループに信頼を付与し、ポートごとのアクセスを制御し、IPv4 と IPv6 の両方をサポートします (IPv6 サポートは最近追加されました)。
  1. インストール:apt-get install authbind

  2. 関連するポートへのアクセスを構成します (例: すべてのユーザーとグループの 80 と 443)。

    sudo touch /etc/authbind/byport/80
    sudo touch /etc/authbind/byport/443
    sudo chmod 777 /etc/authbind/byport/80
    sudo chmod 777 /etc/authbind/byport/443

  3. 次の方法でコマンドを実行しますauthbind
    (必要に応じて--deepまたはその他の引数を指定します。man ページを参照してください)。

         authbind --deep /path/to/binary command line args
    
     e.g.  
    
         authbind --deep java -jar SomeServer.jar
    

カーネルをハックする Joshua の素晴らしい (=あなたが何をしているのかを知らない限り、お勧めしません) 推奨事項のフォローアップとして:

ここに最初に投稿しました。

単純。通常または古いカーネルでは、そうではありません。
他の人が指摘したように、iptables はポートを転送できます。
他の人も指摘しているように、 CAP_NET_BIND_SERVICE も仕事をすることができます。
もちろん、スクリプトからプログラムを起動すると CAP_NET_BIND_SERVICE は失敗します。シェル インタープリターにキャップを設定しない限り、これは無意味です。サービスを root として実行することもできます。
たとえば、Java の場合は、それを適用する必要があります。 JAVA JVMに

sudo /sbin/setcap 'cap_net_bind_service=ep' /usr/lib/jvm/java-8-openjdk/jre/bin/java

明らかに、これはどの Java プログラムもシステム ポートをバインドできることを意味します。
mono/.NET 用の Dito。

また、xinetd が最善のアイデアではないことも確信しています。
しかし、どちらの方法もハックなので、制限を解除して制限を解除してみませんか?
通常のカーネルを実行する必要があるとは誰も言っていないので、独自のカーネルを実行するだけでかまいません。

最新のカーネル (または現在持っているもの) のソースをダウンロードするだけです。その後、次の場所に移動します。

/usr/src/linux-<version_number>/include/net/sock.h:

そこでこの行を探します

/* Sockets 0-1023 can't be bound to unless you are superuser */
#define PROT_SOCK       1024

そしてそれをに変更します

#define PROT_SOCK 0

安全でない ssh の状況を避けたい場合は、次のように変更します: #define PROT_SOCK 24

通常、私はあなたが必要とする最も低い設定を使用します。たとえば、http の場合は 79、ポート 25 で SMTP を使用する場合は 24 です。

それだけです。
カーネルをコンパイルしてインストールします。
リブート。
完了 - そのばかげた制限はなくなっており、スクリプトでも機能します。

カーネルをコンパイルする方法は次のとおりです。

https://help.ubuntu.com/community/Kernel/Compile

# You can get the kernel-source via package linux-source, no manual download required
apt-get install linux-source fakeroot

mkdir ~/src
cd ~/src
tar xjvf /usr/src/linux-source-<version>.tar.bz2
cd linux-source-<version>

# Apply the changes to PROT_SOCK define in /include/net/sock.h

# Copy the kernel config file you are currently using
cp -vi /boot/config-`uname -r` .config

# Install ncurses libary, if you want to run menuconfig
apt-get install libncurses5 libncurses5-dev

# Run menuconfig (optional)
make menuconfig

# Define the number of threads you wanna use when compiling (should be <number CPU cores> - 1), e.g. for quad-core
export CONCURRENCY_LEVEL=3
# Now compile the custom kernel
fakeroot make-kpkg --initrd --append-to-version=custom kernel-image kernel-headers

# And wait a long long time

cd ..

簡単に言えば、安全を確保したい場合は iptables を使用し、この制限が二度と気にならないようにしたい場合はカーネルをコンパイルします。

注: 最近では、カーネルの更新は不要になりました。
設定できるようになりました

sysctl net.ipv4.ip_unprivileged_port_start=80

または持続する

sysctl -w net.ipv4.ip_unprivileged_port_start=80.

それでエラーが発生した場合は、nano で /etc/sysctl.conf を編集し、再起動後も持続するようにパラメーターを設定します。

またはprocfs経由

echo 80 | sudo tee /proc/sys/net/ipv4/ip_unprivileged_port_start
于 2015-01-16T17:25:11.633 に答える
33

標準的な方法は、それらを「setuid」にして root として起動し、ポートにバインドするとすぐにその root 権限を破棄しますが、ポートへの接続を受け入れ始める前です。Apache と INN のソース コードで、その良い例を見ることができます。Lighttpd も良い例だと言われています。

もう 1 つの例は Postfix です。これは、パイプを介して通信する複数のデーモンを使用し、そのうちの 1 つまたは 2 つ (バイトの受け入れまたは送信以外はほとんど何もしません) のみが root として実行され、残りはより低い権限で実行されます。

于 2009-01-05T17:29:56.763 に答える
32

または、カーネルにパッチを適用してチェックを削除します。

(最後の手段のオプションであり、推奨されません)。

net/ipv4/af_inet.c、次の 2 行を削除します。

      if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
              goto out;

カーネルは特権ポートをチェックしなくなります。

于 2009-01-05T17:32:13.313 に答える
28

何らかの理由で、sysctl net.ipv4.ip_unprivileged_port_start を必要な値に下げることについて誰も言及していません。例: アプリを 443 ポートにバインドする必要があります。

sysctl net.ipv4.ip_unprivileged_port_start=443

潜在的なセキュリティ上の問題があると言う人もいるかもしれません: 非特権ユーザーが他の特権ポート (444-1024) にバインドされる可能性があります。ただし、他のポートをブロックすることで、iptables を使用してこの問題を簡単に解決できます。

iptables -I INPUT -p tcp --dport 444:1024 -j DROP
iptables -I INPUT -p udp --dport 444:1024 -j DROP

他の方法との比較。この方法:

  • ある時点から (IMO) CAP_NET_BIND_SERVICE/setuid を設定するよりもさらに安全です。アプリケーションは部分的にでもまったく setuid しないためです (機能は実際にはあります)。たとえば、機能が有効なアプリケーションのコアダンプをキャッチするには、sysctl fs.suid_dumpable を変更する必要があります (別の潜在的なセキュリティ問題につながります)。また、CAP/suid が設定されている場合、/proc/PID ディレクトリは root によって所有されるため、 root 以外のユーザーは、実行中のプロセスの完全な情報/制御を持っていません。たとえば、ユーザーは (一般的に) /proc/PID/fd/ (netstat -aptn | grep) を介して、どの接続がアプリケーションに属しているかを判断できません。 PID)。
  • セキュリティ上の欠点があります。アプリ (またはポート 443-1024 を使用するアプリ) が何らかの理由でダウンしている間、別のアプリがポートを使用する可能性があります。ただし、この問題は CAP/suid (java/nodejs などのインタープリターで設定した場合) および iptables-redirect にも適用される可能性があります。この問題を除外するには、systemd-socket メソッドを使用します。authbind メソッドを使用して、特別なユーザー バインディングのみを許可します。
  • 新しいバージョンのアプリケーションをデプロイするたびに CAP/suid を設定する必要はありません。
  • systemd-socket メソッドのように、アプリケーションのサポートや変更は必要ありません。
  • カーネルの再構築は必要ありません (実行中のバージョンがこの sysctl 設定をサポートしている場合)
  • authbind/privbind メソッドのように LD_PRELOAD を実行しないため、パフォーマンス、セキュリティ、動作に影響を与える可能性があります (そうですか? テストしていません)。残りの authbind は本当に柔軟で安全な方法です。
  • アドレス変換や接続状態の追跡などを必要としないため、iptables REDIRECT/DNAT メソッドよりもパフォーマンスが高くなります。これは高負荷システムでのみ顕著です。

状況に応じて、sysctl、CAP、authbind、iptables-redirect のいずれかを選択します。そして、これは非常に多くのオプションがあることです。

于 2018-07-20T09:33:07.827 に答える
25

たとえば、ポート 80 を 3000 にバインドされたアプリにヒットさせたい場合は、ローカル SSH トンネルをセットアップできます。

sudo ssh $USERNAME@localhost -L 80:localhost:3000 -N

これには、スクリプト サーバーを使用できるという利点があり、非常に単純です。

于 2013-08-03T16:06:13.947 に答える
20

これは古い質問であることは知っていますが、最近の (>= 4.3) カーネルでは、最終的にこれに対する良い答えがあります - アンビエント機能です。

簡単な答えは、git からlibcap の最新 (まだリリースされていない) バージョンのコピーを取得してコンパイルすることです。progs/capsh結果のバイナリをどこかにコピーします(/usr/local/bin良い選択です)。次に、ルートとして、プログラムを開始します

/usr/local/bin/capsh --keep=1 --user='your-service-user-name' \
    --inh='cap_net_bind_service' --addamb='cap_net_bind_service' \ 
    -- -c 'your-program'

順番に、私たちは

  • ユーザーを切り替えるときに、現在の機能セットを維持することを宣言する
  • ユーザーとグループを「your-service-user-name」に切り替えています
  • cap_net_bind_service継承およびアンビエント セットへの機能の追加
  • フォークbash -c 'your-command'(capshの後の引数で bash が自動的に開始されるため--)

ここでは、ボンネットの下で多くのことが行われています。

まず、ルートとして実行しているため、デフォルトですべての機能を利用できます。setuidこれには、およびsyscallsを使用して uid と gid を切り替える機能が含まれていますsetgid。ただし、通常、プログラムがこれを行うと、一連の機能が失われます。これは、ルートを削除する古い方法がsetuidまだ機能するためです。--keep=1フラグは、 syscallcapshを発行するように指示します。これにより、ユーザーの変更時に機能の削除が無効になります。prctl(PR_SET_KEEPCAPS)によるユーザーの実際の変更は、およびを実行capshする--userフラグで行われます。setuidsetgid

私たちが解決しなければならない次の問題は、exec私たちの子供の後に続く方法で機能を設定する方法です。ケーパビリティ システムには常に、「継承された」一連のケーパビリティがありました。これは、「execve(2) 全体で保持される一連のケーパビリティ」[ capabilities(7) ] です。これは私たちの問題を解決するように思えますが (cap_net_bind_serviceケイパビリティを継承に設定するだけですよね?)、これは実際には特権プロセスにのみ適用されます - そして私たちのプロセスは特権プロセスではなくなりました--user

新しいアンビエント機能セットは、この問題を回避します。これは、「特権を持たないプログラムの execve(2) 全体で保持される一連の機能」です。cap_net_bind_serviceアンビエント セットを入れることで、 capshexec がサーバー プログラムの場合、プログラムはこの機能を継承し、リスナーを低いポートにバインドできるようになります。

詳細を知りたい場合は、機能のマニュアル ページで詳細に説明されています。駆け抜けも大変参考になりますcapshstrace

于 2016-05-27T15:17:55.433 に答える
19

パッケージの更新後に破損する可能性があるため、ファイル機能は理想的ではありません。

理想的な解決策である私見は、継承可能なセットでシェルを作成する機能でなければなりませんCAP_NET_BIND_SERVICE

これを行うためのやや複雑な方法を次に示します。

sg $DAEMONUSER "capsh --keep=1 --uid=`id -u $DAEMONUSER` \
     --caps='cap_net_bind_service+pei' -- \
     YOUR_COMMAND_GOES_HERE"

capshユーティリティは、Debian/Ubuntu ディストリビューションの libcap2-bin パッケージにあります。何が起こっているかは次のとおりです。

  • sg有効なグループ ID をデーモン ユーザーの ID に変更します。これは、capshGID が変更されないままであり、絶対に望んでいないため必要です。
  • 「UID 変更時の機能を維持する」ビットを設定します。
  • UID を次のように変更します$DAEMONUSER
  • --keep=1継承可能なものを除いて、すべての大文字を削除します (この時点では、すべての大文字は のためまだ存在しています)。cap_net_bind_service
  • コマンドを実行します (「--」はセパレーターです)

結果は、指定されたユーザーとグループ、およびcap_net_bind_service権限を持つプロセスです。

例として、ejabberd起動スクリプトの行:

sg $EJABBERDUSER "capsh --keep=1 --uid=`id -u $EJABBERDUSER` --caps='cap_net_bind_service+pei' -- $EJABBERD --noshell -detached"
于 2011-10-09T06:19:33.040 に答える
16

他の2つの単純な可能性:

「ローポートにバインドし、デーモンに制御を渡すデーモン」には、古い(ファッショナブルではない)ソリューションがあります。これはinetd(またはxinetd)と呼ばれます。短所は次のとおりです。

  • デーモンはstdin/stdoutで通信する必要があります(デーモンを制御しない場合-ソースがない場合-これはおそらくショートッパーですが、一部のサービスにはinetd-compatibilityフラグがある場合があります)
  • 接続ごとに新しいデーモンプロセスがフォークされます
  • それはチェーンの1つの余分なリンクです

長所:

  • 古いUNIXで利用可能
  • システム管理者が構成を設定したら、開発に取り掛かることができます(デーモンを再構築すると、setcap機能が失われる可能性がありますか?その後、管理者に戻る必要があります。 。")
  • デーモンはそのネットワーキングに関することを心配する必要はなく、stdin/stdoutについて話すだけです。
  • 要求に応じて、デーモンを非rootユーザーとして実行するように構成できます

別の方法:特権ポートからターゲットデーモンを実行できる任意の番号の大きいポートへのハッキングされたプロキシ(netcatまたはさらに堅牢なもの)。(Netcatは明らかに本番ソリューションではありませんが、「私の開発ボックス」ですよね?)このようにして、ネットワーク対応バージョンのサーバーを引き続き使用でき、プロキシを起動するためにroot / sudoのみが必要であり(起動時)、複雑で脆弱な可能性のある機能に依存しません。

于 2009-01-06T02:07:23.320 に答える
15

私の「標準的な回避策」では、socat をユーザー空間リダイレクタとして使用します。

socat tcp6-listen:80,fork tcp6:8080

これはスケーリングしないことに注意してください。分岐にはコストがかかりますが、それが socat の仕組みです。

于 2009-06-15T14:08:34.780 に答える
14

Linux は、「このアプリケーションをルートとして実行する」だけでなく、よりきめ細かいパーミッションをサポートする機能をサポートしています。これらの機能の 1 つはCAP_NET_BIND_SERVICE、特権ポート (<1024) へのバインドに関するものです。

残念ながら、それを利用して、アプリケーションを提供しながら非ルートとしてアプリケーションを実行する方法はわかりませんCAP_NET_BIND_SERVICE(おそらく を使用setcapしますが、これには既存のソリューションがあるはずです)。

于 2009-01-05T17:49:12.247 に答える
12

systemdはsysvinitの代替品であり、特定の機能を備えたデーモンを起動するオプションがあります。systemd.exec(5)のマンページにあるオプションCapabilities =、CapabilityBoundingSet= 。

于 2012-02-03T12:55:13.027 に答える
12

TLDR:「答え」については(私が見ているように)、この回答の >>TLDR<< 部分にジャンプしてください。

OK、私はそれを理解しました(今回は実際に)、この質問に対する答え、そしてこの私の答えは、私が「最高だと思った別の答え(こことツイッターの両方)を宣伝したことに対する謝罪の方法でもあります。 」ですが、試してみると、それが間違っていることがわかりました。私の過ちから学んでください。実際に自分で試してみるまで宣伝しないでください。

繰り返しますが、ここですべての回答を確認しました。私はそれらのいくつかを試しました(そして、単に解決策が気に入らなかったので、他のものを試さないことにしました)。systemd解決策は、その設定Capabilities=で使用することだと思いましたCapabilitiesBindingSet=。しばらくこれに取り組んだ後、次の理由により、これが解決策ではないことがわかりました。

機能は、ルート プロセスを制限することを目的としています。

OPが賢明に述べたように、それを避けるのが常に最善です(可能であればすべてのデーモンに対して!)。

ケイパビリティ関連のオプションをユニット ファイルと一緒に使用しUser=たりGroup=、ユニット ファイル内で使用したりすることはできません。つまり、perm を fork してドロップすると、機能がリセットされます。これを回避する方法はありません。カーネル内のバインディング ロジックはすべて、機能ではなく、uid=0 に関する基本的なものです。これは、機能がこの質問に対する正しい答えになる可能性が低いことを意味します (少なくとも近いうちに)。ちなみに、他の人が述べたように、解決策ではありません。それは私にとってはうまくいきませんでした.スクリプトではうまく機能しません.ファイルが変更されるたびにスクリプトはとにかくリセットされます.systemdexecevsystemdsetcap

私の貧弱な弁護では、Jamesのiptablesの提案(OPも言及している)が「2番目に良い解決策」であると述べました(コメントで削除しました) 。:-P

>>TLDR<<

systemd解決策は、次のようなオンザフライiptablesコマンドと組み合わせることです( DNSChain から取得)。

[Unit]
Description=dnschain
After=network.target
Wants=namecoin.service

[Service]
ExecStart=/usr/local/bin/dnschain
Environment=DNSCHAIN_SYSD_VER=0.0.1
PermissionsStartOnly=true
ExecStartPre=/sbin/sysctl -w net.ipv4.ip_forward=1
ExecStartPre=-/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT
ExecStartPre=-/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
ExecStartPre=/sbin/iptables -A INPUT -p udp --dport 5333 -j ACCEPT
ExecStartPre=/sbin/iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
ExecStopPost=/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT
ExecStopPost=/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
User=dns
Group=dns
Restart=always
RestartSec=5
WorkingDirectory=/home/dns
PrivateTmp=true
NoNewPrivileges=true
ReadOnlyDirectories=/etc

# Unfortunately, capabilities are basically worthless because they're designed to restrict root daemons. Instead, we use iptables to listen on privileged ports.
# Capabilities=cap_net_bind_service+pei
# SecureBits=keep-caps

[Install]
WantedBy=multi-user.target

ここでは、次のことを行います。

  • デーモンは 5333 でリッスンしますが、接続は 53 で正常に受け入れられます。iptables
  • ユニットファイル自体にコマンドを含めることができるため、人々の頭痛の種を減らすことができます。systemdファイアウォール ルールをクリーンアップし、デーモンが実行されていないときにそれらを削除するようにします。
  • root として実行することは決してなくsystemd、デーモンが危険にさらされてuid=0.

iptables残念ながら、依然として非常に見苦しく使いにくいユーティリティです。たとえば、デーモンが のeth0:0代わりにリッスンしている場合eth0、コマンドはわずかに異なります。

于 2014-02-08T23:29:21.850 に答える
11

systemd では、事前にアクティブ化されたソケットを受け入れるようにサービスをわずかに変更するだけです。

後でsystemd socket activateを使用できます。

機能、iptables、またはその他のトリックは必要ありません。

これは、単純なpython http サーバーのこの例からの関連する systemd ファイルの内容です。

ファイルhttpd-true.service

[Unit]
Description=Httpd true 

[Service]
ExecStart=/usr/local/bin/httpd-true
User=subsonic

PrivateTmp=yes

ファイルhttpd-true.socket

[Unit]
Description=HTTPD true

[Socket]
ListenStream=80

[Install]
WantedBy=default.target
于 2017-01-27T09:37:41.970 に答える
7

起動時:

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

次に、転送先のポートにバインドできます。

于 2013-03-05T19:28:18.263 に答える
4

「djb 方法」もあります。このメソッドを使用して、tcpserver の下の任意のポートで実行されている root としてプロセスを開始すると、プロセスの開始直後に指定したユーザーにプロセスの制御が渡されます。

#!/bin/sh

UID=$(id -u username)
GID=$(id -g username)
exec tcpserver -u "${UID}" -g "${GID}" -RHl0 0 port /path/to/binary &

詳細については、http: //thedjbway.b0llix.net/daemontools/uidgid.htmlを参照してください。

于 2013-08-03T17:25:29.367 に答える
3

privbindユーティリティを使用します。特権のないアプリケーションが予約済みポートにバインドできるようにします。

于 2014-09-19T07:51:49.100 に答える
1

iptables PREROUTING REDIRECT メソッドを試しました。古いカーネルでは、このタイプのルールは IPv6 でサポートされていないようです。しかし、現在は ip6tables v1.4.18 と Linux カーネル v3.8 でサポートされているようです。

また、マシン内で開始された接続に対して PREROUTING REDIRECT が機能しないこともわかりました。ローカル マシンからの接続で機能するには、OUTPUT ルールも追加します — iptables port redirect not working for localhostを参照してください。例:

iptables -t nat -I OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080

また、PREROUTING REDIRECTも転送されたパケットに影響することがわかりました。つまり、マシンがインターフェイス間でパケットを転送している場合 (たとえば、イーサネット ネットワークに接続された Wi-Fi アクセス ポイントとして機能している場合)、iptables ルールは、接続されたクライアントのインターネットの宛先への接続もキャッチし、それらを次の場所にリダイレクトします。この機械。それは私が望んでいたことではありません。マシン自体に向けられた接続をリダイレクトしたかっただけです。を追加することで、ボックス宛てのパケットのみに影響を与えることができることがわかりました-m addrtype --dst-type LOCAL。例:

iptables -A PREROUTING -t nat -p tcp --dport 80 -m addrtype --dst-type LOCAL -j REDIRECT --to-port 8080

もう 1 つの可能性は、TCP ポート転送を使用することです。例socat

socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080

ただし、この方法の欠点の 1 つは、ポート 8080 でリッスンしているアプリケーションが、着信接続の送信元アドレスを知らないことです (たとえば、ログ記録やその他の識別目的で)。

于 2015-09-04T03:17:32.963 に答える