On Tue, Jul 31, 2018 at 02:08:54PM -0700, Qiuyu Xiao wrote:
> This patch adds step-by-step guide for configuring OVN Role-Based Access
> Control and IPsec.
>
> Signed-off-by: Qiuyu Xiao <[email protected]>
You wrote a lot of documentation, and it's really good! Thank you.
I spent some time working to make it even better. I'm appending an
incremental that I'd suggest folding in. Does it make sense to you?
Thanks,
Ben.
--8<--------------------------cut here-------------------------->8--
diff --git a/Documentation/howto/ipsec.rst b/Documentation/howto/ipsec.rst
index 17dead5010cf..32e55b5acd0d 100644
--- a/Documentation/howto/ipsec.rst
+++ b/Documentation/howto/ipsec.rst
@@ -48,7 +48,10 @@ 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 fowarding modes based on your system requirement.
+and forwarding modes based on your requirements.
+
+OVS does not currently provide any support for IPsec encryption for traffic not
+encapsulated in a tunnel.
Configuration
-------------
@@ -59,7 +62,7 @@ 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 pre-shared key (PSK) to do authentication. In both hosts, set
+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::
@@ -72,9 +75,9 @@ channel. There are three authentication methods:
.. note::
- The local_ip field is required for the IPsec tunnel.
+ The ``local_ip`` field is required for the IPsec tunnel.
-2) You can use self-signed certificate to do authentication. In each host,
+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::
@@ -98,6 +101,10 @@ channel. There are three authentication methods:
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
@@ -133,8 +140,8 @@ actually taking affect to encrypt packets. To offset the
risk of unencrypted
packets leaking out during this period, you can choose a more secure forwarding
mode. There are three forwarding modes:
-1) The default mode allows unencrypted packets being sent out before IPsec
- taking effect::
+1) The default mode allows unencrypted packets to be sent before IPsec
+ completes negotiation::
$ ovs-vsctl add-port br0 ipsec_gre0 -- \
set interface ipsec_gre0 type=gre \
@@ -146,7 +153,7 @@ mode. There are three forwarding modes:
and/or if there is firewall that can drop the plain packets that
occasionally leak the tunnel unencrypted on OVSDB (re)configuration events.
-2) The ipsec_skb_mark mode filters unencrypted packets by using skb mark of
+2) The ipsec_skb_mark mode drops unencrypted packets by using skb_mark of
tunnel packets::
$ ovs-vsctl set Open_vSwitch . other_config:ipsec_skb_mark=0/1
@@ -156,15 +163,15 @@ mode. There are three forwarding modes:
options:remote_ip=2.2.2.2 \
options:psk=swordfish
- OVS IPsec filters unencrypted packets which carry the same skb mark as
+ 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
+ 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 whitelist
- those non-IPsec tunnels by setting the skb mark of the tunnel traffic as
+ 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 filters tunnel packets with skb mark
+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
@@ -174,9 +181,9 @@ mode. There are three forwarding modes:
options:remote_ip=2.2.2.2 \
options:psk=swordfish
- Opposite to 2), this mode doesn't filter unencrypted tunnel packets by
- default. To filter unencrypted IPsec tunnel traffic, you need to explicitly
- set skb mark to a non-zero value for those tunnel traffic by installing
+ Opposite to 2), this mode 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
@@ -185,9 +192,9 @@ 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;
+2) IPsec protected tunnel allowed packets to leave unencrypted
-Then report such bugs according to :doc:`/internals/security`.
+then please report such bugs according to :doc:`/internals/security`.
-If bug does not have security implications, then report it according to
+If the bug does not have security implications, then report it according to
instructions in :doc:`/internals/bugs`.
diff --git a/Documentation/index.rst b/Documentation/index.rst
index 06602f7289ee..bab5ba1f1a98 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -65,7 +65,8 @@ vSwitch? Start here.
:doc:`tutorials/ovs-advanced` |
:doc:`tutorials/ovn-sandbox` |
:doc:`tutorials/ovn-openstack` |
- :doc:`tutorials/ovs-conntrack`
+ :doc:`tutorials/ovs-conntrack` |
+ :doc:`tutorials/ipsec`
Deeper Dive
-----------
diff --git a/Documentation/tutorials/ipsec.rst
b/Documentation/tutorials/ipsec.rst
index d25fcb0f717f..e78766705598 100644
--- a/Documentation/tutorials/ipsec.rst
+++ b/Documentation/tutorials/ipsec.rst
@@ -99,18 +99,24 @@ Configuring IPsec tunnel
Suppose you want to build IPsec tunnel between two hosts. `host_1`'s external
IP is `ip_1`. `host_2`'s external IP is `ip_2`.
+0. Set up some variables to make life easier. On both hosts, set ``ip_1`` and
+ ``ip_2`` variables, e.g.::
+
+ $ ip_1=192.0.0.1
+ $ ip_2=192.0.0.2
+
1. Set up OVS bridges in both hosts.
In `host_1`::
$ ovs-vsctl add-br br-ipsec
- $ ip addr add 192.0.0.1/24 dev br-ipsec
+ $ ip addr $ip_1 dev br-ipsec
$ ip link set br-ipsec up
In `host_2`::
$ ovs-vsctl add-br br-ipsec
- $ ip addr add 192.0.0.2/24 dev br-ipsec
+ $ ip addr add $ip_2 dev br-ipsec
$ ip link set br-ipsec up
2. Set up IPsec tunnel.
@@ -118,31 +124,31 @@ IP is `ip_1`. `host_2`'s external IP is `ip_2`.
There are three authentication methods. You can choose one to set up your
IPsec tunnel.
- a) Using pre-shared key
+ a) Using pre-shared key:
In `host_1`::
$ ovs-vsctl add-port br-ipsec tun -- \
set interface tun type=gre \
- options:local_ip=ip_1 \
- options:remote_ip=ip_2 \
+ options:local_ip=$ip_1 \
+ options:remote_ip=$ip_2 \
options:psk=swordfish
In `host_2`::
$ ovs-vsctl add-port br-ipsec tun -- \
set interface tun type=gre \
- options:local_ip=ip_2 \
- options:remote_ip=ip_1 \
+ options:local_ip=$ip_2 \
+ options:remote_ip=$ip_1 \
options:psk=swordfish
.. note::
Pre-shared key (PSK) based authentication is easy to set up but less
secure compared with other authentication methods. You should use it
- cautiously in production system.
+ cautiously in production systems.
- b) Using self-signed certificate
+ b) Using self-signed certificate:
Generate self-signed certificate in both `host_1` and `host_2`. Then copy
the certificate of `host_1` to `host_2` and the certificate of `host_2`
@@ -152,13 +158,13 @@ IP is `ip_1`. `host_2`'s external IP is `ip_2`.
$ ovs-pki req -u host_1
$ ovs-pki self-sign host_1
- $ scp host_1-cert.pem host_2@ip_2:/path/to/host_1-cert.pem
+ $ scp host_1-cert.pem $ip_2:/etc/keys/host_1-cert.pem
In `host_2`::
$ ovs-pki req -u host_2
$ ovs-pki self-sign host_2
- $ scp host_2-cert.pem host_1@ip_1:/path/to/host_2-cert.pem
+ $ scp host_2-cert.pem $ip_1:/etc/keys/host_2-cert.pem
.. note::
@@ -166,36 +172,37 @@ IP is `ip_1`. `host_2`'s external IP is `ip_2`.
to /etc/ipsec.d/certs/ and private key to /etc/ipsec.d/private/ so that
StrongSwan has permission to access those files.
- Configure IPsec tunnel to use self-signed certificate.
+ Configure IPsec tunnel to use self-signed certificates.
In `host_1`::
$ ovs-vsctl set Open_vSwitch . \
- other_config:certificate=/path/to/host_1-cert.pem \
- other_config:private_key=/path/to/host_1-privkey.pem
+ other_config:certificate=/etc/keys/host_1-cert.pem \
+ other_config:private_key=/etc/keys/host_1-privkey.pem
$ ovs-vsctl add-port br-ipsec tun -- \
set interface tun type=gre \
- options:local_ip=ip_1 \
- options:remote_ip=ip_2 \
- options:remote_cert=/path/to/host_2-cert.pem
+ options:local_ip=$ip_1 \
+ options:remote_ip=$ip_2 \
+ options:remote_cert=/etc/keys/host_2-cert.pem
In `host_2`::
$ ovs-vsctl set Open_vSwitch . \
- other_config:certificate=/path/to/host_2-cert.pem \
- other_config:private_key=/path/to/host_2-privkey.pem
+ other_config:certificate=/etc/keys/host_2-cert.pem \
+ other_config:private_key=/etc/keys/host_2-privkey.pem
$ ovs-vsctl add-port br-ipsec tun -- \
set interface tun type=gre \
- options:local_ip=ip_2 \
- options:remote_ip=ip_1 \
- options:remote_cert=/path/to/host_1-cert.pem
+ options:local_ip=$ip_2 \
+ options:remote_ip=$ip_1 \
+ options:remote_cert=/etc/keys/host_1-cert.pem
.. note::
- The security of the private key is very critical. Don't copy the
- private key to unsafe place.
+ The confidentiality of the private key is very critical. Don't copy it
+ to places where it might be compromised. (The certificate need not be
+ kept confidential.)
- c) Using CA-signed certificate
+ c) Using CA-signed certificate:
First you need to establish a public key infrastructure (PKI). Suppose
you choose `host_1` to host PKI.
@@ -214,7 +221,7 @@ IP is `ip_1`. `host_2`'s external IP is `ip_2`.
In `host_2`::
$ ovs-pki req -u host_2
- $ scp host_2-req.pem host_1@ip_1:/path/to/host_2-req.pem
+ $ scp host_2-req.pem $ip_1:/etc/keys/host_2-req.pem
Sign the certificate requests with the CA key. Copy `host_2`'s signed
certificate and the CA certificate to `host_2`.
@@ -223,9 +230,9 @@ IP is `ip_1`. `host_2`'s external IP is `ip_2`.
$ ovs-pki sign host_1 switch
$ ovs-pki sign host_2 switch
- $ scp host_2-cert.pem host_2@ip_2:/path/to/host_2-cert.pem
+ $ scp host_2-cert.pem $ip_2:/etc/keys/host_2-cert.pem
$ scp /var/lib/openvswitch/pki/switchca/cacert.pem \
- host_2@ip_2:/path/to/cacert.pem
+ $ip_2:/etc/keys/cacert.pem
.. note::
@@ -239,40 +246,42 @@ IP is `ip_1`. `host_2`'s external IP is `ip_2`.
In `host_1`::
$ ovs-vsctl set Open_vSwitch . \
- other_config:certificate=/path/to/host_1-cert.pem \
- other_config:private_key=/path/to/host_1-privkey.pem \
- other_config:ca_cert=/path/to/cacert.pem
+ other_config:certificate=/etc/keys/host_1-cert.pem \
+ other_config:private_key=/etc/keys/host_1-privkey.pem \
+ other_config:ca_cert=/etc/keys/cacert.pem
$ ovs-vsctl add-port br-ipsec tun -- \
set interface tun type=gre \
- options:local_ip=ip_1 \
- options:remote_ip=ip_2 \
+ options:local_ip=$ip_1 \
+ options:remote_ip=$ip_2 \
options:remote_name=host_2
In `host_2`::
$ ovs-vsctl set Open_vSwitch . \
- other_config:certificate=/path/to/host_2-cert.pem \
- other_config:private_key=/path/to/host_2-privkey.pem \
- other_config:ca_cert=/path/to/cacert.pem
+ other_config:certificate=/etc/keys/host_2-cert.pem \
+ other_config:private_key=/etc/keys/host_2-privkey.pem \
+ other_config:ca_cert=/etc/keys/cacert.pem
$ ovs-vsctl add-port br-ipsec tun -- \
set interface tun type=gre \
- options:local_ip=ip_2 \
- options:remote_ip=ip_1 \
+ options:local_ip=$ip_2 \
+ options:remote_ip=$ip_1 \
options:remote_name=host_1
.. note::
- remote_name is the common name (CN) of the signed-certificate. It
- should be set correctly so that only certificate with the expected CN
- can be authenticated.
+ remote_name is the common name (CN) of the signed-certificate. It must
+ match the name given as the argument to the ``ovs-pki sign command``.
+ It ensures that only certificate with the expected CN can be
+ authenticated; otherwise, any certificate signed by the CA would be
+ accepted.
3. Test IPsec tunnel.
Now you should have an IPsec GRE tunnel running between two hosts. To verify
it, in `host_1`::
- $ ping 192.0.0.2 &
- $ tcpdump -ni any net ip_2
+ $ ping $ip_2 &
+ $ tcpdump -ni any net $ip_2
You should be able to see that ESP packets are being sent from `host_1` to
`host_2`.
@@ -280,7 +289,7 @@ IP is `ip_1`. `host_2`'s external IP is `ip_2`.
Troubleshooting
---------------
-Use following ovs-apptcl command to get ovs-monitor-ipsec internal
+Use following ovs-appctl command to get ovs-monitor-ipsec internal
representation of tunnel configuration::
$ ovs-appctl -t ovs-monitor-ipsec tunnels/show
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index df96f30d1146..3caef4f79539 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -770,57 +770,32 @@
<group title="IPsec">
<p>
- The global configuration of IPsec tunnels is set in the
- <code>other_config</code> column of the <code>Open_vSwitch</code>
- table. The individual IPsec tunnel configuration is set in the
- <code>options</code> column of the <code>Interface</code> table.
+ These settings control the global configuration of IPsec tunnels. The
+ <code>options</code> column of the <code>Interface</code> table
+ configures IPsec for individual tunnels.
</p>
<p>
- <code>ipsec_skb_mark</code> is set to choose forwarding mode which
- prevents unencrypted packets being sent out since there is delay
- between the user setting up IPsec tunnel and the IPsec tunnel actually
- taking affect to encrypt packets.
- </p>
- <p>
- There are three authentication modes:
+ OVS IPsec supports the following three forms of authentication.
+ Currently, all IPsec tunnels must use the same form:
</p>
<ol>
<li>
- Pre-shared key mode: <code>private_key</code>,
- <code>certificate</code>, and <code>ca_cert</code> must not be set.
- <code>psk</code> in the <code>options</code> column of the
- <code>Interface</code> table should be set as the preshared key.
+ Pre-shared keys: Omit the global settings. On each tunnel, set <ref
+ column="options" key="psk"/>.
</li>
<li>
- Self-signed certificate mode: <code>private_key</code> and
- <code>certificate</code> must be set. <code>remote_cert</code> in the
- <code>options</code> column of the <code>Interface</code> table must
- be set. The remote certificate can be self-signed.
+ Self-signed certificates: Set the <code>private_key</code> and
+ <code>certificate</code> global settings. On each tunnel, set <ref
+ column="options" key="remote_cert"/>. The remote certificate can be
+ self-signed.
</li>
<li>
- CA-signed certificate mode: <code>private_key</code>,
- <code>certificate</code>, and <code>ca_cert</code> must be set.
- <code>remote_name</code> in the <code>options</code> column of the
- <code>Interface</code> table must be set as the common name (CN) of
- the remote certificate. The remote certificate must be signed by the
- CA.
+ CA-signed certificates: Set all of the global settings. On each
+ tunnel, set <ref column="options" key="remote_name"/> to the common
+ name (CN) of the remote certificate. The remote certificate must be
+ signed by the CA.
</li>
</ol>
- <column name="other_config" key="ipsec_skb_mark"
- type='{"type": "string"}'>
- <p>
- Setting ipsec_skb_mark as 1/1 blocks unecrypted packets with skb
- mark setting as 1. Besides, the OpenFlow rule with set SKB mark
- action specified in OVSDB needs to be installed in Open_vSwitch
- table before the first packet was able to leave the OVS tunnel.
- </p>
- <p>
- Setting ipsec_skb_mark as 0/1 blocks unecrypted packets without skb
- mark. As a result, IPsec assumes that all packets coming from
- tunnels should be encrypted unless OpenFlow actions explicitly
- set skb mark to a non-zero value.
- </p>
- </column>
<column name="other_config" key="private_key"
type='{"type": "string"}'>
<p>
@@ -845,6 +820,60 @@
that a remote switch of the IPsec tunnel is trustworthy.
</p>
</column>
+
+ <group title="Plaintext Tunnel Policy">
+ <p>
+ After an IPsec tunnel is configured, it takes a few round trips to
+ negotiate details of the encryption with the remote host. In the
+ meantime, packets sent by the local host over the tunnel can be
+ transmitted in plaintext. This setting controls the behavior in this
+ situation.
+ </p>
+ <column name="other_config" key="ipsec_skb_mark"
+ type='{"type": "string"}'>
+ <p>
+ This setting takes the form
+ <code><var>value</var>/<var>mask</var></code>. If it is specified,
+ then the <code>skb_mark</code> field in every outgoing tunneled
+ packet sent in plaintext is compared against it and, if it matches,
+ the packet is dropped. This is a global setting that is applied to
+ every tunneled packet, regardless of whether IPsec encryption is
+ enabled for the tunnel, the type of tunnel, or whether OVS is
+ involved.
+ </p>
+
+ <p>
+ Example policies:
+ </p>
+
+ <dl>
+ <dt><code>1/1</code></dt>
+ <dd>
+ Drop all unencrypted tunneled packets in which the
+ least-significant bit of <code>skb_mark</code> is 1. This would
+ be a useful policy given an OpenFlow flow table that sets
+ <code>skb_mark</code> to 1 for traffic that should be encrypted.
+ The default <code>skb_mark</code> is 0, so this would not affect
+ other traffic.
+ </dd>
+
+ <dt><code>0/1</code></dt>
+ <dd>
+ Drop all unencrypted tunneled packets in which the
+ least-significant bit of <code>skb_mark</code> is 0. This would
+ be a useful policy if no unencrypted tunneled traffic should exit
+ the system without being specially whitelisted by setting
+ <code>skb_mark</code> to 1.
+ </dd>
+
+ <dt>(empty)</dt>
+ <dd>
+ If this setting is empty or unset, then all unencrypted tunneled
+ packets are transmitted in the usual way.
+ </dd>
+ </dl>
+ </column>
+ </group>
</group>
<group title="Common Columns">
@@ -2475,9 +2504,9 @@
<column name="options" key="local_ip">
<p>
- Optional (except for IPsec tunnels). The tunnel destination IP that
- received packets must match. Default is to match all addresses. If
- specified, may be one of:
+ Normally optional; required for IPsec tunnels. The tunnel
+ destination IP that received packets must match. Default is to match
+ all addresses. If specified, may be one of:
</p>
<ul>
@@ -2753,28 +2782,30 @@
<group title="Tunnel Options: IPsec">
<p>
- <code>gre</code>, <code>geneve</code>, <code>vxlan</code>, and
- <code>stt</code> interfaces support these options.
+ Setting any of these options enables IPsec support for a given
+ tunnel. <code>gre</code>, <code>geneve</code>, <code>vxlan</code>,
+ and <code>stt</code> interfaces support these options. See the
+ <code>IPsec</code> section in the <ref table="Open_vSwitch"/> table
+ for a description of each mode.
</p>
<column name="options" key="psk" type='{"type": "string"}'>
<p>
- The preshared secret to negotiate tunnel in PSK mode. This value
- must match on both tunnel ends and must be unset when
- <code>remote_cert</code> or <code>remote_name</code>is set.
+ In PSK mode only, the preshared secret to negotiate tunnel. This
+ value must match on both tunnel ends.
</p>
</column>
<column name="options" key="remote_cert" type='{"type": "string"}'>
<p>
- Name of a PEM file containing a certificate of the remote switch.
- The certificate must be x.509 version 3 and with the string in
- common name (CN) also set in the subject alternative name (SAN). It
- must be unset when <code>psk</code> is set.
+ In self-signed certificate mode only, name of a PEM file
+ containing a certificate of the remote switch. The certificate
+ must be x.509 version 3 and with the string in common name (CN)
+ also set in the subject alternative name (SAN).
</p>
</column>
<column name="options" key="remote_name" type='{"type": "string"}'>
<p>
- Common name (CN) of the remote certificate. It must be unset when
- <code>psk</code> is set.
+ In CA-signed certificate mode only, common name (CN) of the remote
+ certificate.
</p>
</column>
</group>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev