EN JA
INETD(8)
INETD(8) FreeBSD System Manager's Manual INETD(8)

名称

inetdインターネット“スーパサーバ”

書式

inetd [ -d][ -l][ -w][ -W][ -c maximum][ -C rate][ -s maximum][ -a address | hostname][ -p filename][ -R rate][ configuration file]

解説

inetd ユーティリティは、ブート時に /etc/rc の中で起動されます ( rc(8) 参照)。起動されると、 inetd は定められたインターネットソケットを監視し、接続要求を待ちます。監視しているソケットに対して接続要求が出されると、 inetd はそのソケットに対応したサービスを判定し、サービスを提供するプログラムを起動します。サーバプログラムはサービスソケットを標準入力・標準出力・エラー出力として起動されます。サービスプログラムが完了すると、 inetd は再びソケットの監視を行ないます (後述するような例外もあります)。 inetd を用いれば 1 つのデーモンで複数のサービスプログラムを起動することができるので、システムの負荷を軽減することができます。

inetd は、起動時に以下のオプションを指定できます。

-d
デバッグモードにします。
-l
成功した接続のログをとります。
-w
外部サービスに対して TCP Wrapping をオンにします。 TCP Wrappers サポートについての更なる情報については、 実装に関する注 の節を参照してください。
-W
inetd 組み込みの内部サービスに対して TCP Wrapping をオンにします。
-c maximum
同時に起動可能なサービスの、デフォルトにおける最大値を指定します。デフォルトでは、無制限です。サービスごとに指定される "max-child"パラメータによって上書きされ得ます。
-C rate
1 分間に単一の IP アドレスから起動されるサービスのデフォルトにおける最大値を指定します。デフォルトは未設定です。サービスごとに指定される "max-connections-per-ip-per-minute"パラメータによって上書きされ得ます。
-R rate
1 分間に起動できる最大のサービス数を指定します。デフォルトは 256 です。 rate に 0 を指定すると、起動可能な数は無制限になります。
-s maximum
単一 IP アドレスに対して同時起動可能な各サービスの最大数のデフォルト値です。デフォルトは無限です。「IP あたりの子の数の最大」パラメータを使用して、サービス毎に上書き可能です。
-a
バインドする IP アドレスを 1 個指定します。代りに、ホスト名を指定可能です。この場合、ホスト名に対応する IPv4 または IPv6 のアドレスが使用されます。通常、ホスト名が、 jail(8) 環境変数のものに対応している場合に、ホスト名は、 inetdjail(8) 内で実行されるとき、指定されます。

ホスト名指定が使用され、IPv4 および IPv6 両方のバインドを望む場合、 /etc/inetd.conf の各サービスに対して、各バインドに対する適切な プロトコル のエントリが必要です。例えば TCP ベースのサービスは 2 エントリが必要であり、ひとつは、 プロトコル に“tcp4”を使用し、もうひとつは“tcp6”を使用します。後で説明する /etc/inetd.confプロトコル フィールドを参照してください。

-p
デフォルトとは異なるプロセス ID を保持するファイルを指定します。

inetd は実行時に設定情報を設定ファイルから読み込みます。デフォルトでは設定ファイルは /etc/inetd.conf です。設定ファイルの各フィールドにはエントリが 1 つなければなりません。各フィールドのエントリはタブやスペースで区切ります。コメントは行頭に“#”をつけます。設定ファイルのフィールドは、次の通りです:

service-name 
socket-type 
protocol 
{wait|nowait}[/max-child[/max-connections-per-ip-per-minute[/max-child-per-ip]]] 
user[:group][/login-class] 
server-program 
server-program-arguments

ONC RPC ベースのサービスを記述するためのエントリは、次のフィールドを含みます:

service-name/version 
socket-type 
rpc/protocol 
{wait|nowait}[/max-child[/max-connections-per-ip-per-minute[/max-child-per-ip]]] 
user[:group][/login-class] 
server-program 
server-program-arguments

inetd が起動することのできるサービスは 2 種類あります。 1 つは標準で、もう 1 つは TCPMUX です。標準サービスには割り当てられた well-known ポートがあります。これは公式のインターネット標準を実装したサービスや BSD 特有のサービスです。 RFC 1078 に書かれているように、TCPMUX は非標準サービスであり、 well-known ポートが割り当てられていません。そういった非標準サービスは、あるプログラムが“tcpmux” well-known ポートに接続してそのサービス名を指定したとき、 inetd によって起動されます。この機能はローカルに開発されたサーバを追加するときに便利です。 TCPMUX リクエストが受理されるのは、 TCPMUX ベースのサーバに至るまでにおいて、マルチプレクササービス自身が有効にされているときのみです。後述の内部サービスに関する議論を参照してください。

