测试环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ip netns exec ns1 ip l s veth1 down ip l delete veth0 ip netns delete ns1
ip l add type veth ip netns add ns1
ip l s dev veth1 netns ns1 ip l set veth0 up ip netns exec ns1 ip l set veth1 up
ip a a dev veth0 192.168.100.1/24 ip netns exec ns1 ip a a dev veth1 192.168.100.2/24 ip netns exec ns1 ip r a default via 192.168.100.1
|
启用转发
1
| echo 1 > /proc/sys/net/ipv4/ip_forward
|
配置xfrm SA and SP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| SRC=172.17.0.2 DST=120.244.227.44 LOCAL=172.17.0.0/16 REMOTE=192.168.1.0/24 SRC_PORT=40001 DST_PORT=18181
ID=1234 KEY=0xabcdef01234567890abcd
ip xfrm state flush && ip xfrm policy flush
ip xfrm policy add src $LOCAL dst $REMOTE dir out tmpl src $SRC dst $DST proto esp spi $ID reqid $ID mode tunnel level required ip xfrm policy add src $REMOTE dst $LOCAL dir fwd tmpl src $DST dst $SRC proto esp spi $ID reqid $ID mode tunnel level use ip xfrm policy add src $REMOTE dst $LOCAL dir in tmpl src $DST dst $SRC proto esp spi $ID reqid $ID mode tunnel level use
ip xfrm state add src $SRC dst $DST proto esp spi $ID reqid $ID mode tunnel enc blowfish $KEY encap espinudp $SRC_PORT $DST_PORT 0.0.0.0 ip xfrm state add src $DST dst $SRC proto esp spi $ID reqid $ID mode tunnel enc blowfish $KEY encap espinudp $DST_PORT $SRC_PORT 0.0.0.0
|
udp server
创建一个udp socket,并设置UDP_ENCAP_ESPINUDP属性,这样内核收到报文后,剥离掉udp头后,将报文内容当做xfrm报文处理。
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 31 32 33 34 35 36 37 38 39 40 41
| #include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <netinet/in.h> #include <netinet/udp.h>
#define SERV_PORT 40000
int main() { int len; int val; struct sockaddr_in addr_serv;
int sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if(sock_fd < 0) return -EINVAL;
memset(&addr_serv, 0, sizeof(struct sockaddr_in)); addr_serv.sin_family = AF_INET; addr_serv.sin_port = htons(SERV_PORT); len = sizeof(addr_serv);
if (bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0) goto fin;
val = UDP_ENCAP_ESPINUDP; if (setsockopt(sock_fd, SOL_UDP, UDP_ENCAP, &val, sizeof(val)) < 0) { printf("Set val failed\n"); goto fin; }
while (1) sleep(10);
fin: close(sock_fd);
return 0; }
|
常用调试命令
xfrm proc 统计
SA: ip -s x s
SP: ip -s x p