vyos-1x icon indicating copy to clipboard operation
vyos-1x copied to clipboard

DMVPN IPSec T4667: Fix security issue with cleartext GRE escaping when IPSec reconnecting in DMVPN environment

Open jmarmorato opened this issue 3 years ago • 11 comments

Change Summary

Added start_action = trap to data/templates/ipsec/swanctl/profile.j2 This prevents almost all unencrypted GRE packets from escaping DMVPN when IPSec is configured

Types of changes

  • [x] Bug fix (non-breaking change which fixes an issue)
  • [ ] New feature (non-breaking change which adds functionality)
  • [ ] Code style update (formatting, renaming)
  • [ ] Refactoring (no functional changes)
  • [ ] Migration from an old Vyatta component to vyos-1x, please link to related PR inside obsoleted component
  • [ ] Other (please describe):

Related Task(s)

  • https://phabricator.vyos.net/T4667

Component(s) name

IPSec, DMVPN

Proposed changes

Added start_action = trap to data/templates/ipsec/swanctl/profile.j2

How to test

I tested this fix by making the same change in an existing fresh install of VyOS 1.4. Without this fix, all traffic that would normally be encrypted will be sent out of the WAN interface encapsulated, but not encrypted. With the fix in place, only a single NHRP Registration Request is sent in the cleartext. I ran Wireshark to view packets traversing my simulated WAN bridge and confirmed that this fix prevented any application traffic from escaping unencrypted.

Checklist:

  • [x] I have read the CONTRIBUTING document
  • [x] I have linked this PR to one or more Phabricator Task(s)
  • [ ] I have run the components SMOKETESTS if applicable
  • [x] My commit headlines contain a valid Task id
  • [ ] My change requires a change to the documentation
  • [ ] I have updated the documentation accordingly

jmarmorato avatar Sep 01 '22 19:09 jmarmorato

Read, please CONTRIBUTING

Once there is an entry in Phabricator, you should reference its id in your commit message, as shown below:

    ddclient: T1030: auto create runtime directories
    Jenkins: add current Git commit ID to build description

sever-sever avatar Sep 02 '22 09:09 sever-sever

My apologies, I had the pull request include the phabricator ID, not the commit. See new commit message...

jmarmorato avatar Sep 02 '22 17:09 jmarmorato

swanctl states:

Action to perform after loading the configuration. The default of none loads the connection only, which then can be manually initiated or used as a responder configuration. The value trap installs a trap policy which triggers the tunnel as soon as matching traffic has been detected. The value start initiates the connection actively. These two modes can be combined with trap|start, to immediately initiate a connection for which trap policies have been installed. When unloading or replacing a CHILD_SA configuration having a start_action different from none, the inverse action is performed. Configurations with start get closed while those with trap get uninstalled (both happens for connections with trap|start).

c-po avatar Sep 02 '22 18:09 c-po

Maybe it will break regular GRE tunnels without DMVPN

sever-sever avatar Sep 02 '22 18:09 sever-sever

Maybe it will break regular GRE tunnels without DMVPN

Check the file out (original) https://github.com/vyos/vyos-1x/blob/current/data/templates/ipsec/swanctl/profile.j2

My proposed / changed file: https://github.com/jmarmorato/vyos-1x/blob/current/data/templates/ipsec/swanctl/profile.j2

The file opens a block "dmvpn-{{ name }}-{{ interface }}", and a child called "dmvpn" under the "children" block. Also, the fie is in the "ipsec" directory, so I would think this template is only filled and installed when DMVPN is configured with IPSec. Can anyone confirm this?

jmarmorato avatar Sep 02 '22 20:09 jmarmorato

Maybe it will break regular GRE tunnels without DMVPN

Check the file out (original) https://github.com/vyos/vyos-1x/blob/current/data/templates/ipsec/swanctl/profile.j2

My proposed / changed file: https://github.com/jmarmorato/vyos-1x/blob/current/data/templates/ipsec/swanctl/profile.j2

The file opens a block "dmvpn-{{ name }}-{{ interface }}", and a child called "dmvpn" under the "children" block. Also, the fie is in the "ipsec" directory, so I would think this template is only filled and installed when DMVPN is configured with IPSec. Can anyone confirm this?

I mean case when you have DMVPN + regular GRE tunnels without DMVPN. Regular GRE tunnels won't work if you set start_action = trap Check ip xfrm policy

sever-sever avatar Sep 02 '22 20:09 sever-sever

I mean case when you have DMVPN + regular GRE tunnels without DMVPN.

What is DMVPN without DMVPN?