サービス名 のエントリには、 /etc/services ファイルに記述されているサービス名か、 UNIX ドメインソケット (後述) の指定が記述されます。“内部”サービス (後述) については、名前としてそのサービスのオフィシャル名 (すなわち /etc/services 内の最初のエントリ) を指定すべきです ONC RPC ベースのサービスを指定するために使用するとき、このフィールドはファイル /etc/rpc でリストされた有効な RPC サービス名です。“/”の右の部分が RPC のバージョン番号です。バージョン番号は、数字もしくは、バージョンの幅 (レンジ) で指定します。幅を指定する場合は低い番号から高い番号を指定します。たとえば“rusers/1-3”のように記述します。 TCPMUX サービスでは、 サービス名 のフィールドは、文字列“tcpmux”、スラッシュ、そしてローカルに選ばれたサービス名からなります。 /etc/services に書かれたサービス名と“help”は予約済であり、ローカルなサービス名には使用できません。 TCPMUX サービスのためにユニークな名前をつけるには、頭に組織名をつけ、末尾にバージョン番号をつけるとよいでしょう。

ソケットタイプ のエントリは、“stream”, “dgram”, “raw”, “rdm”, “seqpacket”のいずれかである必要があります。それぞれ、ソケットが stream, datagram, raw, reliably delivered message, sequenced packet socket である場合に対応しています。 TCPMUX サービスは“stream”を使わなければなりません。

プロトコル のエントリには、有効なプロトコル名か“unix”が記述されます。例えば“tcp”や“udp”などです。この場合、後方互換性のため、暗黙的に本エントリは IPv4 を意味します。名前“tcp4”, “udp4”は、IPv4 のみを指定します。名前“tcp6”, “udp6”は、IPv6 のみを指定します。名前“tcp46”, “udp46”は、エントリに IPv4 とワイルドカード AF_INET6 ソケット経由の IPv6 の両方を受理させます。 RPC ベースのサービスの場合、“rpc/tcp”や“rpc/udp”のような指定になります。 IPv4 と IPv6 を、4, 6, 46 のいずれかのサフィックスを使用して指定可能です。例えば“rpc/tcp6”や“rpc/udp46”とします。 TCPMUX サービスは“tcp”, “tcp4”, “tcp6”, “tcp46”のいずれかを使用する必要があります。

wait/nowait エントリは、 inetd によって起動されたサーバがサービスアクセスポイントに関連付けられたソケットを引き継ぐかどうか、すなわちサーバが終了するまで inetd が新しいサービス要求を監視するのを待つ必要があるか否かを指定します。 datagram サーバは、特定のサービスアドレスと結び付いた datagram ソケットで毎回起動されるため、“wait”を使わなければなりません。こういったサーバは、終了する前に少なくとも 1 データグラムをソケットから読まなければなりません。もし datagram サーバが相手に接続したときソケットを解放するなら、 inetd はソケットに対するメッセージをさらに受けることができます。このようなサーバは“マルチスレッド”サーバと呼ばれます。サーバはソケットから datagram を 1 つ読み込み、相手に接続する新しいソケットをつくります。サーバは fork() を行い、親プロセス側は終了しなければいけません。これにより inetd は新しいサービス要求をチェックし、新しいサーバを起動することができるようになります。入って来る全ての datagram を処理し、時間切れまで動作する datagram サーバは、“シングルスレッド”サーバと呼ばれます。 comsat(8)talkd(8) ユーティリティは、後者のタイプの datagram サーバの例です。 tftpd(8) ユーティリティは、マルチスレッドで動く datagram サーバの例です。

stream ソケットを使うサーバは一般にマルチスレッドで動き“nowait”エントリを使います。こういったサーバへの接続要求は inetd で受け付けられ、新たに受理し、クライアントにつながったソケットのみがサーバに与えられます。多くの stream ベースのサービスはこのように行われます。“wait”エントリを使う stream ベースのサーバは、サービスのソケットを監視し、少なくとも 1 つの接続要求を受け入れてから終了しなければなりません。そういったサーバは通常、時間切れとなるまで、入って来る要求を受け付け処理します。 TCPMUX サービスは“nowait”を使わなければなりません。

