inetd 経由で起動されても peeraddr は取得可能
TCP/IPとアプリ層を組み合わせたアクセス制御が出来ない
例:http の名前バーチャルでIPアクセス制限
の意味がよくわからない。HTTP/1.1 のバーチャルホストって、
GET /index.html HTTP/1.1 Host: example.com
の Host: example.com をみて挙動を切り換えるだけなので TCP/IP 関係ないですよね。というか inetd 経由で起動されたプログラムも peeraddr わかりますよね。
元の資料は環境が UNIX としか書いていませんが、以下は全て
% uname -srm FreeBSD 6.2-RELEASE-p2 i386
上でやりました。
/etc/inetd.conf を編集
test_inetd stream tcp nowait root /path/to/in.inetd_test test_inetd
/etc/services を編集
test_inetd 12345/tcp # TEST
/etc/rc.conf を編集
inetd_enable="YES"
inetd 起動
# /etc/rc.d/inetd start
port 12345 が listen になっていることを確認する
% sockstat | grep 12345 root inetd 5087 5 tcp4 *:12345 *:* % netstat -anf inet | grep 12345 tcp4 0 0 *.12345 *.* LISTEN
in.inetd_test を作る
#!/usr/bin/perl use strict; use warnings; use IO::Socket; # get peeraddr my $peername = getpeername(STDIN); if ($peername) { my( $peerport, $peeraddr ) = sockaddr_in($peername); my $ip_address = inet_ntoa($peeraddr); printf "Hello %s %s\n", $ip_address, $peerport; } else { print "no peername\n"; }
このスクリプトを普通に起動すると peername は取得できませんが、
% perl in.inetd_test no peername
inetd 経由で接続すると
% telnet localhost 12345 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Hello 127.0.0.1 51445 Connection closed by foreign host.
と、接続元はわかる。念のため他のホスト(Linux)から接続してみたけど、
% telnet 192.168.1.xxx 12345 Trying 192.168.1.xxx... Connected to xxx. Escape character is '^]'. Hello 192.168.1.6 53199 Connection closed by foreign host.
接続元はわかる。ウノウの人が「inetd 経由だと接続元IPアドレスがわからない」と言っているのだとしたら、そんなことはないんじゃないかと。元資料が大雑把にしか書いてないので僕の指摘が的外れかもしれませんけどね。そうだったらすみません。
ところで Perl で inetd 起動のスクリプト書くと STDIN から入力を読み取って, STDOUT に出力すれば良いだけなんだけど、実は STDERR も inetd を通してネットワークストリームに出力されるので use warnings; する人は注意が必要です。