That change only affects tunnels that are used by NHRP and an IPSec profile. Its not related to site2site or remote-access VPN. Or Is there another way where to use IPSec profiles without DMVPN?

c-po avatar Sep 03 '22 05:09 c-po

I mean case when you have DMVPN + regular GRE tunnels without DMVPN.

What is DMVPN without DMVPN?

That change only affects tunnels that are used by NHRP and an IPSec profile. Its not related to site2site or remote-access VPN. Or Is there another way where to use IPSec profiles without DMVPN?

It is related all GRE traffic If tunnel not used in dmvpn/ipsec this traffic also will be dropped For example gre0 for dmvpn and gre 1-4 without ipsec

@zsdc tested it and can confirm that it affected on regular GRE tunnels Policy dropped this traffic Or maybe I’m wrong

sever-sever avatar Sep 03 '22 06:09 sever-sever

@sever-sever is right if we use start_action = trap all gre traffic will pass through trap policy

vyos@vyos:~$ sudo swanctl -P
dmvpn-NHRPVPN-tun100/dmvpn, TRANSPORT
  local:  0.0.0.0/0[gre]
  remote: 0.0.0.0/0[gre]

I created a lab with DMVP with encryption and 1 GRE without encryption on the spoke router. GRE tunnel without encryption did not work.

aapostoliuk avatar Sep 05 '22 10:09 aapostoliuk

@zdc @aapostoliuk can you please share your configuration? Was the ip key parameter used?

c-po avatar Sep 15 '22 14:09 c-po

@c-po

set interfaces ethernet eth0 address '10.0.2.20/24'
set interfaces ethernet eth1 address '192.168.2.1/24'

set interfaces tunnel tun100 address '10.10.100.2/24'
set interfaces tunnel tun100 encapsulation 'gre'
set interfaces tunnel tun100 multicast 'enable'
set interfaces tunnel tun100 parameters ip key '1'
set interfaces tunnel tun100 source-address '10.0.2.20'

set interfaces tunnel tun101 address '10.10.101.1/30'
set interfaces tunnel tun101 encapsulation 'gre'
set interfaces tunnel tun101 remote '10.0.2.10'
set interfaces tunnel tun101 source-interface 'eth0'

set protocols bgp address-family ipv4-unicast network 192.168.2.0/24
set protocols bgp neighbor 10.10.100.1 address-family ipv4-unicast
set protocols bgp neighbor 10.10.100.1 remote-as '65000'
set protocols bgp parameters router-id '2.2.2.2'
set protocols bgp system-as '65000'
set protocols nhrp tunnel tun100 cisco-authentication 'dmvpn'
set protocols nhrp tunnel tun100 holding-time '300'
set protocols nhrp tunnel tun100 map 10.10.100.1/24 nbma-address '10.0.1.2'
set protocols nhrp tunnel tun100 map 10.10.100.1/24 register
set protocols nhrp tunnel tun100 multicast 'nhs'
set protocols nhrp tunnel tun100 redirect
set protocols nhrp tunnel tun100 shortcut
set protocols static route 0.0.0.0/0 next-hop 10.0.2.1

set vpn ipsec esp-group ESP-HUB compression 'disable'
set vpn ipsec esp-group ESP-HUB lifetime '1800'
set vpn ipsec esp-group ESP-HUB mode 'transport'
set vpn ipsec esp-group ESP-HUB pfs 'dh-group2'
set vpn ipsec esp-group ESP-HUB proposal 1 encryption 'aes256'
set vpn ipsec esp-group ESP-HUB proposal 1 hash 'sha1'
set vpn ipsec esp-group ESP-HUB proposal 2 encryption '3des'
set vpn ipsec esp-group ESP-HUB proposal 2 hash 'md5'
set vpn ipsec ike-group ESP-HUB lifetime '300'

set vpn ipsec ike-group IKE-HUB close-action 'restart'
set vpn ipsec ike-group IKE-HUB dead-peer-detection action 'restart'
set vpn ipsec ike-group IKE-HUB dead-peer-detection interval '3'
set vpn ipsec ike-group IKE-HUB dead-peer-detection timeout '30'
set vpn ipsec ike-group IKE-HUB ikev2-reauth 'no'
set vpn ipsec ike-group IKE-HUB key-exchange 'ikev2'
set vpn ipsec ike-group IKE-HUB lifetime '600'
set vpn ipsec ike-group IKE-HUB proposal 1 dh-group '2'
set vpn ipsec ike-group IKE-HUB proposal 1 encryption 'aes256'
set vpn ipsec ike-group IKE-HUB proposal 1 hash 'sha1'
set vpn ipsec ike-group IKE-HUB proposal 2 dh-group '2'
set vpn ipsec ike-group IKE-HUB proposal 2 encryption 'aes128'
set vpn ipsec ike-group IKE-HUB proposal 2 hash 'sha1'