“nowait”サービスの子プロセス (あるいは“スレッド”) の最大数は、“nowait”キーワードの後に“/”と数字を付け加えることで指定できます。通常 (あるいは 0 が指定された場合)、子プロセスの数に制限はありません。一方、最大数に達すると、それ以降の接続要求は、存在する子プロセスが終了するまで待ち行列に蓄えられます。これは、“wait”モードでも同様ですが、通常は 1 (デフォルトの値) 以外は意味がありません。指定した IP アドレスからの 1 分あたりの最大接続数を指定することも可能です。この場合、“/”および最大子プロセス数を指定します。最大値に達した場合、指定した IP アドレスからの接続は、この 1 分が経過するまで、落とされます。さらに、単一 IP アドレスに対して同時起動可能な各サービスの最大数の指定が、“/”に続けて未完了の子プロセスの最大数を追加することで可能です。最大値に達した場合、指定した IP アドレスからの接続は、落とされます。

ユーザ名 エントリには、サーバを実行するユーザ名を書きます。これによりサーバを root よりも低い権限で実行できます。オプションの グループ名 部分は“:”で分離され、指定された、このユーザのデフォルトグループ以外のグループ名を指定できます。オプションの ログインクラス 部分は“/”で分離され、デフォルトの“daemon”ログインクラス以外のログインを指定できます。

サーバプログラム名 のエントリには、ソケットに要求があったとき inetd が起動し、当該エントリのサービスを提供するサーバプログラムのパス名を指定します。 inetd 内部にすでに実装されているサービスを提供する場合には、サーバプログラムとして“internal”を指定します。

サーバプログラム引数 エントリは、通常プログラムの名前である、argv[0] で始まる サーバプログラム へ渡される引数をリストします。 inetd 内部に実装されているサービスを提供する場合には、サーバプログラム引数として、サービスの サービス名 (と引数) または語“internal”を指定します。

現在、引数を取る内部サービスは“auth”のみです。オプション無しだと、このサービスは常に“ERROR : HIDDEN-USER”を返します。このサービスの動作を変更するために使用可能な引数は次の通りです:

-d fallback
fallback ユーザ名を指定します。本物の“auth”サービスが (後述の -r オプションで) 有効になっている場合、ソケットの credential 取得またはユーザ名検索に失敗したときに、エラーを返す代りにこのユーザ名を返します。本物の“auth”サービスが無効になっている場合、すべての要求に対してこのユーザ名を返します。主に、本サービスを NAT マシン上で実行しているときに有用です。
-g
ident 要求者にユーザ名を返す代りに、アルファベットと数字からなるランダムなユーザ名を報告します。例えば“c0c993”です。 -g フラグは、ユーザ名に優先するだけでなく、 .fakeid.noident のファイルにも優先します。
-t sec[ . usec]
サービスのタイムアウトを指定します。デフォルトのタイムアウトは 10.0 秒です。
-r
RFC 1413 にある、真の“auth”サービスを提供します。残りのすべてのフラグが使用されるのは、この場合のみです。
-i
ユーザ名の代りに数値のユーザ ID を返します。
-f
識別されるユーザのホームディレクトリに .fakeid というファイルがある場合、本当のユーザ名の代りにそのファイル中のユーザ名を報告します。 .fakeid 中のユーザ名が実在するユーザのものの場合、本当のユーザ名を報告します。 -i が共に指定されると、 .fakeid 中のユーザ名が既存のユーザ ID の代りにチェックされます。
-F
-f と同じですが、 .fakeid が実在するユーザ名にマッチしてはならないという制約が除外されます。
-n
識別されるユーザのホームディレクトリに .noident というファイルがある場合、“ERROR : HIDDEN-USER”を返します。これは、 fakeid ファイルに優先します。
-o osname
uname(3) が報告するシステム名の代りに、 osname を使用します。

inetd ユーティリティはまた、内部ルーチンを用いて“簡単な”サービスを自身で提供します。これらのサービスとは“echo”, “discard”, “chargen” (文字生成), “daytime” (人間に読みとれる形式で時間を出力します), “time” (機械可読形式の時間。 1900 年 1 月 1 日 0 時からの経過秒数を出力します) です。これらのサービスは TCP と UDP バージョンのいずれでも利用できます。 UDP バージョンは返事のポートとして内部サービスに相当するポートを要求されたとき、サービスを拒否します。 (これはループ攻撃に対する防護です。リモート IP アドレスは記録されます。) これらのサービスの詳細については適当な RFC ドキュメントを参照して下さい。

TCPMUX のデマルチプレクスサービスもまた内部サービスとして実装されています。 TCPMUX ベースのサービスを動作させるためには、以下の行を inetd.conf に含む必要があります:

tcpmux stream tcp nowait root internal

-l オプションが指定された場合、 inetd は接続を受け付けるたび、エントリを syslog に記録します。この際、利用可能であれば、選択されたサービスと要求を発したリモートの IP 番号を記録します。設定ファイルで他に指定しておらず、 -W-w のオプションを指定していないと、 inetd は“daemon”ファシリティに対してログ出力します。

SIGHUP を受けとると、 inetd ユーティリティは、設定ファイルを再度読み込みます。デバッグモードで開始されるか、または -p オプションで別の方法で設定されるときを除いて、 inetd は、再設定を助けるために、ファイル /var/run/inetd.pid にそのプロセス ID を記録します。

実装に関する注

TCP Wrappers

-w オプションが指定されたとき、“stream nowait”または“dgram”と指定さた全サービスのうち“内部”サービス以外を、 inetd はラッピングします (包みます)。 -W オプションが指定されると、前述の条件の“内部”サービスがラッピングされます。両方のオプションが指定された場合、内部サービスと外部サービスの両方をラッピングするようになります。どちらのラッピングオプションも、失敗した接続を“auth” syslog ファシリティでログします。ラッピングオプションに -l フラグを追加すると、成功した接続も“auth”ファシリティへのログに含めるようになります。

“wait”サービスに対する要求は、サービス要求に対するサーバが無い間のみ inetd はラッピングすることに注意してください。このようなサービスに対してひとたび接続が許されると、接続要求に対して listen するサーバが無くなるまで、このサービスに対する後続の接続を inetd は制御できません。

ラッピングが有効にされた場合、この機能は組み込みであるため、 tcpd デーモンは不要です。 TCP Wrappers についての更なる情報は、関連する文書 ( hosts_access(5)) を参照してください。この文書を読むときには、“内部”サービスに対しては、関連するデーモン名は無いことを覚えておいてください。このような理由で、“内部”サービスのデーモン名としては、 inetd.conf で指定されるサービス名を使用すべきです。

TCPMUX

RFC 1078 は TCPMUX プロトコルについて述べています。「 TCP クライアントは他のホストに TCP ポート番号 1 で接続します。クライアントは、サービス名に <CRLF>を付加して送ります。サービス名は大文字/小文字を区別しません。サーバは、肯定 (+) もしくは否定 (-) を表す 1 文字を返します。 + あるいは-のすぐ後にメッセージが続く場合があります。返答は <CRLF>で終わります。もし返答が肯定であれば、選択されたプロトコルが開始されます。そうでなければ接続は切られます。」プログラムにはファイルディスクプリタ 0 と 1 で TCP コネクションが渡されます。

TCPMUX サービス名が“+”で始まっているとき、 inetd は、プログラムに肯定返答 (+) を返します。これによって、特別なサーバコードを追加することなく標準入出力を使うプログラムを起動することができます。

特別なサービス名である“help”により、 inetdinetd.conf で有効にされる TCPMUX サービスをリストします。

IPsec

本実装は、各ソケットに対する IPsec ポリシ設定のサポートのためのちょっとしたハックを含みます。“ #@”から開始する特別な形式のコメント行が、ポリシ指示子として解釈されます。“ #@”の後のすべてが、 ipsec_set_policy(3) に記述されているように、IPsec ポリシ文字列として使用されます。各ポリシ指定子は、 inetd.conf 中で後続するすべての行に適用され、これは次のポリシ指定子が登場するまで続きます。空のポリシ指定子は、IPsec ポリシをリセットします。

不正な IPsec ポリシ文字列が inetd.conf にあると、 inetdsyslog(3) インタフェースを使用してエラーメッセージを残し、終了します。

UNIX ドメインソケット

サービスを IP ソケット上で動作させることに加え、 inetdUNIX ドメインソケットも扱えます。このためには プロトコル に“unix”を指定し、 UNIX ドメインソケットを サービス名 として指定します。 サービスタイプ は“stream”か“dgram”のいずれかです。ソケットの指定は、絶対パス名であることが必要であり、 :user:group:mode: の形式で所有者とモードを前に付けることが可能です。

:news:daemon:220:/var/run/sock

