summaryrefslogtreecommitdiff
path: root/docs/vpn/openvpn.rst
blob: 5451c78d18bf465bbfc50ef2e4c07f136c0c3e9b (plain)
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
.. _openvpn:

OpenVPN
-------

Traditionally hardware routers implement IPsec exclusively due to relative
ease of implementing it in hardware and insufficient CPU power for doing
encryption in software. Since VyOS is a software router, this is less of a
concern. OpenVPN has been widely used on UNIX platform for a long time and is
a popular option for remote access VPN, though it's also capable of
site-to-site connections.

Advantages of OpenVPN are:

* It uses a single TCP or UDP connection and does not rely on packet source
  addresses, so it will work even through a double NAT: perfect for public
  hotspots and such

* It's easy to setup and offers very flexible split tunneling

* There's a variety of client GUI frontends for any platform

Disadvantages are:

* It's slower than IPsec due to higher protocol overhead and the fact it runs
  in user mode while IPsec, on Linux, is in kernel mode

* None of the operating systems have client software installed by default

In the VyOS CLI, a key point often overlooked is that rather than being
configured using the `set vpn` stanza, OpenVPN is configured as a network
interface using `set interfaces openvpn`.

OpenVPN Site-To-Site
^^^^^^^^^^^^^^^^^^^^

While many are aware of OpenVPN as a Client VPN solution, it is often
overlooked as a site-to-site VPN solution due to lack of support for this mode
in many router platforms.

Site-to-site mode supports x.509 but doesn't require it and can also work with
static keys, which is simpler in many cases. In this example, we'll configure
a simple site-to-site OpenVPN tunnel using a 2048-bit pre-shared key.

First, one one of the systems generate the key using the operational command
`generate openvpn key <filename>`. This will generate a key with the name
provided in the `/config/auth/` directory. Once generated, you will need to
copy this key to the remote router.

In our example, we used the filename `openvpn-1.key` which we will reference
in our configuration.

* The public IP address of the local side of the VPN will be 198.51.100.10
* The remote will be 203.0.113.11
* The tunnel will use 10.255.1.1 for the local IP and 10.255.1.2 for the remote.
* OpenVPN allows for either TCP or UDP. UDP will provide the lowest latency,
  while TCP will work better for lossy connections; generally UDP is preferred
  when possible.
* The official port for OpenVPN is 1194, which we reserve for client VPN; we
  will use 1195 for site-to-site VPN.
* The `persistent-tunnel` directive will allow us to configure tunnel-related
  attributes, such as firewall policy as we would on any normal network
  interface.
* If known, the IP of the remote router can be configured using the
  `remote-host` directive; if unknown, it can be omitted. We will assume a
  dynamic IP for our remote router.

Local Configuration:

.. code-block:: sh

  set interfaces openvpn vtun1 mode site-to-site
  set interfaces openvpn vtun1 protocol udp
  set interfaces openvpn vtun1 persistent-tunnel
  set interfaces openvpn vtun1 local-host '198.51.100.10'
  set interfaces openvpn vtun1 local-port '1195'
  set interfaces openvpn vtun1 remote-port '1195'
  set interfaces openvpn vtun1 shared-secret-key-file '/config/auth/openvpn-1.key'
  set interfaces openvpn vtun1 local-address '10.255.1.1'
  set interfaces openvpn vtun1 remote-address '10.255.1.2'

Remote Configuration:

.. code-block:: sh

  set interfaces openvpn vtun1 mode site-to-site
  set interfaces openvpn vtun1 protocol udp
  set interfaces openvpn vtun1 persistent-tunnel
  set interfaces openvpn vtun1 remote-host '198.51.100.10'
  set interfaces openvpn vtun1 local-port '1195'
  set interfaces openvpn vtun1 remote-port '1195'
  set interfaces openvpn vtun1 shared-secret-key-file '/config/auth/openvpn-1.key'
  set interfaces openvpn vtun1 local-address '10.255.1.2'
  set interfaces openvpn vtun1 remote-address '10.255.1.1'