set vpn ipsec interface 'eth0'

set vpn ipsec profile NHRPVPN authentication mode 'pre-shared-secret'
set vpn ipsec profile NHRPVPN authentication pre-shared-secret 'dmvpn'
set vpn ipsec profile NHRPVPN bind tunnel 'tun100'
set vpn ipsec profile NHRPVPN esp-group 'ESP-HUB'
set vpn ipsec profile NHRPVPN ike-group 'IKE-HUB'

swanctl.conf

### Autogenerated by vpn_ipsec.py ###

connections {
    dmvpn-NHRPVPN-tun100 {
        proposals = aes256-sha1-modp1024,aes128-sha1-modp1024
        version = 2
        rekey_time = 600s
        keyingtries = 0
        dpd_timeout = 30
        dpd_delay = 3
        local {
            auth = psk
        }
        remote {
            auth = psk
        }
        children {
            dmvpn {
                esp_proposals = aes256-sha1-modp1024,3des-md5-modp1024
                rekey_time = 1800s
                rand_time = 540s
                local_ts = dynamic[gre]
                remote_ts = dynamic[gre]
                mode = transport
                dpd_action = restart
                start_action = trap
            }
        }
    }

}

pools {
}

secrets {
    ike-dmvpn-tun100 {
        secret = dmvpn
    }
}

vyos@vyos:~$ sudo swanctl -P
dmvpn-NHRPVPN-tun100/dmvpn, TRANSPORT
  local:  0.0.0.0/0[gre]
  remote: 0.0.0.0/0[gre]
--- 10.10.100.1 ping statistics ---
7 packets transmitted, 7 received, 0% packet loss, time 6013ms
rtt min/avg/max/mdev = 2.045/2.758/4.654/0.836 ms
--- 10.10.101.2 ping statistics ---
6 packets transmitted, 0 received, 100% packet loss, time 5097ms

From tcpdump I see that router try initiate IKE connection to 10.0.2.10

vyos@vyos:~$ sudo tcpdump -i eth0 dst 10.0.2.10
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
08:07:48.908782 IP 10.0.2.20.isakmp > 10.0.2.10.isakmp: isakmp: parent_sa ikev2_init[I]
08:07:52.909444 IP 10.0.2.20.isakmp > 10.0.2.10.isakmp: isakmp: parent_sa ikev2_init[I]
08:07:53.923838 ARP, Reply 10.0.2.20 is-at 0c:bb:21:9c:00:00 (oui Unknown), length 28
08:07:54.090162 ARP, Request who-has 10.0.2.10 tell 10.0.2.20, length 28
08:08:00.111313 IP 10.0.2.20.isakmp > 10.0.2.10.isakmp: isakmp: parent_sa ikev2_init[I]
08:08:13.072331 IP 10.0.2.20.isakmp > 10.0.2.10.isakmp: isakmp: parent_sa ikev2_init[I]

aapostoliuk avatar Sep 16 '22 08:09 aapostoliuk

What happens if tun101 is configured with gre ip key 2?

c-po avatar Jan 21 '23 17:01 c-po

What happens if tun101 is configured with gre ip key 2?

Checked. The result is the same.

aapostoliuk avatar Jan 25 '23 15:01 aapostoliuk

Okay, after a very long time I can confirm the follwoing:

Topology

image

spoke02

Using VyOS 1.5-rolling-202311250022 with the patch in question both a DMVPN and a regular GRE tunnel work.

