learning:vpp-sswan 实现ipsec策略模式 (2)

2023-12-04 19:08:12 浏览数 (2)

上一节完成了vpp-sswan基本环境的安装部署,接下来搭建环境来验证ike协商及转发功能,下图是基本环境配置组网情况:

接下来配置VPP1和VPP2基础网络环境,在vpp配置文件strartup.conf中unix 配置项分别加入"exec /etc/vpp/ipsec1.conf"及"exec /etc/vpp/ipsec2.conf",重启vpp之后,将自动生成上面组网环境。

创建/etc/vpp/ipsec1.conf文件

代码语言:javascript复制
cat << EOF > /etc/vpp/ipsec1.conf
set interface state GigabitEthernet0/6/0 up
#创建lcp接口,将接口映射到内核中去,给strongswan ike交互使用。
lcp create GigabitEthernet0/6/0 host-if eth0

set interface ip address GigabitEthernet0/6/0 192.168.100.113/24
#创建lan侧接口,用于验证ipsec转发面流量,
create tap id 100 host-ip4-addr 192.168.200.2/24 host-ip4-gw 192.168.200.1
set interface state tap100 up
set interface ip address tap100 192.168.200.1/24
EOF

这里需要注意的是lcp创建需要在接口配置ip之前,才能将接口ip地址同步配置到内核eth0接口上。这应该算是lcp功能的一个bug吧?

创建/etc/vpp/ipsec2.conf文件

代码语言:javascript复制
cat << EOF > /etc/vpp/ipsec2.conf
set interface state GigabitEthernet0/6/0 up
lcp create GigabitEthernet0/6/0 host-if eth0
set interface ip address GigabitEthernet0/6/0 192.168.100.2/24
create tap id 100 host-ip4-addr 192.168.110.2/24 host-ip4-gw 192.168.110.1
set interface state tap100 up
set interface ip address tap100 192.168.110.1/24

EOF

接下来配置strongswan,分别在两个环境中创建ipsec1.conf及ipsec2.conf文件,具体文件内容如下:vpp1环境 ipsec1配置文件/etc/swanstl/conf.d/ipsec1.conf

代码语言:javascript复制
cat << EOF > /etc/swanctl/conf.d/ipsec1.conf 
connections {
  net-net {
    local_addrs = 192.168.100.113
    remote_addrs = 192.168.100.2
    local {
      auth = psk
      id = sun.strongswan.org
    }
    remote {
      auth = psk
      id = moon.strongswan.org
    }
    children {
      net-net {
        local_ts = 192.168.200.0/24
        remote_ts = 192.168.110.0/24
        esp_proposals = aes128-sha1-modp2048
        rekey_time = 240m
      }
    }
    version = 1
    mobike = yes
    encap = yes # NAT-T if needed
    proposals = aes128-sha256-x25519
    }
}
secrets {
  ike-net-net {
    id = moon.strongswan.org
    secret = simplepsk
  }
}

EOF

vpp2系统中 ipsec2配置文件/etc/swanstl/conf.d/ipsec2.conf

代码语言:javascript复制
cat << EOF > /etc/swanctl/conf.d/ipsec2.conf 
connections {
  net-net {
    local_addrs = 192.168.100.2
    remote_addrs = 192.168.100.113
    local {
      auth = psk
      id = moon.strongswan.org
    }
    remote {
      auth = psk
      id = sun.strongswan.org
    }
    children {
      net-net {
        local_ts = 192.168.110.0/24
        remote_ts = 192.168.200.0/24
        esp_proposals = aes128-sha1-modp2048
        rekey_time = 240m

      }
    }
    version = 1
    mobike = yes
    encap = yes # NAT-T if needed
    proposals = aes128-sha256-x25519
    }
}
secrets {
  ike-net-net {
    id = moon.strongswan.org
    secret = simplepsk
  }
}
EOF

配置完成之后,使用sswanctl命令加载ipsec配置,下面是在vpp1环境中操作步骤:

代码语言:javascript复制
#1、动态加载ipsec配置
root@learning-vpp1:~# swanctl --load-all
loaded ike secret 'ike-net-net'
no authorities found, 0 unloaded
no pools found, 0 unloaded
loaded connection 'net-net'
successfully loaded 1 connections, 0 unloaded
#2、查询ipsec配置
root@learning-vpp1:~# swanctl -L
net-net: IKEv1, reauthentication every 14400s
  local:  192.168.100.113
  remote: 192.168.100.2
  local pre-shared key authentication:
    id: sun.strongswan.org
  remote pre-shared key authentication:
    id: moon.strongswan.org
  net-net: TUNNEL, rekeying every 14400s
    local:  192.168.200.0/24
    remote: 192.168.110.0/24

接下来就是通过swanctl命令行发起ike协商,生成ike sa及ipsec sa:

代码语言:javascript复制
#1、发起ike sa协商
root@learning-vpp1:~# swanctl -i -i net-net
[IKE] initiating Main Mode IKE_SA net-net[1] to 192.168.100.2
[ENC] generating ID_PROT request 0 [ SA V V V V V ]
[NET] sending packet: from 192.168.100.113[500] to 192.168.100.2[500] (180 bytes)
[NET] received packet: from 192.168.100.2[500] to 192.168.100.113[500] (160 bytes)
[ENC] parsed ID_PROT response 0 [ SA V V V V ]
[IKE] received XAuth vendor ID
[IKE] received DPD vendor ID
[IKE] received FRAGMENTATION vendor ID
[IKE] received NAT-T (RFC 3947) vendor ID
[CFG] selected proposal: IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/CURVE_25519
[ENC] generating ID_PROT request 0 [ KE No NAT-D NAT-D ]
[NET] sending packet: from 192.168.100.113[500] to 192.168.100.2[500] (172 bytes)
[NET] received packet: from 192.168.100.2[500] to 192.168.100.113[500] (172 bytes)
[ENC] parsed ID_PROT response 0 [ KE No NAT-D NAT-D ]
[IKE] remote host is behind NAT
[ENC] generating ID_PROT request 0 [ ID HASH N(INITIAL_CONTACT) ]
[NET] sending packet: from 192.168.100.113[4500] to 192.168.100.2[4500] (124 bytes)
[NET] received packet: from 192.168.100.2[4500] to 192.168.100.113[4500] (92 bytes)
[ENC] parsed ID_PROT response 0 [ ID HASH ]
[IKE] IKE_SA net-net[1] established between 192.168.100.113[sun.strongswan.org]...192.168.100.2[moon.strongswan.org]
[IKE] scheduling rekeying in 13487s
[IKE] maximum IKE_SA lifetime 14927s
initiate completed successfully
#2、查询这里协商ike sa 并未生成ipsec sa,需要手动生成。
root@learning-vpp1:~# swanctl -l
net-net: #1, ESTABLISHED, IKEv1, 32c65d2fe4e1c557_i* a0f0f26def283ba5_r
  local  'sun.strongswan.org' @ 192.168.100.113[4500]
  remote 'moon.strongswan.org' @ 192.168.100.2[4500]
  AES_CBC-128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/CURVE_25519
  established 42s ago, rekeying in 13445s
