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
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
|
.. _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`.
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 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:: none
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:: none
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 256-bit AES in GCM mode
for encryption (if both sides supports NCP) and SHA-1 for HMAC authentication.
SHA-1 is considered weak, but other hashing algorithms are available, as are
encryption algorithms:
For Encryption:
This sets the cipher when NCP (Negotiable Crypto Parameters) is disabled or
OpenVPN version < 2.4.0.
.. code-block:: none
vyos@vyos# set interfaces openvpn vtun1 encryption cipher
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 CBC
aes128gcm AES algorithm with 128-bit key GCM
aes192 AES algorithm with 192-bit key CBC
aes192gcm AES algorithm with 192-bit key GCM
aes256 AES algorithm with 256-bit key CBC
aes256gcm AES algorithm with 256-bit key GCM
This sets the accepted ciphers to use when version => 2.4.0 and NCP is
enabled (which is default). Default NCP cipher for versions >= 2.4.0 is
aes256gcm. The first cipher in this list is what server pushes to clients.
.. code-block:: none
vyos@vyos# set int open vtun0 encryption ncp-ciphers
Possible completions:
des DES algorithm
3des DES algorithm with triple encryption
aes128 AES algorithm with 128-bit key CBC
aes128gcm AES algorithm with 128-bit key GCM
aes192 AES algorithm with 192-bit key CBC
aes192gcm AES algorithm with 192-bit key GCM
aes256 AES algorithm with 256-bit key CBC
aes256gcm AES algorithm with 256-bit key GCM
For Hashing:
.. code-block:: none
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:: none
set protocols static interface-route 10.1.0.0/16 next-hop-interface vtun1
Remote Configuration:
.. code-block:: none
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.
Server
======
Multi-client server is the most popular OpenVPN mode on routers. It always uses
x.509 authentication and therefore requires a PKI setup. Refer this section
**Generate X.509 Certificate and Keys** to generate a CA certificate,
a server certificate and key, a certificate revocation 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.
.. note:: Using **openvpn-option -reneg-sec** can be tricky. This option is
used to renegotiate data channel after n seconds. When used at both server
and client, the lower value will trigger the renegotiation. If you set it to
0 on one side of the connection (to disable it), the chosen value on the
other side will determine when the renegotiation will occur.
.. code-block:: none
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:: none
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:: none
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:: none
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:: none
set protocols static interface-route 10.23.0.0/20 next-hop-interface vtun10
Generate X.509 Certificate and Keys
-----------------------------------
OpenVPN ships with a set of scripts called Easy-RSA that can generate the
appropriate files needed for an OpenVPN setup using X.509 certificates.
Easy-RSA comes installed by default on VyOS routers.
Copy the Easy-RSA scripts to a new directory to modify the values.
.. code-block:: none
cp -r /usr/share/easy-rsa/ /config/my-easy-rsa-config
cd /config/my-easy-rsa-config
To ensure the consistent use of values when generating the PKI, set default
values to be used by the PKI generating scripts. Rename the vars.example
filename to vars
.. code-block:: none
mv vars.example vars
Following is the instance of the file after editing. You may also change other
values in the file at your discretion/need, though for most cases the defaults
should be just fine. (do not leave any of these parameters blank)
.. code-block:: none
set_var EASYRSA_DN "org"
set_var EASYRSA_REQ_COUNTRY "US"
set_var EASYRSA_REQ_PROVINCE "California"
set_var EASYRSA_REQ_CITY "San Francisco"
set_var EASYRSA_REQ_ORG "Copyleft Certificate Co"
set_var EASYRSA_REQ_EMAIL "me@example.net"
set_var EASYRSA_REQ_OU "My Organizational Unit"
set_var EASYRSA_KEY_SIZE 2048
init-pki option will create a new pki directory or will delete any previously
generated certificates stored in that folder. The term 'central' is used to
refer server and 'branch' for client
.. note:: Remember the “CA Key Passphrase” prompted in build-ca command,
as it will be asked in signing the server/client certificate.
.. code-block:: none
vyos@vyos:/config/my-easy-rsa-config$./easyrsa init-pki
vyos@vyos:/config/my-easy-rsa-config$./easyrsa build-ca
vyos@vyos:/config/my-easy-rsa-config$./easyrsa gen-req central nopass
vyos@vyos:/config/my-easy-rsa-config$./easyrsa sign-req server central
vyos@vyos:/config/my-easy-rsa-config$./easyrsa gen-dh
vyos@vyos:/config/my-easy-rsa-config$./easyrsa build-client-full branch1 nopass
To generate a certificate revocation list for any client, execute these
commands:
.. code-block:: none
vyos@vyos:/config/my-easy-rsa-config$./easyrsa revoke client1
vyos@vyos:/config/my-easy-rsa-config$ ./easyrsa gen-crl
Copy the files to /config/auth/ovpn/ to use in OpenVPN tunnel creation
.. code-block:: none
vyos@vyos:/config/my-easy-rsa-config$ sudo mkdir /config/auth/ovpn
vyos@vyos:/config/my-easy-rsa-config$ sudo cp pki/ca.crt /config/auth/ovpn
vyos@vyos:/config/my-easy-rsa-config$ sudo cp pki/dh.pem /config/auth/ovpn
vyos@vyos:/config/my-easy-rsa-config$ sudo cp pki/private/central.key /config/auth/ovpn
vyos@vyos:/config/my-easy-rsa-config$ sudo cp pki/issued/central.crt /config/auth/ovpn
vyos@vyos:/config/my-easy-rsa-config$ sudo cp pki/crl.pem /config/auth/ovpn
Additionally, each client needs a copy of ca.crt and its own client key and
cert files. The files are plaintext so they may be copied either manually,
or through a remote file transfer tool like scp. Whichever method you use,
the files need to end up in the proper location on each router.
For example, Branch 1's router might have the following files:
.. code-block:: none
vyos@branch1-rtr:$ ls /config/auth/ovpn
ca.crt branch1.crt branch1.key
Client Authentication
=====================
LDAP
----
Enterprise installations usually ship a kind of directory service which is used
to have a single password store for all employees. VyOS and OpenVPN support
using LDAP/AD as single user backend.
Authentication is done by using the ``openvpn-auth-ldap.so`` plugin which is
shipped 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:: none
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:: none
<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:: none
<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>
If you only want to check if the user account is enabled and can authenticate
(against the primary group) the following snipped is sufficient:
.. code-block:: none
<LDAP>
URL ldap://dc01.example.com
BindDN CN=SA_OPENVPN,OU=ServiceAccounts,DC=example,DC=com
Password ThisIsTopSecret
Timeout 15
TLSEnable no
FollowReferrals no
</LDAP>
<Authorization>
BaseDN "DC=example,DC=com"
SearchFilter "sAMAccountName=%u"
RequireGroup false
</Authorization>
A complete LDAP auth OpenVPN configuration could look like the following
example:
.. code-block:: none
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 203.0.113.0.10
name-server 198.51.100.3
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
}
}
Client
======
VyOS can not only act as an OpenVPN site-to-site or Server for multiple clients.
You can indeed also configure any VyOS OpenVPN interface as an OpenVPN client
connecting to a VyOS OpenVPN server or any other OpenVPN server.
Given the following example we have one VyOS router acting as OpenVPN server
and another VyOS router acting as OpenVPN client. The Server also pushes a
static client IP address to the OpenVPN client. Remember, clients are identified
using their CN attribute in the SSL certificate.
Server
------
.. code-block:: none
set interfaces openvpn vtun10 encryption cipher 'aes256'
set interfaces openvpn vtun10 hash 'sha512'
set interfaces openvpn vtun10 local-host '172.18.201.10'
set interfaces openvpn vtun10 local-port '1194'
set interfaces openvpn vtun10 mode 'server'
set interfaces openvpn vtun10 persistent-tunnel
set interfaces openvpn vtun10 protocol 'udp'
set interfaces openvpn vtun10 server client client1 ip '10.10.0.10'
set interfaces openvpn vtun10 server domain-name 'vyos.net'
set interfaces openvpn vtun10 server max-connections '250'
set interfaces openvpn vtun10 server name-server '172.16.254.30'
set interfaces openvpn vtun10 server subnet '10.10.0.0/24'
set interfaces openvpn vtun10 server topology 'subnet'
set interfaces openvpn vtun10 tls ca-cert-file '/config/auth/ca.crt'
set interfaces openvpn vtun10 tls cert-file '/config/auth/server.crt'
set interfaces openvpn vtun10 tls dh-file '/config/auth/dh.pem'
set interfaces openvpn vtun10 tls key-file '/config/auth/server.key'
set interfaces openvpn vtun10 use-lzo-compression
Client
------
.. code-block:: none
set interfaces openvpn vtun10 encryption cipher 'aes256'
set interfaces openvpn vtun10 hash 'sha512'
set interfaces openvpn vtun10 mode 'client'
set interfaces openvpn vtun10 persistent-tunnel
set interfaces openvpn vtun10 protocol 'udp'
set interfaces openvpn vtun10 remote-host '172.18.201.10'
set interfaces openvpn vtun10 remote-port '1194'
set interfaces openvpn vtun10 tls ca-cert-file '/config/auth/ca.crt'
set interfaces openvpn vtun10 tls cert-file '/config/auth/client1.crt'
set interfaces openvpn vtun10 tls key-file '/config/auth/client1.key'
set interfaces openvpn vtun10 use-lzo-compression
Options
=======
We do not have CLI nodes for every single OpenVPN options. If an option is
missing, a feature request should be opened at Phabricator_ so all users can
benefit from it (see :ref:`issues_features`).
If you are a hacker or want to try on your own we support passing raw OpenVPN
options to OpenVPN.
.. cfgcmd:: set interfaces openvpn vtun10 openvpn-option 'persistent-key'
Will add ``persistent-key`` at the end of the generated OpenVPN configuration.
Please use this only as last resort - things might break and OpenVPN won't start
if you pass invalid options/syntax.
.. cfgcmd:: set interfaces openvpn vtun10 openvpn-option
'push "keepalive 1 10"'
Will add ``push "keepalive 1 10"`` to the generated OpenVPN config file.
.. note:: Sometimes option lines in the generated OpenVPN configurarion require
quotes. This is done through a hack on our config generator. You can pass
quotes using the ``"`` statement.
Troubleshooting
===============
VyOS provides some operational commands on OpenVPN.
Check status
------------
The following commands let you check tunnel status.
.. opcmd:: show openvpn client
Use this command to check the tunnel status for OpenVPN client interfaces.
.. opcmd:: show openvpn server
Use this command to check the tunnel status for OpenVPN server interfaces.
.. opcmd:: show openvpn site-to-site
Use this command to check the tunnel status for OpenVPN site-to-site
interfaces.
Reset OpenVPN
-------------
The following commands let you reset OpenVPN.
.. opcmd:: reset openvpn client <text>
Use this command to reset specified OpenVPN client.
.. opcmd:: reset openvpn interface <interface>
Uset this command to reset the OpenVPN process on a specific interface.
.. include:: /_include/common-references.txt
|