set interfaces ethernet eth0 address 'dhcp'
set interfaces ethernet eth1 address '192.0.2.0/31'
set interfaces tunnel tun0 address '10.0.0.1/30'
set interfaces tunnel tun0 encapsulation 'gre'
set interfaces tunnel tun0 parameters ip key '2'
set interfaces tunnel tun0 remote '192.0.2.1'
set interfaces tunnel tun0 source-interface 'eth1'
set interfaces tunnel tun100 address '172.16.253.130/29'
set interfaces tunnel tun100 enable-multicast
set interfaces tunnel tun100 encapsulation 'gre'
set interfaces tunnel tun100 parameters ip key '1'
set interfaces tunnel tun100 source-address '0.0.0.0'
set protocols nhrp tunnel tun100 cisco-authentication 'secret'
set protocols nhrp tunnel tun100 holding-time '300'
set protocols nhrp tunnel tun100 map 172.16.253.134/29 nbma-address '172.18.200.10'
set protocols nhrp tunnel tun100 map 172.16.253.134/29 register
set protocols nhrp tunnel tun100 multicast 'nhs'
set protocols nhrp tunnel tun100 redirect
set protocols nhrp tunnel tun100 shortcut
set service ssh
set system config-management commit-revisions '100'
set system conntrack modules ftp
set system conntrack modules h323
set system conntrack modules nfs
set system conntrack modules pptp
set system conntrack modules sip
set system conntrack modules sqlnet
set system conntrack modules tftp
set system console device ttyS0 speed '115200'
set system host-name 'spoke-02'
set system login user vyos authentication encrypted-password '$6$R.OnGzfXSfl6J$Iba/hl9bmjBs0VPtZ2zdW.Snh/nHuvxUwi0R6ruypgW63iKEbicJH.uUst8xZCyByURblxRtjAC1lAnYfIt.b0'
set system login user vyos authentication plaintext-password ''
set system name-server 'eth0'
set system syslog global facility all level 'info'
set system syslog global facility local7 level 'debug'
set vpn ipsec authentication psk peer_192-0-2-1 id '192.0.2.0'
set vpn ipsec authentication psk peer_192-0-2-1 id '192.0.2.1'
set vpn ipsec authentication psk peer_192-0-2-1 secret 'MYSECRETKEY'
set vpn ipsec esp-group ESP-HUB lifetime '1800'
set vpn ipsec esp-group ESP-HUB mode 'transport'
set vpn ipsec esp-group ESP-HUB pfs 'dh-group2'
set vpn ipsec esp-group ESP-HUB proposal 1 encryption 'aes256'
set vpn ipsec esp-group ESP-HUB proposal 1 hash 'sha1'
set vpn ipsec esp-group ESP-HUB proposal 2 encryption '3des'
set vpn ipsec esp-group ESP-HUB proposal 2 hash 'md5'
set vpn ipsec esp-group MyESPGroup lifetime '3600'
set vpn ipsec esp-group MyESPGroup mode 'tunnel'
set vpn ipsec esp-group MyESPGroup pfs 'enable'
set vpn ipsec esp-group MyESPGroup proposal 1 encryption 'aes128'
set vpn ipsec esp-group MyESPGroup proposal 1 hash 'sha1'
set vpn ipsec ike-group IKE-HUB close-action 'none'
set vpn ipsec ike-group IKE-HUB key-exchange 'ikev1'
set vpn ipsec ike-group IKE-HUB lifetime '3600'
set vpn ipsec ike-group IKE-HUB proposal 1 dh-group '2'
set vpn ipsec ike-group IKE-HUB proposal 1 encryption 'aes256'
set vpn ipsec ike-group IKE-HUB proposal 1 hash 'sha1'
set vpn ipsec ike-group IKE-HUB proposal 2 dh-group '2'
set vpn ipsec ike-group IKE-HUB proposal 2 encryption 'aes128'
set vpn ipsec ike-group IKE-HUB proposal 2 hash 'sha1'
set vpn ipsec ike-group MyIKEGroup close-action 'none'
set vpn ipsec ike-group MyIKEGroup key-exchange 'ikev2'
set vpn ipsec ike-group MyIKEGroup lifetime '28800'
set vpn ipsec ike-group MyIKEGroup proposal 1 dh-group '2'
set vpn ipsec ike-group MyIKEGroup proposal 1 encryption 'aes128'
set vpn ipsec ike-group MyIKEGroup proposal 1 hash 'sha1'
set vpn ipsec interface 'eth0'
set vpn ipsec interface 'eth1'
set vpn ipsec profile NHRPVPN authentication mode 'pre-shared-secret'
set vpn ipsec profile NHRPVPN authentication pre-shared-secret 'secret'
set vpn ipsec profile NHRPVPN bind tunnel 'tun100'
set vpn ipsec profile NHRPVPN esp-group 'ESP-HUB'
set vpn ipsec profile NHRPVPN ike-group 'IKE-HUB'
set vpn ipsec site-to-site peer peer_192-0-2-1 authentication local-id '192.0.2.0'
set vpn ipsec site-to-site peer peer_192-0-2-1 authentication mode 'pre-shared-secret'
set vpn ipsec site-to-site peer peer_192-0-2-1 authentication remote-id '192.0.2.1'
set vpn ipsec site-to-site peer peer_192-0-2-1 connection-type 'respond'
set vpn ipsec site-to-site peer peer_192-0-2-1 default-esp-group 'MyESPGroup'
set vpn ipsec site-to-site peer peer_192-0-2-1 ike-group 'MyIKEGroup'
set vpn ipsec site-to-site peer peer_192-0-2-1 ikev2-reauth 'inherit'
set vpn ipsec site-to-site peer peer_192-0-2-1 local-address '192.0.2.0'
set vpn ipsec site-to-site peer peer_192-0-2-1 remote-address '192.0.2.1'
set vpn ipsec site-to-site peer peer_192-0-2-1 tunnel 1 protocol 'gre'

