$Id: report-NRL.txt,v 1.1.1.1 1999/10/26 17:19:16 sakane Exp $ %Hd: NRL のIPsecまわりの動作 注意: 1996年3月頃に調査したものです。もったいないので公開。 - README より抜粋 NRL IPv6/IPsec Software Distribution Alpha Release 4 Release Notes September, 1996 ==================================== =============== Introduction ------------ The NRL IPv6/IPsec Software Distribution is a reference implementation of IPv6 and IP Security for the 4.4BSD-Lite2 networking software. It is freely distributable (subject to U.S. export controls) and usable for commercial and non-commercial purposes as long as the NRL and UC Berkeley license terms are adhered to. We have tested this software on SPARC systems using the UC Berkeley 4.4 BSD UNIX operating system with 4.4-Lite updates. We have also tested this software on x86 systems running NetBSD 1.2, SPARC systems running NetBSD 1.2, and x86 systems using BSDI 2.1. We believe that our code should be easily portable to reasonable 4.4BSD-Lite derived systems (BSDI, NetBSD, OpenBSD, and Lites). We believe that it would be difficult, though not impossible, to port our code to other systems. This implementation includes kernel networking software, a small IPv6 support library, and several applications (e.g. telnet, telnetd, ping, tftp, tftpd, socktest, netstat, ifconfig, ping, route, tcpdump) modified to support IPv6/IPsec. This implementation also includes the NRL Key Engine (aka PF_KEY) and applications to interface with it. There are manual pages for the modified and new software, but they might not yet be as detailed as one might like. This "alpha-quality" release of the IPv6 software is intended to be used by kernel hackers and implementers who want to get early access and experience with IPv6 and IPsec. Use at your own risk. It is complete enough to use for experimenting but it is not entirely complete. In some areas this is because the IPv6 specifications are not yet stable. - 処理条件 送信時は、src, dst, socket で判断する。 受信時は、ip->ip_p で判断する。 socket構造体に、so_securitylevelを作成。 恐らく、socket単位でsecurity levelが設定出来る。 送信時は、src, dst, socket で判断する。 受信時は、ip->ip_p で判断する。 socket V A layer | | ----|-------------------------------------------------|----- | | tcp_output tcp_input | | | ipsec_??_input <===> (ip->ip_p) protocol | | layer ip_output <===> ipsec_??_output ipintr | | | | | | ----|-------------------------------------------------|----- interface | | layer ether_output ether_input | | ----|-------------------------------------------------|----- | | V A - パケット送信 ip_output [mbuf, opt, route, flags, ip_moptions] sys.common/netinet/ip_output.c ラベルsendit:の先頭の部分で処理を行う IP_FORWARDINGがオフならば(自ホストから出発点なら?) ipsec_output_policy [mbuf->m_pkthdr.rcvif, sockaddr_in_src, route->ro_dst, &needed, &SA_ready, &ah_ktn, &esp_t_ktn, &esp_n_ktn] をコール needed, SA_ready によって、(排他的に)カプセル化を行う。 SA_ready == IPSEC_SA_READY needed & IPSEC_ESP_TRANSPORT_NEEDED ipsec_esp_transport_output(m,SA) 未実装(?) needed & IPSEC_AH_NEEDED ipsec_ah_output(m,SA) needed & IPSEC_ESP_TUNNEL_NEEDED ipsec_esp_tunnel_output(m,SA) else ipsec_enqueue(m) 以降オリジナル処理 ipsec_output_policy [socket, src, dst] sys.common/netsec/ipsec_policy.c SAを取得するために getassocbysocket [KEY_TYPE, src, dst, socket ] をコール 以降を順にコール getassocbysocket [KEY_TYPE_ESP, src, dst, socket ] getassocbysocket [KEY_TYPE_ESP, src, dst, socket ] getassocbysocket [KEY_TYPE_AH, src, dst, socket ] getassocbysocket [KEY_TYPE, src, dst, socket ] sys.common/netkey/key.c type, src, dst, socket より SAを取得する key_sosearch [type,src,dst,socket] SAを検索 key_alloc [type,src,dst,socket] SAを作成 - パケット受信 ipintr sys.common/netinet/ip_input.c 先頭で処理を行う。 ipv4_input [mbuf, 0] をコールする ipv4_input [mbuf, extra] sys.common/netinet/ip_input.c extra!=0の時、カプセル化されたパケットとみなし、SAを取得し、mbufを調整する IPngのためにあるのか? IPsecには直接関係ない? ipsec_input_policy [mbuf, NULL, NEXTHDR_IPV6] をコール mbuf調整(?) 以降オリジナル処理 (ip->ip_p).pr_input (ipsec_ah_input, ipsec_esp_input)をコールする ipsec_input_policy [mbuf, NULL, NEXTHDR_IPV6] socket_input_policy_check SS_AUTHENTICATION SS_ENCRYPTION_TRANSPORT SS_ENCRYPTION_NETWORK 最後 ipsec_esp_input ESP 50番 未実装(?) ipsec_ah_input AH 51番 I/F uipc_socket.c: sosetopt() ソケットにフラグ?を立てている。 so->so_securitylevel[LEVEL] = *(mtod(m, int *)); net_secassoc_list らしい?? SO_SECURITY_AUTHENTICATION AHを使用する。 SO_SECURITY_ENCRYPTION_TRANSPORT ESP/トランスポート・モードを使用する。 SO_SECURITY_ENCRYPTION_NETWORK ??? ESP/トンネル・モードを使用する。 それぞれのモードに以下のレベルを設定 IPSEC_LEVEL_DEFAULT 何もしない IPSEC_LEVEL_USE 外向けにのみ適用 IPSEC_LEVEL_REQUIRE 外内向け共に適用。要求を満たさないものは破棄。 IPSEC_LEVEL_UNIQUE IPSEC_LEVEL_REQUIRE。key management database - KEY管理 ユーザI/F KEY_ADD key_add * key_add(): * Add a new security association to the key table. Caller is * responsible for allocating memory for the key_secassoc as * well as the buffer space for the key and iv. Assumes the security * association passed in is well-formed. KEY_DELETE key_delete * Delete a security association from the key table. KEY_UPDATE key_update * Update a keytable entry that has an spi value assigned but is * incomplete (e.g. no key/iv). KEY_GET key_get * Get a security association from the key table. KEY_GETSPI key_getspi * Get a unique spi value for a key management daemon/program. The * spi value, once assigned, cannot be assigned again (as long as the * entry with that same spi value remains in the table). KEY_REGISTER key_register * Register a socket as one capable of acquiring security associations * for the kernel. KEY_DUMP key_dump * Dump all valid entries in the keytable to a pf_key socket. Each * security associaiton is sent one at a time in a pf_key message. A * message with seqno = 0 signifies the end of the dump transaction. KEY_FLUSH key_flush * Delete all entries from the key table. kernel I/F KEY_ACQUIRE key_acquire * key_acquire(): * Send a key_acquire message to all registered key mgnt daemons * capable of acquire security association of type type. * * Return: 0 if succesfully called key mgnt. daemon(s) * -1 if not successfull. KEY_EXPIRE 未使用