.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in Open vSwitch documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ======================================= Encrypt Open vSwitch Tunnels with IPsec ======================================= This document gives detailed description on the OVS IPsec tunnel and its configuration modes. If you want to follow a step-by-step guide to run and test IPsec tunnel, please refer to :doc:`/tutorials/ipsec`. Overview -------- Why do encryption? ~~~~~~~~~~~~~~~~~~ OVS tunnel packets are transported from one machine to another. Along the path, the packets are processed by physical routers and physical switches. There are risks that these physical devices might read or write the contents of the tunnel packets. IPsec encrypts IP payload and prevents the malicious party sniffing or manipulating the tunnel traffic. OVS IPsec ~~~~~~~~~ OVS IPsec aims to provide a simple interface for user to add encryption on OVS tunnels. It supports GRE, GENEVE, VXLAN, and STT tunnel. The IPsec configuration is done by setting options of the tunnel interface and other_config of Open_vSwitch. You can choose different authentication methods and plaintext tunnel policies based on your requirements. OVS does not currently provide any support for IPsec encryption for traffic not encapsulated in a tunnel. Configuration ------------- Authentication Methods ~~~~~~~~~~~~~~~~~~~~~~ Hosts of the IPsec tunnel need to authenticate each other to build a secure channel. There are three authentication methods: 1) You can use a pre-shared key (PSK) to do authentication. In both hosts, set the same PSK value. This PSK is like your password. You should never reveal it to untrusted parties. This method is easier to use but less secure than the certificate-based methods:: $ ovs-vsctl add-port br0 ipsec_gre0 -- \ set interface ipsec_gre0 type=gre \ options:remote_ip=2.2.2.2 \ options:psk=swordfish 2) You can use a self-signed certificate to do authentication. In each host, generate a certificate and the paired private key. Copy the certificate of the remote host to the local host and configure the OVS as following:: $ ovs-vsctl set Open_vSwitch . \ other_config:certificate=/path/to/local_cert.pem \ other_config:private_key=/path/to/priv_key.pem $ ovs-vsctl add-port br0 ipsec_gre0 -- \ set interface ipsec_gre0 type=gre \ options:remote_ip=2.2.2.2 \ options:remote_cert=/path/to/remote_cert.pem `local_cert.pem` is the certificate of the local host. `priv_key.pem` is the private key of the local host. `priv_key.pem` needs to be stored in a secure location. `remote_cert.pem` is the certificate of the remote host. .. note:: OVS IPsec requires x.509 version 3 certificate with the subjectAltName DNS field setting the same string as the common name (CN) field. You can follow the tutorial in :doc:`/tutorials/ipsec` and use ovs-pki(8) to generate compatible certificate and key. (Before OVS version 2.10.90, ovs-pki(8) did not generate x.509 v3 certificates, so if your existing PKI was generated by an older version, it is not suitable for this purpose.) 3) You can also use CA-signed certificate to do authentication. First, you need to create a CA certificate and sign each host certificate with the CA key (please see :doc:`/tutorials/ipsec`). Copy the CA certificate to each host and configure the OVS as following:: $ ovs-vsctl set Open_vSwitch . \ other_config:certificate=/path/to/local_cert.pem \ other_config:private_key=/path/to/priv_key.pem \ other_config:ca_cert=/path/to/ca_cert.pem $ ovs-vsctl add-port br0 ipsec_gre0 -- \ set interface ipsec_gre0 type=gre \ options:remote_ip=2.2.2.2 \ options:remote_name=remote_cn `ca_cert.pem` is the CA certificate. You need to set `remote_cn` as the common name (CN) of the remote host's certificate so that only the certificate with the expected CN can be trusted in this connection. It is preferable to use this method than 2) if there are many remote hosts since you don't have to copy every remote certificate to the local host. .. note:: When using certificate-based authentication, you should not set psk in the interface options. When using psk-based authentication, you should not set certificate, private_key, ca_cert, remote_cert, and remote_name. Plaintext Policies ~~~~~~~~~~~~~~~~~~ When an IPsec tunnel is configured in this database, multiple independent components take responsibility for implementing it. ``ovs-vswitchd`` and its datapath handle packet forwarding to the tunnel and a separate daemon pushes the tunnel's IPsec policy configuration to the kernel or other entity that implements it. There is a race: if the former configuration completes before the latter, then packets sent by the local host over the tunnel can be transmitted in plaintext. Using this setting, OVS users can avoid this undesirable situation. 1) The default setting allows unencrypted packets to be sent before IPsec completes negotiation:: $ ovs-vsctl add-port br0 ipsec_gre0 -- \ set interface ipsec_gre0 type=gre \ options:remote_ip=2.2.2.2 \ options:psk=swordfish This setting should be used only and only if tunnel configuration is static and/or if there is firewall that can drop the plain packets that occasionally leak the tunnel unencrypted on OVSDB (re)configuration events. 2) Setiing ipsec_skb_mark drops unencrypted packets by using skb_mark of tunnel packets:: $ ovs-vsctl set Open_vSwitch . other_config:ipsec_skb_mark=0/1 $ ovs-vsctl add-port br0 ipsec_gre0 -- \ set interface ipsec_gre0 type=gre \ options:remote_ip=2.2.2.2 \ options:psk=swordfish OVS IPsec drops unencrypted packets which carry the same skb_mark as `ipsec_skb_mark`. By setting the ipsec_skb_mark as 0/1, OVS IPsec prevents all unencrypted tunnel packets leaving the host since the default skb_mark value for tunnel packets are 0. This affects all OVS tunnels including those without IPsec being set up. You can install OpenFlow rules to enable those non-IPsec tunnels by setting the skb_mark of the tunnel traffic as non-zero value. 3) Setting `ipsec_skb_mark` as 1/1 only drops tunnel packets with skb_mark value being 1:: $ ovs-vsctl set Open_vSwitch . other_config:ipsec_skb_mark=1/1 $ ovs-vsctl add-port br0 ipsec_gre0 -- \ set interface ipsec_gre0 type=gre \ options:remote_ip=2.2.2.2 \ options:psk=swordfish Opposite to 2), this setting passes through unencrypted tunnel packets by default. To drop unencrypted IPsec tunnel traffic, you need to explicitly set skb_mark to a non-zero value for those tunnel traffic by installing OpenFlow rules. Bug Reporting ------------- If you think you may have found a bug with security implications, like 1) IPsec protected tunnel accepted packets that came unencrypted; OR 2) IPsec protected tunnel allowed packets to leave unencrypted then please report such bugs according to :doc:`/internals/security`. If the bug does not have security implications, then report it according to instructions in :doc:`/internals/bugs`.