Hatena::ブログ(Diary)

TECHNERD::INIT このページをアンテナに追加

2009-02-17 ip6tables このエントリーを含むブックマーク

IPv6フィルタを行うときは以下のようなシェルを作って対応しています。

#!/bin/sh

# 全てのルールを削除
ip6tables -F
# 全てのユーザ定義チェインを削除
ip6tables -X

# 基本的には外部からのパケットの通過を拒否
ip6tables -P INPUT DROP
#ip6tables -P INPUT ACCEPT
# 基本的には外部へのパケットの通過を許可
ip6tables -P OUTPUT ACCEPT
# 基本的には他のインターフェイスへ再送信を拒否
ip6tables -P FORWARD DROP

# lo( ループバック)からのINPUTを許可
ip6tables -A INPUT -i lo -j ACCEPT

#RS,RA,NS,NAを受け入れる
ip6tables -A INPUT -i eth0 -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT
ip6tables -A INPUT -i eth0 -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT
ip6tables -A INPUT -i eth0 -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
ip6tables -A INPUT -i eth0 -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT

# 個々のアクセス制御を以下に記述
# HTTPアクセスを許可
ip6tables -A INPUT -i eth0 -p tcp -s 2001:1234:1234::/48 --dport 80 -j ACCEPT

# HTTPSアクセスを許可
ip6tables -A INPUT -i eth0 -p tcp -s 2001:1234:1234:1234::cafe/128 --dport 443 -j ACCEPT

# ip6tablesに保存する
ip6tables-save > /etc/sysconfig/ip6tables

このシェルを実行することでルールが適用されます。

# ip6tables -L

でルールを確認することができます。

2009-01-09

Shim6 (Site Multihoming by IPv6 Intermediation)

概要

  • 端末ベースのサイトマルチホーム技術といいながら実質ホストマルチホーム技術である
    • 端末に振られたアドレスを2種類に分類
      • Identifierアドレス
      • Locatorアドレス
        • ルーティングするための場所を示すアドレス
    • IPv6層の間にShim層を導入
      • Shim層の上からは、Identifierアドレスで通信しているように見える
      • Shim層の下からは、Locatorアドレスで通信しているように見える
    • 欠点
      • ホストベースマルチホームなので、TEは端末のアドレス選択に依存
        • →網側での制御が困難
 +----------------+
 | Application    |
 +----------------+
 |   TCP/UDP      |
 +--------+-------+
 |        |IPv6(2)| <- IP end-point sub-layer (IPsec,Fragment,Destination Option処理)
 |        +-------+ 
 |  IPv4  |  Shim | <- Locator/Identifier対応付け及びアドレス付け替え
 |        +-------+
 |        |IPv6(1)| <- IP routing sub-layer(NDP,IPv6パケット送受信処理)
 +--------+-------+
 |                |
 +----------------+

最近、あまり追っかけてなかったのですが、yebo blogしたそうですね。

関連リンク

Shim6 WG

2008-12-17

Wireshark(Ethereal)で独自パケットフォーマットを解析する方法

Luaプラグインを使うと、独自パケットフォーマットのパーサーを簡単に定義することができます。

Lua - The Wireshark Wiki

プラグインの有効化

Wiresharkのインストールディレクトリ → init.luaを編集

disable_lua = true; do return end;
をコメントアウト
-- disable_lua = true; do return end;
run_user_scripts_when_superuser = falseを
run_user_scripts_when_superuser = trueに

一番最下行に実行したいluaスクリプトを記述したファイルをWiresharkのインストールディレクトリに置き、dofileで指定する。

dofile("hoge.lua")

以下の例は、プロトコル名をTRIVIALとし、UDPの7777番にきたパケットをサブツリーで分解する例です。

hoge.lua

-- trivial protocol example
-- プロトコルの定義
trivial_proto = Proto("trivial","TRIVIAL","Trivial Protocol")
-- パース用の関数定義
function trivial_proto.dissector(buffer,pinfo,tree)
    pinfo.cols.protocol = "TRIVIAL"
    local subtree = tree:add(trivial_proto,buffer(),"Trivial Protocol Data")
    subtree:add(buffer(0,2),"The first two bytes: " .. buffer(0,2):uint())
    subtree = subtree:add(buffer(2,2),"The next two bytes")
    subtree:add(buffer(2,1),"The 3rd byte: " .. buffer(2,1):uint())
    subtree:add(buffer(3,1),"The 4th byte: " .. buffer(3,1):uint())