という指定は、所有者が“news”でグループが“daemon”で所有者とグループのみに接続を許可するソケットを作成します。デフォルトの所有者は、 inetd を実行しているユーザです。デフォルトのモードは、ソケットの所有者のみに接続を許可するというものです。

警告: UNIX ドメインソケットの作成中に、 inetd はソケットの所有者とパーミッションを変更する必要があります。これが安全に行われるのは、ソケットが作成されるディレクトリが root のみ書き込み可能な場合だけです。 /tmp のような、誰でも書き込み可能なディレクトリにソケットを作成するために inetd を使用し ない でください。代わりに /var/run または同様のディレクトリを使用します。

内部サービスは、通常通り、 UNIX ドメインソケットでも実行可能です。この場合、ソケットのパス名の最後の部分から内部サービス名が判定されます。例えば、 /var/run/chargen と名前がつけられたソケットを指定すると、そのソケットで接続を受信するとき、“chargen”サービスが呼び出されるでしょう。

関連ファイル

/etc/inetd.conf
設定ファイル
/etc/netconfig
ネットワーク設定データベース
/etc/rpc
サービス名を RPC プログラム番号に変換するテーブル
/etc/services
サービス名をポート番号に変換するテーブル
/var/run/inetd.pid
現在実行中の inetd の pid

使用例

次に、いくつかのサービスについてサービスエントリの例を挙げておきます。

ftp          stream  tcp   nowait root  /usr/libexec/ftpd        ftpd -l 
ntalk        dgram   udp   wait   root  /usr/libexec/ntalkd      ntalkd 
telnet       stream  tcp6  nowait root  /usr/libexec/telnetd  telnetd 
shell        stream  tcp46  nowait root  /usr/libexec/rshd rshd 
tcpmux/+date stream  tcp   nowait guest /bin/date                date 
tcpmux/phonebook stream tcp nowait guest /usr/local/bin/phonebook phonebook 
rstatd/1-3   dgram   rpc/udp wait root  /usr/libexec/rpc.rstatd  rpc.rstatd 
/var/run/echo stream unix  nowait root internal 
#@ ipsec ah/require 
chargen      stream  tcp   nowait root  internal 
#@

エラーメッセージ

inetd サーバは、 syslog(3) を使ってエラーメッセージを記録します。重要なエラーメッセージとその説明は以下の通りです。

service/ protocol server failing (looping), service terminated.
直前の 1 分間に、そのサービスについての要求数が制限に達しました。不完全なプログラムや悪意のあるユーザがシステムをハングアップさせないために、このような制限が設けられています。このメッセージが出力される理由はいくつかあります。
  1. 短時間の間に多くのホストがこのサービスを要求している。
  2. 不完全なクライアントプログラムがサービスを頻繁に要求しすぎている。
  3. 悪意あるユーザがあるプログラムを起動し、サービスが '拒否' されるように攻撃している。
  4. 起動されたサービスプログラムにエラーがあり、クライアントがすぐにリトライを起こしてしまう。

-R rate オプションを使うと、制限を変えることができます。制限に達したとき、10 分経つとサービスは自動的に再許可されます。

service/ protocol: No such user user, service ignored
service/ protocol: getpwnam: user: No such user
passwd(5) データベースに user のエントリがありません。最初のメッセージは inetd が設定ファイルを (再度) 読み込むときに出されます。 2 つ目のメッセージは、サービスが呼び出されたときに出されます。

service: can't set uid uid
service: can't set gid gid
user フィールドのユーザ ID もしくはグループ ID が無効です。

setsockopt(SO_PRIVSTATE): Operation not supported
inetd ユーティリティはそのソケットに設定されている特権状態を放棄しようとしましたが、失敗しました。

unknown rpc/udp または rpc/tcp
netconfig(5) データベースに udptcp のいずれもエントリも見つけられませんでした。

unknown rpc/udp6 または rpc/tcp6
netconfig(5) データベースに udp6tcp6 のいずれもエントリも見つけられませんでした。

歴史

inetd ユーティリティは 4.3BSD で登場しました。 TCPMUX は Mark Lottor によるコードとドキュメントを元にしています。 ONC RPC ベースのサービスのサポートは、 SunOS 4.1 が供給されてから、それにならって作られました。 IPsec のハックは、1999 年に KAME プロジェクトが提供しました。 FreeBSD の TCP Wrappers サポートは FreeBSD 3.2 ではじめて登場しました。
January 12, 2008 FreeBSD