Slide 1

Slide 1 text

nftables: The Next Generation Firewall in Linux Tomofumi Hayashi @s1061123 第11回 カーネル/VM探検隊

Slide 2

Slide 2 text

Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 • nftablesの書き方 • 宣伝 • まとめ

Slide 3

Slide 3 text

Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 • nftablesの書き方 • 宣伝 • まとめ

Slide 4

Slide 4 text

自己紹介 なまえ: はやしともふみ twitter: @s1061123 カーネル/VM勉強会歴: 5年ぶり2度目の出場

Slide 5

Slide 5 text

とりあえず Notice: • この発表は個人の見解、また調査結果に基づくものであり、 所属する組織、nftables開発チームの公式見解ではありませ ん • 幾つかの技術的資料についてはその出展をなるべく明記し ています • nftablesを開発しているチームの方に感謝致します

Slide 6

Slide 6 text

http://s1061123.net/nft/

Slide 7

Slide 7 text

お詫び

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

?!

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

お詫び • LinuxConとネタが被りましたww – 気付いたのは発表申し込みした後です… • タイトルは意図的にダブらせました

Slide 14

Slide 14 text

お詫び • LinuxConとネタが被りましたww – 気付いたのは発表申し込みした後です… • タイトルは意図的にダブらせました

Slide 15

Slide 15 text

Fiirewall ?!

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

お詫び • LinuxConとネタが被りましたww – 気付いたのは発表申し込みした後です… • タイトルは意図的にダブらせました • LinuxCon怖いところ…っ! – こわいのでLinuxConには参加していません – 内容がLinuxConとダブっていたら申し訳ありません – ↑の内容知ってる人いらっしゃいましたら後で教えて下さい • 知らないなりにカーネル/VMらしい発表をする方向で

Slide 18

Slide 18 text

そんなふうに考えていた時期が… 俺にもありました…

Slide 19

Slide 19 text

?! LinuxCon前日のタイムテーブル

Slide 20

Slide 20 text

?!

Slide 21

Slide 21 text

お詫び • LinuxConとネタが被りましたwwせんでした – 気付いたのは2日前です… • タイトルは意図的にダブらせました • LinuxCon怖いところ…っ! – こわいのでLinuxConには参加していません – 内容がLinuxConとダブっていたら申し訳ありません – ↑の内容知ってる人いらっしゃいましたら後で教えて下さい • 知らないなりにカーネル/VMらしい発表をする方向で

Slide 22

Slide 22 text

Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 • nftablesの書き方 • 宣伝 • まとめ

Slide 23

Slide 23 text

nftablesってなに? http://netfilter.org/projects/nftables/ • nftablesとは{ip,ip6,arp,eb}tables関係のtoolを新たに 置き換えるプロジェクト • {ip,ip6,arp,eb}tables 同様にnetfilterを使っている

Slide 24

Slide 24 text

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を使用している

Slide 25

Slide 25 text

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を使用している

Slide 26

Slide 26 text

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 };

Slide 27

Slide 27 text

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!!

Slide 28

Slide 28 text

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を使用している

Slide 29

Slide 29 text

{ip,ip6,arp,eb}tables? iptablesはLinuxでパケットをフィルタしたり、NATなどで パケットを書き換えたりすることができるソフトです Linuxでホームルータを作る際には(ほぼ)必須 iptablesは以下のもので構成されています – iptablesコマンド – カーネル側の(netfilterを呼ぶ)iptables用コード

Slide 30

Slide 30 text

{ip,ip6,arp,eb}tables? 各種通信プロトコル・ネットワーク機能毎に以下のコマ ンドが存在します • IPv4: iptables • IPv6: ip6tables • ARP: arptables (ロードバランサ・LVS/Linux Virtual Server等で使用) • Bridge: ebtables (カーネルのBridge内で処理)

Slide 31

Slide 31 text

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を使用している

Slide 32

Slide 32 text

nftables? なんでnftables? • 技術的負債の解消 • パフォーマンス向上

Slide 33

Slide 33 text

