2007年7月31日火曜日

rp_filter って?

linux ネットワークセキュリティのことはじめ。みたいなページに /proc/sys/net/conf/eth#/rpfilter は 1 にしましょう。らしき事が書かれており、盲目的にそーゆーモン。と信じていたが LSRR 試し始めてふと気になった。

本来ならば net/ipv4/fib_frontend.c の fib_validate_source() をフムフムと読みたいところなのだが... Understanding Linux Network Internals の力を借りる始末。曰く入ってきたデバイスの経路を調べて、そのデバイスを経由した到達の可否を判断 --- Reverse Path Filter --- ということらしい。淋しい自身の経路を示すと
# ip route ls
172.27.202.0/24 via 172.27.129.1 dev eth0 proto zebra metric 20
172.27.200.0/24 via 172.27.129.1 dev eth0 proto zebra metric 20
172.27.140.0/24 dev tap0 proto kernel scope link src 172.27.140.1
172.27.102.0/24 via 172.27.129.1 dev eth0 proto zebra metric 20
172.27.129.0/24 dev eth0 proto kernel scope link src 172.27.129.2
172.27.130.0/24 dev vmnet1 proto kernel scope link src 172.27.130.1
172.27.100.0/24 via 172.27.129.1 dev eth0 proto zebra metric 20
172.27.131.0/24 via 172.27.130.254 dev vmnet1 proto zebra
172.27.1.0/24 via 172.27.129.1 dev eth0 proto zebra metric 20
default via 172.27.129.1 dev eth0
となっている場合において vmnet1 は 172.27.130.0/24 と 172.27.131.0/24 のみ。よって、これら以外のソースアドレスを持ったパケットが vmnet1 に入ってきた場合は落とすよ。というお話。

名前から推測するという情けなさだが、先の fib_validate_source() を一瞥すると rpfilter エントリは
  rpf = IN_DEV_RPFILTER(in_dev);
さらにinclude/linux/inetdevice.h を眺めて
#define IN_DEV_ANDCONF(in_dev, attr) \
(IPV4_DEVCONF_ALL(attr) && IN_DEV_CONF_GET((in_dev), attr))
....
#define IN_DEV_RPFILTER(in_dev) IN_DEV_ANDCONF((in_dev), RP_FILTER)
となっているので vmnet1 というデバイスの場合であれば /proc/sys/net/ipv4/conf/all/rpfilter と /proc/sys/net/ipv4/conf/vmnet1/rpfilter 両方が 1 となっている場合のみ有効...らしい。FIB 周りっていつになったら理解できるんだろう。

2007年7月12日木曜日

lguest for 2.6.22

コンパイルでエラーになってしまったので、2.6.21 の頃のものと比較。
--- arch/i386/kernel/asm-offsets.c.orig 2007-07-12 00:06:33.000000000 +0900
+++ arch/i386/kernel/asm-offsets.c 2007-07-12 00:17:51.000000000 +0900
@@ -16,6 +16,10 @@
#include <asm/processor.h>
#include <asm/thread_info.h>
#include <asm/elf.h>
+#ifdef CONFIG_LGUEST_GUEST
+#include <linux/lguest.h>
+#include "../../../drivers/lguest/lg.h"
+#endif

#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -115,4 +119,17 @@
OFFSET(PARAVIRT_iret, paravirt_ops, iret);
OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0);
#endif
+#ifdef CONFIG_LGUEST_GUEST
+ BLANK();
+ OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled);
+ OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc);
+ OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc);
+ OFFSET(LGUEST_PAGES_host_cr3, lguest_pages, state.host_cr3);
+ OFFSET(LGUEST_PAGES_host_sp, lguest_pages, state.host_sp);
+ OFFSET(LGUEST_PAGES_guest_gdt_desc, lguest_pages,state.guest_gdt_desc);
+ OFFSET(LGUEST_PAGES_guest_idt_desc, lguest_pages,state.guest_idt_desc);
+ OFFSET(LGUEST_PAGES_guest_gdt, lguest_pages, state.guest_gdt);
+ OFFSET(LGUEST_PAGES_regs_trapnum, lguest_pages, regs.trapnum);
+ OFFSET(LGUEST_PAGES_regs_errcode, lguest_pages, regs.errcode);
+ OFFSET(LGUEST_PAGES_regs, lguest_pages, regs);
+#endif
}
とりあえず通るは通った。

2007年7月11日水曜日

LSRR の受信

