inetd(スーパーサーバー)とは
telnet や FTP のような古いサービスは、自分では待ち受けず、接続が来たときだけ起動される形が使われてきました。その受付役が inetd(スーパーサーバー) です。日本語ではスーパーデーモンとも呼ばれます。
| 編集するファイル | 用途 |
|---|---|
/etc/inetd.conf | 内蔵サービスの有効・無効 |
/etc/inetd.d/<名前> | サービスを1つずつ追加する(パッケージもここに置く) |
/etc/hosts.allow / /etc/hosts.deny | TCP Wrappers による接続元の制限 |
Ubuntu 26.04 で選べる実装は次のとおりです。この記事では inetutils-inetd を使います(inetutils-telnetd が依存で入れるのもこれです)。
| パッケージ | 備考 |
|---|---|
inetutils-inetd | GNU Inetutils 版。この記事で使う |
openbsd-inetd | OpenBSD 版 |
xinetd | 拡張版。上流の最終リリースは 2012 年で、RHEL 9 では削除された |
systemd のソケット起動 | inetd を使わずに同じことができる(最後に比較します) |
導入する
sudo apt install -y inetutils-inetd導入前は設定ファイルもありません。
kazulog@sv1:~$ apt-cache policy inetutils-inetd | head -3
inetutils-inetd:
Installed: (none)
Candidate: 2:2.7-2ubuntu1.1
kazulog@sv1:~$ ls -l /etc/inetd.conf /etc/inetd.d 2>&1
ls: cannot access '/etc/inetd.conf': No such file or directory
ls: cannot access '/etc/inetd.d': No such file or directory
kazulog@sv1:~$ sudo ss -tlnp | grep -E ":(7|13|10013|10014) " ; echo "ss rc=$?"
ss rc=1TCP Wrappers の tcpd と、設定を書き換える update-inetd が一緒に入ります。
kazulog@sv1:~$ sudo apt install -y inetutils-inetd | cat
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Reading package lists...
Building dependency tree...
Reading state information...
Solving dependencies...
Installing:
inetutils-inetd
Installing dependencies:
tcpd update-inetd
Summary:
Upgrading: 0, Installing: 3, Removing: 0, Not Upgrading: 96
Download size: 92.8 kB
Space needed: 361 kB / 63.1 GB available
Get:1 http://archive.ubuntu.com/ubuntu resolute/universe amd64 tcpd amd64 7.6.q-36build2 [24.6 kB]
Get:2 http://archive.ubuntu.com/ubuntu resolute/main amd64 update-inetd all 4.54build1 [23.0 kB]
Get:3 http://archive.ubuntu.com/ubuntu resolute-updates/universe amd64 inetutils-inetd amd64 2:2.7-2ubuntu1.1 [45.2 kB]
Preconfiguring packages ...
Fetched 92.8 kB in 1s (62.2 kB/s)
Selecting previously unselected package tcpd.
(Reading database ... 91400 files and directories currently installed.)
Preparing to unpack .../tcpd_7.6.q-36build2_amd64.deb ...
Unpacking tcpd (7.6.q-36build2) ...
Selecting previously unselected package update-inetd.
Preparing to unpack .../update-inetd_4.54build1_all.deb ...
Unpacking update-inetd (4.54build1) ...
Selecting previously unselected package inetutils-inetd.
Preparing to unpack .../inetutils-inetd_2%3a2.7-2ubuntu1.1_amd64.deb ...
Unpacking inetutils-inetd (2:2.7-2ubuntu1.1) ...
Setting up update-inetd (4.54build1) ...
Setting up tcpd (7.6.q-36build2) ...
Setting up inetutils-inetd (2:2.7-2ubuntu1.1) ...
Created symlink '/etc/systemd/system/inetd.service' → '/usr/lib/systemd/system/inetutils-inetd.service'.
Created symlink '/etc/systemd/system/multi-user.target.wants/inetutils-inetd.service' → '/usr/lib/systemd/system/inetutils-inetd.service'.設定ファイルの中身
/etc/inetd.conf ができますが、内蔵サービスの4行(17〜20行目)はすべてコメントです。/etc/inetd.d/ は空です。
kazulog@sv1:~$ ls -l /etc/inetd.conf /etc/inetd.d
-rw-r--r-- 1 root root 1062 Sep 12 09:46 /etc/inetd.conf
/etc/inetd.d:
total 0
kazulog@sv1:~$ cat /etc/inetd.conf
# /etc/inetd.conf: see inetd(8) for further informations.
#
# Internet superserver configuration database.
#
#
# Lines starting with "#:LABEL:" or "#<off>#" should not
# be changed unless you know what you are doing!
#
# If you want to disable an entry so it is not touched during
# package updates just comment it out with a single '#' character.
#
# Packages should modify this file by using update-inetd(8).
#
# <service_name> <sock_type> <proto> <flags> <user> <server_path> <args>
#
#:INTERNAL: Internal services
#discard stream tcp6 nowait root internal
#discard dgram udp6 wait root internal
#daytime stream tcp6 nowait root internal
#time stream tcp6 nowait root internal
#:STANDARD: These are standard services.
#:BSD: Shell, login, exec and talk are BSD protocols.
#:MAIL: Mail, news and uucp services.
#:INFO: Info services
#:BOOT: TFTP service is provided primarily for booting. Most sites
# run this only on machines acting as "boot servers."
#:RPC: RPC based services
#:HAM-RADIO: amateur-radio services
#:OTHER: Other services行の書式は次のとおりです。
<service_name> <sock_type> <proto> <flags> <user> <server_path> <args>| 欄 | 意味 |
|---|---|
service_name | /etc/services に書かれたサービス名(ポート番号はそこで決まる) |
sock_type | stream(TCP)か dgram(UDP) |
proto | tcp / udp / tcp6 / udp6。tcp6 は IPv4 の接続も受ける |
flags | nowait(接続ごとに起動)か wait |
user | 実行する利用者 |
server_path | 起動するプログラム。internal は inetd 自身が処理する |
有効な行が1つも無いと、inetd は起動しません。
kazulog@sv1:~$ systemctl status inetutils-inetd --no-pager | head -8 | cat
○ inetutils-inetd.service - GNU Network Utilities internet superserver
Loaded: loaded (/usr/lib/systemd/system/inetutils-inetd.service; enabled; preset: enabled)
Active: inactive (dead) (Result: exec-condition) since Sat 2026-09-12 09:46:26 JST; 7s ago
Invocation: 1648d08c1ead40689a99100fac11824a
Condition: start condition unmet at Sat 2026-09-12 09:46:26 JST; 7s ago
Docs: man:inetutils-inetd(8)
https://www.gnu.org/software/inetutils/manual/
Process: 2617 ExecCondition=grep -qr ^[0-9A-Za-z/] /etc/inetd.conf /etc/inetd.d/ (code=exited, status=1/FAILURE)内蔵サービスを有効にする(/etc/inetd.conf)
daytime(13番、日時を返す)を有効にします。19行目の行頭の # を1文字消します。
sudo vi /etc/inetd.confdaytime stream tcp6 nowait root internalkazulog@sv1:~$ grep -n "daytime\|discard" /etc/inetd.conf
17:#discard stream tcp6 nowait root internal
18:#discard dgram udp6 wait root internal
19:daytime stream tcp6 nowait root internal
kazulog@sv1:~$ sudo systemctl restart inetutils-inetd
kazulog@sv1:~$ systemctl is-active inetutils-inetd
active
kazulog@sv1:~$ sudo ss -tlnp 'sport = :13'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 10 *:13 *:* users:(("inetutils-inetd",pid=3158,fd=4)) 待ち受けが *:13 になっている点に注目してください。 行のプロトコル欄が tcp6 なので、IPv6 のソケットで IPv4 の接続も受けます。実際に IPv4 で接続すると日時が返ります。
kazulog@sv2:~$ timeout 5 nc 192.168.100.10 13 < /dev/null
Sat Sep 12 09:47:04 2026サービスを1つ追加する(/etc/inetd.d/)
/etc/inetd.conf を直接増やす代わりに、/etc/inetd.d/ にファイルを1つ置く方法があります。echo(7番、送った文字をそのまま返す)を追加します。
sudo vi /etc/inetd.d/echo# echo サービス(inetd の内蔵サービス)
echo stream tcp nowait root internalkazulog@sv1:~$ ls -l /etc/inetd.d/
total 4
-rw-r--r-- 1 root root 90 Sep 12 09:47 echo
kazulog@sv1:~$ cat /etc/inetd.d/echo
# echo サービス(inetd の内蔵サービス)
echo stream tcp nowait root internal
kazulog@sv1:~$ sudo systemctl restart inetutils-inetd
kazulog@sv1:~$ sudo ss -tlnp 'sport = :7'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 10 0.0.0.0:7 0.0.0.0:* users:(("inetutils-inetd",pid=3692,fd=6)) kazulog@sv2:~$ printf 'hello inetd\n' | timeout 5 nc 192.168.100.10 7自作のサービスを動かす
server_path に自分のプログラムを書くと、接続のたびにそれが起動されます。ここでは 10013番で動く hello サービスを作ります。用意するファイルは3つです。
sudo vi /etc/inetd.d/hello
sudo vi /usr/local/bin/hello.sh
sudo vi /etc/services# 自作サービス: 10013 番につながると /usr/local/bin/hello.sh を実行する
hello stream tcp nowait nobody /usr/sbin/tcpd /usr/local/bin/hello.sh#!/bin/sh
echo "hello from inetd on $(hostname)"hello 10013/tcp # 検証用の自作サービスserver_path を /usr/sbin/tcpd にし、実際のプログラムを引数に渡すと、TCP Wrappers(次の節)の判定を通してから起動されます。
kazulog@sv1:~$ cat /etc/inetd.d/hello
# 自作サービス: 10013 番につながると /usr/local/bin/hello.sh を実行する
hello stream tcp nowait nobody /usr/sbin/tcpd /usr/local/bin/hello.sh
kazulog@sv1:~$ grep -n hello /etc/services
366:hello 10013/tcp # 検証用の自作サービス
kazulog@sv1:~$ cat /usr/local/bin/hello.sh
#!/bin/sh
echo "hello from inetd on $(hostname)"
kazulog@sv1:~$ sudo systemctl restart inetutils-inetd
kazulog@sv1:~$ sudo ss -tlnp 'sport = :10013'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 10 0.0.0.0:10013 0.0.0.0:* users:(("inetutils-inetd",pid=4189,fd=7)) kazulog@sv2:~$ timeout 5 nc 192.168.100.10 10013 < /dev/null
hello from inetd on sv1接続元を制限する(/etc/hosts.allow と /etc/hosts.deny)
tcpd を通したサービスは、/etc/hosts.allow と /etc/hosts.deny で接続元を制限できます。hosts.allow が先に評価され、そこで許可されたものは hosts.deny を見ません。
/etc/hosts.deny に ALL: ALL を書くと SSH も切れます。 OpenSSH 9.8 以降は接続ごとの処理を担う sshd-session が libwrap にリンクされているためです。先に /etc/hosts.allow へ sshd: ALL を入れてください。sudo vi /etc/hosts.allow
sudo vi /etc/hosts.deny# SSH は必ず許可する(締め出し防止)
sshd: ALL# 自作サービスは 192.168.100.20 からの接続を拒否する
hello.sh: 192.168.100.20書く名前はサービス名ではなく、起動するプログラムのファイル名です。 /etc/inetd.d/hello の server_path が /usr/local/bin/hello.sh なので hello.sh と書きます。tcpdmatch で確かめられます。
kazulog@sv1:~$ cat /etc/hosts.allow
# /etc/hosts.allow: list of hosts that are allowed to access the system.
# See the manual pages hosts_access(5) and hosts_options(5).
#
# Example: ALL: LOCAL @some_netgroup
# ALL: .foobar.edu EXCEPT terminalserver.foobar.edu
#
# If you're going to protect the portmapper use the name "rpcbind" for the
# daemon name. See rpcbind(8) and rpc.mountd(8) for further information.
#
# SSH は必ず許可する(締め出し防止)
sshd: ALL
kazulog@sv1:~$ cat /etc/hosts.deny
# /etc/hosts.deny: list of hosts that are _not_ allowed to access the system.
# See the manual pages hosts_access(5) and hosts_options(5).
#
# Example: ALL: some.host.name, .some.domain
# ALL EXCEPT in.fingerd: other.host.name, .other.domain
#
# If you're going to protect the portmapper use the name "rpcbind" for the
# daemon name. See rpcbind(8) and rpc.mountd(8) for further information.
#
# The PARANOID wildcard matches any host whose name does not match its
# address.
#
# You may wish to enable this to ensure any programs that don't
# validate looked up hostnames still leave understandable logs. In past
# versions of Debian this has been the default.
# ALL: PARANOID
# 自作サービスは 192.168.100.20 からの接続を拒否する
hello.sh: 192.168.100.20
kazulog@sv1:~$ tcpdmatch hello.sh 192.168.100.20
client: address 192.168.100.20
server: process hello.sh
access: denied拒否された側は、接続はできますが何も返りません。
kazulog@sv2:~$ timeout 5 nc 192.168.100.10 10013 < /dev/null; echo "nc rc=$?"
nc rc=0kazulog@sv1:~$ sudo journalctl --since "-5 min" --no-pager | grep -a "hello.sh" | tail -3
Sep 12 09:47:46 sv1 tcpdmatch[5059]: warning: hello.sh: no such process name in /etc/inetd.conf
Sep 12 09:48:11 sv1 tcpdmatch[5271]: warning: hello.sh: no such process name in /etc/inetd.conf
Sep 12 09:48:15 sv1 hello.sh[5575]: refused connect from 192.168.100.20 (192.168.100.20)systemd のソケット起動と比べる
同じこと(接続が来たときだけプログラムを起動する)は、inetd を使わずに systemd でもできます。 10014番で同じ hello.sh を起動する例です。
sudo vi /etc/systemd/system/hello-socket.socket
sudo vi /etc/systemd/system/hello-socket@.service
sudo systemctl daemon-reload
sudo systemctl enable --now hello-socket.socketkazulog@sv1:~$ ls -l /etc/systemd/system/hello-socket.socket /etc/systemd/system/hello-socket@.service
-rw-r--r-- 1 root root 125 Sep 12 09:48 /etc/systemd/system/hello-socket.socket
-rw-r--r-- 1 root root 127 Sep 12 09:48 /etc/systemd/system/hello-socket@.service
kazulog@sv1:~$ cat /etc/systemd/system/hello-socket.socket
[Unit]
Description=hello service socket (systemd)
[Socket]
ListenStream=10014
Accept=yes
[Install]
WantedBy=sockets.target
kazulog@sv1:~$ cat /etc/systemd/system/hello-socket@.service
[Unit]
Description=hello service (systemd socket activation)
[Service]
ExecStart=/usr/local/bin/hello.sh
StandardInput=socket
kazulog@sv1:~$ systemctl is-active hello-socket.socket
active
kazulog@sv1:~$ sudo ss -tlnp 'sport = :10014'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 *:10014 *:* users:(("systemd",pid=1,fd=79)) 待ち受けているのは systemd 自身(pid=1)です。hosts.deny で hello.sh を拒否したままでも、こちらは応答します。 systemd のソケット起動は tcpd を通らないためです。
kazulog@sv2:~$ timeout 5 nc 192.168.100.10 10014 < /dev/null; echo "nc rc=$?"
hello from inetd on sv1
nc rc=0| 項目 | inetd | systemd のソケット起動 |
|---|---|---|
| 待ち受けるもの | inetutils-inetd | systemd(pid=1) |
| 設定 | /etc/inetd.conf / /etc/inetd.d/ | .socket と .service のユニット |
| TCP Wrappers | server_path を tcpd にすれば効く | 通らない(別途 IPAddressDeny= などを使う) |
設定ファイルの最終状態
ここまでの設定が入った状態です。触ったファイルは6つです。
kazulog@sv1:~$ grep -vE '^(#|$)' /etc/inetd.conf
daytime stream tcp6 nowait root internal
kazulog@sv1:~$ ls -l /etc/inetd.d/
total 8
-rw-r--r-- 1 root root 90 Sep 12 09:47 echo
-rw-r--r-- 1 root root 160 Sep 12 09:47 hello
kazulog@sv1:~$ cat /etc/inetd.d/echo /etc/inetd.d/hello
# echo サービス(inetd の内蔵サービス)
echo stream tcp nowait root internal
# 自作サービス: 10013 番につながると /usr/local/bin/hello.sh を実行するkazulog@sv1:~$ cat /etc/hosts.allow
# /etc/hosts.allow: list of hosts that are allowed to access the system.
# See the manual pages hosts_access(5) and hosts_options(5).
#
# Example: ALL: LOCAL @some_netgroup
# ALL: .foobar.edu EXCEPT terminalserver.foobar.edu
#
# If you're going to protect the portmapper use the name "rpcbind" for the
# daemon name. See rpcbind(8) and rpc.mountd(8) for further information.
#
# SSH は必ず許可する(締め出し防止)
sshd: ALL
kazulog@sv1:~$ cat /etc/hosts.deny
# /etc/hosts.deny: list of hosts that are _not_ allowed to access the system.
# See the manual pages hosts_access(5) and hosts_options(5).
#
# Example: ALL: some.host.name, .some.domain
# ALL EXCEPT in.fingerd: other.host.name, .other.domain
#
# If you're going to protect the portmapper use the name "rpcbind" for the
# daemon name. See rpcbind(8) and rpc.mountd(8) for further information.
#
# The PARANOID wildcard matches any host whose name does not match its
# address.
#
# You may wish to enable this to ensure any programs that don't
# validate looked up hostnames still leave understandable logs. In past
# versions of Debian this has been the default.
# ALL: PARANOID
# 自作サービスは 192.168.100.20 からの接続を拒否する
hello.sh: 192.168.100.20
kazulog@sv1:~$ systemctl is-enabled inetutils-inetd; systemctl is-active inetutils-inetd
enabled
active
kazulog@sv1:~$ systemctl is-active hello-socket.socket
active
kazulog@sv1:~$ sudo ss -tlnp | grep -E ":(7|13|10013|10014) "
LISTEN 0 10 0.0.0.0:10013 0.0.0.0:* users:(("inetutils-inetd",pid=4189,fd=7))
LISTEN 0 10 0.0.0.0:7 0.0.0.0:* users:(("inetutils-inetd",pid=4189,fd=6))
LISTEN 0 4096 *:10014 *:* users:(("systemd",pid=1,fd=79))
LISTEN 0 10 *:13 *:* users:(("inetutils-inetd",pid=4189,fd=4)) | ファイル | 変更内容 |
|---|---|
/etc/inetd.conf | 19行目(daytime)の # を外す |
/etc/inetd.d/echo | 新規作成(内蔵サービス echo) |
/etc/inetd.d/hello | 新規作成(自作サービス、tcpd 経由) |
/usr/local/bin/hello.sh | 新規作成(自作サービスの中身) |
/etc/services | hello 10013/tcp を追記 |
/etc/hosts.allow / /etc/hosts.deny | sshd: ALL と hello.sh: 192.168.100.20 |
/etc/systemd/system/hello-socket.socket / hello-socket@.service | 新規作成(比較用) |
削除する
sudo apt purge -y inetutils-inetd/etc/inetd.d/ に自分で置いたファイルが残っていると、ディレクトリごと残ります(dpkg が警告を出します)。/etc/inetd.conf も残るので、不要なら手で削除してください。
kazulog@sv1:~$ sudo apt purge -y inetutils-inetd | cat
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Reading package lists...
Building dependency tree...
Reading state information...
Solving dependencies...
The following packages were automatically installed and are no longer required:
tcpd update-inetd
Use 'sudo apt autoremove' to remove them.
REMOVING:
inetutils-inetd*
Summary:
Upgrading: 0, Installing: 0, Removing: 1, Not Upgrading: 96
Freed space: 159 kB
(Reading database ... 91429 files and directories currently installed.)
Removing inetutils-inetd (2:2.7-2ubuntu1.1) ...
Processing triggers for man-db (2.13.1-1build1) ...
(Reading database ... 91420 files and directories currently installed.)
Purging configuration files for inetutils-inetd (2:2.7-2ubuntu1.1) ...
dpkg: warning: while removing inetutils-inetd, directory '/etc/inetd.d' not empty so not removed
kazulog@sv1:~$ dpkg -l | grep -E "inetd" | cat
ii update-inetd 4.54build1 all inetd configuration file updater
kazulog@sv1:~$ ls -l /etc/inetd.conf /etc/inetd.d 2>&1
-rw-r--r-- 1 root root 1061 Sep 12 09:46 /etc/inetd.conf
/etc/inetd.d:
total 8
-rw-r--r-- 1 root root 90 Sep 12 09:47 echo
-rw-r--r-- 1 root root 160 Sep 12 09:47 hello
kazulog@sv1:~$ sudo ss -tlnp | grep -E ":(7|13|10013) " ; echo "ss rc=$?"
ss rc=1検証環境と実行ログ
CML 上に Ubuntu 26.04 LTS Server 2台を置いて採取しました。ディスクを wipe した直後の状態から始めています(前の検証で入れたパッケージが残っていると手順が再現しないため)。
sv1 sv2
ens3 192.168.100.10/24 ens3 192.168.100.20/24
inetutils-inetd 7/13/10013 nc
systemd socket 10014
| |
+----------- LAB-SW ------------+| 手順 | sv1 | sv2 |
|---|---|---|
| 初期状態(wipe 直後) | show / conf / log | — |
| inetutils-inetd の導入 | show / conf / log | — |
| daytime の有効化 | show / conf / log | — |
| daytime への接続 | — | show / conf / log |
| echo の追加と接続 | show / conf / log | show / conf / log |
| 自作サービスの追加と接続 | show / conf / log | show / conf / log |
| 接続元の制限 | show / conf / log | show / conf / log |
| 拒否のログ | show / conf / log | — |
| systemd のソケット起動 | show / conf / log | show / conf / log |
| 設定ファイルの最終状態 | show / conf / log | — |
| 削除 | show / conf / log | — |
参考リンク
関連記事
- Ubuntu 26.04 LTS Server のホスト名の変更(hostnamectl)
- Ubuntu 26.04 LTS Server のパッケージ更新(apt update / upgrade)
- Ubuntu 26.04 LTS Server のタイムゾーン設定と時刻同期
- Ubuntu 26.04 LTS Server のユーザー作成と sudo 権限の設定
- Ubuntu 26.04 LTS Server の SSH サーバー設定(公開鍵認証)
- Ubuntu 26.04 LTS Server の telnet サーバー設定
- Ubuntu 26.04 LTS Server の inetd(スーパーサーバー)設定
- Ubuntu 26.04 LTS Server の TFTP サーバー設定(tftpd-hpa)
- Ubuntu 26.04 LTS Server の FTP サーバー設定(vsftpd)
- Ubuntu 26.04 LTS Server の syslog サーバー設定(rsyslog)
- Ubuntu 26.04 LTS Server のサービス管理(systemctl)とログ確認(journalctl)
- Ubuntu 26.04 LTS Server の自動更新設定(unattended-upgrades)
- Ubuntu 26.04 LTS Server の初期設定を自動化する(cloud-init)
- Ubuntu 26.04 LTS Server のカーネルパラメータ設定(sysctl)
- Ubuntu 26.04 LTS Server のネットワーク設定(Netplan)
- Ubuntu 26.04 LTS Server の名前解決設定(systemd-resolved)
- Ubuntu 26.04 LTS Server の NTP 同期先の変更(chrony)
- Ubuntu 26.04 LTS Server のスタティックルート設定(Netplan)
- neovim 公式サイトから最新バージョンをインストールする手順 Ubuntu 26.04 LTS Server