The configurations above will default to using 128-bit Blowfish in CBC mode
for encryption and SHA-1 for HMAC authentication. These are both considered
weak, but a number of other encryption and hashing algorithms are available:

For Encryption:

.. code-block:: sh

  vyos@vyos# set interfaces openvpn vtun1 encryption
  Possible completions:
    des          DES algorithm
    3des         DES algorithm with triple encryption
    bf128        Blowfish algorithm with 128-bit key
    bf256        Blowfish algorithm with 256-bit key
    aes128       AES algorithm with 128-bit key
    aes192       AES algorithm with 192-bit key
    aes256       AES algorithm with 256-bit key

For Hashing:

.. code-block:: sh

  vyos@vyos# set interfaces openvpn vtun1 hash
  Possible completions:
    md5          MD5 algorithm
    sha1         SHA-1 algorithm
    sha256       SHA-256 algorithm
    sha512       SHA-512 algorithm

If you change the default encryption and hashing algorithms, be sure that the
local and remote ends have matching configurations, otherwise the tunnel will
not come up.

Static routes can be configured referencing the tunnel interface; for example,
the local router will use a network of 10.0.0.0/16, while the remote has a
network of 10.1.0.0/16:

Local Configuration:

.. code-block:: sh

  set protocols static interface-route 10.1.0.0/16 next-hop-interface vtun1

Remote Configuration:

.. code-block:: sh

  set protocols static interface-route 10.0.0.0/16 next-hop-interface vtun1

Firewall policy can also be applied to the tunnel interface for `local`, `in`,
and `out` directions and function identically to ethernet interfaces.

If making use of multiple tunnels, OpenVPN must have a way to distinguish
between different tunnels aside from the pre-shared-key. This is either by
referencing IP address or port number. One option is to dedicate a public IP
to each tunnel. Another option is to dedicate a port number to each tunnel
(e.g. 1195,1196,1197...).

OpenVPN status can be verified using the `show openvpn` operational commands.
See the built-in help for a complete list of options.

OpenVPN Server
^^^^^^^^^^^^^^

Multi-client server is the most popular OpenVPN mode on routers. It always uses
x.509 authentication and therefore requires a PKI setup. This guide assumes you
have already setup a PKI and have a CA certificate, a server certificate and
key, a certificate revokation list, a Diffie-Hellman key exchange parameters
file. You do not need client certificates and keys for the server setup.

In this example we will use the most complicated case: a setup where each
client is a router that has its own subnet (think HQ and branch offices), since
simpler setups are subsets of it.

Suppose you want to use 10.23.1.0/24 network for client tunnel endpoints and
all client subnets belong to 10.23.0.0/20. All clients need access to the
192.168.0.0/16 network.

First we need to specify the basic settings. 1194/UDP is the default. The
`persistent-tunnel` option is recommended, it prevents the TUN/TAP device from
closing on connection resets or daemon reloads.

.. code-block:: sh

  set interfaces openvpn vtun10 mode server
  set interfaces openvpn vtun10 local-port 1194
  set interfaces openvpn vtun10 persistent-tunnel
  set interfaces openvpn vtun10 protocol udp

Then we need to specify the location of the cryptographic materials. Suppose
you keep the files in `/config/auth/openvpn`

.. code-block:: sh

  set interfaces openvpn vtun10 tls ca-cert-file /config/auth/openvpn/ca.crt
  set interfaces openvpn vtun10 tls cert-file /config/auth/openvpn/server.crt
  set interfaces openvpn vtun10 tls key-file /config/auth/openvpn/server.key
  set interfaces openvpn vtun10 tls crl-file /config/auth/openvpn/crl.pem
  set interfaces openvpn vtun10 tls dh-file /config/auth/openvpn/dh2048.pem

Now we need to specify the server network settings. In all cases we need to
specify the subnet for client tunnel endpoints. Since we want clients to access
a specific network behind out router, we will use a push-route option for
installing that route on clients.

.. code-block:: sh

  set interfaces openvpn vtun10 server push-route 192.168.0.0/16
  set interfaces openvpn vtun10 server subnet 10.23.1.0/24

