回答:
基本的に2つの異なるアプローチがあります。
最初にルートとして実行を開始し、特権ポートにバインドしてから、非特権ユーザーにドロップダウンします。
inetd、またはxinetdは特権付きで実行され、要求を特権なしで実行されているWebサーバーに転送します。
ポート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はおそらく起動に失敗します。