[Openvpn-devel,v3] Add detailed man page section to setup a OpenVPN setup with peer-fingerprint

Message ID 20210728154922.568796-1-arne@rfc2549.org
State Accepted
Headers show
Series [Openvpn-devel,v3] Add detailed man page section to setup a OpenVPN setup with peer-fingerprint | expand

Commit Message

Arne Schwabe July 28, 2021, 5:49 a.m. UTC
This is meant to give new users a quickstart for a useable OpenVPN
setup. Our own documentation is lacking in this regard and many
tutorials that can be found online are often questionable in some
aspects.

Linking the individaul RST file on github also give a tutorial
in a nicely formatted way.

Patch V2: Fix grammar/spelling mistakes (thanks ticantech), move
          to openvpn-examples(5).

Patch v3: use server.key and server.crt instead of server.pem/serverkey.pem

Signed-off-by: Arne Schwabe <arne@rfc2549.org>
---
 Changes.rst                              |   4 +
 doc/Makefile.am                          |   1 +
 doc/man-sections/example-fingerprint.rst | 196 +++++++++++++++++++++++
 doc/openvpn-examples.5.rst               |   1 +
 4 files changed, 202 insertions(+)
 create mode 100644 doc/man-sections/example-fingerprint.rst

Comments

Kristof Provost via Openvpn-devel July 28, 2021, 10 a.m. UTC | #1
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hi,

six minor improvements, could probably be made on commit.

One comment: This tutorial will not work on Windows because it relies
on a bashism to generate the self-signed certs.  There is no mention
of that anywhere, may be it could be pointed out somewhere ?

Other than that, excellent work!

And for the record: Easy-TLS can create these cert/keys and share
fingerprints to relevant inline files with relative ease.
https://github.com/TinCanTech/easy-tls


Sent with ProtonMail Secure (but still git unfriendly) Email.

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐

On Wednesday, July 28th, 2021 at 16:49, Arne Schwabe <arne@rfc2549.org> wrote:

> This is meant to give new users a quickstart for a useable OpenVPN

quickstart -> quick start

> setup. Our own documentation is lacking in this regard and many
> tutorials that can be found online are often questionable in some
> aspects.
>
> Linking the individaul RST file on github also give a tutorial

individual (au->ua)

> in a nicely formatted way.
>
> Patch V2: Fix grammar/spelling mistakes (thanks ticantech), move

tincantech

>           to openvpn-examples(5).
>
> Patch v3: use server.key and server.crt instead of server.pem/serverkey.pe=
> m
>
> Signed-off-by: Arne Schwabe <arne@rfc2549.org>
> ---
>  Changes.rst                              |   4 +
>  doc/Makefile.am                          |   1 +
>  doc/man-sections/example-fingerprint.rst | 196 +++++++++++++++++++++++
>  doc/openvpn-examples.5.rst               |   1 +
>  4 files changed, 202 insertions(+)
>  create mode 100644 doc/man-sections/example-fingerprint.rst
>
> diff --git a/Changes.rst b/Changes.rst
> index 9185b55f7..5ac24307f 100644
> --- a/Changes.rst
> +++ b/Changes.rst
> @@ -25,6 +25,10 @@ Certificate pinning/verify peer fingerprint
>      fingerprint of the peer. The option takes use a number of allowed
>      SHA256 certificate fingerprints.
>
> +    See the man page section "Small OpenVPN setup with peer-fingerprint"
> +    for a tutorial on how to use this feature. This is also available onl=
> ine
> +    under https://github.com/openvpn/openvpn/blob/master/doc/man-sections=
> /example-fingerprint.rst
> +
>  TLS mode with self-signed certificates
>      When ``--peer-fingerprint`` is used, the ``--ca`` and ``--capath`` op=
> tion
>      become optional. This allows for small OpenVPN setups without setting=
>  up
> diff --git a/doc/Makefile.am b/doc/Makefile.am
> index 1e4fcdea3..1a67f7b52 100644
> --- a/doc/Makefile.am
> +++ b/doc/Makefile.am
> @@ -31,6 +31,7 @@ dist_noinst_DATA =3D \
>  	man-sections/client-options.rst \
>  	man-sections/connection-profiles.rst \
>  	man-sections/encryption-options.rst \
> +	man-sections/example-fingerprint.rst \
>  	man-sections/examples.rst \
>  	man-sections/generic-options.rst \
>  	man-sections/inline-files.rst \
> diff --git a/doc/man-sections/example-fingerprint.rst b/doc/man-sections/e=
> xample-fingerprint.rst
> new file mode 100644
> index 000000000..ba948dd07
> --- /dev/null
> +++ b/doc/man-sections/example-fingerprint.rst
> @@ -0,0 +1,196 @@
> +Small OpenVPN setup with peer-fingerprint
> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> +This section consists of instructions how to build a small OpenVPN setup =
> with the
> +:code:`peer-fingerprint` option. This has the advantage of being easy to =
> setup
> +and should be suitable for most small lab and home setups without the nee=
> d for a PKI.
> +For bigger scale setup setting up a PKI (e.g. via easy-rsa) is still reco=
> mmended.
> +
> +Both server and client configuration can of be further modified to custom=

