1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
..
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, and VXLAN tunnels. 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`.
|