Solaris 网络虚拟化: Firewall 部分

Solaris 的 Containers(AKA zones) 的模型 在 Solaris 10 中就出现了, CPU, 内存,Disk 空间的虚拟化已经可以提供出基本的 OS 级的虚拟环境, 但是网络部分还是没能完善。 Solaris 10 的zone 提供了独立的name space(logic IP 地址, TCP/UDP/SCTP 端口, ), 但是基本的说, 一个系统中 Zones 共享这一个 TCP/IP 协议栈。 - Routing - ARP - Firewall policy - Statitics 都是共享着的, 这也就意味着: - Zone 与 Zone 之间有安全漏洞: 一个Zone 的网络配置和信息可能(或一定)为别的Zone 开到 - 配置问题: 为 一个 Zone 做配置(如路由配置)可能会使得别的zone 也受影响甚至不能工作 The Old Solaris 10 Network Model Zone A Zone B +_________________++________________ | APPLICATION || APPLICATION | | || | | TCP UDP || TCP UDP | |_________________||________________| __________|________________|________ | | | IP/ARP/IPSEC/Firewall | |___________________________________| ______|_______ _____|______ | NIC1 | | NIC2 | |------------| |----------| The New Solaris 10 Network Model Zone A Zone B +_________________++________________ | APPLICATION | | APPLICATION | | | | | | TCP UDP | | TCP UDP | |_________________| |________________| __________|________ ________|_______ | | | | | IP/ARP/ | | IP/ARP/ | | IPSEC/Firewall | | IPSEC/Firewall | |_________________| |________________| ______|_______ _____|______ | NIC1 | | NIC2 | |------------| |----------| 我设计和实现了Solaris Firewall 的虚拟化。 Soaris 的 Firewall 有 pfhook framework(neti 和 hook) 以及 firewall 引擎 ipf 组成。 Architecture: IP +---------+ module: neti Firewall | | +----------------------------------------------+ +-----------+ | | | | | | | | | | | | | | | | | | | | -----------> net_register/unregister | | | | | net_lookup <------ | | | | net_release | | | | | | | | | | net_walk | | | | | | | | | | -----------> net_register_family/unregister | | | | | -----------> net_register_event/unregister | | | | | \\ \\ net_register_hook/unregister <------ | | | \\-- | | | | | | | | \\ | net_getifname <------ | | | | \\ | net_getmtu <------ | | | | \\ | net_getpmtuenabled <------ | | | | | | net_lifaddr <------ | | | | \\ | net_phygetnext <------ | | | | \\ | net_phylookup <------ | | | | \\ | net_lifgetnext <------ | | | | \\ | net_inject <------ | | | | \\ | net_routeto <------ | | | | | | net_ispartialchecksum <------ | | | | | | net_isvalidchecksum <------ | | | | \\ | | | | | | | \\| | | | | | +-------------------\^\^\^\^\^----------------------+ | | | | || | (neti, hook interaction) | | | | module: hook || | | | | | +-------------------<<>>|----------------------+ | | | | | | | | | | -----------> hook_run | | | | | | | | | | | +----------------------------------------------+ +-----------+ | | +---------+ Note: A few external functions in module hook called by neti hook_family_add/remove hook_event_add/remove hook_register/unregister The steps: 1. neti, and hook initialization 2. ip stack in ip_ddi_init - call ip_neti_init() - call net_register(&ipv4info) - call net_register(&ipv6info) - create task queue for eventq_queue_out eventq_queue_in eventq_queue_nic - call ipv4_hook_init() - call net_register_family(ipv4, &ipv4root) - call net_register_event(ipv4, &ip4_physical_in_event) - call net_register_event(ipv4, &ip4_physical_out_event) - call net_register_event(ipv4, &ip4_physical_forwarding_event) - call net_register_event(ipv4, &ip4_loopback_in_event) - call net_register_event(ipv4, &ip4_loopback_out_event) - call net_register_event(ipv4, &ip4_nic_events) - call ipv6_hook_init() - call net_register_family(ipv6, &ipv6root) - call net_register_event(ipv6, &ip6_physical_in_event) - call net_register_event(ipv6, &ip6_physical_out_event) - call net_register_event(ipv6, &ip6_physical_forwarding_event) - call net_register_event(ipv6, &ip6_loopback_in_event) - call net_register_event(ipv6, &ip6_loopback_out_event) - call net_register_event(ipv6, &ip6_nic_events) 3. arp - call arp_hook_init() - call net_register_family(arp, &arproot) - call net_register_event(arp, &arp_physical_in_event) - call net_register_event(arp, &arp_physical_out_event) - call net_register_event(arp, &arp_nic_events) 4. ipf iplattach: - ipf_ipv4 = net_lookup(NHF_INET); - net_register_hook(ipf_ipv4, NH_NIC_EVENTS, &ipfhook_nicevents) - net_register_hook(ipf_ipv4, NH_PHYSICAL_IN, &ipfhook_in) - net_register_hook(ipf_ipv4, NH_PHYSICAL_OUT, &ipfhook_out) - net_register_hook(ipf_ipv4, NH_LOOPBACK_IN, &ipfhook_in) - net_register_hook(ipf_ipv4, NH_LOOPBACK_OUT, &ipfhook_out) - ipf_ipv6 = net_lookup(NHF_INET6); - net_register_hook(ipf_ipv6, NH_NIC_EVENTS, &ipfhook_nicevents) - net_register_hook(ipf_ipv6, NH_PHYSICAL_IN, &ipfhook_in) - net_register_hook(ipf_ipv6, NH_PHYSICAL_OUT, &ipfhook_out) - net_register_hook(ipf_ipv6, NH_LOOPBACK_IN, &ipfhook_in) - net_register_hook(ipf_ipv6, NH_LOOPBACK_OUT, &ipfhook_out) 5. - when packets come in/out, nic event happens, IP calls hook_run() The data structures relationship looks like: netd_head -- \\ \\ net_data_t(ip4) ip6 arp \\ ->+------------+ ---------> +------------+ -------------> +------------+ \\ |net_info | |net_info | |net_info | | | | | | | | | | netd_hooks___ | netd_hooks___ | netd_hooks___ | +------------+ \\ +------------+ \\ +------------+ \\ | neti \\ \\ \\ / | | | / | | | / | | | | | | | | | \\|/ \\|/ \\|/ \\ familylist -------> +----------+ ----------> +----------+ -------------> +----------+ \\ | | | | | | \\ | | | | | | | hook_family_int_t | ____ | | | | | +----------+ \\ +----------+ +----------+ | \\ | +------+ | hook_event_int_t | |-------+----+ hook_int_t | hook | | | | | +------+ +----+ | | | | | +------+ | hook_event_int_t | |-------+----+ hook_int_t | | | | | | +------+ +----+ | | | | | +------+ | hook_event_int_t | |-------+----+ hook_int_t / | | | | / +------+ +----+ / 虚拟化之后的过程是: 1. kernel module neti: has the neti_stack_t, and neti_stack_init(), which malloc the local storage; 2. kernel module hook has the hook_stack_t, and hook_stack_init(), which malloc the local storage; 3. arp module changes: move the following from arp_ddi_init to arp_stack_init - call arp_neti_init(as) - call net_register(&arpinfo) - call arp_hook_init() - call net_register_family(arp, &arproot) - call net_register_event(arp, &arp_physical_in_event) - call net_register_event(arp, &arp_physical_out_event) - call net_register_event(arp, &arp_nic_events) 4. ip module: Move the following from ip_ddi_init to ip_stack_init, to make the - call ip_neti_init(pfs) - call net_register(&ipv4info) - call net_register(&ipv6info) - create task queue for eventq_queue_out eventq_queue_in eventq_queue_nic - call ipv4_hook_init() - call net_register_family(ipv4, &ipv4root) - call net_register_event(ipv4, &ip4_physical_in_event) - call net_register_event(ipv4, &ip4_physical_out_event) - call net_register_event(ipv4, &ip4_physical_forwarding_event) - call net_register_event(ipv4, &ip4_loopback_in_event) - call net_register_event(ipv4, &ip4_loopback_out_event) - call net_register_event(ipv4, &ip4_nic_events) - call ipv6_hook_init() - call net_register_family(ipv6, &ipv6root) - call net_register_event(ipv6, &ip6_physical_in_event) - call net_register_event(ipv6, &ip6_physical_out_event) - call net_register_event(ipv6, &ip6_physical_forwarding_event) - call net_register_event(ipv6, &ip6_loopback_in_event) - call net_register_event(ipv6, &ip6_loopback_out_event) - call net_register_event(ipv6, &ip6_nic_events) 下面的函数接口增加了一个 netstack_t \* net_register(..., netstack_t \*) net_lookup(..., netstack_t \*) net_walk(..., netstack_t \*) 其他函数保持不变: net_unregister(...) net_release(...) net_register_family(...) net_unregister_family(...) net_register_family(...) net_unregister_family(...) net_register_hook(...) net_unregister_hook(...) net_getifname(...) net_getmtu(...) net_getpmtuenabled(...) net_lifaddr(...) net_phygetnext(...) net_phylookup(...) net_lifgetnext(...) net_inject(...) net_routeto(...) net_ispartialchecksum(...) net_isvalidchecksum(...) 相应的这些数据结构和原型也有了一些变化: ------------------------------------------------------------------------------------- Old: 118 typedef struct net_info { 119 int neti_version; 120 char \*neti_protocol; 121 int (\*neti_getifname)(phy_if_t, char \*, const size_t); 122 int (\*neti_getmtu)(phy_if_t, lif_if_t); 123 int (\*neti_getpmtuenabled)(void); 124 int (\*neti_getlifaddr)(phy_if_t, lif_if_t, size_t, 125 net_ifaddr_t [], void \*); 126 phy_if_t (\*neti_phygetnext)(phy_if_t); 127 phy_if_t (\*neti_phylookup)(const char \*); 128 lif_if_t (\*neti_lifgetnext)(phy_if_t, lif_if_t); 129 int (\*neti_inject)(inject_t, net_inject_t \*); 130 phy_if_t (\*neti_routeto)(struct sockaddr \*); 131 int (\*neti_ispartialchecksum)(mblk_t \*); 132 int (\*neti_isvalidchecksum)(mblk_t \*); 133 } net_info_t; New: 118 typedef struct net_info { 119 int neti_version; 120 char \*neti_protocol; 121 int (\*neti_getifname)(phy_if_t, char \*, const size_t, netstack_t\*); 122 int (\*neti_getmtu)(phy_if_t, lif_if_t); 123 int (\*neti_getpmtuenabled)(netstack_t \*); 124 int (\*neti_getlifaddr)(phy_if_t, lif_if_t, size_t, 125 net_ifaddr_t [], void \*); 126 phy_if_t (\*neti_phygetnext)(phy_if_t, netstack_t \*); 127 phy_if_t (\*neti_phylookup)(const char \*, netstack_t \*); 128 lif_if_t (\*neti_lifgetnext)(phy_if_t, lif_if_t); 129 int (\*neti_inject)(inject_t, net_inject_t \*, netstack_t \*); 130 phy_if_t (\*neti_routeto)(struct sockaddr \*, netstack_t \*); 131 int (\*neti_ispartialchecksum)(mblk_t \*); 132 int (\*neti_isvalidchecksum)(mblk_t \*); 133 } net_info_t; ------------------------------------------------------------------------------------- Old: 139 struct net_data { 140 LIST_ENTRY(net_data) netd_list; 141 net_info_t netd_info; 142 int netd_refcnt; 143 hook_family_int_t \*netd_hooks; 144 }; New: 139 struct net_data { 140 LIST_ENTRY(net_data) netd_list; 141 net_info_t netd_info; 142 int netd_refcnt; 143 hook_family_int_t \*netd_hooks; 144 void \* netd_netstack; 145 }; 146 ------------------------------------------------------------------------------------- Old: 147 typedef struct injection_s { 148 net_inject_t inj_data; 149 boolean_t inj_isv6; 150 } injection_t; New: 148 typedef struct injection_s { 149 net_inject_t inj_data; 150 boolean_t inj_isv6; 151 void \* inj_ptr; 152 } injection_t; ------------------------------------------------------------------------------------- Old: 165 extern net_data_t net_register(const net_info_t \*); New: 180 extern net_data_t net_register(const net_info_t \*, netstack_t \*); ------------------------------------------------------------------------------------- Old: 167 extern net_data_t net_lookup(const char \*); New: 182 extern net_data_t net_lookup(const char \*, netstack_t \*); ------------------------------------------------------------------------------------- Old: 169 extern net_data_t net_walk(net_data_t); New: 184 extern net_data_t net_walk(net_data_t, netstack_t \*);
Comments:

Post a Comment:
Comments are closed for this entry.
About

yukun

Search

Archives
« September 2015
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today