end
-- udp.portテーブルのロード
udp_table = DissectorTable.get("udp.port")
-- ポート7777番とプロトコルの紐付けをする
udp_table:add(7777,trivial_proto)

他にも本家にいくつかサンプルがあります。

Lua/Examples - The Wireshark Wiki

この中でも、下記のスクリプトは結構利用場面は多いのではないでしょうか。

  • 任意のポートを特定のプロトコルに結びつける
-- HTTPを 4888-4891番に割り当てる
do
        local tcp_port_table = DissectorTable.get("tcp.port")
        local http_dissector = tcp_port_table:get_dissector(80)
        for port in {4888,4889,4890,4891} do
                tcp_port_table:add(port,http_dissector)
        end
end
-- 10.0.0.0/8の通信のパケット数を計測する
do
    packets = 0;
    local function init_listener()
        local tap = Listener.new("frame","ip.addr == 10.0.0.0/8")
        function tap.reset()
            packets = 0;
        end
        function tap.packet(pinfo,tvb,ip)
            packets = packets + 1
        end
        function tap.draw()
            print("Packets to/from 10.0.0./8",packets)
        end
    end
    init_listener()
end

ヘッダ構造体メモ

Ethernetヘッダ(DIX規格)

  • linux/if_ehter.h
 struct ethhdr
 {
    unsigned char   h_dest[ETH_ALEN];   /* destination eth addr */
    unsigned char   h_source[ETH_ALEN]; /* source ether addr    */
    unsigned short  h_proto;        /* packet type ID field */
 };

IPv4ヘッダ

  • netinet/ip.h
 struct iphdr
   {
 #if __BYTE_ORDER == __LITTLE_ENDIAN
     unsigned int ihl:4;
     unsigned int version:4;
 #elif __BYTE_ORDER == __BIG_ENDIAN
     unsigned int version:4;
     unsigned int ihl:4;
 #else
 # error "Please fix <bits/endian.h>"
 #endif
     u_int8_t tos;
     u_int16_t tot_len;
     u_int16_t id;
     u_int16_t frag_off;
     u_int8_t ttl;
     u_int8_t protocol;
     u_int16_t check;
     u_int32_t saddr;
     u_int32_t daddr;
     /*The options start here. */
   };

IPv6ヘッダ

  • netinet/ip6.h
 struct ip6_hdr
  {
    union
      {
        struct ip6_hdrctl
          {
            uint32_t ip6_un1_flow;   /* 4 bits version, 8 bits TC, 20 bits flow-ID */
            uint16_t ip6_un1_plen;   /* payload length */
            uint8_t  ip6_un1_nxt;    /* next header */
            uint8_t  ip6_un1_hlim;   /* hop limit */
          } ip6_un1;
        uint8_t ip6_un2_vfc;       /* 4 bits version, top 4 bits tclass */
      } ip6_ctlun;
    struct in6_addr ip6_src;      /* source address */
    struct in6_addr ip6_dst;      /* destination address */
  };
 #define ip6_vfc   ip6_ctlun.ip6_un2_vfc
 #define ip6_flow  ip6_ctlun.ip6_un1.ip6_un1_flow
 #define ip6_plen  ip6_ctlun.ip6_un1.ip6_un1_plen
 #define ip6_nxt   ip6_ctlun.ip6_un1.ip6_un1_nxt
 #define ip6_hlim  ip6_ctlun.ip6_un1.ip6_un1_hlim
 #define ip6_hops  ip6_ctlun.ip6_un1.ip6_un1_hlim