Since it's a HQ and branch offices setup, we will want all clients to have
fixed addresses and we will route traffic to specific subnets through them. We
need configuration for each client to achieve this.

.. note:: Clients are identified by the CN field of their x.509 certificates,
   in this example the CN is ``client0``:

.. code-block:: sh

  set interfaces openvpn vtun10 server client client0 ip 10.23.1.10
  set interfaces openvpn vtun10 server client client0 subnet 10.23.2.0/25

OpenVPN **will not** automatically create routes in the kernel for client
subnets when they connect and will only use client-subnet association
internally, so we need to create a route to the 10.23.0.0/20 network ourselves:

.. code-block:: sh

  set protocols static interface-route 10.23.0.0/20 next-hop-interface vtun10

LDAP Authentication
*******************

Enterprise installations usually ship a kind of directory service which is used
to have a single password store for all employes. VyOS and OpenVPN support using
LDAP/AD as single user backend.

Authentication is done by using the ``openvpn-auth-ldap.so`` plugin which is
shiped with every VyOS installation. A dedicated configuration file is required.
It is best practise to store it in ``/config`` to survive image updates

.. code-block:: sh

  set interfaces openvpn vtun0 openvpn-option "--plugin /usr/lib/openvpn/openvpn-auth-ldap.so /config/auth/ldap-auth.config"

The required config file may look like:

.. code-block:: sh

  <LDAP>
  # LDAP server URL
  URL             ldap://ldap.example.com
  # Bind DN (If your LDAP server doesn't support anonymous binds)
  BindDN          cn=LDAPUser,dc=example,dc=com
  # Bind Password password
  Password        S3cr3t
  # Network timeout (in seconds)
  Timeout         15
  </LDAP>

  <Authorization>
  # Base DN
  BaseDN          "ou=people,dc=example,dc=com"
  # User Search Filter
  SearchFilter    "(&(uid=%u)(objectClass=shadowAccount))"
  # Require Group Membership - allow all users
  RequireGroup    false
  </Authorization>

Active Directory
****************

Despite the fact that AD is a superset of LDAP

.. code-block:: sh

  <LDAP>
  # LDAP server URL
  URL ldap://dc01.example.com
  # Bind DN (If your LDAP server doesn’t support anonymous binds)
  BindDN CN=LDAPUser,DC=example,DC=com
  # Bind Password
  Password mysecretpassword
  # Network timeout (in seconds)
  Timeout  15
  # Enable Start TLS
  TLSEnable no
  # Follow LDAP Referrals (anonymously)
  FollowReferrals no
  </LDAP>

  <Authorization>
  # Base DN
  BaseDN        "DC=example,DC=com"
  # User Search Filter, user must be a member of the VPN AD group
  SearchFilter  "(&(sAMAccountName=%u)(memberOf=CN=VPN,OU=Groups,DC=example,DC=com))"
  # Require Group Membership
  RequireGroup    false # already handled by SearchFilter
  <Group>
  BaseDN        "OU=Groups,DC=example,DC=com"
  SearchFilter  "(|(cn=VPN))"
  MemberAttribute  memberOf
  </Group>
  </Authorization>


A complete LDAP auth OpenVPN configuration could look like the following example:

.. code-block:: sh

  vyos@vyos# show interfaces openvpn
   openvpn vtun0 {
       mode server
       openvpn-option "--tun-mtu 1500 --fragment 1300 --mssfix"
       openvpn-option "--plugin /usr/lib/openvpn/openvpn-auth-ldap.so /config/auth/ldap-auth.config"
       openvpn-option "--push redirect-gateway"
       openvpn-option --duplicate-cn
       openvpn-option --client-cert-not-required
       openvpn-option --comp-lzo
       openvpn-option --persist-key
       openvpn-option --persist-tun
       server {
           domain-name example.com
           max-connections 5
           name-server 1.1.1.1
           name-server 9.9.9.9
           subnet 172.18.100.128/29
       }
       tls {
           ca-cert-file /config/auth/ca.crt
           cert-file /config/auth/server.crt
           dh-file /config/auth/dh1024.pem
           key-file /config/auth/server.key
       }
   }