"can of be" -> can be

Also, it could simply read: "can be further customised."

> ise the
> +setup.
> +
> +Server setup
> +------------
> +1. Install openvpn
> +
> +   Compile from source-code (see `INSTALL` file) or install via a distrib=
> ution (apt/yum/ports)
> +   or via installer (Windows).

The following method does not work in Windows.

> +
> +2. Generate a self-signed certificate for the server:
> +   ::
> +
> +    openssl req -x509 -newkey ec:<(openssl ecparam -name secp384r1) -keyo=
> ut server.key -out server.crt -nodes -sha256 -days 3650 -subj '/CN=3Dserve=
> r'
> +
> +3. Generate SHA256 fingerprint of the server certificate
> +
> +   Use the OpenSSL command line utility to view the fingerprint of just
> +   created certificate:
> +   ::
> +
> +    openssl x509 -fingerprint -sha256 -in server.crt -noout
> +
> +   This output something similar to:
> +   ::
> +
> +     SHA256 Fingerprint=3D00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff=
> :00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff
> +
> +
> +3. Write a server configuration (`server.conf`):
> +::
> +
> +    # The server certificate we created in step 1
> +    cert server.crt
> +    key server.key
> +
> +    dh none
> +    dev tun
> +
> +    # Listen on IPv6+IPv4 simultaneously
> +    proto udp6
> +
> +    # The ip address the server will distribute
> +    server 10.8.0.0 255.255.255.0
> +    server-ipv6 fd00:6f76:706e::/64
> +
> +    # A tun-mtu of 1400 avoids problems of too big packets after VPN enca=
> psulation
> +    tun-mtu 1400
> +
> +    # The fingerprints of your clients. After adding/removing one here re=
> start the
> +    # server
> +    <peer-fingerprint>
> +    </peer-fingerprint>
> +
> +    # Notify clients when you restart the server to reconnect quickly
> +    explicit-exit-notify 1
> +
> +    # Ping every 60s, restart if no data received for 5 minutes
> +    keepalive 60 300
> +
> +4. Add at least one client as described in the client section.
> +
> +5. Start the server.
> +    - On systemd based distributions move `server.crt`, `server.key` and
> +      `server.conf` to :code:`/etc/openvpn/server` and start it via syste=
> mctl
> +
> +      ::
> +
> +          sudo mv server.conf server.key server.crt /etc/openvpn/server
> +
> +          sudo systemctl start openvpn-server@server
> +
> +Adding a client
> +---------------
> +1. Install OpenVPN
> +
> +2. Generate a self-signed certificate for the client. In this example the=
>  client
> +   name is alice. Each client should have a unique name. Replace alice wi=
> th a
> +   different name for each client.
> +   ::
> +
> +      openssl req -x509 -newkey ec:<(openssl ecparam -name secp384r1) -no=
> des -sha256 -days 3650 -subj '/CN=3Dalice'
> +
> +   This generate a certificate and a key for the client. The output of th=
> e command will look
> +   something like this:
> +   ::
> +
> +      -----BEGIN PRIVATE KEY-----
> +      [base64 content]
> +      -----END PRIVATE KEY-----
> +      -----
> +      -----BEGIN CERTIFICATE-----
> +      [base 64 content]
> +      -----END CERTIFICATE-----
> +
> +
> +3. Create a new client configuration file. In this example we will name t=
> he file
> +   `alice.ovpn`:
> +
> +   ::
> +
> +      # The name of your server to connect to
> +      remote yourserver.example.net
> +      client
> +      # use a random source port instead the fixed 1194
> +      nobind
> +
> +      # Uncomment the following line if you want to route
> +      # all traffic via the VPN
> +      # redirect-gateway def1 ipv6
> +
> +      # To set a a DNS server

a a !

