非ルートプロセスが“ privileged”にバインドする方法はありますかLinuxのポート?

StackOverflow https://stackoverflow.com/questions/413807

質問

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

標準的な回避策は知っていますが、正確には何もしません欲しい:

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

ルート以外のプロセスが" privileged"にバインドできるようにする簡単な sysctl 変数があります。 Linuxのポート(1024未満のポート)、または運が悪いのですか?

編集:場合によっては、機能を使用してこれを行います。

役に立ちましたか?

解決

さて、ケーパビリティシステムと CAP_NET_BIND_SERVICE ケーパビリティを指摘してくれた人々に感謝します。最新のカーネルを使用している場合は、これを使用して、非ルートとしてサービスを開始し、低いポートをバインドすることができます。簡単な答えは、次のとおりです。

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

そして、その後 program が実行されると、いつでも CAP_NET_BIND_SERVICE 機能が使用されます。 setcap はdebianパッケージ libcap2-bin に含まれています。

警告の説明:

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

リソース:

注: RHELはこれをv6で最初に追加しました

他のヒント

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

もう1つの例は、パイプ経由で通信する複数のデーモンを使用するPostfixです。1つまたは2つのデーモン(バイトの受け入れまたは放出以外はほとんど行わない)がrootとして実行され、残りは低い特権で実行されます。

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

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300

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

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

これには、スクリプトサーバーで作業するという利点があり、非常に簡単です。

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

(最後の手段のオプション、非推奨)。

net / ipv4 / af_inet.c で、読み取った2行を削除します

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

そしてカーネルは特権ポートをもうチェックしません。

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

理想的な解決策である私見は、継承可能な 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に変更します。 capsh はGIDを変更せずに残し、絶対にそれを望まないため、これが必要です。
  • ビット「UIDの変更時に機能を維持する」を設定します。
  • UIDを $ DAEMONUSER に変更します
  • 継承可能な cap_net_bind_service
  • を除き、すべてのキャップをドロップします(現時点では、-keep = 1 によりすべてのキャップが引き続き存在します)
  • コマンドを実行します( '-'は区切り記号です)

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

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

sg $EJABBERDUSER "capsh --keep=1 --uid=`id -u $EJABBERDUSER` --caps='cap_net_bind_service+pei' -- $EJABBERD --noshell -detached"

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

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

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

長所:

  • 古いUNIXで利用可能
  • システム管理者が設定をセットアップしたら、開発に取り掛かります(デーモンを再構築すると、setcap機能が失われる可能性があります。その後、管理者に戻る必要があります&quot;どうぞ...&quot;)
  • デーモンはそのネットワークのことを心配する必要はなく、標準入力/標準出力について話すだけです
  • 要求に応じて、root以外のユーザーとしてデーモンを実行するように構成できます

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

私の「標準的な回避策」ユーザースペースリダイレクタとしてsocatを使用します:

socat tcp6-listen:80,fork tcp6:8080

これはスケーリングされないことに注意してください、フォークは高価ですが、それはsocatの動作方法です。

2017年の更新:

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です。

これですべてです。
カーネルをコンパイルし、インストールします。
再起動します。
終了-その愚かな制限はGONEであり、スクリプトでも機能します。

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

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を使用し、この制限が二度とわからないようにしたい場合はカーネルをコンパイルします。

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

