PF_KEY Key Management API, Version 3 o version 2 の問題点 - 複数のSAを同じSGW間にはるための情報が不足している。 例えば、以下の A-B間, A'-B'間に別々のSAを張りたい場合 A B \ / SG1 === SG2 / \ A' B' 具体的にはport,protocolや、パケットの送信先を特定する情報が足りない。 See RFC2367 5.2 Proxy IP Security Example - SADB_ACQUIREにsecurity protocol modeがない。IKEでは交換する パラメータに modeを必要とするので、SADB_ACQUIREからmodeを 牽くメカニズムが必要。 - SADB_ACQUIREでは SA bundleを表現できない。一方、IKEは SA bundle毎に 鍵交換するので、SADB_ACQUIREからbundleを牽く仕組みが必要。 - SADB_EXPIREにsadb_identに相当する情報がないので、SADB_ACQUIREの時に 使ったポリシを正確に導き出すことができないので、 過去に交換した SAに対するポリシを覚えておかなればならない。 - SADB_ACQUIREはポリシが元になり発生するが、SADB_EXPIREは交換したSAが 元になり発生する。つまり、SAの候補がいくつかある場合にSADB_ACQUIREの 時は選択できるがSADB_EXPIREの時には選択できない。 - KINKは、既に設定されたSAのSPI以外のパラメータを置き換える機能を 要求している。PF_KEYv2にはその機能がない。 - SPDを操作する機能に関して、各実装独自拡張ヘッダを定義している。 o version 3 ポリシの構造と切り離されて定義されているので独自拡張が生じた。 特にSAのパラメータの一部やバンドルの情報を持つセキュリティポリシを 特定するために各実装独自拡張している。 PF_KEYv3はセキュリティポリシを特定するインデックスをメッセージに含める。 カーネルはバージョン番号に従い適切な挙動をしなければならない。 もしバージョン3以外をサポートしないならば、EPROTONOSUPPORT を返す。 SADB_FLUSH, SADB_DUMP は SADB_DELETE, SADB_GETの特殊な場合に置き換える。 拡張メッセージに関しては PF_KEYv2と同様 _X_ を付ける。 PF_KEYv3では2つの拡張メッセージを定義する。 SADB_EXPIREについて、ACQUIREを代用してはどうか? 構造は同じだが本質的に別のメッセージである。 acquire はパケット driven expire は sa の lifetime driven 1回も使われなかった sa が消える時 expire 上げない。 sadb_prop っている?ポリシは別に持つべきでは? => ポリシに記述されているはずなので必要ないだろう。 SAバンドルはどう扱うのか? => ポリシに記述されているはず。 PF_KEYv2を流用するか?新しく定義するか? 例えばIPCOMP等の定義はどうあつかうか? => 新しく定義する。 が v2,v3両方喋るアプリケーションのために名前は変える SADB3_xxx o Base Message Header Format struct sadb3_msg { uint8_t sadb3_msg_version; uint8_t sadb3_msg_type; uint8_t sadb3_msg_errno; uint8_t sadb3_msg_satype; uint16_t sadb3_msg_len; uint16_t sadb3_msg_reserved; uint32_t sadb3_msg_seq; uint32_t sadb3_msg_pid; }; /* sizeof(struct sadb3_msg) == 16 */ sadb3_msg_version PF_KEY_V3 sadb3_msg_satype currently the following types are defined. SADB3_SATYPE_UNSPEC SADB3_SATYPE_AH SADB3_SATYPE_ESP SADB3_SATYPE_IPCOMP o Additional Message Fields struct sadb3_ext { uint16_t sadb3_ext_len; uint16_t sadb3_ext_type; }; + Association Extension struct sadb3_sa { uint16_t sadb3_sa_len; uint16_t sadb3_sa_exttype; uint32_t sadb3_sa_spi; uint8_t sadb3_sa_replay; uint8_t sadb3_sa_state; uint8_t sadb3_sa_auth; uint8_t sadb3_sa_encrypt; uint32_t sadb3_sa_flags; }; sadb3_sa_exttype SADB_EXT_SA sadb3_sa_state SADB_SASTATE_LARVAL SADB_SASTATE_MATURE SADB_SASTATE_DYING SADB_SASTATE_DEAD sadb3_sa_auth SADB_AALG_MD5HMAC SADB_AALG_SHA1HMAC SADB_AALG_SHA2_256 SADB_AALG_SHA2_384 SADB_AALG_SHA2_512 SADB_AALG_MD5 SADB_AALG_SHA SADB_AALG_NULL sadb3_sa_encrypt SADB_EALG_DESCBC SADB_EALG_3DESCBC SADB_EALG_NULL SADB_EALG_CAST128CBC SADB_EALG_BLOWFISHCBC SADB_EALG_AESCBC when the satype is IPCOMP, the one of the following value will be in the sadb3_sa_encrypt as its value. SADB_X_CALG_OUI SADB_X_CALG_DEFLATE SADB_X_CALG_LZS sadb3_sa_flags SADB_SAFLAGS_PFS + Lifetime Extension struct sadb3_lifetime { uint16_t sadb3_lifetime_len; uint16_t sadb3_lifetime_exttype; uint32_t sadb3_lifetime_allocations; uint64_t sadb3_lifetime_bytes; uint64_t sadb3_lifetime_addtime; uint64_t sadb3_lifetime_usetime; }; sadb3_lifetime_exttype SADB_EXT_LIFETIME_CURRENT SADB_EXT_LIFETIME_HARD SADB_EXT_LIFETIME_SOFT + Address Extension struct sadb3_address { uint16_t sadb3_address_len; uint16_t sadb3_address_exttype; }; /* followed by some form of struct sockaddr */ sadb3_address_exttype SADB_EXT_ADDRESS_SRC SADB_EXT_ADDRESS_DST + Key Extension struct sadb3_key { uint16_t sadb3_key_len; uint16_t sadb3_key_exttype; uint16_t sadb3_key_bits; uint16_t sadb3_key_reserved; }; sadb3_key_exttype SADB_EXT_KEY_AUTH SADB_EXT_KEY_ENCRYPT + Identity Extension struct sadb3_ident { uint16_t sadb3_ident_len; uint16_t sadb3_ident_exttype; uint16_t sadb3_ident_type; uint16_t sadb3_ident_reserved; uint64_t sadb3_ident_id; }; sadb3_ident_exttype SADB_EXT_IDENTITY_SRC SADB_EXT_IDENTITY_DST sadb3_ident_type SADB_IDENTTYPE_PREFIX SADB_IDENTTYPE_FQDN SADB_IDENTTYPE_USERFQDN SADB_X_IDENTTYPE_ADDR + Sensitivity Extension struct sadb3_sens { uint16_t sadb3_sens_len; uint16_t sadb3_sens_exttype; uint32_t sadb3_sens_dpd; uint8_t sadb3_sens_sens_level; uint8_t sadb3_sens_sens_len; uint8_t sadb3_sens_integ_level; uint8_t sadb3_sens_integ_len; uint32_t sadb3_sens_reserved; }; sadb3_sens_exttype SADB_EXT_SENSITIVITY + Supported Algorithms Extension struct sadb3_supported { uint16_t sadb3_supported_len; uint16_t sadb3_supported_exttype; uint32_t sadb3_supported_reserved; }; /* followed by: struct sadb3_alg sadb3_algs[(sadb3_supported_len * sizeof(uint64_t) - sizeof(struct sadb3_supported)) / sizeof(struct sadb3_alg)]; */ This header is followed by one or more algorithm descriptions. An algorithm description looks like: struct sadb3_alg { uint8_t sadb3_alg_id; uint8_t sadb3_alg_ivlen; uint16_t sadb3_alg_minbits; uint16_t sadb3_alg_maxbits; uint16_t sadb3_alg_reserved; }; sadb3_supported_exttype SADB_EXT_SUPPORTED_AUTH SADB_EXT_SUPPORTED_ENCRYPT + SPI Range Extension struct sadb3_spirange { uint16_t sadb3_spirange_len; uint16_t sadb3_spirange_exttype; uint32_t sadb3_spirange_min; uint32_t sadb3_spirange_max; uint32_t sadb3_spirange_reserved; }; sadb3_spirange_exttype SADB_EXT_SPIRANGE + Policy Index Extension see RFC2367 2.3 Additional Message Fields どのポリシのためのSAなのかを特定するために sadb3_policy_idを導入 struct sadb3_policy_id { u_int16_t sadb3_x_policy_len; u_int16_t sadb3_x_policy_exttype; u_int32_t sadb3_x_policy_index; }; sadb3_policy_indexペイロードが無いか sadb3_x_policy_index が 0 の時は、 全てのポリシに使える SA を意味する。 sadb3_x_policy_exttype SADB3_EXT_POLICY_INDEX o Message Types currently the following types are defined. SADB3_GETSPI SADB3_UPDATE SADB3_ADD SADB3_DELETE SADB3_GET SADB3_ACQUIRE SADB3_REGISTER SADB3_EXPIRE SADB3_X_PCHANGE SADB3_X_PROMISC SADB3_GETSPI 受信用SAのSPIをカーネルから取得する。 send it from an user process to the kernel. return it to all registered processes. SADB3_UPDATE GETSPIに対してSAのパラメータをカーネルへ設定する。 send it from an user process to the kernel. return it to all registered process. SADB3_ADD SAのパラメータをカーネルへ設定する。 send it from an user process to the kernel. return it to all registered processes. SADB3_DELETE あるまとまりでSAを消す。 以下のまとまりが有効な指定。 address(SD) SAタイプ SPI あり あり あり 有効(現行) あり あり なし 有効(?) あり なし なし 有効 なし なし なし 有効(現行のFLUSH相当) 以下は無効な指定。 address(SD) SAタイプ SPI あり なし あり 無効 なし あり あり 無効 なし なし あり 無効 なし あり なし 無効 send it from an user process to the kernel. return it to all registererd processes. SADB3_GET あるまとまりでSAをカーネルから取得する。 以下のまとまりが有効な指定。 address(SD) SAタイプ SPI あり あり あり 有効(現行) あり あり なし 有効(?) あり なし なし 有効 なし なし なし 有効(現行のFLUSH相当) 以下は無効な指定。 address(SD) SAタイプ SPI あり なし あり 無効 なし あり あり 無効 なし なし あり 無効 なし あり なし 無効 send it from an user process to the kernel. return it to the process that sent the above message. SADB3_ACQUIRE カーネルからSAの設定要求を受ける。 identityは付加情報扱い。元のパケット情報を突っ込む。 send it from the kernel to appropriate registered process. retrurn it to the kernel in order to indicate key management failure. the second usage is from an user process to the kernel. send it from an user process to the kernel. send it from the kernel to appropriate registerd sockets. SADB3_REGISTER カーネルにPF_KEYメッセージのリスナーであることを登録する。 カーネルがサポートしている暗号アルゴリズムを取得する。 send it from an user process to the kernel. return it to the socket that sent the above message. SADB3_EXPIRE SAの有効期限が切れる事、または切れた事をカーネルから受ける。 send it from the kernel to all registered processes. SADB3_X_PCHANGE (名前は?) InboundのポリシはあるがSAが無いことをカーネルから通知される。 IKEv2のDPDを実現するために必要 the first usage is the kernel-origianted case. send it from the kernel to appropriate registerd sockets. the second usage is from an user-level consumer of SAs. send it from an user process to the kernel. send it from the kernel to appropriate registerd sockets. SADB3_X_PROMISC promiscuous mode send it from an user process to the kernel. return it from the kernel to all registered processes. ==== #define SADB_EXT_RESERVED 0 #define SADB_EXT_SA 1 #define SADB_EXT_LIFETIME_CURRENT 2 #define SADB_EXT_LIFETIME_HARD 3 #define SADB_EXT_LIFETIME_SOFT 4 #define SADB_EXT_ADDRESS_SRC 5 #define SADB_EXT_ADDRESS_DST 6 #define SADB_EXT_ADDRESS_PROXY 7 #define SADB_EXT_KEY_AUTH 8 #define SADB_EXT_KEY_ENCRYPT 9 #define SADB_EXT_IDENTITY_SRC 10 #define SADB_EXT_IDENTITY_DST 11 #define SADB_EXT_SENSITIVITY 12 #define SADB_EXT_PROPOSAL 13 #define SADB_EXT_SUPPORTED_AUTH 14 #define SADB_EXT_SUPPORTED_ENCRYPT 15 #define SADB_EXT_SPIRANGE 16 /* RFC2367 numbers - meets RFC2407 */ #define SADB_AALG_NONE 0 #define SADB_AALG_MD5HMAC 2 #define SADB_AALG_SHA1HMAC 3 #define SADB_AALG_MAX 251 /* private allocations - based on RFC2407/IANA assignment */ #define SADB_X_AALG_SHA2_256 5 #define SADB_X_AALG_SHA2_384 6 #define SADB_X_AALG_SHA2_512 7 /* private allocations should use 249-255 (RFC2407) */ #define SADB_X_AALG_MD5 249 /* Keyed MD5 */ #define SADB_X_AALG_SHA 250 /* Keyed SHA */ #define SADB_X_AALG_NULL 251 /* null authentication */ /* RFC2367 numbers - meets RFC2407 */ #define SADB_EALG_NONE 0 #define SADB_EALG_DESCBC 2 #define SADB_EALG_3DESCBC 3 #define SADB_EALG_NULL 11 #define SADB_EALG_MAX 253 /* private allocations - based on RFC2407/IANA assignment */ #define SADB_X_EALG_CAST128CBC 6 #define SADB_X_EALG_BLOWFISHCBC 7 #define SADB_X_EALG_RIJNDAELCBC 12 #define SADB_X_EALG_AES 12 /* private allocations should use 249-255 (RFC2407) */ #define SADB_X_EALG_TWOFISHCBC 253 /* draft-ietf-ipsec-ciph-aes-cbc-00 */ #if 1 /*nonstandard */ #define SADB_X_CALG_NONE 0 #define SADB_X_CALG_OUI 1 #define SADB_X_CALG_DEFLATE 2 #define SADB_X_CALG_LZS 3 #define SADB_X_CALG_MAX 4 #endif #define SADB_IDENTTYPE_RESERVED 0 #define SADB_IDENTTYPE_PREFIX 1 #define SADB_IDENTTYPE_FQDN 2 #define SADB_IDENTTYPE_USERFQDN 3 #define SADB_X_IDENTTYPE_ADDR 4 #define SADB_IDENTTYPE_MAX 4 /* `flags' in sadb_sa structure holds followings */ #define SADB_X_EXT_NONE 0x0000 /* i.e. new format. */ #define SADB_X_EXT_OLD 0x0001 /* old format. */ #define SADB_X_EXT_IV4B 0x0010 /* IV length of 4 bytes in use */ #define SADB_X_EXT_DERIV 0x0020 /* DES derived */ #define SADB_X_EXT_CYCSEQ 0x0040 /* allowing to cyclic sequence. */ /* three of followings are exclusive flags each them */ #define SADB_X_EXT_PSEQ 0x0000 /* sequencial padding for ESP */ #define SADB_X_EXT_PRAND 0x0100 /* random padding for ESP */ #define SADB_X_EXT_PZERO 0x0200 /* zero padding for ESP */ #define SADB_X_EXT_PMASK 0x0300 /* mask for padding flag */ #if 1 #define SADB_X_EXT_RAWCPI 0x0080 /* use well known CPI (IPComp) */ #endif #define SADB_KEY_FLAGS_MAX 0x0fff /* SPI size for PF_KEYv2 */ #define PFKEY_SPI_SIZE sizeof(u_int32_t) /* Identifier for menber of lifetime structure */ #define SADB_X_LIFETIME_ALLOCATIONS 0 #define SADB_X_LIFETIME_BYTES 1 #define SADB_X_LIFETIME_ADDTIME 2 #define SADB_X_LIFETIME_USETIME 3 /* The rate for SOFT lifetime against HARD one. */ #define PFKEY_SOFT_LIFETIME_RATE 80 /* Utilities */ #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) #define PFKEY_EXTLEN(msg) \ PFKEY_UNUNIT64(((struct sadb_ext *)(msg))->sadb_ext_len) #define PFKEY_ADDR_PREFIX(ext) \ (((struct sadb_address *)(ext))->sadb_address_prefixlen) #define PFKEY_ADDR_PROTO(ext) \ (((struct sadb_address *)(ext))->sadb_address_proto) #define PFKEY_ADDR_SADDR(ext) \ ((struct sockaddr *)((caddr_t)(ext) + sizeof(struct sadb_address))) /* in 64bits */ #define PFKEY_UNUNIT64(a) ((a) << 3) #define PFKEY_UNIT64(a) ((a) >> 3) #endif /* __PFKEY_V2_H */ #endif /* _NET_PFKEYV2_H_ */ ==== APPENDIX A o PF_KEYv2 実装状況 各プラットフォームの net/pfkeyv2.h を比較したので、 機能が実装されているとは限らない + メッセージタイプ RFC2367 KAME Linux24 Linux25 OpenBSD32 --------------------------------------------------------------- 1 GETSPI O O O O 2 UPDATE O O O O 3 ADD O O O O 4 DELETE O O O O 5 GET O O O O 6 ACQUIRE O O O O 7 REGISTER O O O O 8 EXPIRE O O O O 9 FLUSH O O O O 10 DUMP O O O O 11 X_PROMISC O O O O 12 X_PCHANGE O O O X_ADDFLOW 13 X_SPDUPDATE X_GRPSA X_SPDUPDATE X_DELFLOW 14 X_SPDADD X_ADDFLOW X_SPDADD X_GRPSPIS 15 X_SPDDELETE X_DELFLOW X_SPDDELETE X_ASKPOLICY 16 X_SPDGET X_DEBUG X_SPDGET 17 X_SPDACQUIRE X_FLUSH_SP X_SPDACQUIRE 18 X_SPDDUMP X_SPDDUMP 19 X_SPDFLUSH X_SPDFLUSH 20 X_SPDSETIDX X_SPDSETIDX 21 X_SPDEXPIRE X_SPDEXPIRE 22 X_SPDDELETE2 X_SPDDELETE2 + ヘッダタイプ RFC2367 KAME Linux24 Linux25 OpenBSD32 --------------------------------------------------------------- 1 SA O O O O 2 LIFETIME_CURRENT O O O O 3 LIFETIME_HARD O O O O 4 LIFETIME_SOFT O O O O 5 ADDRESS_SRC O O O O 6 ADDRESS_DST O O O O 7 ADDRESS_PROXY O O O O 8 KEY_AUTH O O O O O 9 KEY_ENCRYPT O O O O 10 IDENTITY_SRC O O O O 11 IDENTITY_DST O O O O 12 SENSITIVITY O O O O 13 PROPOSAL O O O O 14 SUPPORTED_AUTH O O O O 15 SUPPORTED_ENCRYPT O O O O 16 SPIRANGE O O O O 17 KMPRIVATE X_SRC_MASK 18 X_POLICY X_SATYPE2 X_POLICY X_DST_MASK 19 X_SA2 X_SA2 X_SA2 X_PROTOCOL 20 X_ADDRESS_DST2 X_FLOW_TYPE 21 X_ADDRESS_SRC_FLOW X_SRC_FLOW 22 X_ADDRESS_DST_FLOW X_DST_FLOW 23 X_ADDRESS_SRC_MASK X_SA2 24 X_ADDRESS_DST_MASK X_DST2 25 X_DEBUG X_POLICY 26 X_LOCAL_CREDENTIALS 27 X_REMOTE_CREDENTIALS 28 X_LOCAL_AUTH 29 X_REMOTE_AUTH 30 X_SUPPORTED_COMP APPENDIX B o kame実装の問題点 - sadb3_identを置き換える、またSA bundleを表現するためにsadb3_x_policyを 実装したが、既にポリシを特定するためのpolicy-idを導入しているために これは必要なくなっている。 - SAのmodeを表現するために sadb3_x_sa2を追加したが、modeは SPDに 記述されていて、policy-idを用いて牽くことができる。 - SADB_DUMPしても全てのSAをユーザ空間に渡せない - SAの HARD lifetimeが切れたときにSADB_EXPIREメッセージが上がらない。 $Id: memo-pfkeyv3-spec-jp.txt,v 1.4 2003/05/07 02:01:27 sakane Exp $