> +      # dhcp-option DNS 192.168.234.1
> +
> +      <key>
> +      -----BEGIN PRIVATE KEY-----
> +      [Insert here the key created in step 2]
> +      -----END PRIVATE KEY-----
> +      </key>
> +      <cert>
> +      -----BEGIN CERTIFICATE-----
> +      [Insert here the certificate created in step 2]
> +      -----END CERTIFICATE-----
> +      </cert>
> +
> +      # This is the fingerprint of the server that we trust. We generated=
>  this fingerprint
> +      # in step 2 of the server setup
> +      peer-fingerprint 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00=
> :11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff
> +
> +      # The tun-mtu of the client should match the server MTU
> +      tun-mtu 1400
> +      dev tun
> +
> +
> +4. Generate the fingerprint of the client certificate. For that we will
> +   let OpenSSL read the client configuration file as the x509 command wil=
> l
> +   ignore anything that is not between the begin and end markers of the c=
> ertificate:
> +
> +   ::
> +
> +      openssl x509 -fingerprint -sha256 -noout -in alice.ovpn
> +
> +   This will again output something like
> +   ::
> +
> +        SHA256 Fingerprint=3Dff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11=
> :00:ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00
> +
> +5. Edit the `server.conf` configuration file and add this new client
> +   fingerprint as additional line  between :code:`<peer-fingerprint>`
> +   and :code:`</peer-fingerprint>`
> +
> +   After adding *two* clients the part of configuration would look like t=
> his:
> +
> +   ::
> +
> +      <peer-fingerprint>
> +      ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00:ff:ee:dd:cc:bb:aa:9=
> 9:88:77:66:55:44:33:22:11:00
> +      99:88:77:66:55:44:33:22:11:00:ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:3=
> 3:22:11:00:88:77:66:55:44:33
> +      </peer-fingperint>
> +
> +6. (optional) if the client is an older client that does not support the
> +   :code:`peer-fingerprint` (e.g. OpenVPN 2.5 and older, OpenVPN Connect =
> 3.3
> +   and older), the client config `alice.ovpn` can be modified to still wo=
> rk with
> +   these clients.
> +
> +   Remove the line starting with :code:`peer-fingerprint`. Then
> +   add a new :code:`<ca>` section at the end of the configuration file
> +   with the contents of the :code:`server.crt` created in step 2 of the
> +   server setup. The end of `alice.ovpn` file should like:
> +
> +   ::
> +
> +      [...]  # Beginning of the file skipped
> +      </cert>
> +
> +      # The tun-mtu of the client should match the server MTU
> +      tun-mtu 1400
> +      dev tun
> +
> +      <ca>
> +      [contents of the server.crt]
> +      </ca>
> +
> +   Note that we put the :code:`<ca>` section after the :code:`<cert>` sec=
> tion
> +   to make the fingerprint generation from step 4 still work since it wil=
> l
> +   only use the first certificate it find.

'it find' -> found

> +
> +7. Import the file into the OpenVPN client or just use the
> +   :code:`openvpn alice.ovpn` to start the VPN.
> diff --git a/doc/openvpn-examples.5.rst b/doc/openvpn-examples.5.rst
> index 988b6027b..0e1b6c4f6 100644
> --- a/doc/openvpn-examples.5.rst
> +++ b/doc/openvpn-examples.5.rst
> @@ -14,4 +14,5 @@ INTRODUCTION
>
>  This man page gives a few simple examples to create OpenVPN setups and co=
> nfiguration files.
>
> +.. include:: man-sections/example-fingerprint.rst
>  .. include:: man-sections/examples.rst
> --
> 2.32.0
>

-----BEGIN PGP SIGNATURE-----
Version: ProtonMail

wsBzBAEBCAAGBQJhAbdiACEJEE+XnPZrkLidFiEECbw9RGejjXJ5xVVVT5ec
9muQuJ3NdQgAscHRyr3wCUuRtnIdbMBWjAfbvfP5iwPiGHyGh1S00PAUDHeJ
RRSjJAIPlDcVhJircaeRzOVe+rPIf6icwdrzOzkE8wnifE570ivq/z8BtT6d
zgC9s2CXKBVRTY5L/UGWlWkk15yaSzFjHS3ZtXGVlTyfQ2SItHbHh6ceeazo
l44PxOt+qJtDqA6FKzj7SfnAVyVBLq1XSpkebnuL/CXJzVdVXsXGCDl1CSwf
srnLPfAoW8dcKrJyUE4meYovCq8Ym+zHZZY70iLfB6kxfz+1Uyase/BkmrAY
b+j9BUOQ+OPFtGABBJB+FBR9dIN44Q6KTbgmXUC0mq1bYK7QfLZMdw==
=0swD
-----END PGP SIGNATURE-----
Gert Doering Aug. 1, 2021, 7:49 a.m. UTC | #2
Acked-by: Gert Doering <gert@greenie.muc.de>

