openflow 本身没有定义连接状态,需要控制器做sdn 防火墙。但ovs 的实现中支持了conn track,可以利用Linux 的nf_conntrack(类似iptables)。
出口方向放行
第一条flow 是先用ct_state=-trk 匹配出所有的包,action=ct(table=0) 加上trk 再回到table 0继续处理。
第二条flow 匹配所有带有trk 标记且源地址为a.b.c.d(用于标示本地虚拟机)的”new”包,例如icmp ping,tcp 的主动握手包等,通过ct(commit) 创建nf_conntrack 项,并放行(normal)。
第三条flow 匹配所有已经被追踪并建立链接的包(无状态协议icmp,udp 等也可以正常被nf_conntrack 追踪),均放行。
1 | # ovs-ofctl add-flow "cookie=0x100,icmp,ct_state=-trk,actions=ct(table=0)" |
入口方向放行
配置入口方向放行时第一条flow 已经做了对所有包添加trk,和放行+trk+est,因此入口放行只需要允许+trk+new,同样通过ct(commit) 建立nf_conntrack 项并normal 放行即可。nw_src 用于指定希望放行的对方地址,nw_dst 为本地虚拟机地址。
1 | # ovs-ofctl add-flow "cookie=0x100,icmp,ct_state=+trk+new,nw_src=e.f.g.h/x,nw_dst=a.b.c.d actions=ct(commit),normal" |