ユーザーが1024未満のポートをリッスンできるようにする


63

ユーザー(ルートとは異なる)がポート80でリッスンしているサーバーを実行できるようにする必要があります。

これを行う方法はありますか?


1
この質問には解釈が必要です。「セキュリティ上の理由から(rootとして)特権のないアカウントで実行したい新しいシステムサービスを作成した」(良いプラクティスと考えられている)ことを望んでいます。システム上で独自のWebサーバーを実行している場合、アクセスを許可するにはどうすればよいですか?」(かなり悪い練習を考慮)
マイケルショー

3
@Ptolemy、実際の理由は次のとおりです。私のマシンは80以外のすべてのポートをブロックするファイアウォールの背後にあります。 (明らかにセキュリティ上の理由から)rootとして実行することを信頼しないでください。あなたが気にすれば、私はこれを行うことが許可されています。
-peoro

回答:


50

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

これは特定のプロセスで機能します。ただし、特定のユーザーが1024未満のポートにバインドできるようにするには、そのユーザーをsudoersに追加する必要があります。

詳細については、このディスカッションをご覧ください。


31

(これらの方法のいくつかは他の回答で言及されています;私はいくつかの可能な選択肢を大まかな優先順位で与えています。)

低ポートを高ポートにリダイレクトし、高ポートでリッスンできます。

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 1080

サーバーをルートとして起動し、特権ポートでのリッスンを開始した後に特権を削除できます。できれば、自分でコーディングするのではなく、ジョブを実行するラッパーからサーバーを起動してください。サーバーが接続ごとに1つのインスタンスを起動する場合は、inetd(またはのような同様のプログラムxinetd)から起動します。の場合inetd、次のような行を使用します/etc/inetd.conf

http  stream  tcp  nowait  username:groupname  /path/to/server/executable  argv[0] argv[1]…

サーバーが単一のインスタンスでリッスンする場合は、などのプログラムから起動しますauthbind。空のファイル/etc/authbind/byport/80を作成し、サーバーを実行しているユーザーに対して実行可能にします。またはcreate /etc/authbind/byuid/1234、ここで1234は、サーバーを実行しているUIDで、行を含みます0.0.0.0/0:80,80

サーバーの実行可能ファイルが機能をサポートするファイルシステムに保存されている場合、機能を提供できます。機能はまだ比較的新しく、まだいくつかの欠点があることに注意してください。cap_net_bind_service

setcap cap_net_bind_service=ep /path/to/server/executable

4
私が対処しなければならないすべてのケースで、実行可能ファイルはjavaまたはpythonを起動するスクリプトでした。細かい点に費やす10時間のない男として、iptablesソリューションはそれを簡単にカバーします。
srking

iptablesソリューションの場合、-A INPUT -p tcp --dport 1080 -j ACCEPTそれ以外の場合は機能しないようなフィルタールールも追加する必要がありました(-j DROPキャッチオールもあります)。したがって、2つのリッスンソケットが残っています。
thom_nic

4

簡単な答えは、これは設計上不可能だということです。

長い答えは、オープンソースの世界では、多くの人々が設計を試し、別の方法を考え出しているということです。一般に、これは可能ではないことが広く受け入れられている慣行です。あなたがしようとしているという事実は、おそらくあなたのシステムに別の設計上の欠陥があることを意味し、* nixのベストプラクティスとセキュリティの意味に照らしてシステム全体のアーキテクチャを再検討する必要があります。

ただし、低いポートへの非ルートアクセスを許可するプログラムの1つはauthbindです。selinuxgrsecurityの両方は、このような微調整された認証のフレームワークも提供します。

最後に、特定のユーザーに特定のプログラムをrootとして実行させたい場合、本当に必要なのは、ユーザーにapacheなどを再起動させることだけsudoです。


8
ポートの「セキュリティ」は、現代の世界ではあまり意味がありません。
pjc50

3
@ pjc50:はい。それは暗黙の信頼についてです。低いポート番号は高い信頼を意味します。SSH、POP、FTP、およびその他のデーモンは、ポートが開かれるときにシステムレベルのパスワードおよびその他の資格情報を要求することが期待されています。ユーザーがボックスの低いポートでリッスンすることを許可された場合、未使用の(またはクラッシュした)ポートで偽のデーモンを起動し、疑いを持たないユーザーからパスワードを収集できます。これらのパスワードは、そのボックスで使用され、ルートを含む他のアカウントを侵害する可能性があります。
カレブ

8
それはセキュリティの非常に弱い形式です。何かに接続していて証明書のトランザクションを行っていない場合、誰と通信しているかわからない-つまり、MITM攻撃。
pjc50

5
必要なのはポートのchownであると仮定します。その後、「ch25 mail port25」ができ、(a)root権限でメールデーモンを起動する必要がなく、(b)誰もそれを乗っ取ることはできません。
pjc50

7
これは、Linuxがまだ初期段階の「設計上」であったかもしれませんが、当時はほとんど意味がありません。セキュリティとは、ユーザーができることとできないことのすべてです。それはあなたがポート80を使用する必要があるが、人々へのrootアクセス権を与えるしなければならないことを意味するので、ポート80を使用するには、rootユーザーのみを許可する、例えば、巨大なセキュリティ上のリスクであるべきではありません rootアクセスを持っています。非ルートユーザーXがポート80の使用を信頼している場合、OSでその信頼をエンコードできるはずです。幸いなことに、あなたが言ったように、authbindのようなこれを可能にする安っぽい回避策があります。
BT

3

あなたは使うことができnetcatをまたはxinetdまたはiptablesのポート転送を、またはフロントエンドプロキシとしてApacheを使用し、非特権ポートでプロセスを実行します。


3

Authbind、@ Gillesは既に言及しましたが、少し拡張したいと思います。

便利なアクセス制御(マニュアルページの詳細)があります。ポート、インターフェイスアドレス、uid、アドレスまたはポートの範囲、およびこれらの組み合わせでアクセスをフィルタリングできます。

非常に便利なパラメーターがあります--depth

-深さレベル

呼び出しグラフの深さのレベルにあるプログラムにauthbindを影響させます。デフォルトは1です。

「レベルの深さ」とは、スクリプト(またはプログラム)がレベルを下る別のスクリプトを実行することを意味します。したがって、--depth 5レベル1(または0ですか?)から5までを意味する場合、バインドする許可がありますが、レベル6以降ではそうではありません。スクリプトにアクセスさせたいが、知識の有無にかかわらず実行するプログラムにはアクセスさせたくない場合に役立ちます。


たとえば、次のようなものがあります。セキュリティのために、javajavaを実行するだけのユーザーがいて、ポート80へのアクセスを許可したい場合:

echo > /etc/authbind/byport/80
chown root:java /etc/authbind/byport/80
chmod 710 /etc/authbind/byport/80

を作成し../byport/80 filejavaユーザーグループに指定し(各ユーザーには独自のグループがあります)、グループごとに実行可能にしました。つまり、ユーザーごとに実行可能javaです。ポートごとにアクセスを許可する場合、ファイルはアクセス権を持つ必要があるユーザーによって実行可能である必要があるため、それを行いました。

これは平均的なJoeには十分かもしれませんが、--depthパラメーターの使用方法を知っているため、(javaユーザーとして)実行authbind --depth [depth] my_web_app's_start_script--depth 1、動作する最小の深さを見つけて使用するまで作業を進めます。

詳細については、manページを参照してください


1

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

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

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.