I've taken David's ACK on v2, compared the changes to v3 (some of the
nitpicks David has pointed out, .pem/.key/.crt changes, plus language
changes by Richard), and added my own ACK based on that.

Integrated Richard's "6 minor improvements" - thanks :-)

Your patch has been applied to the master branch.

commit f235b5efd6106ad4f899d6da899c617afc6ff9e9
Author: Arne Schwabe
Date:   Wed Jul 28 17:49:22 2021 +0200

     Add detailed man page section to setup a OpenVPN setup with peer-fingerprint

     Signed-off-by: Arne Schwabe <arne@rfc2549.org>
     Acked-by: David Sommerseth <davids@openvpn.net>
     Acked-by: Gert Doering <gert@greenie.muc.de>
     Message-Id: <20210728154922.568796-1-arne@rfc2549.org>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg22674.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering

Patch

diff --git a/Changes.rst b/Changes.rst
index 9185b55f7..5ac24307f 100644
--- a/Changes.rst
+++ b/Changes.rst
@@ -25,6 +25,10 @@  Certificate pinning/verify peer fingerprint
     fingerprint of the peer. The option takes use a number of allowed
     SHA256 certificate fingerprints.
 
+    See the man page section "Small OpenVPN setup with peer-fingerprint"
+    for a tutorial on how to use this feature. This is also available online
+    under https://github.com/openvpn/openvpn/blob/master/doc/man-sections/example-fingerprint.rst
+
 TLS mode with self-signed certificates
     When ``--peer-fingerprint`` is used, the ``--ca`` and ``--capath`` option
     become optional. This allows for small OpenVPN setups without setting up
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 1e4fcdea3..1a67f7b52 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -31,6 +31,7 @@  dist_noinst_DATA = \
 	man-sections/client-options.rst \
 	man-sections/connection-profiles.rst \
 	man-sections/encryption-options.rst \
+	man-sections/example-fingerprint.rst \
 	man-sections/examples.rst \
 	man-sections/generic-options.rst \
 	man-sections/inline-files.rst \