残念ながら、それを活用してアプリケーションを非ルートとして実行しながら、 CAP_NET_BIND_SERVICE (おそらく setcap ですが、これには既存のソリューションが必要です。

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

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

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

順番に、私たちは

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

ここでは、内部で多くのことが行われています。

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

次に解決する必要のある問題は、子を exec 実行した後に機能を設定する方法です。機能システムには、常に「継承された」機能セットがありました。これは&quot; execve(2)で保持される機能のセット&quot; [ capabilities(7)]。これは問題を解決しているように聞こえますが( cap_net_bind_service 機能を継承に設定するだけですか?)、これは実際には特権プロセスにのみ適用されます-そして、すでにユーザーを変更しているため、プロセスは特権がありません( -user フラグを使用)。

新しいアンビエント機能セットはこの問題を回避します-「特権のないプログラムのexecve(2)で保持される機能のセットです」。アンビエントセットに cap_net_bind_service を配置することにより、 capsh がサーバープログラムを実行すると、プログラムはこの機能を継承し、リスナーを低いポートにバインドできます。

詳細を知りたい場合は、機能マニュアルページで詳細に説明しています。 strace を介して capsh を実行することも非常に有益です!

TLDR:「答え」について(私が見るように)、&gt;&gt; TLDR&lt;&lt;にジャンプします。この回答の一部です。

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

また、ここですべての答えを確認しました。私はそれらのいくつかを試しました(そして、私は単に解決策が好きではなかったので、他のものを試さないことを選びました)。その解決策は、 Capabilities = および CapabilitiesBindingSet = の設定で systemd を使用することだと思いました。しばらくこれと格闘した後、これが解決策ではないことを発見しました 理由:

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

OPが賢明に述べているように、それを避けるのは常に常にベストです(可能であれば、すべてのデーモンに!)。

systemd ユニットファイルの User = および Group = でCapabilities関連オプションを使用することはできません。機能は ALWAYS execev (または関数が何であれ)が呼び出されるとリセットされます。言い換えると、 systemd がフォークしてそのパーマをドロップすると、機能がリセットされます。これを回避する方法はなく、カーネル内のバインディングロジックはすべて、機能ではなくuid = 0を中心にしています。これは、ケイパビリティがこの質問に対する正しい答えになる可能性が低いことを意味します(少なくともいつでも)。ちなみに、 setcap は、他の人が述べたように、解決策ではありません。私にとってはうまくいきませんでした。スクリプトではうまく動作せず、ファイルが変更されるたびにスクリプトはリセットされます。

わずかな防御で、私はジェームズの iptables と述べました(今削除したコメントで)。提案(OPも言及)は、「2番目のベストソリューション」でした。 :-P

&gt;&gt; TLDR&lt;&lt;

解決策は、 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でリッスンしますが、 iptables
  • のおかげで53で接続が正常に受け入れられます
  • コマンドをユニットファイル自体に含めることができるため、ユーザーの頭痛の種を節約できます。 systemd はファイアウォールルールをクリーンアップし、デーモンが実行されていないときにそれらを必ず削除します。
  • ルートとして実行することはなく、おそらくデーモンが危険にさらされて uid = 0 に設定されている場合でも、権限の昇格を不可能にします(少なくとも systemd は主張しています)。

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

systemd は、特定の機能を持つデーモンを起動するオプションを持つsysvinitの代替品です。 。 systemd.exec(5)マンページのオプションCapabilities =、CapabilityBoundingSet =。

ポートリダイレクトは私たちにとってもっとも理にかなっていますが、アプリケーションがURLをローカルで解決するという問題に遭遇しました。 (つまり、 shindig になります)。

これにより、ローカルマシンのURLにアクセスするときにリダイレクトすることもできます。

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

何らかの理由で、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ディレクトリはルートによって所有されているため、非ルートユーザーには実行中のプロセスの完全な情報/制御がありません。 / 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のいずれかを選択します。そして、これは非常に多くの選択肢があるということです。

起動時:

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

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

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

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

機能、iptables、またはその他のトリックは不要です。

これは、単純な python httpサーバー

ファイル 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

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

#!/bin/sh

UID=`id -u yourusername`
GID=`id -g yourusername`
exec tcpserver -u $UID -g $GID -RHl0 0 portnumber   /path/to/your/process &

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

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

OPは開発/テストにすぎないため、洗練されたソリューションよりも役立つものがあります。

setcapをスクリプトのインタープリターで使用して、スクリプトに機能を付与できます。グローバルインタープリターバイナリのsetcapsが受け入れられない場合は、バイナリのローカルコピーを作成し(任意のユーザーが可能)、このコピーのrootにsetcapを取得します。 Python2(少なくとも)は、スクリプト開発ツリーのインタープリターのローカルコピーで適切に動作します。 rootユーザーは、ユーザーがアクセスできる機能を制御できるように、suidは必要ありません。

インタープリターのシステム全体の更新を追跡する必要がある場合は、次のようなシェルスクリプトを使用してスクリプトを実行します。

#!/bin/sh
#
#  Watch for updates to the Python2 interpreter

PRG=python_net_raw
PRG_ORIG=/usr/bin/python2.7

cmp $PRG_ORIG $PRG || {
    echo ""
    echo "***** $PRG_ORIG has been updated *****"
    echo "Run the following commands to refresh $PRG:"
    echo ""
    echo "    $ cp $PRG_ORIG $PRG"
    echo "    # setcap cap_net_raw+ep $PRG"
    echo ""
    exit
}

./$PRG $*

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

また、マシン内で開始された接続に対してPREROUTING REDIRECTが機能しないこともわかりました。ローカルマシンからの接続を処理するには、OUTPUTルールも追加します&#8212; localhostでiptablesポートリダイレクトが機能しないをご覧ください。例えば。次のようなもの:

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

PREOUTING 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年の回答/ 9月:

ip6tablesはIPV6 NATをサポートするようになりました: http:// www.netfilter.org/projects/iptables/files/changes-iptables-1.4.17.txt

カーネル3.7+が必要です

証明:

[09:09:23] root@X:~ ip6tables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REDIRECT   tcp      eth0   *       ::/0                 ::/0                 tcp dpt:80 redir ports 8080
    0     0 REDIRECT   tcp      eth0   *       ::/0                 ::/0                 tcp dpt:443 redir ports 1443

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 6148 packets, 534K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 6148 packets, 534K bytes)
 pkts bytes target     prot opt in     out     source               destination
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top