ICMPヘッダ

  • netinet/ip_icmp.h
 struct icmp
 {
   u_int8_t  icmp_type;  /* type of message, see below */
   u_int8_t  icmp_code;  /* type sub code */
   u_int16_t icmp_cksum; /* ones complement checksum of struct */
   union
   {
     u_char ih_pptr;     /* ICMP_PARAMPROB */
     struct in_addr ih_gwaddr;   /* gateway address */
     struct ih_idseq     /* echo datagram */
     {
       u_int16_t icd_id;
       u_int16_t icd_seq;
     } ih_idseq;
     u_int32_t ih_void;

     /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
     struct ih_pmtu
     {
       u_int16_t ipm_void;
       u_int16_t ipm_nextmtu;
     } ih_pmtu;

     struct ih_rtradv
     {
       u_int8_t irt_num_addrs;
       u_int8_t irt_wpa;
       u_int16_t irt_lifetime;
     } ih_rtradv;
   } icmp_hun;
 #define icmp_pptr   icmp_hun.ih_pptr
 #define icmp_gwaddr icmp_hun.ih_gwaddr
 #define icmp_id     icmp_hun.ih_idseq.icd_id
 #define icmp_seq    icmp_hun.ih_idseq.icd_seq
 #define icmp_void   icmp_hun.ih_void
 #define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
 #define icmp_nextmtu    icmp_hun.ih_pmtu.ipm_nextmtu
 #define icmp_num_addrs  icmp_hun.ih_rtradv.irt_num_addrs
 #define icmp_wpa    icmp_hun.ih_rtradv.irt_wpa
 #define icmp_lifetime   icmp_hun.ih_rtradv.irt_lifetime
  union
  {
    struct
    {
      u_int32_t its_otime;
      u_int32_t its_rtime;
      u_int32_t its_ttime;
    } id_ts;
    struct    
    {
      struct ip idi_ip;
      /* options and then 64 bits of data */
    } id_ip;
    struct icmp_ra_addr id_radv;
    u_int32_t   id_mask;
    u_int8_t    id_data[1];
  } icmp_dun;
 #define icmp_otime  icmp_dun.id_ts.its_otime
 #define icmp_rtime  icmp_dun.id_ts.its_rtime
 #define icmp_ttime  icmp_dun.id_ts.its_ttime
 #define icmp_ip     icmp_dun.id_ip.idi_ip
 #define icmp_radv   icmp_dun.id_radv
 #define icmp_mask   icmp_dun.id_mask
 #define icmp_data   icmp_dun.id_data
 };

UDPヘッダ

  • netinet/udp.h
 struct udphdr {
         u_int16_t uh_sport;           /* source port */
         u_int16_t uh_dport;           /* destination port */
         u_int16_t uh_ulen;            /* udp length */
         u_int16_t uh_sum;             /* udp checksum */
 };
 struct udphdr {
    __u16   source;
    __u16   dest;
    __u16   len;
    __u16   check;
 };

TCPヘッダ

  • netinet/tcp.h
 struct tcphdr
   {
    u_int16_t source;
    u_int16_t dest;
    u_int32_t seq;
    u_int32_t ack_seq;
 #  if __BYTE_ORDER == __LITTLE_ENDIAN
    u_int16_t res1:4;
    u_int16_t doff:4;
    u_int16_t fin:1;
    u_int16_t syn:1;
    u_int16_t rst:1;
    u_int16_t psh:1;
    u_int16_t ack:1;
    u_int16_t urg:1;
    u_int16_t res2:2;
 #  elif __BYTE_ORDER == __BIG_ENDIAN
    u_int16_t doff:4;
    u_int16_t res1:4;
    u_int16_t res2:2;
    u_int16_t urg:1;
    u_int16_t ack:1;
    u_int16_t psh:1;
    u_int16_t rst:1;
    u_int16_t syn:1;
    u_int16_t fin:1;
 #  else
 #   error "Adjust your <bits/endian.h> defines"
 #  endif
    u_int16_t window;
    u_int16_t check;
    u_int16_t urg_ptr;
 };

上位層プロトコルタイプ

IPヘッダ上位層プロトコルタイプ(linux/in.h)

 /* Standard well-defined IP protocols.  */
 enum {
  IPPROTO_IP = 0,       /* Dummy protocol for TCP       */
  IPPROTO_ICMP = 1,     /* Internet Control Message Protocol    */
  IPPROTO_IGMP = 2,     /* Internet Group Management Protocol   */
  IPPROTO_IPIP = 4,     /* IPIP tunnels (older KA9Q tunnels use 94) */
  IPPROTO_TCP = 6,      /* Transmission Control Protocol    */
  IPPROTO_EGP = 8,      /* Exterior Gateway Protocol        */
  IPPROTO_PUP = 12,     /* PUP protocol             */
  IPPROTO_UDP = 17,     /* User Datagram Protocol       */
  IPPROTO_IDP = 22,     /* XNS IDP protocol         */
  IPPROTO_RSVP = 46,        /* RSVP protocol            */
  IPPROTO_GRE = 47,     /* Cisco GRE tunnels (rfc 1701,1702)    */
  IPPROTO_IPV6   = 41,      /* IPv6-in-IPv4 tunnelling      */
  IPPROTO_PIM    = 103,     /* Protocol Independent Multicast   */
  IPPROTO_ESP = 50,            /* Encapsulation Security Payload protocol */
  IPPROTO_AH = 51,             /* Authentication Header protocol       */
  IPPROTO_COMP   = 108,                /* Compression Header protocol */
  IPPROTO_RAW    = 255,     /* Raw IP packets           */
  IPPROTO_MAX
 };