#3、生成ipsec sa命令
root@learning-vpp1:~# swanctl -i -c net-net
[ENC] generating QUICK_MODE request 3470917660 [ HASH SA No KE ID ID ]
[NET] sending packet: from 192.168.100.113[4500] to 192.168.100.2[4500] (460 bytes)
[NET] received packet: from 192.168.100.2[4500] to 192.168.100.113[4500] (460 bytes)
[ENC] parsed QUICK_MODE response 3470917660 [ HASH SA No KE ID ID ]
[CFG] selected proposal: ESP:AES_CBC_128/HMAC_SHA1_96/MODP_2048/NO_EXT_SEQ
[KNL] UDP encap
[KNL] UDP encap
[KNL] policy have interface 192.168.100.113
[KNL] firstly created, spd for GigabitEthernet0/6/0 found sw_if_index is 1
[KNL] policy FWD interface
[KNL] policy have interface 192.168.100.113
[IKE] CHILD_SA net-net{1} established with SPIs c0173345_i cba88dca_o and TS 192.168.200.0/24 === 192.168.110.0/24
initiate completed successfully
#4、再次查询ipsec sa创建成功。
root@learning-vpp1:~# swanctl -l
net-net: #1, ESTABLISHED, IKEv1, 32c65d2fe4e1c557_i* a0f0f26def283ba5_r
  local  'sun.strongswan.org' @ 192.168.100.113[4500]
  remote 'moon.strongswan.org' @ 192.168.100.2[4500]
  AES_CBC-128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/CURVE_25519
  established 152s ago, rekeying in 13335s
  net-net: #1, reqid 1, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96/MODP_2048
    installed 12s ago, rekeying in 13256s, expires in 15828s
    in  c0173345,      0 bytes,     0 packets
    out cba88dca,      0 bytes,     0 packets
    local  192.168.200.0/24
    remote 192.168.110.0/24

接下来先了解一下ipsec相关的术语,再vpp中查询sad及spd信息

代码语言:javascript复制
#1、查询sa 安全关联信息,用户
vpp# show ipsec sa       
[0] sa 1 (0x1) spi 3222745925 (0xc0173345) protocol:esp flags:[anti-replay tunnel udp-encap inbound ]
[1] sa 2 (0x2) spi 3416821194 (0xcba88dca) protocol:esp flags:[anti-replay tunnel udp-encap ]
##2、查询spd 安全策略数据库信息。
vpp# show ipsec spd
spd 1
 ip4-outbound:
   [7] priority 2883 action bypass type ip4-outbound protocol UDP
     local addr range 0.0.0.0 - 255.255.255.255 port range 4500 - 4500
     remote addr range 0.0.0.0 - 255.255.255.255 port range 4500 - 4500
     packets 1 bytes 108
   [5] priority 2883 action bypass type ip4-outbound protocol UDP
     local addr range 0.0.0.0 - 255.255.255.255 port range 500 - 500
     remote addr range 0.0.0.0 - 255.255.255.255 port range 500 - 500
     packets 0 bytes 0
   [3] priority 2883 action bypass type ip4-outbound protocol IPSEC_AH
     local addr range 0.0.0.0 - 255.255.255.255 port range 0 - 65535
     remote addr range 0.0.0.0 - 255.255.255.255 port range 0 - 65535
     packets 0 bytes 0
   [1] priority 2883 action bypass type ip4-outbound protocol IPSEC_ESP
     local addr range 0.0.0.0 - 255.255.255.255 port range 0 - 65535
     remote addr range 0.0.0.0 - 255.255.255.255 port range 0 - 65535
     packets 0 bytes 0
   [9] priority 2882 action protect type ip4-outbound protocol any sa 2
     local addr range 192.168.200.0 - 192.168.200.255 port range 0 - 65535
     remote addr range 192.168.110.0 - 192.168.110.255 port range 0 - 65535
     packets 0 bytes 0

 ip6-outbound:

 ip4-inbound-protect:
   [8] priority 2882 action protect type ip4-inbound-protect protocol any sa 1
     local addr range 192.168.200.0 - 192.168.200.255 port range 0 - 65535
     remote addr range 192.168.110.0 - 192.168.110.255 port range 0 - 65535
     packets 0 bytes 0

 ip6-inbound-protect:

 ip4-inbound-bypass:
   [6] priority 2883 action bypass type ip4-inbound-bypass protocol UDP
     local addr range 0.0.0.0 - 255.255.255.255 port range 4500 - 4500
     remote addr range 0.0.0.0 - 255.255.255.255 port range 4500 - 4500
     packets 0 bytes 0
   [4] priority 2883 action bypass type ip4-inbound-bypass protocol UDP
     local addr range 0.0.0.0 - 255.255.255.255 port range 500 - 500
     remote addr range 0.0.0.0 - 255.255.255.255 port range 500 - 500
     packets 0 bytes 0
   [2] priority 2883 action bypass type ip4-inbound-bypass protocol IPSEC_AH
     local addr range 0.0.0.0 - 255.255.255.255 port range 0 - 65535
     remote addr range 0.0.0.0 - 255.255.255.255 port range 0 - 65535
     packets 0 bytes 0
   [0] priority 2883 action bypass type ip4-inbound-bypass protocol IPSEC_ESP
     local addr range 0.0.0.0 - 255.255.255.255 port range 0 - 65535
     remote addr range 0.0.0.0 - 255.255.255.255 port range 0 - 65535
     packets 0 bytes 0

 ip6-inbound-bypass:

 ip4-inbound-discard:

 ip6-inbound-discard:

接下来打流验证一下ipsec隧道是否正常通信,需要在vpp1和vpp2系统中分别配置去往两端的路由。

代码语言:javascript复制
#vpp1 系统上配置192.168.110.0/24路由引入到vpp中。
ip route add 192.168.110.0/24 via 192.168.200.1 dev tap0
#vpp2系统上配置192.168.200.0/24路由引入到vpp中。
ip route add 192.168.200.0/24 via 192.168.110.1 dev tap0

在vpp1上面ping对端tap100接口IP地址192.168.110.2可以ping通。

代码语言:javascript复制
root@learning-vpp1:~# ping 192.168.110.2 -I 192.168.200.2
PING 192.168.110.2 (192.168.110.2) from 192.168.200.2 : 56(84) bytes of data.
64 bytes from 192.168.110.2: icmp_seq=1 ttl=62 time=0.917 ms
64 bytes from 192.168.110.2: icmp_seq=2 ttl=62 time=0.355 ms
64 bytes from 192.168.110.2: icmp_seq=3 ttl=62 time=0.350 ms
64 bytes from 192.168.110.2: icmp_seq=4 ttl=62 time=0.451 ms
^C
--- 192.168.110.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3052ms
rtt min/avg/max/mdev = 0.350/0.518/0.917/0.233 ms

下面是在vpp1上抓取ipsec加密及解密trace流程如下:

代码语言:javascript复制
#1、ping request报文trace流程图
13:52:32:110365: virtio-input
  virtio: hw_if_index 3 next-index 4 vring 0 len 98
    hdr: flags 0x00 gso_type 0x00 hdr_len 0 gso_size 0 csum_start 0 csum_offset 0 num_buffers 1
13:52:32:110366: ethernet-input
  frame: flags 0x1, hw-if-index 3, sw-if-index 3
  IP4: ca:b9:d8:0b:d2:2a -> 02:fe:53:3e:6d:0d
13:52:32:110368: ip4-input
  ICMP: 192.168.200.2 -> 192.168.110.2
    tos 0x00, ttl 64, length 84, checksum 0x5c30 dscp CS0 ecn NON_ECN
    fragment id 0x2723, flags DONT_FRAGMENT
  ICMP echo_request checksum 0xf378 id 6
13:52:32:110369: ip4-lookup
  fib 0 dpo-idx 7 flow hash: 0x00000000
  ICMP: 192.168.200.2 -> 192.168.110.2
    tos 0x00, ttl 64, length 84, checksum 0x5c30 dscp CS0 ecn NON_ECN
    fragment id 0x2723, flags DONT_FRAGMENT
  ICMP echo_request checksum 0xf378 id 6
