80と443はシステムポートですが、ほとんどのWebサーバーはどのようにしてそれらにバインドできますか?


18

通常、ポート80にバインドするWebサービスを実行するには、sudoer特権は必要ありません。ポート80/443はシステムポートであるため、特権ユーザーのみが使用できるため、これらのサービスがこれらのポートにバインドできるのはなぜですか?



1
「通常、sudoer特権は必要ありません」は正しくありません。
tedder42

回答:


29

基本的に2つの異なるアプローチがあります。

  1. 最初にルートとして実行を開始し、特権ポートにバインドしてから、非特権ユーザーにドロップダウンします。

  2. inetd、またはxinetdは特権付きで実行され、要求を特権なしで実行されているWebサーバーに転送します。


3
Linuxでは、CAP_NET_BIND_SERVICE機能をプログラムに適用することも、iptablesを使用してシステムポートを通常のポートにリダイレクトすることもできます。
ザンリンクス

10
OPを明確にするために:オプション#1が機能する理由は、プロセスが特権を落とすと、開いているファイル記述子を保持することが許可されるためです。
15


5

ポート80/443はシステムポートであるため、特権ユーザーのみが使用できます。

間違っていると思います。誰でもこれらのポートを使用できます。それらへのバインドは特権的な操作です。

ここでの理論的根拠は、一部のユーザーJoeが悪意のあるWebサーバーを作成してから、管理者権限を持たないホストを作成できないようにすることです。もちろん、これはかなり弱いモデルであり、通常、Joeがネットワーク上に自分のコンピューターを置くことを妨げるものは何もありません。また、物理的にアクセスできる任意のマシンに対する管理者権限を持つことができます。

netcatでデモを行います。

通常のユーザーとして、ポート80にバインドできません。

$ nc -l -p 80
Can't grab 0.0.0.0:80 with bind : Permission denied

ポート8080にバインドできます。

$ nc -l -p 8080

一方、別のターミナルで、ポート80に接続してデータを送信すると、開始したばかりのサーバーエンドに表示されます。

$ nc 127.0.0.1 8080 <<<"Hello world"

ポート80にバインドする場合は、rootになる必要があります。

$ sudo nc -l -p 80

または、CAP_NET_BIND_SERVICE機能をncバイナリに割り当てることができます。

$ cp `which nc` .
$ sudo setcap 'cap_net_bind_service=+ep' ./nc
$ ./nc -l -p 80

別のオプションは、呼び出された後にlisten()ルート特権を落とすようにサーバープログラムを書くことです。これは非常に一般的なソリューションであり、ほとんどのデーモンで見られます。たとえば、Apacheはinitからrootとして起動し、root権限を削除www-dataし、ポート80にバインドされるとユーザーまたはそれに似たものになります。root以外/etc/init.d/apache startとして実行すると、Apacheはおそらく起動に失敗します。


質問は「これらのポートにバインドする」と言います。なぜ彼は間違っていると思いますか?
バーマー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.