ここでの他の回答やコメントが何を指しているのかわかりません。これはかなり簡単に可能です。 2 つのオプションがあり、どちらもプロセスを root に昇格させずに番号の小さいポートへのアクセスを許可します:
オプション 1:09
を使用 プロセスに番号の小さいポート アクセスを許可するには:
これにより、特定のバイナリへの永続的なアクセスを許可して、17
経由で番号の小さいポートにバインドできます。 コマンド:
sudo setcap CAP_NET_BIND_SERVICE=+eip /path/to/binary
e/i/p 部分の詳細については、24
を参照してください。 .
これを行った後、 39
番号の小さいポートにバインドできます。 44
を使用する必要があることに注意してください シンボリックリンクではなく、バイナリ自体に。
オプション 2:56
を使用 ユーザー/グループ/ポートをより細かく制御して、1 回限りのアクセスを許可するには:
69
(man ページ) ツールはまさにこのために存在します。
75
をインストール お気に入りのパッケージ マネージャーを使用してください。
関連するポートへのアクセスを許可するように構成します。すべてのユーザーとグループからの 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
89
経由でコマンドを実行します (オプションで 96
を指定 またはその他の引数については、man ページを参照してください):
authbind --deep /path/to/binary command line args
例
authbind --deep java -jar SomeServer.jar
上記のどちらにも一長一短があります。オプション 1 は、バイナリ に信頼を付与します ただし、ポートごとのアクセスは制御できません。オプション 2 は ユーザー/グループ に信頼を付与します ポートごとのアクセスを制御できますが、古いバージョンでは IPv4 のみがサポートされていました (最初にこれを書いたので、IPv6 をサポートする新しいバージョンがリリースされました)。
デール・ハグランドが目立ちます。ですから、同じことを別の方法で、いくつかの詳細と例を挙げて説明します。 ☺
Unix と Linux の世界で正しいことは次のとおりです。
- スーパーユーザーとして実行され、リッスン ソケットをバインドする、小さくてシンプルで簡単に監査できるプログラムを用意すること。
- 最初のプログラムによって生成された、権限を削除する別の小さくてシンプルで簡単に監査可能なプログラムを用意すること;
- 別の3分の1で、サービスの要点を得る 非スーパーユーザー アカウントで実行され、2 番目のプログラムによってチェーンがロードされ、ソケットの開いているファイル記述子を単純に継承することを想定しています。
どこにリスクが高いのか、あなたは間違った考えを持っています。高いリスクはネットワークから読み取り、読み取った内容に基づいて行動することです ソケットを開き、それをポートにバインドし、107
を呼び出すという単純な行為ではありません .リスクが高いのは、実際の通信を行うサービスの一部です。開くパーツ 112
、および 129
、さらには (ある程度) 139
という部分まで 、リスクは高くなく、スーパーユーザーの保護下で実行できます。 148
の送信元 IP アドレスを除いて、 ケース) ネットワーク上で信頼できない見知らぬ人によって管理されているデータ。
これには多くの方法があります。
151
Dale Hagglund が言うように、古い「ネットワーク スーパーサーバー」 161
これを行います。サービス プロセスが実行されるアカウントは、175
の列の 1 つです。 .リッスンする部分と権限を削除する部分を、小さくて簡単に監査できる 2 つの別個のプログラムに分割するわけではありませんが、メインのサービス コードを別個のプログラム 189
に分割します。 ソケット用の開いているファイル記述子で生成されるサービス プロセスで ed.
1 つのプログラムを監査すればよいので、監査の難しさはそれほど問題ではありません。 194
の主な問題は、監査がそれほど多くないことではなく、最近のツールと比較して、単純できめ細かいランタイム サービス制御を提供していないことです。
UCSPI-TCP とデーモンツール
Daniel J. Bernstein の UCSPI-TCP と daemontools パッケージは、これを組み合わせて行うように設計されています。代わりに、Bruce Guenter のほぼ同等の daemontools-encore ツールセットを使用することもできます。
ソケット ファイル記述子を開き、特権ローカル ポートにバインドするプログラムは 205
です。 、UCSPI-TCP から。 214
の両方を行います そして 227
.
237
次に、ルート権限自体を削除するサービス プログラムを生成します (提供されるプロトコルは、たとえば FTP や SSH デーモンの場合のように、スーパーユーザーとして開始してから「ログオン」する必要があるため) または 240
これは自己完結型の小さく、簡単に監査可能なプログラムであり、特権をドロップしてから、ロードを適切なサービス プログラムに連鎖させます (そのため、たとえば 254の場合のように、スーパーユーザー特権で実行される部分はありません)。コード> ).
サービス 264
したがって、スクリプトはたとえば次のようになります (これは null IDENT サービスを提供するための dummyidentd 用です):
#!/bin/sh -e
exec 2>&1
exec \
tcpserver 0 113 \
setuidgid nobody \
dummyidentd.pl
ノッシュ
私の nosh パッケージはこれを行うように設計されています。 276
が小さい 他のものと同じようにユーティリティ。わずかな違いの 1 つは、288
で使用できることです。 スタイルの「LISTEN_FDS」サービスと UCSPI-TCP サービスを使用するため、従来の 297
プログラムは 2 つの別個のプログラムに置き換えられます:303
と 316
.
ここでも、単一目的のユーティリティが生成され、相互にチェーン ロードされます。この設計の興味深い癖の 1 つは、329
の後にスーパーユーザー権限を削除できることです。 しかし 333
よりも前に .これが 347
です 356
のスクリプト まさにそれを行います:
#!/bin/nosh
fdmove -c 2 1
clearenv --keep-path --keep-locale
envdir env/
softlimit -m 70000000
tcp-socket-listen --combine4and6 --backlog 2 ::0 smtp
setuidgid qmaild
sh -c 'exec \
tcp-socket-accept -v -l "${LOCAL:-0}" -c "${MAXSMTPD:-1}" \
ucspi-socket-rules-check \
qmail-smtpd \
'
スーパーユーザーの保護の下で実行されるプログラムは、サービスに依存しない小さなチェーン読み込みツール 364
です。 、 370
、 382
、 392
、 402
、および 412
. 420
の時点で が開始され、ソケットが開いて 438
にバインドされます ポートであり、プロセスにはスーパーユーザー権限がありません。
s6、s6-networking、execline
Laurent Bercot の s6 および s6-networking パッケージは、これを組み合わせて行うように設計されています。コマンドの構造は 440
のものと非常によく似ています。 および UCSPI-TCP。
455
468
の置換を除いて、スクリプトはほとんど同じです。 478
の場合 と 481
492
の場合 .ただし、M. Bercot の execline ツールセットを同時に利用することもできます。
以下は、Wayne Marshall のオリジナルを少し変更した FTP サービスの例です。これは、execline、s6、s6-networking、および publicfile の FTP サーバー プログラムを使用します:
#!/command/execlineb -PW
multisubstitute {
define CONLIMIT 41
define FTP_ARCHIVE "/var/public/ftp"
}
fdmove -c 2 1
s6-envuidgid pubftp
s6-softlimit -o25 -d250000
s6-tcpserver -vDRH -l0 -b50 -c ${CONLIMIT} -B '220 Features: a p .' 0 21
ftpd ${FTP_ARCHIVE}
ipsvd
Gerrit Pape の ipsvd は、ucspi-tcp や s6-networking と同様に動作する別のツールセットです。ツールは 502
です および 511
今回は、しかし、それらは同じことを行い、信頼できないクライアントによってネットワーク経由で送信されたものの読み取り、処理、および書き込みを行うリスクの高いコードは、依然として別のプログラムにあります。
525
を実行する M. Pape の例を次に示します。 538
で スクリプト:
#!/bin/sh
exec 2>&1
cd /public/10.0.5.4
exec \
chpst -m300000 -Uwwwuser \
tcpsvd -v 10.0.5.4 443 sslio -v -unobody -//etc/fnord/jail -C./cert.pem \
fnord
547
554
一部の Linux ディストリビューションに見られる新しいサービス監視および初期化システムである は、560
を行うことを目的としています。 できる。ただし、小さな自己完結型プログラムのスイートは使用しません。 571
を監査する必要があります 残念ながら全体的に.
585
で 構成ファイルを作成して、590
というソケットを定義します。 リッスンし、601
するサービス 開始します。サービス「ユニット」ファイルには、サービスを実行するユーザーなど、サービス プロセスを大幅に制御できる設定があります。
そのユーザーを非スーパーユーザーに設定すると、 614
ソケットを開き、ポートにバインドし、626
を呼び出すというすべての作業を行います (必要に応じて 630
) プロセス #1 でスーパーユーザーとして実行され、それが生成するサービス プロセスはスーパーユーザー権限なしで実行されます。
私はかなり異なるアプローチをしています。 node.js サーバーにポート 80 を使用したいと考えていました。 Node.js が非 sudo ユーザー用にインストールされていたため、実行できませんでした。シンボリックリンクを使用しようとしましたが、うまくいきませんでした。
次に、あるポートから別のポートに接続を転送できることを知りました。そこで、ポート 3000 でサーバーを起動し、ポート 80 からポート 3000 へのポート転送をセットアップしました。
このリンクは、これを行うために使用できる実際のコマンドを提供します。コマンドは次のとおりです -
<ブロック引用>localhost/ループバック
642
外部
650
2番目のコマンドを使用しましたが、うまくいきました。したがって、これは、ユーザープロセスが下位ポートに直接アクセスすることを許可せず、ポート転送を使用してアクセスできるようにするための中間点だと思います.