最近、私はGoのルールに触れることにiptables
気づきました。桟橋労働者そしてコアラッパーライブラリはコマンドexec()
として出力iptables
し、画面は標準出力を取得します。私はこれが私を驚かせた。
Pythonの世界ではPython iptables:
iptablesバイナリを呼び出して出力を解析する代わりに、iptables Cライブラリ(libiptc、libxtables、iptables拡張)を使用してiptablesとの相互運用性を実現します。
私の考えでは、PythonライブラリがCライブラリを実行時にロードできるようにするようですが、Goは[編集:私は間違っています]。しかし、Goはこれらのライブラリに静的にリンクできませんか? Goライブラリはlibxtables.a
どこかから得るべきであるのでか。 (Debianで関連パッケージを探していますが、dpkg -L
sだけです。)-dev
.so
とにかく、Webフィルタのよくある質問:
4.5ルールを追加/削除するためのC / C ++ APIはありますか?
残念ながら、答えは「いいえ」です。
今、「しかしlibiptcはどうですか?」と思うかもしれません。メーリングリストで何度も指摘したように、libiptcはいいえパブリックインターフェイスとして使用するためのものです。私たちは信頼性の高いインターフェイスを保証せず、次のバージョンのLinuxパケットからそれらを削除する予定です。
我々はこれらのAPIに根本的な欠陥があることに精通しており、状況を改善するために一生懸命努力しています。それまでは、system()を使用するか、iptables-restoreの標準入力でパイプを開くことをお勧めします。後者はより良いパフォーマンスフィルタリングを提供します。 libiptcは合理的に使用するには低すぎるレベルです。
まあ、おそらくこれらのCライブラリを安定しているとは思わないでしょう。それから「自分で話すのはどうですか?」と思いました。ほとんどの場合、カーネルとの会話には使用されず(単にテーブル名を読み取るために?)、メインインタフェースは実際にはバインドされていないソケットにある/proc
ことがわかりました。iptables
/proc
getsockopt()
setsockopt()
これはもう一つの驚きです! (しかし、おそらく私はこの種のコードに慣れていないので、カーネルと対話する興味深い方法のようです。)
iptables
私はからまでipchains
考古学をして、ipfw
次のことを見つけました。1997年のipfwのマニュアルページこれで気分が良くなります。
BUGS
The setsockopt(2) interface is a crock. This should be
put under /proc/sys/net/ipv4 and the world would be a bet-
ter place.
他の場所では、「ipfwユーティリティはFreeBSD 2.0に初めて提供されます」を見つけることができます。
HISTORY
Initially this utility was written for BSDI by:
Daniel Boulet <[email protected]>
The FreeBSD version is written completely by:
Ugen J.S.Antsilevich <[email protected]>
while synopsis partially compatible with old one.
ipfw
これは1994年のFreeBSD 2.0バージョンです。。まだ使用されていますが、代わりにsetsockopt()
使用されているようです。kvm_read()
getsockopt()
私の質問
- 上記の内容が間違っている場合は訂正してください:)
{get,set}sockopt()
なぜ彼らは最初にそれを選んだのですか?これは珍しいものですか、それとも私にとって新しいものですか?- なぜどの時点で変わらなかったのですか?
/proc
1997のマニュアルページで提案されているのと同じです。 - なぜ彼らは信頼性の高い/パブリックCインタフェースを思い出せなかったのですか
iptables
?
私のフォローアップの質問
「正確ではありません。デフォルトのインターフェイスは、netlinkのNETLINK_NETFILTERファミリです。」
このヒントを提供していただきありがとうございます!
私が見ています。https://git.netfilter.org/iptables/treeそして、libipq
何か欠けていない場合は、netlinkソケットだけが使用されているようです。
$ ick "socket\("
include/libiptc/libiptc.h
158:int iptc_get_raw_socket(void);
include/libiptc/libip6tc.h
152:int ip6tc_get_raw_socket(void);
utils/nfsynproxy.c
129: fd = socket(AF_INET, SOCK_STREAM, 0);
libiptc/libiptc.c
1312: sockfd = socket(TC_AF, SOCK_RAW, IPPROTO_RAW);
extensions/libxt_set.h
14: int res, sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
libipq/libipq.c
223: h->fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_FIREWALL);
225: h->fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_IP6_FW);
libxtables/xtables.c
881: sockfd = socket(afinfo->family, SOCK_RAW, IPPROTO_RAW);
このlibipq
内容は私にとって「正常」と思われます。ソケットを作成し、sockaddrなどでsendto()
バインドします。recvfrom()
ネットワークリンク操作を実行するために使用されるラッパーxtables-monitor
もあるようです。mnl_socket_*
しかし、私はそれを理解することはできませんlibiptc
。xtables
netlinkへの言及はなく、ソケットをバインドすることもありません。
https://git.netfilter.org/iptables/tree/libxtables/xtables.c#n881
https://git.netfilter.org/iptables/tree/libiptc/libiptc.c#n1312
mozilla rrデバッガの次のコードのように、netlinkを使用しない(見えますか?)他の例もあります。https://github.com/mozilla/rr/blob/master/src/test/netfilter.c
2000年(2.2)現在、netlinkは{get,set}sockopt()
(少なくとも)ipfw
古いBSD領域であるLinuxでのみ利用可能です。
bind()
もはや私の問題が何であるかよくわかりません:) netlinkではなくソケットがどのようにsockaddrなしで正しいカーネル側と通信するのですか?
答え1
私の考えでは、Pythonライブラリは実行時にCライブラリをロードできますが、Goはそうではありません。
行くできる共有Cライブラリを使用してください。
iptables
ほとんどの場合、カーネルとの通信には使用されず(/proc
テーブル名のみを読みますか?)、デフォルトのインタフェースは実際にはgetsockopt()
ですsetsockopt()
。
{get,set}sockopt()
なぜ彼らは最初にそれを選んだのですか?これは珍しいものですか、それとも私にとって新しいものですか?
(この回答は、以前はデフォルトのインターフェイスが次のようになっていると誤って指定しました。netlink
家族NETLINK_NETFILTER
。 )
あなたは正しいです。適切なタイプのバインドされていないソケットへの呼び出しをiptables
使用してgetsockopt
カーネルと対話し、最終的にカーネルnetfilter
コード。私はこれが歴史的な理由だと思います...
ただし、バインド解除を含むさまざまな状態のソケットで作業getsockopt
し、setsockopt
接続する前にオプションを設定するために使用されるため、これを行う必要があります。 -via-netfilter
接続はsockopt
実際にはサブチャネルです。
なぜどの時点で変わらなかったのですか?
/proc
1997のマニュアルページで提案されているのと同じです。
いくつかの理由があるかもしれませんが、その1つは間違いなく以前のバージョンとの互換性です。 Linuxでは、ユーザースペースのインターフェースが絶対に破損してはいけません。これにより、新しいインターフェイスを提供できますが、既存のインターフェイスはそのまま残り、インターフェイスを改善したり、すでに実行されているプログラムを再構築したりするインセンティブを減らします。
コマンドラインツールを少ない労力で使用でき、より良いインターフェースを提供するためには、より多くの労力が必要な限りiptables
変更は困難です。適切に維持されたlibiptc
スタイルライブラリも可能でしたが、開発者はiptables
そうする動機があまりありませんでした。
なぜ彼らは信頼性の高い/パブリックCインタフェースを思い出せなかったのですか
iptables
?
なぜなら、彼らは問題を解決しなかったからです。今iptables
段階的に廃止nftables
、これには、さまざまな抽象化レベルでアクセスを提供する複数のライブラリ(libnftables
、、、libnftnl
)が含まれています。カーネルとユーザー空間の間で情報を転送するためのソケットベースのインターフェースとして設計されており、libnfnetlink
(および)などのツールに最適です。ドキュメントには他の利用可能なスイートがリストされており、これにはかなりのカーネルホスティング機能が含まれています。 。netlink
nftables
iptables
netlink
netlink
あなたは見つけることができますhttps://github.com/vishvananda/netlinkiptables
Goで運転するときに便利です。 (これは多くの作業が必要ですが、最初から始めるよりも優れています。)