IPSec NAT穿越静态配置和问题

网络安全 同时被 2 个专栏收录
14 篇文章 0 订阅
32 篇文章 2 订阅

网络拓扑

    |-------------------|             |-------------------|
    |                   |             |                   |
    |   192.168.1.115   | <---------> |   192.168.1.142   |
    |                   |             |                   |
    |-------------------|             |-------------------|

 

配置192.168.1.115


查看ip-xfrm的man文档,ip xfrm的state配置说明如下。

ip xfrm state add ID [ ALGO-LIST ] [ mode MODE ] [ mark MARK [ mask MASK ] ] [ reqid REQID ] [ seq SEQ ] [
        replay-window SIZE ] [ replay-seq SEQ ] [ replay-oseq SEQ ] [ flag FLAG-LIST ] [ sel SELECTOR ] [ LIMIT-LIST ] [
        encap ENCAP ] [ coa ADDR[/PLEN] ] [ ctx CTX ] [ extra-flag EXTRA-FLAG-LIST ]

以上语法可见,在配置IPSec的SA安全关联时仅ID时必选项,其于全部为可选,但是根据配置的不同有些可选项会变成必选项。本示例使用的可选项有:ALGO-LIST、MODE和ENCAP三个。

ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM-PROTO ] [ spi SPI ]
    XFRM-PROTO := esp | ah | comp | route2 | hao

ALGO-LIST := [ ALGO-LIST ] ALGO
    ALGO := { enc | auth } ALGO-NAME ALGO-KEYMAT |
        auth-trunc ALGO-NAME ALGO-KEYMAT ALGO-TRUNC-LEN |
        aead ALGO-NAME ALGO-KEYMAT ALGO-ICV-LEN | comp ALGO-NAME

MODE := transport | tunnel | beet | ro | in_trigger
ENCAP := { espinudp | espinudp-nonike } SPORT DPORT OADDR

即使用如下的配置语法:

ip xfrm state add ID [ ALGO-LIST ] [ mode MODE ] [encap ENCAP ]

具体配置如下,协议类型选择ESP;哈希算法选择SHA1;加密算法选择AES;模式选择隧道tunnel;封装采用ESP-in-UDP,源端口和目的端口使用4500。

ip xfrm state add src 192.168.1.115 dst 192.168.1.142 proto esp spi 0x00000301 auth sha1 0x8896ab8654cd9875e214a978bd31209f enc aes 0xea89273861739abc9e0d527ad98462108365289dcb1a6738 mode tunnel encap espinudp 4500 4500 0.0.0.0

ip xfrm state add src 192.168.1.142 dst 192.168.1.115 proto esp spi 0x00000302 auth sha1 0x8ab2639471536c8d92a0e82618e92ac7 enc aes 0xec91728a907c6d526178493027139dce56473926ac947289 mode tunnel encap espinudp 4500 4500 0.0.0.0

查看配置的内容:

$ sudo ip xfrm state list
src 192.168.1.142 dst 192.168.1.115
        proto esp spi 0x00000302 reqid 0 mode tunnel
        replay-window 0 
        auth-trunc hmac(sha1) 0x8ab2639471536c8d92a0e82618e92ac7 96
        enc cbc(aes) 0xec91728a907c6d526178493027139dce56473926ac947289
        encap type espinudp sport 4500 dport 4500 addr 0.0.0.0
        anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000
        sel src 0.0.0.0/0 dst 0.0.0.0/0 
src 192.168.1.115 dst 192.168.1.142
        proto esp spi 0x00000301 reqid 0 mode tunnel
        replay-window 0 
        auth-trunc hmac(sha1) 0x8896ab8654cd9875e214a978bd31209f 96
        enc cbc(aes) 0xea89273861739abc9e0d527ad98462108365289dcb1a6738
        encap type espinudp sport 4500 dport 4500 addr 0.0.0.0
        anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000
        sel src 0.0.0.0/0 dst 0.0.0.0/0 

 

完整的IPSec安全策略的添加命令如下,本示例用到四个选项:SELECTOR、DIR、PTYPE和TMPL-LIST。

ip xfrm policy add SELECTOR dir DIR [ ctx CTX ] [ mark MARK [ mask MASK ] ] [ index INDEX ] [ ptype PTYPE ]
               [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ] [ LIMIT-LIST ] [ TMPL-LIST ]

SELECTOR := [ src ADDR[/PLEN] ] [ dst ADDR[/PLEN] ] [ dev DEV ] [ UPSPEC ]

DIR := in | out | fwd

PTYPE := main | sub

TMPL-LIST := [ TMPL-LIST ] tmpl TMPL
    TMPL := ID [ mode MODE ] [ reqid REQID ] [ level LEVEL ]
        ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM-PROTO ] [ spi SPI ]
		XFRM-PROTO := esp | ah | comp | route2 | hao
	    MODE := transport | tunnel | beet | ro | in_trigger

即使用如下的配置语法:

ip xfrm policy add SELECTOR dir DIR [ ptype PTYPE ] [ TMPL-LIST ]

具体的配置如下。DIR数据流向选择入和出(out/in);ptype选择main;tmpl的协议选择RSP,模式选择隧道tunnel。

ip xfrm policy add src 192.168.1.115 dst 192.168.1.142 dir out ptype main tmpl src 192.168.1.115 dst 192.168.1.142 proto esp mode tunnel
ip xfrm policy add src 192.168.1.142 dst 192.168.1.115 dir in ptype main tmpl src 192.168.1.142 dst 192.168.1.115 proto esp mode tunnel

查看配置的安全策略。

$ sudo ip xfrm policy list
src 192.168.1.142/32 dst 192.168.1.115/32 
        dir in priority 0 
        tmpl src 192.168.1.142 dst 192.168.1.115
                proto esp reqid 0 mode tunnel
src 192.168.1.115/32 dst 192.168.1.142/32 
        dir out priority 0 
        tmpl src 192.168.1.115 dst 192.168.1.142
                proto esp reqid 0 mode tunnel

 

配置192.168.1.142

配置IPSec安全关联。

ip xfrm state add src 192.168.1.115 dst 192.168.1.142 proto esp spi 0x00000301 mode tunnel auth sha1 0x8896ab8654cd9875e214a978bd31209f enc aes 0xea89273861739abc9e0d527ad98462108365289dcb1a6738 encap espinudp 4500 4500 0.0.0.0

ip xfrm state add src 192.168.1.142 dst 192.168.1.115 proto esp spi 0x00000302 mode tunnel auth sha1 0x8ab2639471536c8d92a0e82618e92ac7 enc aes 0xec91728a907c6d526178493027139dce56473926ac947289 encap espinudp 4500 4500 0.0.0.0

查看配置的安全关联。

$ sudo ip xfrm state list
src 192.168.1.142 dst 192.168.1.115
        proto esp spi 0x00000302 reqid 0 mode tunnel
        replay-window 0 
        auth-trunc hmac(sha1) 0x8ab2639471536c8d92a0e82618e92ac7 96
        enc cbc(aes) 0xec91728a907c6d526178493027139dce56473926ac947289
        encap type espinudp sport 4500 dport 4500 addr 0.0.0.0
        sel src 0.0.0.0/0 dst 0.0.0.0/0 
src 192.168.1.115 dst 192.168.1.142
        proto esp spi 0x00000301 reqid 0 mode tunnel
        replay-window 0 
        auth-trunc hmac(sha1) 0x8896ab8654cd9875e214a978bd31209f 96
        enc cbc(aes) 0xea89273861739abc9e0d527ad98462108365289dcb1a6738
        encap type espinudp sport 4500 dport 4500 addr 0.0.0.0
        sel src 0.0.0.0/0 dst 0.0.0.0/0 


配置IPSec安全策略。

ip xfrm policy add src 192.168.1.115 dst 192.168.1.142 dir in ptype main tmpl src 192.168.1.115 dst 192.168.1.142 proto esp mode tunnel
ip xfrm policy add src 192.168.1.142 dst 192.168.1.115 dir out ptype main tmpl src 192.168.1.142 dst 192.168.1.115 proto esp mode tunnel