13:52:32:110370: ip4-rewrite
  tx_sw_if_index 1 dpo-idx 7 : ipv4 via 192.168.100.2 GigabitEthernet0/6/0: mtu:9000 next:5 flags:[features ] 525400e31ca652540052388b0800 flow hash: 0x00000000
  00000000: 525400e31ca652540052388b080045000054272340003f015d30c0a8c802c0a8
  00000020: 6e020800f3780006003f22966c6500000000aa730c00000000001011
13:52:32:110370: ipsec4-output-feature
  spd 1 policy 15
13:52:32:110371: esp4-encrypt
  esp: sa-index 7 spi 3390304942 (0xca13f2ae) seq 63 sa-seq-hi 0 crypto aes-cbc-128 integrity sha1-96 udp-encap-enabled
13:52:32:110376: ip4-load-balance
  fib 1 dpo-idx 7 flow hash: 0x00000000
  UDP: 192.168.100.113 -> 192.168.100.2
    tos 0x00, ttl 255, length 160, checksum 0x7188 dscp CS0 ecn NON_ECN
    fragment id 0x0000
  UDP: 4500 -> 4500
    length 140, checksum 0x0000
13:52:32:110377: ip4-rewrite
  tx_sw_if_index 1 dpo-idx 7 : ipv4 via 192.168.100.2 GigabitEthernet0/6/0: mtu:9000 next:5 flags:[features ] 525400e31ca652540052388b0800 flow hash: 0x00000000
  00000000: 525400e31ca652540052388b0800450000a000000000ff117188c0a86471c0a8
  00000020: 640211941194008c0000ca13f2ae0000003fee6baf19a9526939e558
13:52:32:110378: ipsec4-output-feature
  spd 1 policy 7
13:52:32:110378: GigabitEthernet0/6/0-output
  GigabitEthernet0/6/0 flags 0x02180001
  IP4: 52:54:00:52:38:8b -> 52:54:00:e3:1c:a6
  UDP: 192.168.100.113 -> 192.168.100.2
    tos 0x00, ttl 255, length 160, checksum 0x7188 dscp CS0 ecn NON_ECN
    fragment id 0x0000
  UDP: 4500 -> 4500
    length 140, checksum 0x0000
13:52:32:110379: GigabitEthernet0/6/0-tx
  GigabitEthernet0/6/0 tx queue 0
  buffer 0x9708b: current data -52, length 174, buffer-pool 0, ref-count 1, trace handle 0x6
                  local l2-hdr-offset 0 l3-hdr-offset 14 
  PKT MBUF: port 65535, nb_segs 1, pkt_len 174
    buf_len 2176, data_len 174, ol_flags 0x0, data_off 76, phys_addr 0xa09c2340
    packet_type 0x0 l2_len 0 l3_len 0 outer_l2_len 0 outer_l3_len 0 
    rss 0x0 fdir.hi 0x0 fdir.lo 0x0
  IP4: 52:54:00:52:38:8b -> 52:54:00:e3:1c:a6
  UDP: 192.168.100.113 -> 192.168.100.2
    tos 0x00, ttl 255, length 160, checksum 0x7188 dscp CS0 ecn NON_ECN
    fragment id 0x0000
  UDP: 4500 -> 4500
    length 140, checksum 0x0000

#2、ping reply报文trace流程
13:52:32:110575: dpdk-input
  GigabitEthernet0/6/0 rx queue 0
  buffer 0x9c8c0: current data 0, length 174, buffer-pool 0, ref-count 1, trace handle 0x7
                  ext-hdr-valid 
  PKT MBUF: port 0, nb_segs 1, pkt_len 174
    buf_len 2176, data_len 174, ol_flags 0x0, data_off 128, phys_addr 0xa0b23080
    packet_type 0x0 l2_len 0 l3_len 0 outer_l2_len 0 outer_l3_len 0 
    rss 0x0 fdir.hi 0x0 fdir.lo 0x0
  IP4: 52:54:00:e3:1c:a6 -> 52:54:00:52:38:8b
  UDP: 192.168.100.2 -> 192.168.100.113
    tos 0x00, ttl 255, length 160, checksum 0x7188 dscp CS0 ecn NON_ECN
    fragment id 0x0000
  UDP: 4500 -> 4500
    length 140, checksum 0x0000