ちょっと情けないが、ちょっと jot。興味があちこちしてしまいデジャヴばかりの様な気がする。
ip_rcv()
NF_IP_PREROUTING
ip_rcv_finish()
ip_rcv_options() ヘッダ長 20バイト超ならばオプションあり
ip_rcv_options_compile() sk_buff 内 cb に設定
ip_opeions_rcv_srr()
ip_route_input()
ip_route_input()
dst_input()

ip_forward()
NF_IP_FORWARD
ip_forward_finish()
ip_forward_options()
dst_output()
ip_output()
ip_fragment()

skb->pkt_type は eth_type_trans() にて設定
rt->rt_type の設定は....
ip_route_input()
ip_route_input_slow()
ip_mkroute_input()
(ip_mkroute_input_def())
__mkroute_input()
rt_set_nexthop()
output側も同じ感じ。
ip_local_deliver() は ip_route_input_slow() にて rth->u.dst.input に

ip_local_deliver()
NF_IP_LOCAL_IN
ip_local_deliver_finish()

先日の見難い図を簡単にすると
hostA ---- host B ---- host C
にて
  1. host B から host A , hostB を通って hostC
  2. hostC から hostB, hostA 再度 hostB に戻って hostC
といった lsrr を投げと、1.の場合は hostB。2.の場合は hostC の PREROUTING で -j LOG は取れるものの INPUT にはログが残らず、もちろん到達せず。両方の場合で IP上は src dst 共に自アドレスとなっている。/proc の accept_source_route を 1。rp_filter を 0。netfilter の全ての hook のポリシを ACCEPT としたが、通さず。2. にて hostB を通過している点、1. 2. にて PREROUTING に LOG が残っているので、ip_rcv_finish() あたりなのか...調べること。

2007年7月10日火曜日

conntrackd の internal と external キャッシュ

ソースをつらつらと眺めていたところ、少し理解できた。
internal
カーネルから (netlink 経由で) 受け取った内容を展開。なので master 側の話

external
マスタから (マルチキャストで) 受け取った内容を展開。なので slave 側の話。VRRP でマスタが落ちたと判断した場合、この内容を (netlink 経由で) カーネルに通知。通知を受けたカーネルは netlink で通知。で巡り巡って旧 slave 現 master となった internal に展開される。
じゃ internal って意味ないじゃん。と思ったのだが、これは master と slave のやりとり --- プロトコル --- の問題らしい。

sync モードと nack モードなるものがあり、現在 nack モードを推奨。internal を参照しているのは sync モードのみらしく、しかも ENOBUFS の時のみ。nack モードの場合どんなやりとりか調べること。でも、まだ実際に稼働させたことなし.... virtualize 何にしようか。

2007年7月9日月曜日

いろいろ。

元気がないので、記事引用などなど
OLS 2日目:カーネル開発、ファイルシステムについての講演。タイトルとは無関係っぽいが
 Anton Blanchard氏によって手短にデモが行なわれたPower6プロセッサには、4.7GHzのコアが16基搭載されていた。Blanchard氏がデモを印象付けるために、Linuxカーネルを10回コンパイルするベンチマークツールを使用してデモを行なったところ、たったの20秒で完了した。
あーはっはっはっはっはっはぁ....

Lguest ソッコーで 2.6.22 のパッチが出ていた
Releases

The good news is: lguest is all one big kernel patch, including the launcher. You can download the latest patch for 2.6.22.
やっぱ買うなら x86 かぁ。

TCPの輻輳制御について。2.6.22 のもの全てではないが TCP and Linux' Pluggable Congestion Control Algorithmsなくなってくれるな。まだ読んでいない。また末尾のリンクも良さげ。

2007年7月3日火曜日

conntrack と LSRR

ソースルーティング (ポリシのではない) を試すべく

~~~~~~~~~~~~~~~ +-----------+ +---------+ +---------+
{ The Internet} ----+ firewall+----+ host 1 +----+ host 2 |
~~~~~~~~~~~~~~~ +-----------+ +---------+ +---------+
<-----------------<
>-------------------------------->

みたいな構成で試したところ... firewall から出ない。accept_source_route は 0 なのに何故? ふと思い HOWTO 見た一般過程向き? のルールの抜粋
 
-A block -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A block -i ! eth0 -m conntrack --ctstate NEW -j ACCEPT
-A block -j DROP
DROP の前に LOG を入れてみると見事 dmesg に表示。う〜んと悩むこと小一時間。結果は state に INVALID を入れてあげれば通った。iptables (8) から抜粋すると
Possible states are INVALID meaning that the packet is associated with no known connection,
lsrr 面倒見ないよ、知らん。って事らしい。
で、こちらも中途....