diff --git a/doc/man-sections/example-fingerprint.rst b/doc/man-sections/example-fingerprint.rst
new file mode 100644
index 000000000..ba948dd07
--- /dev/null
+++ b/doc/man-sections/example-fingerprint.rst
@@ -0,0 +1,196 @@ 
+Small OpenVPN setup with peer-fingerprint
+=========================================
+This section consists of instructions how to build a small OpenVPN setup with the
+:code:`peer-fingerprint` option. This has the advantage of being easy to setup
+and should be suitable for most small lab and home setups without the need for a PKI.
+For bigger scale setup setting up a PKI (e.g. via easy-rsa) is still recommended.
+
+Both server and client configuration can of be further modified to customise the
+setup.
+
+Server setup
+------------
+1. Install openvpn
+
+   Compile from source-code (see `INSTALL` file) or install via a distribution (apt/yum/ports)
+   or via installer (Windows).
+
+2. Generate a self-signed certificate for the server:
+   ::
+
+    openssl req -x509 -newkey ec:<(openssl ecparam -name secp384r1) -keyout server.key -out server.crt -nodes -sha256 -days 3650 -subj '/CN=server'
+
+3. Generate SHA256 fingerprint of the server certificate
+
+   Use the OpenSSL command line utility to view the fingerprint of just
+   created certificate:
+   ::
+
+    openssl x509 -fingerprint -sha256 -in server.crt -noout
+
+   This output something similar to:
+   ::
+
+     SHA256 Fingerprint=00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff
+
+
+3. Write a server configuration (`server.conf`):
+::
+
+    # The server certificate we created in step 1
+    cert server.crt
+    key server.key
+
+    dh none
+    dev tun
+
+    # Listen on IPv6+IPv4 simultaneously
+    proto udp6
+
+    # The ip address the server will distribute
+    server 10.8.0.0 255.255.255.0
+    server-ipv6 fd00:6f76:706e::/64
+
+    # A tun-mtu of 1400 avoids problems of too big packets after VPN encapsulation
+    tun-mtu 1400
+
+    # The fingerprints of your clients. After adding/removing one here restart the
+    # server
+    <peer-fingerprint>
+    </peer-fingerprint>
+
+    # Notify clients when you restart the server to reconnect quickly
+    explicit-exit-notify 1
+
+    # Ping every 60s, restart if no data received for 5 minutes
+    keepalive 60 300
+
+4. Add at least one client as described in the client section.
+
+5. Start the server.
+    - On systemd based distributions move `server.crt`, `server.key` and
+      `server.conf` to :code:`/etc/openvpn/server` and start it via systemctl
+
+      ::
+
+          sudo mv server.conf server.key server.crt /etc/openvpn/server
+
+          sudo systemctl start openvpn-server@server
+
+Adding a client
+---------------
+1. Install OpenVPN
+
+2. Generate a self-signed certificate for the client. In this example the client
+   name is alice. Each client should have a unique name. Replace alice with a
+   different name for each client.
+   ::
+
+      openssl req -x509 -newkey ec:<(openssl ecparam -name secp384r1) -nodes -sha256 -days 3650 -subj '/CN=alice'
+
+   This generate a certificate and a key for the client. The output of the command will look
+   something like this:
+   ::
+
+      -----BEGIN PRIVATE KEY-----
+      [base64 content]
+      -----END PRIVATE KEY-----
+      -----
+      -----BEGIN CERTIFICATE-----
+      [base 64 content]
+      -----END CERTIFICATE-----
+
+
+3. Create a new client configuration file. In this example we will name the file
+   `alice.ovpn`:
+
+   ::
+
+      # The name of your server to connect to
+      remote yourserver.example.net
+      client
+      # use a random source port instead the fixed 1194
+      nobind
+
+      # Uncomment the following line if you want to route
+      # all traffic via the VPN
+      # redirect-gateway def1 ipv6
+
+      # To set a a DNS server
+      # dhcp-option DNS 192.168.234.1
+
+      <key>
+      -----BEGIN PRIVATE KEY-----
+      [Insert here the key created in step 2]
+      -----END PRIVATE KEY-----
+      </key>
+      <cert>
+      -----BEGIN CERTIFICATE-----
+      [Insert here the certificate created in step 2]
+      -----END CERTIFICATE-----
+      </cert>
+
+      # This is the fingerprint of the server that we trust. We generated this fingerprint
+      # in step 2 of the server setup
+      peer-fingerprint 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff
+
+      # The tun-mtu of the client should match the server MTU
+      tun-mtu 1400
+      dev tun
+
+
+4. Generate the fingerprint of the client certificate. For that we will
+   let OpenSSL read the client configuration file as the x509 command will
+   ignore anything that is not between the begin and end markers of the certificate:
+
+   ::
+
+      openssl x509 -fingerprint -sha256 -noout -in alice.ovpn
+
+   This will again output something like
+   ::
+
+        SHA256 Fingerprint=ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00:ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00
+
+5. Edit the `server.conf` configuration file and add this new client
+   fingerprint as additional line  between :code:`<peer-fingerprint>`
+   and :code:`</peer-fingerprint>`
+
+   After adding *two* clients the part of configuration would look like this:
+
+   ::
+
+      <peer-fingerprint>
+      ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00:ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00
+      99:88:77:66:55:44:33:22:11:00:ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00:88:77:66:55:44:33
+      </peer-fingperint>
+
+6. (optional) if the client is an older client that does not support the
+   :code:`peer-fingerprint` (e.g. OpenVPN 2.5 and older, OpenVPN Connect 3.3
+   and older), the client config `alice.ovpn` can be modified to still work with
+   these clients.
+
+   Remove the line starting with :code:`peer-fingerprint`. Then
+   add a new :code:`<ca>` section at the end of the configuration file
+   with the contents of the :code:`server.crt` created in step 2 of the
+   server setup. The end of `alice.ovpn` file should like:
+
+   ::
+
+      [...]  # Beginning of the file skipped
+      </cert>
+
+      # The tun-mtu of the client should match the server MTU
+      tun-mtu 1400
+      dev tun
+
+      <ca>
+      [contents of the server.crt]
+      </ca>
+
+   Note that we put the :code:`<ca>` section after the :code:`<cert>` section
+   to make the fingerprint generation from step 4 still work since it will
+   only use the first certificate it find.
+
+7. Import the file into the OpenVPN client or just use the
+   :code:`openvpn alice.ovpn` to start the VPN.
diff --git a/doc/openvpn-examples.5.rst b/doc/openvpn-examples.5.rst
index 988b6027b..0e1b6c4f6 100644
--- a/doc/openvpn-examples.5.rst
+++ b/doc/openvpn-examples.5.rst
@@ -14,4 +14,5 @@  INTRODUCTION
 
 This man page gives a few simple examples to create OpenVPN setups and configuration files.
 
+.. include:: man-sections/example-fingerprint.rst
 .. include:: man-sections/examples.rst