Ethernetヘッダ上位層プロトコルタイプ(linux/if_ehter.h)

 /*
  *  These are the defined Ethernet Protocol ID's.
  */
 #define ETH_P_LOOP  0x0060      /* Ethernet Loopback packet */
 #define ETH_P_PUP   0x0200      /* Xerox PUP packet     */
 #define ETH_P_PUPAT 0x0201      /* Xerox PUP Addr Trans packet  */
 #define ETH_P_IP    0x0800      /* Internet Protocol packet */
 #define ETH_P_X25   0x0805      /* CCITT X.25           */
 #define ETH_P_ARP   0x0806      /* Address Resolution packet    */
 #define ETH_P_BPQ   0x08FF      /* G8BPQ AX.25 Ethernet Packet  [ NOT AN OFFICIALLY REGISTERED ID ] */
 #define ETH_P_IEEEPUP   0x0a00      /* Xerox IEEE802.3 PUP packet */
 #define ETH_P_IEEEPUPAT 0x0a01      /* Xerox IEEE802.3 PUP Addr Trans packet */
 #define ETH_P_DEC       0x6000          /* DEC Assigned proto           */
 #define ETH_P_DNA_DL    0x6001          /* DEC DNA Dump/Load            */
 #define ETH_P_DNA_RC    0x6002          /* DEC DNA Remote Console       */
 #define ETH_P_DNA_RT    0x6003          /* DEC DNA Routing              */
 #define ETH_P_LAT       0x6004          /* DEC LAT                      */
 #define ETH_P_DIAG      0x6005          /* DEC Diagnostics              */
 #define ETH_P_CUST      0x6006          /* DEC Customer use             */
 #define ETH_P_SCA       0x6007          /* DEC Systems Comms Arch       */
 #define ETH_P_RARP      0x8035      /* Reverse Addr Res packet  */
 #define ETH_P_ATALK 0x809B      /* Appletalk DDP        */
 #define ETH_P_AARP  0x80F3      /* Appletalk AARP       */
 #define ETH_P_IPX   0x8137      /* IPX over DIX         */
 #define ETH_P_IPV6  0x86DD      /* IPv6 over bluebook       */
 #define ETH_P_PPP_DISC  0x8863      /* PPPoE discovery messages     */
 #define ETH_P_PPP_SES   0x8864      /* PPPoE session messages   */
 #define ETH_P_ATMMPOA   0x884c      /* MultiProtocol Over ATM   */
 #define ETH_P_ATMFATE   0x8884      /* Frame-based ATM Transport over Ethernet */

2008-03-06

Tcpdump解析スクリプト

とりあえず、簡単なものを。

単純に-xで出力される右列のアスキーをつらつらと表示するだけ。

  • 使い方
# tcpdump port ほげほげ -ieth0  -s 1500 -x  | ./myfilter.pl
  • myfilter.pl
#!/usr/bin/perl

while(<STDIN>){
    if(m/^[ \t]/){
        #print "Line: $_\n";
        @data = (split);
        print "@data[9]";
    } else {
        print "\n\n";
        print "### $_\n";
    }
}

2008-02-21

SCTP(Stream Control Transmission Protocol)

  • 次世代TCPプロトコル
  • 3つの転送方式を持つ
    • Strict orderd mode(RFC2960)
      • TCPと同様に厳密な順序制御を行う
    • Unorderd mode
      • UDPのように順序制御を行わない
    • Partial orderd mode
      • SCTP Partial Reliability Extension (RFC 3758)
    • 一部分のみ順序制御

SCTPのユーザランド実装

http://www.sctp.jp/index.php/ja/Stream%20Control%20Transmission%20Protocol(SCTP)/sctplib