-
Notifications
You must be signed in to change notification settings - Fork 710
VPP IPSec
Two flavours of IPSec are available: Tunnel and Policy mode.
An IP-in-IP or GRE tunnel is 'protected' by a pair of Security Associations (SA) - one for inbound/local traffic and one for outbound/remote. All ESP packets whose SPI matches that of the inbound SA are 'classified' to have arrived on the tunnel. All packets that egress the tunnel are ESP protected using the outbound SA.
The current (deprecated) model for creating such a protected tunnel is a dedicated interface type; either ipsec or ipsec-gre. These are created e.g.;
create ipsec tunnel local-ip 10.0.0.1 remote-ip 10.0.0.2 local-spi 100 remote-spi 101 local-crypto-key A11E51E5B1E0 remote-crypto-key A11E51E5B1E0 crypto-alg aes-gcm-128
This command will create: one tunnel ipsecX and two associated SAs.
DBGvpp# sh int
Name Idx State MTU (L3/IP4/IP6/MPLS) Counter Count
ipsec0 6 up 9000/0/0/0
DBGvpp# sh ipsec sa
[0] sa 0x80000000 spi 101 mode tunnel protocol esp tunnel
[1] sa 0xc0000000 spi 100 mode tunnel protocol esp tunnel
DBGvpp# sh ipsec tun
Tunnel interfaces
ipsec0
out-bound sa: [1] sa 0xc0000000 spi 100 mode tunnel protocol esp tunnel
in-bound sa: [0] sa 0x80000000 spi 101 mode tunnel protocol esp tunnel
There are several drawbacks to this approach:
-
- for the API user to know the ID/index of the created SAs (in order to read stats) it must use the dump API s to determine which SAs are associated with the tunnel. The SAs have an automatically generated SA-ID.
-
- VPP has two interface types, ipsec and -ipsec-gre, that act exactly like a IP-in-IP and GRE tunnel respectively that have ESP as an output feature
-
- the API above is a concatenation of the 'create ipip tunnel ...' and 'ipsec sa add ...' APIs and needs to track changes in both.
-
- the user has no control over whether the ESP mode is tunnel mode or transport mode.
A separation of the creation of the interface, SAs and the protection that they provide:
create ipip tunnel src 10.0.0.1 dst 10.0.0.2
ipsec sa add 20 spi 200 crypto-key 6541686776336961656264656f6f6579 crypto-alg aes-gcm-128
ipsec sa add 30 spi 300 crypto-key 6541686776336961656264656f6f6579 crypto-alg aes-gcm-128
ipsec tunnel protect ipip0 sa-in 20 sa-out 30
This results in:
DBGvpp# sh int
Name Idx State MTU (L3/IP4/IP6/MPLS) Counter Count
ipip0 6 up 9000/0/0/0
DBGvpp# sh ipsec sa
[0] sa 0x14 spi 200 mode transport protocol esp
[1] sa 0x1e spi 300 mode transport protocol esp
DBGvpp# sh ipsec protect
ipip0
output-sa:
[1] sa 0x1e spi 300 mode transport protocol esp
input-sa:
[0] sa 0x14 spi 200 mode transport protocol esp
Note that the SAs are in transport mode. For tunnels the ESP acts on the post-encapsulated packet. So if this packet:
+---------+------+
| Payload | O-IP |
+---------+------+
where O-IP is the overlay IP addrees that was routed into the tunnel, the resulting encapsulated packet will be:
+---------+------+------+
| Payload | O-IP | T-IP |
+---------+------+------+
where T-IP is the tunnel's src.dst IP addresses. If the SAs used for protection are in transport mode then the ESP is inserted before T-IP, i.e.:
+---------+------+-----+------+
| Payload | O-IP | ESP | T-IP |
+---------+------+-----+------+
If the SAs used for protection are in tunnel mode then another encapsulation occurs, i.e.:
+---------+------+------+-----+------+
| Payload | O-IP | T-IP | ESP | C-IP |
+---------+------+------+-----+------+
where C-IP are the crypto endpoint IP addresses defined as the tunnel endpoints in the SA. The mode for the inbound and outbound SA must be the same.
This approach solves all the above drawbacks:
-
- the user is directly responsible fro constructing the SAs so knows their identity.
-
- we reuse the existing IP-in-IP (or GRE) tunnel
-
- re-use of the separate APIs for the creation of the tunnel and SAs
-
- the mode of the SA controls the mode of the ESP encapsulation.
The drawback, from the user's perspective, is that what used to take 1 API call now takes 4.
For VPP code this introduces a new data-type, an ipsec-tun-protection, which acts as the 'binding' between the tunnel and its associated SAs.
Rekeying a tunnel is achevied by updating the tunnel protection to provide the new set of protecting SAs. It is also possible to rekey a tunnel in 3 phases to achieve a make-before break:T
-
- the inbould set of SAs includes both the old and the new inbound SA
ipsec tun protect ipip0 sa-in [old, new] sa-out old
-
- after some time (when it is considered the peer has updated to the new inbound SA) we switch to using the new outbound SA.
ipsec tun protect ipip0 sa-in [old, new] sa-out new
-
- after some more time or when the SA stats say traffic has arrived on the new inbound SA, we can safely remove the old inbound SA
ipsec tun protect ipip0 sa-in [new] sa-out new
IPSec is also supported on multi-point tunnels (currently for IP-in-IP and GRE).
In P2P mode the protecting SAs apply to all the traffic egressing/ingressing the tunnel - one can also think of this as the SA protects all traffic going to/from the only peer on the link. Likewise, since there's only one peer, there's also only one 'destination' for the tunnel - hence a tunnel can be considered as having a source and destination. When we switch to multi-point interfaces, then there is more than one peer on the link and hence more than one tunnel 'destination'. So we create a multi-point tunnel with its own subnet:
create ipip tunnel src 10.0.0.1 p2mp
set int ip addr ipip0 192.168.0.1/24
there are thus up to 256 peers on this link. this is the 'overlay'. But how is each of the peers reachable - i.e. what is there 'destination' in the underlay. This mapping between the overlay and underlay address is populated in the Tunnel Endpoint Information Base (TEIB). Control plane protocols like Next-Hop Resolution Protocol (NHRP) can provide these sorts of mappings. To programme an entry in the TEIB:
create teib ipip0 peer 192.168.0.2 nh 10.1.1.1
What's the point of multipoint interfaces? Why not just create multiple p2p interfaces to each peer, each with a different subnet? Scale! interfaces are not cheap. Otherwise both solutions provide the same functionality.
The consequences for IPSec when we switch to multi-point interfaces, are that the SAs protect a specific peer on the link. So we create SAs as usual, then when adding tunnel protection, we must specify which peer on the link the SA applies to:
create ipip tunnel src 10.0.0.1 p2mp
set int ip addr ipip0 192.168.0.1/24
ipsec sa add 20 spi 200 crypto-key A11E51E5B111 crypto-alg aes-gcm-128
ipsec sa add 30 spi 300 crypto-key A11E51E5B222 crypto-alg aes-gcm-128
ipsec tunnel protect ipip0 sa-in 20 sa-out 30 nh 192.168.0.2
and that's all there is to it.
Policy mode follows the use of IPSec as described in RFC4301.
First an SPD is created:
ipsec spd add 1
SAs are created to protected traffic:
ipsec sa add id 2 spi X ...
that match given policies:
ipsec policy add spd AA action .. sa 2 [inbound|outbound] [match criteria]
then the SPD is applied to an interface:
set interface ipsec spd eth0 AA
traffic that ingresses and egresses eth0 is subject to the inbound and outbound policies respectively of the SPD
There are many implementations for IPSec that are open sourced, principally there is the suite of implementations (both SW and HW) that are provided by the DPDK crypto-devices and openSSL. As of 19.04 VPP also has its own IPSec implementation that makes use of Intel's vector cyptographic instructions.
There are two, slightly overlapping, mechanisms to choose an implementation; backends and engines. Engines were introduced in 19.04 and is the preferred mechanism we are migrating away from backends as time and resource permits.
Engines and/or backends apply to both modes of IPSec as described above.
As of 19.04 there are only two backends; native (i.e. use engined - the default) and DPDK (provided by the dpdk plugin). Backends must provide their own ESP and/or AH VPP nodes to perform the packet encrypt and decrypt -in other words a backend must provide the full packet switch path. This is a real barrier to the use of some new crypto library and a significant effort for the community to support.
DBGvpp# sh ipsec backends
IPsec AH backends available:
Name Index Active
crypto engine backend 0 yes
IPsec ESP backends available:
Name Index Active
crypto engine backend 0 yes
dpdk backend 1 no
The default IPSEc backend makes use of 'engines' that provide a byte stream based encrypt/decrypt service. The API between VPP and the engine is represented as an 'operation'. Each operation specifies, e.g., the algorithm[s] and keys and the address of the data to encrypt and the location to place any output.
There are three engines to choose from:
DBGvpp# sh crypto engines
Name Prio Description
ia32 100 Intel IA32 ISA Optimized Crypto
ipsecmb 80 Intel(R) Multi-Buffer Crypto for IPsec Library 0.52.0
openssl 50 OpenSSL
The engines are all plugins. Each engine registers at a given priority and indicates its capability to support a particular cryptographic algorithm. Not all engines support all algorithms. The engines are listed above in priority order.
DBGvpp# sh crypto handlers
Algo Type Active Candidates
des-cbc encrypt openssl openssl
decrypt openssl openssl
3des-cbc encrypt openssl openssl
decrypt openssl openssl
aes-128-cbc encrypt ia32 ia32 ipsecmb openssl
decrypt ia32 ia32 ipsecmb openssl
aes-192-cbc encrypt ia32 ia32 ipsecmb openssl
decrypt ia32 ia32 ipsecmb openssl
aes-256-cbc encrypt ia32 ia32 ipsecmb openssl
decrypt ia32 ia32 ipsecmb openssl
aes-128-ctr encrypt openssl openssl
decrypt openssl openssl
aes-192-ctr encrypt openssl openssl
decrypt openssl openssl
aes-256-ctr encrypt openssl openssl
decrypt openssl openssl
aes-128-gcm aead-encrypt ipsecmb ipsecmb openssl
aead-decrypt ipsecmb ipsecmb openssl
aes-192-gcm aead-encrypt ipsecmb ipsecmb openssl
aead-decrypt ipsecmb ipsecmb openssl
aes-256-gcm aead-encrypt ipsecmb ipsecmb openssl
aead-decrypt ipsecmb ipsecmb openssl
hmac-md5 hmac openssl openssl
hmac-sha-1 hmac ipsecmb ipsecmb openssl
hmac-sha-224 hmac ipsecmb ipsecmb openssl
hmac-sha-256 hmac ipsecmb ipsecmb openssl
hmac-sha-384 hmac ipsecmb ipsecmb openssl
hmac-sha-512 hmac ipsecmb ipsecmb openssl
- VPP 2022 Make Test Use Case Poll
- VPP-AArch64
- VPP-ABF
- VPP Alternative Builds
- VPP API Concepts
- VPP API Versioning
- VPP-ApiChangeProcess
- VPP-ArtifactVersioning
- VPP-BIER
- VPP-Bihash
- VPP-BugReports
- VPP Build System Deep Dive
- VPP Build, Install, And Test Images
- VPP-BuildArtifactRetentionPolicy
- VPP-c2cpel
- VPP Code Walkthrough VoD
- VPP Code Walkthrough VoD Topic Index
- VPP Code Walkthrough VoDs
- VPP-CodeStyleConventions
- VPP-CodingTips
- VPP Command Line Arguments
- VPP Command Line Interface CLI Guide
- VPP-CommitMessages
- VPP-Committers-SMEs
- VPP-CommitterTasks-ApiFreeze
- VPP CommitterTasks Compare API Changes
- VPP-CommitterTasks-CutPointRelease
- VPP-CommitterTasks-CutRelease
- VPP-CommitterTasks-FinalReleaseCandidate
- VPP-CommitterTasks-PullThrottleBranch
- VPP-CommitterTasks-ReleasePlan
- VPP Configuration Tool
- VPP Configure An LW46 MAP E Terminator
- VPP Configure VPP As A Router Between Namespaces
- VPP Configure VPP TAP Interfaces For Container Routing
- VPP-CoreFileMismatch
- VPP-cpel
- VPP-cpeldump
- VPP-CurrentData
- VPP-DHCPKit
- VPP-DHCPv6
- VPP-DistributedOwnership
- VPP-Documentation
- VPP DPOs And Feature Arcs
- VPP EC2 Instance With SRIOV
- VPP-elog
- VPP-FAQ
- VPP Feature Arcs
- VPP-Features
- VPP-Features-IPv6
- VPP-FIB
- VPP-g2
- VPP Getting VPP 16.06
- VPP Getting VPP Release Binaries
- VPP-HA
- VPP-HostStack
- VPP-HostStack-BuiltinEchoClientServer
- VPP-HostStack-EchoClientServer
- VPP-HostStack-ExternalEchoClientServer
- VPP HostStack Hs Test
- VPP-HostStack-LDP-iperf
- VPP-HostStack-LDP-nginx
- VPP-HostStack-LDP-sshd
- VPP-HostStack-nginx
- VPP-HostStack-SessionLayerArchitecture
- VPP-HostStack-TestHttpServer
- VPP-HostStack-TestProxy
- VPP-HostStack-TLS
- VPP-HostStack-VCL
- VPP-HostStack-VclEchoClientServer
- VPP-Hotplug
- VPP How To Add A Tunnel Encapsulation
- VPP How To Build The Sample Plugin
- VPP How To Connect A PCI Interface To VPP
- VPP How To Create A VPP Binary Control Plane API
- VPP How To Deploy VPP In EC2 Instance And Use It To Connect Two Different VPCs
- VPP How To Optimize Performance %28System Tuning%29
- VPP How To Use The API Trace Tools
- VPP How To Use The C API
- VPP How To Use The Packet Generator And Packet Tracer
- VPP-Howtos
- VPP-index
- VPP Installing VPP Binaries From Packages
- VPP Interconnecting vRouters With VPP
- VPP Introduction To IP Adjacency
- VPP Introduction To N Tuple Classifiers
- VPP IP Adjacency Introduction
- VPP-IPFIX
- VPP-IPSec
- VPP IPSec And IKEv2
- VPP IPv6 SR VIRL Topology File
- VPP Java API
- VPP Java API Plugin Support
- VPP Jira Workflow
- VPP-Macswapplugin
- VPP-MakeTestFramework
- VPP-Meeting
- VPP-MFIB
- VPP Missing Prefetches
- VPP Modifying The Packet Processing Directed Graph
- VPP MPLS FIB
- VPP-NAT
- VPP Nataas Test
- VPP-OVN
- VPP Per Feature Notes
- VPP Performance Analysis Tools
- VPP-perftop
- VPP Progressive VPP Tutorial
- VPP Project Meeting Minutes
- VPP Pulling, Building, Running, Hacking And Pushing VPP Code
- VPP Pure L3 Between Namespaces With 32s
- VPP Pure L3 Container Networking
- VPP Pushing And Testing A Tag
- VPP Python API
- VPP-PythonVersionPolicy
- VPP-QuickTrexSetup
- VPP Random Hints And Kinks For KVM Usage
- VPP Release Plans Release Plan 16.09
- VPP Release Plans Release Plan 17.01
- VPP Release Plans Release Plan 17.04
- VPP Release Plans Release Plan 17.07
- VPP Release Plans Release Plan 17.10
- VPP Release Plans Release Plan 18.01
- VPP Release Plans Release Plan 18.04
- VPP Release Plans Release Plan 18.07
- VPP Release Plans Release Plan 18.10
- VPP Release Plans Release Plan 19.01
- VPP Release Plans Release Plan 19.04
- VPP Release Plans Release Plan 19.08
- VPP Release Plans Release Plan 20.01
- VPP Release Plans Release Plan 20.05
- VPP Release Plans Release Plan 20.09
- VPP Release Plans Release Plan 21.01
- VPP Release Plans Release Plan 21.06
- VPP Release Plans Release Plan 21.10
- VPP Release Plans Release Plan 22.02
- VPP Release Plans Release Plan 22.06
- VPP Release Plans Release Plan 22.10
- VPP Release Plans Release Plan 23.02
- VPP Release Plans Release Plan 23.06
- VPP Release Plans Release Plan 23.10
- VPP Release Plans Release Plan 24.02
- VPP Release Plans Release Plan 24.06
- VPP Release Plans Release Plan 24.10
- VPP Release Plans Release Plan 25.02
- VPP Release Plans Release Plan 25.06
- VPP Release Plans Release Plan 25.10
- VPP Release Plans Release Plan 26.02
- VPP Release Plans Release Plan 26.06
- VPP-RM
- VPP-SecurityGroups
- VPP Segment Routing For IPv6
- VPP Segment Routing For MPLS
- VPP Setting Up Your Dev Environment
- VPP-SNAT
- VPP Software Architecture
- VPP STN Testing
- VPP The VPP API
- VPP Training Events
- VPP-Troubleshooting
- VPP-Troubleshooting-BuildIssues
- VPP-Troubleshooting-Vagrant
- VPP Tutorial DPDK And MacSwap
- VPP Tutorial Routing And Switching
- VPP-Tutorials
- VPP Use VPP To Chain VMs Using Vhost User Interface
- VPP Use VPP To Connect VMs Using Vhost User Interface
- VPP Using mTCP User Mode TCP Stack With VPP
- VPP Using VPP As A VXLAN Tunnel Terminator
- VPP Using VPP In A Multi Thread Model
- VPP-VOM
- VPP VPP BFD Nexus
- VPP VPP Home Gateway
- VPP VPP WIKI DEPRECATED CONTENT
- VPP-VPPCommunicationsLibrary
- VPP-VPPConfig
- VPP What Is ODP4VPP
- VPP What Is VPP
- VPP Working Environments
- VPP Working With The 16.06 Throttle Branch