13:52:32:110588: ethernet-input
  frame: flags 0x1, hw-if-index 1, sw-if-index 1
  IP4: 52:54:00:e3:1c:a6 -> 52:54:00:52:38:8b
13:52:32:110589: ip4-input
  UDP: 192.168.100.2 -> 192.168.100.113
    tos 0x00, ttl 255, length 160, checksum 0x7188 dscp CS0 ecn NON_ECN
    fragment id 0x0000
  UDP: 4500 -> 4500
    length 140, checksum 0x0000
13:52:32:110589: ipsec4-input-feature
  UDP: sa_id 7 type: 0 spd 1 policy 14 spi 3290334885 (0xc41e86a5) seq 63
13:52:32:110590: esp4-decrypt
  esp: crypto aes-cbc-128 integrity sha1-96 pkt-seq 63 sa-seq 63 sa-seq-hi 0 pkt-seq-hi 0
13:52:32:110595: ip4-input-no-checksum
  ICMP: 192.168.110.2 -> 192.168.200.2
    tos 0x00, ttl 63, length 84, checksum 0x38e0 dscp CS0 ecn NON_ECN
    fragment id 0x8b73
  ICMP echo_reply checksum 0xfb78 id 6
13:52:32:110596: ip4-lookup
  fib 0 dpo-idx 6 flow hash: 0x00000000
  ICMP: 192.168.110.2 -> 192.168.200.2
    tos 0x00, ttl 63, length 84, checksum 0x38e0 dscp CS0 ecn NON_ECN
    fragment id 0x8b73
  ICMP echo_reply checksum 0xfb78 id 6
13:52:32:110597: ip4-rewrite
  tx_sw_if_index 3 dpo-idx 6 : ipv4 via 192.168.200.2 tap100: mtu:9000 next:6 flags:[] cab9d80bd22a02fe533e6d0d0800 flow hash: 0x00000000
  00000000: cab9d80bd22a02fe533e6d0d0800450000548b7300003e0139e0c0a86e02c0a8
  00000020: c8020000fb780006003f22966c6500000000aa730c00000000001011
13:52:32:110597: tap100-output
  tap100 flags 0x01180009
  IP4: 02:fe:53:3e:6d:0d -> ca:b9:d8:0b:d2:2a
  ICMP: 192.168.110.2 -> 192.168.200.2
    tos 0x00, ttl 62, length 84, checksum 0x39e0 dscp CS0 ecn NON_ECN
    fragment id 0x8b73
  ICMP echo_reply checksum 0xfb78 id 6
13:52:32:110597: tap100-tx
    buffer 0x9c8c0: current data 52, length 98, buffer-pool 0, ref-count 1, trace handle 0x7
                    ext-hdr-valid 
                    ip4 l2-hdr-offset 0 l3-hdr-offset 14 
  ipv4 hdr-sz 34 l2-hdr-offset 52 l3-hdr-offset 14 l4-hdr-offset 34 l4-hdr-sz 0
  IP4: 02:fe:53:3e:6d:0d -> ca:b9:d8:0b:d2:2a
  ICMP: 192.168.110.2 -> 192.168.200.2
    tos 0x00, ttl 62, length 84, checksum 0x39e0 dscp CS0 ecn NON_ECN
    fragment id 0x8b73
  ICMP echo_reply checksum 0xfb78 id 6

至此,strongswan vpp实现ipsec策略模式转发已经打通,我也是首次接触策略模式处理逻辑,后面会详细分析一下业务处理流程。

0 人点赞