私はTCPポート/ソケットをリッスンして接続を受け入れる単純なPerlサーバーを作成しました。今私は知りたいです:
アドレスベースのアクセス制御を実装する場合は、接続を受け入れる前に接続を要求するピアのアドレスを確認できますか?
可能であれば、接続を受け入れてすぐに再度閉じるのではなく、接続要求を拒否できます(希望)。
答え1
カーネルによって TCP/IP 接続が確立され、その接続を使用してアプリケーションが開始されます。
不要な接続をフィルタリング/ブロックする唯一の方法は、カーネルファイアウォールを使用することです。オペレーティングシステムを指定していませんが、Linuxではiptables / nftablesになります。
答え2
実際には答えではありませんが、いくつかのコメントが長すぎます。
MacOS Xでは、次のようにman accept
言います。
msg_iovlen が 0 で msg_controllen が 0 でない状態で recvmsg(2) 呼び出しを実行すると、接続を確認せずにユーザー接続要求データを取得できます。、または getsockopt(2) 要求を発行することによって。同様に、制御情報のみを提供するsendmsg(2)呼び出しを実行するか、setockopt(2)を呼び出してユーザー接続拒否情報を提供できます。
(強調は私のもの)
man recvmsg
ただし、このトピックの詳細は見つかりません。man getsockopt
man tcp
Debian はman accept
こう述べています:
ソケットからの着信接続に関する通知を受け取るには、select(2)、poll(2)、または epoll(7) を使用します。新しい接続が試行されると、読み取り可能なイベントが送出され、次にaccept()を呼び出してその接続のソケットを取得できます。または、ソケットでアクティビティが発生したときにSIGIOを転送するようにソケットを設定できます。詳しくは Sockets(7) をご覧ください。
IMHO、そこにはそれしかない可能より多くの情報を提供できれば幸いですepoll
。
しかし、実際に情報を得ることができるとしても、気に入らなければ接続をどのように拒否するのかわかりません。
ネットワークスタック/ファイアウォールレベル(iptablesと友達)でフィルタリングすることをお勧めします。
答え3
私はPerlの専門知識があると主張しません。しかし、それが可能かどうか疑問です。サーバーへのアクセスを制御するために、優先順位に基づいて以下を制限します。
- インターフェイス/バインドアドレス別
- カーネルファイアウォール(iptables、nftables、eBPF)経由
- TCPラッパーまたはホスト構成を介して
現在、ホスト構成による調整機能がないことを考慮すると、それを開始点として選択することは確かに異例のようです。
上記の 1 と 2 が次のようになっているとします。いいえ1つのオプションは、PerlコードでTCPラッパーを使用することをお勧めします。これにより、柔軟で標準的で強力なネットワークアクセス制御メカニズムを活用しながら、最小限のコード変更で起動して実行できます。また、見ることができますhttps://metacpan.org/pod/Net::TCPwrappers
実行時にLD_LIBRARY_PATHを調整して(つまり、コードを変更せずに)tcpラッパーを適用することも可能だと思いますが、クイックGoogle検索ではこれへの参照が見つかりません。
答え4
転送制御プロトコルはアクセス制御には使用されません。
TLSを確認することをお勧めしますhttps://en.m.wikipedia.org/wiki/Transport_Layer_Security
また、netfilterファイアウォール入力フックを見てください。不要なピアを削除して拒否できます。