gre-ipsec

Running 1.4-rolling-202311011332 with the configuration

set interfaces ethernet eth1 address '192.0.2.1/31'
set interfaces tunnel tun0 address '10.0.0.2/30'
set interfaces tunnel tun0 encapsulation 'gre'
set interfaces tunnel tun0 parameters ip key '2'
set interfaces tunnel tun0 remote '192.0.2.0'
set interfaces tunnel tun0 source-interface 'eth1'
set service
set system config-management commit-revisions '100'
set system conntrack modules ftp
set system conntrack modules h323
set system conntrack modules nfs
set system conntrack modules pptp
set system conntrack modules sip
set system conntrack modules sqlnet
set system conntrack modules tftp
set system console device ttyS0 speed '115200'
set system host-name 'gre-test'
set system login user vyos authentication encrypted-password '$6$BjKJWG6UhcrwMN.v$VJp351f2pM2XLwvCSGV7Zg/NFaHq17MR/eq0c/7lKipGzbumLYW9biqUEdOEHSDubZbp5mVglWVDtS89T8MO4.'
set system login user vyos authentication plaintext-password ''
set system syslog global facility all level 'info'
set system syslog global facility local7 level 'debug'
set vpn ipsec authentication psk vyos id '192.0.2.0'
set vpn ipsec authentication psk vyos id '192.0.2.1'
set vpn ipsec authentication psk vyos secret 'MYSECRETKEY'
set vpn ipsec esp-group MyESPGroup proposal 1 encryption 'aes128'
set vpn ipsec esp-group MyESPGroup proposal 1 hash 'sha1'
set vpn ipsec ike-group MyIKEGroup key-exchange 'ikev2'
set vpn ipsec ike-group MyIKEGroup proposal 1 dh-group '2'
set vpn ipsec ike-group MyIKEGroup proposal 1 encryption 'aes128'
set vpn ipsec ike-group MyIKEGroup proposal 1 hash 'sha1'
set vpn ipsec interface 'eth1'
set vpn ipsec site-to-site peer GRE-TEST authentication local-id '192.0.2.1'
set vpn ipsec site-to-site peer GRE-TEST authentication mode 'pre-shared-secret'
set vpn ipsec site-to-site peer GRE-TEST authentication remote-id '192.0.2.0'
set vpn ipsec site-to-site peer GRE-TEST connection-type 'respond'
set vpn ipsec site-to-site peer GRE-TEST default-esp-group 'MyESPGroup'
set vpn ipsec site-to-site peer GRE-TEST ike-group 'MyIKEGroup'
set vpn ipsec site-to-site peer GRE-TEST local-address '192.0.2.1'
set vpn ipsec site-to-site peer GRE-TEST remote-address '192.0.2.0'
set vpn ipsec site-to-site peer GRE-TEST tunnel 1 protocol 'gre'

tcpdump

I see proper ESP packets on both links inside EVE-NG environment

image

c-po avatar Nov 25 '23 19:11 c-po

@sever-sever pointed out that the above configuration might be correct for IPSec encapsulated GRE tunnels, but unencrypted GRE tunnels will break. This is confirmed by a simple GRE tunnel using

set interfaces tunnel tun1 address '10.0.0.6/30'
set interfaces tunnel tun1 encapsulation 'gre'
set interfaces tunnel tun1 parameters ip key '10'
set interfaces tunnel tun1 remote '192.0.2.128'
set interfaces tunnel tun1 source-interface 'eth2'

after extending the topolog ywith a GRE only node

image

It is confirmed working on VyOS 1.3.4

c-po avatar Nov 25 '23 21:11 c-po

@vyos/maintainers I'm thinking of closing this PR as this solution is breaking the regular GRE tunnels (without DMVPN) So there should be another solution.

sever-sever avatar Dec 08 '23 20:12 sever-sever

... Working on other solution with @sarthurdev

c-po avatar Dec 14 '23 16:12 c-po