Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
nftables: the Next Generation Firewall in Linux
Search
Tomofumi Hayashi
June 06, 2015
0
97
nftables: the Next Generation Firewall in Linux
Presented in Kernel/VM tankentai vol.11, June 6, 2015.
Tomofumi Hayashi
June 06, 2015
Tweet
Share
More Decks by Tomofumi Hayashi
See All by Tomofumi Hayashi
CNIふぉーびぎなーず
s1061123
0
21
4 rhtn tohayash-multus
s1061123
0
26
Opnfv primer how to get into opnfv
s1061123
0
7
コンテナのネットワークインターフェース その実装手法とその応用について
s1061123
0
38
Opnfv handson apex intro
s1061123
0
10
OpenStack Summit Boston DMA Appendix
s1061123
0
6
Software forwarding path
s1061123
0
13
OPNFV Meetup Tokyo #1 / Projects Summary
s1061123
0
10
ocamllec01-100605110859-phpapp01.pdf
s1061123
0
9
Featured
See All Featured
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
228
22k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2.1k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
29
9.5k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
47
2.8k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.5k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
For a Future-Friendly Web
brad_frost
179
9.8k
Java REST API Framework Comparison - PWX 2021
mraible
31
8.6k
How STYLIGHT went responsive
nonsquared
100
5.6k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
16
910
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
32
5.9k
Transcript
nftables: The Next Generation Firewall in Linux Tomofumi Hayashi @s1061123
第11回 カーネル/VM探検隊
Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 •
nftablesの書き方 • 宣伝 • まとめ
Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 •
nftablesの書き方 • 宣伝 • まとめ
自己紹介 なまえ: はやしともふみ twitter: @s1061123 カーネル/VM勉強会歴: 5年ぶり2度目の出場
とりあえず Notice: • この発表は個人の見解、また調査結果に基づくものであり、 所属する組織、nftables開発チームの公式見解ではありませ ん • 幾つかの技術的資料についてはその出展をなるべく明記し ています •
nftablesを開発しているチームの方に感謝致します
http://s1061123.net/nft/
お詫び
None
None
?!
None
None
お詫び • LinuxConとネタが被りましたww – 気付いたのは発表申し込みした後です… • タイトルは意図的にダブらせました
お詫び • LinuxConとネタが被りましたww – 気付いたのは発表申し込みした後です… • タイトルは意図的にダブらせました
Fiirewall ?!
None
お詫び • LinuxConとネタが被りましたww – 気付いたのは発表申し込みした後です… • タイトルは意図的にダブらせました • LinuxCon怖いところ…っ! –
こわいのでLinuxConには参加していません – 内容がLinuxConとダブっていたら申し訳ありません – ↑の内容知ってる人いらっしゃいましたら後で教えて下さい • 知らないなりにカーネル/VMらしい発表をする方向で
そんなふうに考えていた時期が… 俺にもありました…
?! LinuxCon前日のタイムテーブル
?!
お詫び • LinuxConとネタが被りましたwwせんでした – 気付いたのは2日前です… • タイトルは意図的にダブらせました • LinuxCon怖いところ…っ! –
こわいのでLinuxConには参加していません – 内容がLinuxConとダブっていたら申し訳ありません – ↑の内容知ってる人いらっしゃいましたら後で教えて下さい • 知らないなりにカーネル/VMらしい発表をする方向で
Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 •
nftablesの書き方 • 宣伝 • まとめ
nftablesってなに? http://netfilter.org/projects/nftables/ • nftablesとは{ip,ip6,arp,eb}tables関係のtoolを新たに 置き換えるプロジェクト • {ip,ip6,arp,eb}tables 同様にnetfilterを使っている
netfilter, iptables and nftables? • netfilter – Linux にあるパケット書き換えのフレームワーク –
NAT, NAPT, IP MASQUERADE等を実装 – conntrackもnetfilterの機能 • iptables, ip6tables, ebtables and arptables – netfilterを使って実装したパケットフィルタリング コマンド – ‘-m udp’のように必要な機能がコマンド・カーネルで拡張されている – fedora‘s ’firewalld‘ も実際呼んでるのはこのコマンド • nftables <- これ! – パケットフィルタリングコマンド – iptables等と同様にnetfilterを使用している
netfilter, iptables and nftables? • netfilter – Linux にあるパケット書き換えのフレームワーク –
NAT, NAPT, IP MASQUERADE等を実装 – conntrackもnetfilterの機能 • iptables, ip6tables, ebtables and arptables – netfilterを使って実装したパケットフィルタリング コマンド – ‘-m udp’のように必要な機能がコマンド・カーネルで拡張されている – fedora‘s ’firewalld‘ も実際呼んでるのはこのコマンド • nftables <- これ! – パケットフィルタリングコマンド – iptables等と同様にnetfilterを使用している
netfilter, iptables and nftables? 30秒で分かるnetfilter: netfilterはLinux内でネットワークのパケットを書き換えることが できます。以下のようにどこで呼ぶかを指定できるようにhookが 存在します In include/uapi/linux/netfilter.h:
enum nf_inet_hooks { NF_INET_PRE_ROUTING, NF_INET_LOCAL_IN, NF_INET_FORWARD, NF_INET_LOCAL_OUT, NF_INET_POST_ROUTING, NF_INET_NUMHOOKS };
netfilter, iptables and nftables? なので、hookを指定して自分の関数を登録すれば以下のような カーネルがパケットを処理するタイミングでその関数が呼ばれ ることになります net/ipv4/ip_forward.c: int ip_forward(struct
sk_buff *skb) { u32 mtu; struct iphdr *iph; /* Our header */ struct rtable *rt; /* Route we use */ struct ip_options *opt = &(IPCB(skb)->opt); (snip) return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, skb, skb->dev, rt->dst.dev, ip_forward_finish); sr_failed: (snip) } SKB!!
netfilter, iptables and nftables? • netfilter – Linux にあるパケット書き換えのフレームワーク –
NAT, NAPT, IP MASQUERADE等を実装 – conntrackもnetfilterの機能 • iptables, ip6tables, ebtables and arptables – netfilterを使って実装したパケットフィルタリング コマンド – ‘-m udp’のように必要な機能がコマンド・カーネルで拡張されている – fedora‘s ’firewalld‘ も実際呼んでるのはこのコマンド • nftables <- これ! – パケットフィルタリングコマンド – iptables等と同様にnetfilterを使用している
{ip,ip6,arp,eb}tables? iptablesはLinuxでパケットをフィルタしたり、NATなどで パケットを書き換えたりすることができるソフトです Linuxでホームルータを作る際には(ほぼ)必須 iptablesは以下のもので構成されています – iptablesコマンド – カーネル側の(netfilterを呼ぶ)iptables用コード
{ip,ip6,arp,eb}tables? 各種通信プロトコル・ネットワーク機能毎に以下のコマ ンドが存在します • IPv4: iptables • IPv6: ip6tables •
ARP: arptables (ロードバランサ・LVS/Linux Virtual Server等で使用) • Bridge: ebtables (カーネルのBridge内で処理)
netfilter, iptables and nftables? • netfilter – Linux にあるパケット書き換えのフレームワーク –
NAT, NAPT, IP MASQUERADE等を実装 – conntrackもnetfilterの機能 • iptables, ip6tables, ebtables and arptables – netfilterを使って実装したパケットフィルタリング コマンド – ‘-m udp’のように必要な機能がコマンド・カーネルで拡張されている – fedora‘s ’firewalld‘ も実際呼んでるのはこのコマンド • nftables <- 今日はこれ! – パケットフィルタリングコマンド – iptables等と同様にnetfilterを使用している
nftables? なんでnftables? • 技術的負債の解消 • パフォーマンス向上
nftables? iptablesが持つ技術的負債 • iptablesが産まれたのは1999年11月 – http://www.netfilter.org/about.html#history – 16年経過! • Extension
Modulesの増加 – 現在70個以上のModuleが存在 – それぞれカーネル側・ユーザランド側に存在 • プロトコル毎に別コマンド – 似たようなコードが各種コマンドに存在 • そもそもシンタックス・ルールが複雑化
nftables? iptablesが持つパフォーマンス問題 • そもそもルールセット追加・削除がAtomic! • ルールの更新の際はそのルールを全部ユーザランドにコピー して処理 • ルールが増えればそれだけ処理が重くなる… from
http://www.slideshare.net/ennael/2013-kernel-recipesnftables
nftables! 技術的負債の解消やパフォーマンス向上を目的にして 開発 • 2008年にPatrick McHardy氏が開発 • 2010年に一回開発が止まったものの • 2012年にPablo
Neira Ayuso氏がiptables互換レイヤー を開発 • 2014年1月にカーネルメインライン(3.13)にマージ済
Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 •
nftablesの書き方 • 宣伝 • まとめ
nftablesの使い方 • カーネルにNF_TABLES(と好きなOPTION)を付けてビルド • ユーザ側のコマンドをビルド (Gentooならばnet- firewall/nftables をemerge) • iptablesを使っている場合はiptablesを止める
(モジュールのビルド・ロードだけならば大丈夫) • `service nftables start`等でサービスを開始 • `nft`コマンドでルールの追加・削除が可能 – `nft –f <filename>`でファイルからの読み込み – `nft –i`でインタラクティブモード nft_test ~ $ nft -i nft> list tables table nat table filter nft>
nftablesのシンタックス % sudo iptables -t filter -S -P INPUT ACCEPT
-P FORWARD ACCEPT -P OUTPUT ACCEPT -N ssh_whitelist -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 --tcp-flags FIN,SYN,RST,ACK SYN –j ssh_whitelist // (略) -A ssh_whitelist -s 192.168.0.0/16 -j ACCEPT -A ssh_whitelist -s 10.0.0.0/8 -j ACCEPT -A ssh_whitelist -j DROP nftables: # nft list table ip filter table ip filter { chain input { type filter hook input priority 0; } chain forward { type filter hook forward priority 0; iif eth0 oif != eth0 jump miniupnpd drop } chain output { type filter hook output priority 0; } chain miniupnpd { iif eth0 ip daddr 192.168.1.10 tcp dport ssh accept } } iptables:
nftablesのシンタックス 詳細はwebで!
nftablesのシンタックス 詳細はwebで!
nftablesのシンタックス 詳細はwebで!
nftablesのフロー nftで入力されたコマンドは以下のパスを通って カーネルに送られます from https://www.netdev01.org/docs/nftables-rmll-2014.pdf
nftablesのフロー libnftnl/examples/nft-rule-get でルールを見ると…
nftablesのフロー libnftnl/examples/nft-rule-get でルールを見ると… ip saddr 192.168.1.0/24 oif eth0 snat 10.0.0.1
=> ip nat postrouting 7 6 [ payload load 4b @ network header + 12 => reg 1 ] [ bitwise reg 1 = (reg=1 & 0x00ffffff ) ^ 0x00000000 ] [ cmp eq reg 1 0x0001a8c0 ] [ meta load oif => reg 1 ] [ cmp eq reg 1 0x00000004 ] [ immediate reg 1 0x100000a ] [ nat snat ip addr_min reg 1 addr_max reg 1 ]
nftablesのフロー nftで入力されたコマンドは以下のパスを通って カーネルに送られます from https://www.netdev01.org/docs/nftables-rmll-2014.pdf コンパイル?
nftablesのフロー nftで入力されたコマンドは以下のパスを通って カーネルに送られます from https://www.netdev01.org/docs/nftables-rmll-2014.pdf コンパイル?
nftables (internal) カーネル内のnftablesのフィルタリング実装はpseudo- state machineとして実装されています • bpf (Berkeley Packet Filter)
からインスパイア (*1原文ママ) – 4 registers – 1 verdict (e.g. 'accept', 'drop', 'jump' or so ...) – A extensive instruction set reject, meta, masq, bitwise, byteorder, cmp, counter, ct (conntrack), exthdr, immediate, limit, log, lookup, nat, payload, queue (順不同、適当に検索) *1 http://www.slideshare.net/ennael/2013-kernel-recipesnftables
nftables (internal) カーネル内のnftablesのフィルタリング実装はpseudo- state machineとして実装されています = カーネル内のVM → カーネル/VM!! •
bpf (Berkeley Packet Filter) からインスパイア (*1原文ママ) – 4 registers – 1 verdict (e.g. 'accept', 'drop', 'jump' or so ...) – A extensive instruction set reject, meta, masq, bitwise, byteorder, cmp, counter, ct (conntrack), exthdr, immediate, limit, log, lookup, nat, payload, queue (順不同、適当に検索) *1 http://www.slideshare.net/ennael/2013-kernel-recipesnftables
Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 •
nftablesの書き方 • 宣伝 • まとめ
Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの内部のVMコードの読み方 •
nftablesの書き方 • 宣伝 • まとめ
nftablesの読み方 libnftnl/examples/nft-rule-get ip saddr 192.168.1.0/24 oif eth0 snat 10.0.0.1 =>
ip nat postrouting 7 6 [ payload load 4b @ network header + 12 => reg 1 ] [ bitwise reg 1 = (reg=1 & 0x00ffffff ) ^ 0x00000000 ] [ cmp eq reg 1 0x0001a8c0 ] [ meta load oif => reg 1 ] [ cmp eq reg 1 0x00000004 ] [ immediate reg 1 0x100000a ] [ nat snat ip addr_min reg 1 addr_max reg 1 ]
nftablesの読み方 libnftnl/examples/nft-rule-get ip saddr 192.168.1.0/24 oif eth0 snat 10.0.0.1 =>
ip nat postrouting 7 6 // 7:handle, 6:position [ payload load 4b @ network header + 12 => reg 1 ] ネットワークヘッダの12byte (saddr)から4byteロードしてreg1に [ bitwise reg 1 = (reg=1 & 0x00ffffff ) ^ 0x00000000 ] reg1を0x00ffffffでマスクして0でxorをreg1に [ cmp eq reg 1 0x0001a8c0 ] reg1 が 0x0001a8c0と比較(0x0001a8c0 => 192.168.1.0) もしマッチしないならばここでリターン [ meta load oif => reg 1 ] [ cmp eq reg 1 0x00000004 ] [ immediate reg 1 0x100000a ] [ nat snat ip addr_min reg 1 addr_max reg 1 ] ip saddr 192.168.1.0/24
nftablesの読み方 libnftnl/examples/nft-rule-get ip saddr 192.168.1.0/24 oif eth0 snat 10.0.0.1 =>
ip nat postrouting 7 6 [ payload load 4b @ network header + 12 => reg 1 ] [ bitwise reg 1 = (reg=1 & 0x00ffffff ) ^ 0x00000000 ] [ cmp eq reg 1 0x0001a8c0 ] [ meta load oif => reg 1 ] oifのifindex値をreg1に [ cmp eq reg 1 0x00000004 ] reg1と0x4を比較 [ immediate reg 1 0x100000a ] [ nat snat ip addr_min reg 1 addr_max reg 1 ] oif eth0
nftablesの読み方 libnftnl/examples/nft-rule-get ip saddr 192.168.1.0/24 oif eth0 snat 10.0.0.1 =>
ip nat postrouting 7 6 [ payload load 4b @ network header + 12 => reg 1 ] [ bitwise reg 1 = (reg=1 & 0x00ffffff ) ^ 0x00000000 ] [ cmp eq reg 1 0x0001a8c0 ] [ meta load oif => reg 1 ] [ cmp eq reg 1 0x00000004 ] [ immediate reg 1 0x100000a ] reg1に0x100000aを代入 (0x100000a = 10.0.0.1) [ nat snat ip addr_min reg 1 addr_max reg 1 ] snatを行なう (sourceはreg1に入っている値) snat 10.0.0.1
nftablesの読み方 libnftnl/examples/nft-rule-get ip saddr 192.168.1.0/24 oif eth0 snat 10.0.0.1 =>
ip nat postrouting 7 6 [ payload load 4b @ network header + 12 => reg 1 ] [ bitwise reg 1 = (reg=1 & 0x00ffffff ) ^ 0x00000000 ] [ cmp eq reg 1 0x0001a8c0 ] [ meta load oif => reg 1 ] [ cmp eq reg 1 0x00000004 ] [ immediate reg 1 0x100000a ] [ nat snat ip addr_min reg 1 addr_max reg 1 ]
nftablesの読み方 libnftnl/examples/nft-rule-get ip saddr 192.168.1.0/24 oif eth0 snat 10.0.0.1 =>
ip nat postrouting 7 6 [ payload load 4b @ network header + 12 => reg 1 ] [ bitwise reg 1 = (reg=1 & 0x00ffffff ) ^ 0x00000000 ] [ cmp eq reg 1 0x0001a8c0 ] [ meta load oif => reg 1 ] [ cmp eq reg 1 0x00000004 ] [ immediate reg 1 0x100000a ] [ nat snat ip addr_min reg 1 addr_max reg 1 ] ね、簡単でしょ?
Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 •
nftablesの書き方 • 宣伝 • まとめ
Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 •
nftablesの内部のVMコードの書き方 • 宣伝 • まとめ
nftablesにルールを書きたい! libnftnlを使うことでnftablesのルールを追加・削除することが可 能です • libnftnl/examples/* と libnftnl/tests/* を参考にすれば、ほら この通り! e
= nft_rule_expr_alloc("nat"); nft_rule_expr_set_u32(e, NFT_EXPR_NAT_TYPE, NFT_NAT_SNAT); nft_rule_expr_set_u32(e, NFT_EXPR_NAT_FAMILY, AF_INET); nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MIN, NFT_REG_1); nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MAX, NFT_REG_1); nft_rule_add_expr(r, e); [ immediate reg 1 0x100000a ] [ nat snat ip addr_min reg 1 addr_max reg 1 ] =>
nftablesにルールを書きたい! libnftnlを使うことでnftablesのルールを追加・削除することが可 能です • libnftnl/examples/* と libnftnl/tests/* を参考にすれば、ほら この通り! e
= nft_rule_expr_alloc("nat"); nft_rule_expr_set_u32(e, NFT_EXPR_NAT_TYPE, NFT_NAT_SNAT); nft_rule_expr_set_u32(e, NFT_EXPR_NAT_FAMILY, AF_INET); nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MIN, NFT_REG_1); nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MAX, NFT_REG_1); nft_rule_add_expr(r, e); [ immediate reg 1 0x100000a ] [ nat snat ip addr_min reg 1 addr_max reg 1 ] =>
nftablesにルールを書きたい! nl = mnl_socket_open(NETLINK_NETFILTER); if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0)
{ perror("mnl_socket_bind"); return -1; } } batch = mnl_nlmsg_batch_start(buf, sizeof(buf)); nft_mnl_batch_put(mnl_nlmsg_batch_current(batch), NFNL_MSG_BATCH_BEGIN, seq++); mnl_nlmsg_batch_next(batch); nlh = nft_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch), cmd, nft_rule_attr_get_u32(rule, NFT_RULE_ATTR_FAMILY), NLM_F_APPEND|NLM_F_CREATE|NLM_F_ACK, seq++); nft_rule_nlmsg_build_payload(nlh, rule); nft_rule_free(rule); mnl_nlmsg_batch_next(batch); nft_mnl_batch_put(mnl_nlmsg_batch_current(batch), NFNL_MSG_BATCH_END, seq++); mnl_nlmsg_batch_next(batch); ret = mnl_socket_sendto(nl, mnl_nlmsg_batch_head(batch), mnl_nlmsg_batch_size(batch)); mnl_nlmsg_batch_stop(batch); ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); ret = mnl_cb_run(buf, ret, 0, mnl_socket_get_portid(nl), NULL, NULL); Netlink (libnml等)でカーネルに送信!!!
nftablesにルールを書きたい! nl = mnl_socket_open(NETLINK_NETFILTER); if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0)
{ perror("mnl_socket_bind"); return -1; } } batch = mnl_nlmsg_batch_start(buf, sizeof(buf)); nft_mnl_batch_put(mnl_nlmsg_batch_current(batch), NFNL_MSG_BATCH_BEGIN, seq++); mnl_nlmsg_batch_next(batch); nlh = nft_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch), cmd, nft_rule_attr_get_u32(rule, NFT_RULE_ATTR_FAMILY), NLM_F_APPEND|NLM_F_CREATE|NLM_F_ACK, seq++); nft_rule_nlmsg_build_payload(nlh, rule); nft_rule_free(rule); mnl_nlmsg_batch_next(batch); nft_mnl_batch_put(mnl_nlmsg_batch_current(batch), NFNL_MSG_BATCH_END, seq++); mnl_nlmsg_batch_next(batch); ret = mnl_socket_sendto(nl, mnl_nlmsg_batch_head(batch), mnl_nlmsg_batch_size(batch)); mnl_nlmsg_batch_stop(batch); ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); ret = mnl_cb_run(buf, ret, 0, mnl_socket_get_portid(nl), NULL, NULL); ほら、 簡単でしょ? Netlink (libnml等)でカーネルに送信!!!
Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 •
nftablesの書き方 • 宣伝 • まとめ
宣伝 MiniUPnPがnftablesをサポートすることになりました – MiniUPnPはNATの内側からforwardingの穴を簡単に開け ることができるNAT向けの機能IGDの実装です – 先月からgithubのcurrentのコードに入っています => 「UPnPが無いから…」と思う人も安心!!
まとめ さぁ、みんなもnftablesで人柱になろう!!
None