检查配置的安全策略。

$ sudo ip xfrm policy list
src 192.168.1.142/32 dst 192.168.1.115/32 
        dir out priority 0 ptype main 
        tmpl src 192.168.1.142 dst 192.168.1.115
                proto esp reqid 0 mode tunnel
src 192.168.1.115/32 dst 192.168.1.142/32 
        dir in priority 0 ptype main 
        tmpl src 192.168.1.115 dst 192.168.1.142
                proto esp reqid 0 mode tunnel


使能UDP封装功能


以上几节的配置完成之后,两台机器互相ping的话,两边是不通的。需要使能UDP的封装/解封装功能,以下的代码参考strongswan开源项目而来,编译之后,需要在两台机器上运行。由于此程序不退出,需要另外启动中断,进行ping操作验证联通性。

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <linux/udp.h>

#include <netinet/in.h>
#include <netinet/ip.h>

#include <linux/xfrm.h>
#include <linux/ipsec.h>
#include <linux/pfkeyv2.h>


int main(int argc, char *argv[])
{
        int on = 1;
        struct xfrm_userpolicy_info policy;
        int type = UDP_ENCAP_ESPINUDP;

        struct sockaddr_in addr = {
                .sin_family = AF_INET,
                .sin_port = htons(4500),
                .sin_addr = {
                        .s_addr = INADDR_ANY,
                },
        };


        int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (fd == -1)
                return -1;

        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0) {
                printf("unable to set SO_REUSEADDR on socket: %s", strerror(errno));
                return -1;
        }

        /* bind the socket */
        if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
                printf("unable to bind socket: %s", strerror(errno));
                return -1;
        }

        memset(&policy, 0, sizeof(policy));
        policy.action = XFRM_POLICY_ALLOW;
        policy.sel.family = AF_INET;

        policy.dir = XFRM_POLICY_OUT;
        if (setsockopt(fd, IPPROTO_IP, IP_XFRM_POLICY, &policy, sizeof(policy)) < 0) {
                printf("unable to set XFRM_POLICY on socket: %s\n",
                                strerror(errno));
                return -1;
        }
        policy.dir = XFRM_POLICY_IN;
        if (setsockopt(fd, IPPROTO_IP, IP_XFRM_POLICY, &policy, sizeof(policy)) < 0) {
                printf("unable to set XFRM_POLICY2 on socket: %s\n",
                                strerror(errno));
                return -1;
        }


        if (setsockopt(fd, IPPROTO_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) {
                printf("unable to set UDP_ENCAP: %s\n", strerror(errno));
                return -1;
        }

        while (1) {
                pause();
        }

        return 0;
}

在192.168.1.142上执行ping操作。

$ ping 192.168.1.115
PING 192.168.1.115 (192.168.1.115) 56(84) bytes of data.
64 bytes from 192.168.1.115: icmp_seq=1 ttl=64 time=0.202 ms
64 bytes from 192.168.1.115: icmp_seq=2 ttl=64 time=0.142 ms

在192.168.1.115使用tcpdump抓包如下:

$ sudo tcpdump -i any port 4500 -ven
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
21:05:55.017443  In 00:0c:29:69:5d:54 ethertype IPv4 (0x0800), length 176: (tos 0x0, ttl 64, id 48166, offset 0, flags [DF], proto UDP (17), length 160)
    192.168.1.142.4500 > 192.168.1.115.4500: UDP-encap: ESP(spi=0x00000302,seq=0x177), length 132
21:05:55.017612 Out 00:0c:29:de:95:00 ethertype IPv4 (0x0800), length 176: (tos 0x0, ttl 64, id 211, offset 0, flags [none], proto UDP (17), length 160)
    192.168.1.115.4500 > 192.168.1.142.4500: UDP-encap: ESP(spi=0x00000301,seq=0x14c), length 132
21:05:56.017437  In 00:0c:29:69:5d:54 ethertype IPv4 (0x0800), length 176: (tos 0x0, ttl 64, id 48410, offset 0, flags [DF], proto UDP (17), length 160)

 

END

 

  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值