iptablesで -j LOG でsyslogに出力した時のそれぞれのフィールドについてわからないことが多かったので調べました。
どこにも詳しい説明がなかったので、最終的にLinuxのカーネルソースで確認しました。
kernel versionは、2.6.34.13 で確認しています。
→net/ipv4/netfilter/ipt_LOG.c で生成しています。
今回は –log-ip-options , –log-tcp-options をつけたものについては省略してます。
(ソース見れば書いてあるのでわかるだろうってことで)
Oct 30 12:34:56 hoge kernel: [xxxxx.xxxxx] IPTLOG_FW : IN=eth1 OUT=eth0 MAC=aa:bb:cc:dd:ee:ff:11:22:33:44:55:66:08:00 SRC=192.168.201.1 DST=172.16.101.30 LEN=118 TOS=0x00 PREC=0x00 TTL=254 ID=3120 DF PROTO=TCP SPT=3300 DPT=80 WINDOW=1460 RES=0x00 ACK PSH URGP=0
4つのパートにわかれています。
一番目
Oct 30 12:34:56 hoge kernel: [xxxxx.xxxxx] IPTLOG_FW :
syslogの先頭領域(共通)。
‘IPTLOG_FW’ の部分は、iptablesの引数 –log-prefix で指定できます。
二番目
IN=eth1 OUT=eth0 MAC=aa:bb:cc:dd:ee:ff:11:22:33:44:55:66:08:00
MACレイヤ(L2)。
MACアドレスは先頭6octetがethポート(つまり、宛先の)MACアドレス、次の6octetが送信元MACアドレス、次の2octetはイーサネットタイプです。IPの場合0800になります(RFC1340のpage 53「ETHERNET NUMBERS OF INTEREST」に記載あり)。
この値は、skb_mac_header ( ) が返したものをそのまま出しています。
include/linux/skbuff.h
#ifdef NET_SKBUFF_DATA_USES_OFFSET typedef unsigned int sk_buff_data_t; #else typedef unsigned char *sk_buff_data_t; #endif struct sk_buff { /* 中略 */ sk_buff_data_t mac_header; /* 中略 */ unsigned char *head, } static inline unsigned char *skb_mac_header(const struct sk_buff *skb) { return skb->head + skb->mac_header; }
参考:連載:詳説 TCP/IPプロトコル 第7回 イーサネット(その2) イーサネットのフレーム構造 — 3.イーサネットのフレーム・フォーマット
三番目
SRC=192.168.201.1 DST=172.16.101.30 LEN=118 TOS=0x00 PREC=0x00 TTL=254 ID=3120 DF PROTO=TCP
IPレイヤ(L3)。
IPについては詳しくはRFC791を参照されたし。
- SRC : ソースIPアドレス
- DST : デスティネーションIPアドレス
- LEN : IPパケット長
- TOS : IPヘッダ TOSフィールドの値
- PREC : IPヘッダ TOSフィールド内、PRECEDENCEの値
- TTL : IPヘッダ TTLの値
- ID : IPヘッダ IDの値
- DF : IPヘッダ Flag の DFビット(Don’t Fragment)が立っている場合
- PROTO : プロトコル(TCP,UDPなど)
該当ソースは下記のようになっております。(後半、省略してます)
/* Important fields: * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */ /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */ printk("SRC=%pI4 DST=%pI4 ", &ih->saddr, &ih->daddr); /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */ printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ", ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK, ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id)); /* Max length: 6 "CE DF MF " */ if (ntohs(ih->frag_off) & IP_CE) printk("CE "); if (ntohs(ih->frag_off) & IP_DF) printk("DF "); if (ntohs(ih->frag_off) & IP_MF) printk("MF ");
四番目
SPT=3300 DPT=80 WINDOW=1460 RES=0x00 ACK PSH URGP=0
TCPレイヤ(L4)。
TCPについては詳しくはRFC793を参照されたし。
- SPT : ソースポート番号
- DPT : デスティネーションポート番号
- WINDOW : TCP Window
- RES : Reservedの値
- ACK , PSH , RST , SYN . FIN : Control Bitsのそれぞれに対応
- URGP : Urgent Pointerの値
該当箇所のソースは下記の通りになってます。(一部省略)
/* Max length: 20 "SPT=65535 DPT=65535 " */ printk("SPT=%u DPT=%u ", ntohs(th->source), ntohs(th->dest)); /* 中略 */ /* Max length: 13 "WINDOW=65535 " */ printk("WINDOW=%u ", ntohs(th->window)); /* Max length: 9 "RES=0x3F " */ printk("RES=0x%02x ", (u8)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */ if (th->cwr) printk("CWR "); if (th->ece) printk("ECE "); if (th->urg) printk("URG "); if (th->ack) printk("ACK "); if (th->psh) printk("PSH "); if (th->rst) printk("RST "); if (th->syn) printk("SYN "); if (th->fin) printk("FIN "); /* Max length: 11 "URGP=65535 " */ printk("URGP=%u ", ntohs(th->urg_ptr));