web-dev-qa-db-ja.com

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

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

18
adaml

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

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

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

29
Joe Sniderman

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

あなたはそれが間違っていると思います。誰でもこれらのポートを使用できます。 Bindingそれらへの特権操作です。

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

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
_

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

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

もう1つのオプションは、listen()が呼び出された後、root特権を削除するようにサーバープログラムを作成することです。これはかなり一般的なソリューションであり、ほとんどのデーモンで表示されます。たとえば、Apacheは、ルートとしてのinitから開始し、ルート権限を削除し、ポート80にバインドされると、ユーザー_www-data_または同様の何かになります。ルートではなく_/etc/init.d/Apache start_を実行してみてください。Apacheはおそらく開始に失敗しました。

5
Phil Frost