nftables? iptablesが持つ技術的負債 • iptablesが産まれたのは1999年11月 – http://www.netfilter.org/about.html#history – 16年経過! • Extension Modulesの増加 – 現在70個以上のModuleが存在 – それぞれカーネル側・ユーザランド側に存在 • プロトコル毎に別コマンド – 似たようなコードが各種コマンドに存在 • そもそもシンタックス・ルールが複雑化

Slide 34

Slide 34 text

nftables? iptablesが持つパフォーマンス問題 • そもそもルールセット追加・削除がAtomic! • ルールの更新の際はそのルールを全部ユーザランドにコピー して処理 • ルールが増えればそれだけ処理が重くなる… from http://www.slideshare.net/ennael/2013-kernel-recipesnftables

Slide 35

Slide 35 text

nftables! 技術的負債の解消やパフォーマンス向上を目的にして 開発 • 2008年にPatrick McHardy氏が開発 • 2010年に一回開発が止まったものの • 2012年にPablo Neira Ayuso氏がiptables互換レイヤー を開発 • 2014年1月にカーネルメインライン(3.13)にマージ済

Slide 36

Slide 36 text

Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 • nftablesの書き方 • 宣伝 • まとめ

Slide 37

Slide 37 text

nftablesの使い方 • カーネルにNF_TABLES(と好きなOPTION)を付けてビルド • ユーザ側のコマンドをビルド (Gentooならばnet- firewall/nftables をemerge) • iptablesを使っている場合はiptablesを止める (モジュールのビルド・ロードだけならば大丈夫) • `service nftables start`等でサービスを開始 • `nft`コマンドでルールの追加・削除が可能 – `nft –f `でファイルからの読み込み – `nft –i`でインタラクティブモード nft_test ~ $ nft -i nft> list tables table nat table filter nft>

Slide 38

Slide 38 text

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:

Slide 39

Slide 39 text

nftablesのシンタックス 詳細はwebで!

Slide 40

Slide 40 text

nftablesのシンタックス 詳細はwebで!

Slide 41

Slide 41 text

nftablesのシンタックス 詳細はwebで!

Slide 42

Slide 42 text

nftablesのフロー nftで入力されたコマンドは以下のパスを通って カーネルに送られます from https://www.netdev01.org/docs/nftables-rmll-2014.pdf

Slide 43

Slide 43 text

nftablesのフロー libnftnl/examples/nft-rule-get でルールを見ると…

Slide 44

Slide 44 text

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 ]

Slide 45

Slide 45 text

nftablesのフロー nftで入力されたコマンドは以下のパスを通って カーネルに送られます from https://www.netdev01.org/docs/nftables-rmll-2014.pdf コンパイル?

Slide 46

Slide 46 text

nftablesのフロー nftで入力されたコマンドは以下のパスを通って カーネルに送られます from https://www.netdev01.org/docs/nftables-rmll-2014.pdf コンパイル?

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 • nftablesの書き方 • 宣伝 • まとめ

Slide 50

Slide 50 text

Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの内部のVMコードの読み方 • nftablesの書き方 • 宣伝 • まとめ

Slide 51

Slide 51 text

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 ]

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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 ]

Slide 56

Slide 56 text

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 ] ね、簡単でしょ?

Slide 57

Slide 57 text

Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 • nftablesの書き方 • 宣伝 • まとめ

Slide 58

Slide 58 text

Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 • nftablesの内部のVMコードの書き方 • 宣伝 • まとめ

Slide 59

Slide 59 text

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 ] =>

Slide 60

Slide 60 text

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 ] =>

Slide 61

Slide 61 text

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等)でカーネルに送信!!!

Slide 62

Slide 62 text

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等)でカーネルに送信!!!

Slide 63

Slide 63 text

Agenda • 自己紹介 • nftablesについて • nftablesの使い方 • nftablesの読み方 • nftablesの書き方 • 宣伝 • まとめ

Slide 64

Slide 64 text

宣伝 MiniUPnPがnftablesをサポートすることになりました – MiniUPnPはNATの内側からforwardingの穴を簡単に開け ることができるNAT向けの機能IGDの実装です – 先月からgithubのcurrentのコードに入っています => 「UPnPが無いから…」と思う人も安心!!

Slide 65

Slide 65 text

まとめ さぁ、みんなもnftablesで人柱になろう!!

Slide 66

Slide 66 text

No content