summaryrefslogtreecommitdiff
path: root/docs/configuration/interfaces/openvpn.rst
blob: f51dfa947f5601cea52b1d9b7d25a754b6487a5f (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
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
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
:lastproofread: 2021-07-05

.. _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
************

.. figure:: /_static/images/openvpn_site2site_diagram.jpg

OpenVPN is popular for client-server setups, but its site-to-site mode
remains a relatively obscure feature, and many router appliances
still don't support it. However, it's very useful for quickly setting up
tunnels between routers.

As of VyOS 1.4, OpenVPN site-to-site mode can use either pre-shared keys or x.509 certificates.

The pre-shared key mode is deprecated and will be removed from future OpenVPN versions,
so VyOS will have to remove support for that option as well. The reason is that using pre-shared keys
is significantly less secure than using TLS.

We'll configure OpenVPN using self-signed certificates, and then discuss the legacy
pre-shared key mode.

In both cases, we will use the following settings:

* The public IP address of the local side of the VPN will be 198.51.100.10.
* The public IP address of the remote side of the VPN 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.
* The local site will have a subnet of 10.0.0.0/16.
* The remote site will have a subnet of 10.1.0.0/16.
* 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.

Setting up certificates
=======================

Setting up a full-blown PKI with a CA certificate would arguably defeat the purpose
of site-to-site OpenVPN, since its main goal is supposed to be configuration simplicity,
compared to server setups that need to support multiple clients.

However, since VyOS 1.4, it is possible to verify self-signed certificates using
certificate fingerprints.

On both sides, you need to generate a self-signed certificate, preferrably using the "ec" (elliptic curve) type.
You can generate them by executing command ``run generate pki certificate self-signed install <name>`` in the configuration mode.
Once the command is complete, it will add the certificate to the configuration session, to the ``pki`` subtree.
You can then review the proposed changes and commit them.

.. code-block:: none

  vyos@vyos# run generate pki certificate self-signed install openvpn-local
  Enter private key type: [rsa, dsa, ec] (Default: rsa) ec
  Enter private key bits: (Default: 256) 
  Enter country code: (Default: GB) 
  Enter state: (Default: Some-State) 
  Enter locality: (Default: Some-City) 
  Enter organization name: (Default: VyOS) 
  Enter common name: (Default: vyos.io) 
  Do you want to configure Subject Alternative Names? [y/N] 
  Enter how many days certificate will be valid: (Default: 365) 
  Enter certificate type: (client, server) (Default: server) 
  Note: If you plan to use the generated key on this router, do not encrypt the private key.
  Do you want to encrypt the private key with a passphrase? [y/N] 
  2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
  [edit]

  vyos@vyos# compare 
  [pki]
  + certificate openvpn-local {
  +     certificate "MIICJTCCAcugAwIBAgIUMXLfRNJ5iOjk/    uAZqUe4phW8MdgwCgYIKoZIzj0EAwIwVzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzEQMA4GA1UEAwwHdnlvcy5pbzAeFw0yMzA5MDcyMTQzMTNaFw0yNDA5MDYyMTQzMTNaMFcxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxEDAOBgNVBAMMB3Z5b3MuaW8wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASp7D0vE3SKSAWAzr/lw9Eq9Q89r247AJR6ec/GT26AIcVA1bsongV1YaWvRwzTPC/yi5pkzV/PcT/WU7JQIyMWo3UwczAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQUBrAxRdFppdG/UBRdo7qNyHutaTQwHwYDVR0jBBgwFoAUBrAxRdFppdG/UBRdo7qNyHutaTQwCgYIKoZIzj0EAwIDSAAwRQIhAI2+8C92z9wTcTWkQ/goRxs10EBC+h78O+vgo9k97z5iAiBSeqfaVr5taQTS31+McGTAK3cYWNTg0DlOBI8aKO2oRg=="
  +     private {
  +         key "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgtOeEb0dMb5P/2Exi09WWvk6Cvz0oOBoDuP68ZimS2LShRANCAASp7D0vE3SKSAWAzr/lw9Eq9Q89r247AJR6ec/GT26AIcVA1bsongV1YaWvRwzTPC/yi5pkzV/PcT/WU7JQIyMW"
  +     }
  + }

  [edit]

  vyos@vyos# commit

You do **not** need to copy the certificate to the other router. Instead, you need to retrieve its SHA-256 fingerprint.
OpenVPN only supports SHA-256 fingerprints at the moment, so you need to use the following command:

.. code-block:: none

  vyos@vyos# run show pki certificate openvpn-local fingerprint sha256 
  5C:B8:09:64:8B:59:51:DC:F4:DF:2C:12:5C:B7:03:D1:68:94:D7:5B:62:C2:E1:83:79:F1:F0:68:B2:81:26:79

Note: certificate names don't matter, we use 'openvpn-local' and 'openvpn-remote' but they can be arbitrary.

Repeat the procedure on the other router.

Setting up OpenVPN
==================

Local Configuration:

.. code-block:: none

  Configure the tunnel:

  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 '203.0.113.11'                         # Public IP of the other side
  set interfaces openvpn vtun1 local-port '1195'
  set interfaces openvpn vtun1 remote-port '1195'
  set interfaces openvpn vtun1 local-address '10.255.1.1'                         # Local IP of vtun interface
  set interfaces openvpn vtun1 remote-address '10.255.1.2'                        # Remote IP of vtun interface
  set interfaces openvpn vtun1 tls certificate 'openvpn-local'                    # The self-signed certificate
  set interfaces openvpn vtun1 tls peer-fingerprint <remote cert fingerprint>     # The output of 'run show pki certificate <name> fingerprint sha256
                                                                                    on the remote rout

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'                         # Pub IP of other site
  set interfaces openvpn vtun1 local-port '1195'
  set interfaces openvpn vtun1 remote-port '1195'
  set interfaces openvpn vtun1 local-address '10.255.1.2'                          # Local IP of vtun interface
  set interfaces openvpn vtun1 remote-address '10.255.1.1'                         # Remote IP of vtun interface
  set interfaces openvpn vtun1 tls certificate 'openvpn-remote'                    # The self-signed certificate
  set interfaces openvpn vtun1 tls peer-fingerprint <local cert fingerprint>       # The output of 'run show pki certificate <name> fingerprint sha256
                                                                                    on the local router

Pre-shared keys
===============

Until VyOS 1.4, the only option for site-to-site OpenVPN without PKI was to use pre-shared keys.
That option is still available but it is deprecated and will be removed in the future.
However, if you need to set up a tunnel to an older VyOS version or a system with older OpenVPN,
you need to still need to know how to use it.

First, you need to generate a key by running ``run generate pki openvpn shared-secret install <name>`` from configuration mode.
You can use any name, we will use ``s2s``.

.. code-block:: none

  vyos@local# run generate pki openvpn shared-secret install s2s
  2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
  [edit]
  vyos@local# compare
  [pki openvpn shared-secret]
  + s2s {
  +     key   "7c73046a9da91e874d31c7ad894a32688cda054bde157c64270f28eceebc0bb2f44dbb70335fad45148b0456aaa78cb34a34c0958eeed4f75e75fd99ff519ef940f7029a316c436d2366a2b0fb8ea1d1c792a65f67d10a461af83ef4530adc25d1c872de6d9c7d5f338223d1f3b66dc3311bbbddc0e05228c47b91c817c721aadc7ed18f0662df52ad14f898904372679e3d9697d062b0869d12de47ceb2e626fa12e1926a3119be37dd29c9b0ad81997230f4038926900d5edb78522d2940cfe207f8e2b948e0d459fa137ebb18064ac5982b28dd1899020b4f2b082a20d5d4eb65710fbb1e62b5e061df39620267eab429d3eedd9a1ae85957457c8e4655f3"
  +     version "1"
  + }

  [edit]

  vyos@local# commit
  [edit]

Then you need to install the key on the remote router:

.. code-block:: none

  vyos@remote# set pki openvpn shared-secret s2s key <generated key string>

Then you need to set the key in your OpenVPN interface settings:

.. code-block:: none

  set interfaces openvpn vtun1 shared-secret-key s2s

Firewall Exceptions
===================

For the OpenVPN traffic to pass through the WAN interface, you must create a
firewall exception.

.. code-block:: none

    set firewall name OUTSIDE_LOCAL rule 10 action accept
    set firewall name OUTSIDE_LOCAL rule 10 description 'Allow established/related'
    set firewall name OUTSIDE_LOCAL rule 10 state established enable
    set firewall name OUTSIDE_LOCAL rule 10 state related enable
    set firewall name OUTSIDE_LOCAL rule 20 action accept
    set firewall name OUTSIDE_LOCAL rule 20 description OpenVPN_IN
    set firewall name OUTSIDE_LOCAL rule 20 destination port 1195
    set firewall name OUTSIDE_LOCAL rule 20 log enable
    set firewall name OUTSIDE_LOCAL rule 20 protocol udp
    set firewall name OUTSIDE_LOCAL rule 20 source

You should also ensure that the OUTISDE_LOCAL firewall group is applied to the
WAN interface and a direction (local).

.. code-block:: none

    set firewall interface eth0 local name 'OUTSIDE-LOCAL'


Static Routing:

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 route 10.1.0.0/16 interface vtun1

Remote Configuration:

.. code-block:: none

  set protocols static route 10.0.0.0/16 interface vtun1

The configurations above will default to using 256-bit AES in GCM mode
for encryption (if both sides support 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 the 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.


Firewall policy can also be applied to the tunnel interface for `local`, `in`,
and `out` directions and functions 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 topic
:ref:`configuration/pki/index:pki` 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 generate, add and specify the names of the cryptographic materials.
Each of the install command should be applied to the configuration and commited
before using under the openvpn interface configuration.

.. code-block:: none

  run generate pki ca install ca-1                                # Follow the instructions to generate CA cert.
  Configure mode commands to install:
  set pki ca ca-1 certificate 'generated_cert_string'
  set pki ca ca-1 private key 'generated_private_key'

  run generate pki certificate sign ca-1 install srv-1            # Follow the instructions to generate server cert.
  Configure mode commands to install:
  set pki certificate srv-1 certificate 'generated_server_cert'
  set pki certificate srv-1 private key 'generated_private_key'

  run generate pki dh install dh-1                                # Follow the instructions to generate set of
                                                                    Diffie-Hellman parameters.
  Generating parameters...
  Configure mode commands to install DH parameters:
  set pki dh dh-1 parameters 'generated_dh_params_set'

  set interfaces openvpn vtun10 tls ca-certificate ca-1
  set interfaces openvpn vtun10 tls certificate srv-1
  set interfaces openvpn vtun10 tls dh-params dh-1

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 our 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 route 10.23.0.0/20 interface vtun10

Additionally, each client needs a copy of ca cert and its own client key and
cert files. The files are plaintext so they may be copied either manually from the CLI.
Client key and cert files should be signed with the proper ca cert and generated on the
server side.

HQ's router requires the following steps to generate crypto materials for the Branch 1:

.. code-block:: none

  run generate pki certificate sign ca-1 install branch-1            # Follow the instructions to generate client
                                                                       cert for Branch 1
  Configure mode commands to install:

Branch 1's router might have the following lines:

.. code-block:: none

  set pki ca ca-1 certificate 'generated_cert_string'                # CA cert generated on HQ router
  set pki certificate branch-1 certificate 'generated_branch_cert'   # Client cert generated and signed on HQ router
  set pki certificate branch-1 private key 'generated_private_key'   # Client cert key generated on HQ router

  set interfaces openvpn vtun10 tls ca-cert ca-1
  set interfaces openvpn vtun10 tls certificate branch-1

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 this:

.. 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 "--verify-client-cert none"
       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-certificate ca.crt
           certificate server.crt
           dh-params dh1024.pem
       }
   }


******
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.

.. _openvpn:client_server:

Configuration
=============

Server Side
-----------

.. 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 ca-1
  set interfaces openvpn vtun10 tls certificate srv-1
  set interfaces openvpn vtun10 tls crypt-key srv-1
  set interfaces openvpn vtun10 tls dh-params dh-1
  set interfaces openvpn vtun10 use-lzo-compression

.. _openvpn:client_client:

Client Side
-----------

.. 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 ca-1
  set interfaces openvpn vtun10 tls certificate client-1
  set interfaces openvpn vtun10 tls crypt-key client-1
  set interfaces openvpn vtun10 use-lzo-compression

Options
=======

We do not have CLI nodes for every single OpenVPN option. 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 &quot;keepalive 1 10&quot;'

Will add ``push "keepalive 1 10"`` to the generated OpenVPN config file.

.. note:: Sometimes option lines in the generated OpenVPN configuration require
   quotes. This is done through a hack on our config generator. You can pass
   quotes using the ``&quot;`` statement.

***************************
Multi-factor Authentication
***************************

VyOS supports multi-factor authentication (MFA) or two-factor authentication 
using Time-based One-Time Password (TOTP). Compatible with Google Authenticator
software token, other software tokens.

MFA TOTP options
================

.. cfgcmd:: set interfaces openvpn <interface> server mfa totp challenge <enable | disable>

  If set to enable, openvpn-otp will expect password as result of challenge/
  response protocol.

.. cfgcmd:: set interfaces openvpn <interface> server mfa totp digits <1-65535>    

  Configure number of digits to use for totp hash (default: 6)
    
.. cfgcmd:: set interfaces openvpn <interface> server mfa totp drift <1-65535>

  Configure time drift in seconds (default: 0)

.. cfgcmd:: set interfaces openvpn <interface> server mfa totp slop <1-65535>

  Configure maximum allowed clock slop in seconds (default: 180)

.. cfgcmd:: set interfaces openvpn <interface> server mfa totp step <1-65535>

  Configure step value for totp in seconds (default: 30)

Example
=======

.. code-block:: none

  set interfaces openvpn vtun20 encryption cipher 'aes256'
  set interfaces openvpn vtun20 hash 'sha512'
  set interfaces openvpn vtun20 mode 'server'
  set interfaces openvpn vtun20 persistent-tunnel
  set interfaces openvpn vtun20 server client user1
  set interfaces openvpn vtun20 server mfa totp challenge 'disable'
  set interfaces openvpn vtun20 server subnet '10.10.2.0/24'
  set interfaces openvpn vtun20 server topology 'subnet'
  set interfaces openvpn vtun20 tls ca-certificate 'openvpn_vtun20'
  set interfaces openvpn vtun20 tls certificate 'openvpn_vtun20'
  set interfaces openvpn vtun20 tls dh-params 'dh-pem'

For every client in the openvpn server configuration a totp secret is created.
To display the authentication information, use the command:

.. cfgcmd:: show interfaces openvpn <interface> user <username> mfa <qrcode|secret|uri>

An example:

.. code-block:: none

   vyos@vyos:~$ sh interfaces openvpn vtun20 user user1 mfa qrcode
   █████████████████████████████████████
   █████████████████████████████████████
   ████ ▄▄▄▄▄ █▀▄▀ ▀▀▄▀ ▀▀▄ █ ▄▄▄▄▄ ████
   ████ █   █ █▀▀▄ █▀▀▀█▀██ █ █   █ ████
   ████ █▄▄▄█ █▀█ ▄ █▀▀ █▄▄▄█ █▄▄▄█ ████
   ████▄▄▄▄▄▄▄█▄█ █ █ ▀ █▄▀▄█▄▄▄▄▄▄▄████
   ████▄▄ ▄ █▄▄ ▄▀▄█▄ ▄▀▄█ ▄▄▀ ▀▄█ ▀████
   ████ ▀██▄▄▄█▄ ██ █▄▄▄▄ █▄▀█ █ █▀█████
   ████ ▄█▀▀▄▄  ▄█▀  ▀▄ ▄▄▀▄█▀▀▀ ▄▄▀████
   ████▄█ ▀▄▄▄▀  ▀ ▄█ ▄ █▄█▀ █▀  █▀█████
   ████▀█▀ ▀ ▄█▀▄▀▀█▄██▄█▀▀  ▀ ▀ ▄█▀████
   ████ ██▄▄▀▄▄█ ██ ▀█ ▄█ ▀▄█  █▀██▀████
   ████▄███▄█▄█ ▀█▄ ██▄▄▄█▀ ▄▄▄ █ ▀ ████
   ████ ▄▄▄▄▄ █▄█▀▄ ▀▄ ▀█▀  █▄█ ██▀█████
   ████ █   █ █ ▄█▀█▀▀▄ ▄▀▀▄▄▄▄▄▄   ████
   ████ █▄▄▄█ █ ▄ ▀ █▄▄▄██▄▀█▄▀▄█▄ █████
   ████▄▄▄▄▄▄▄█▄██▄█▄▄▄▄▄█▄█▄█▄██▄██████
   █████████████████████████████████████
   █████████████████████████████████████

Use the QR code to add the user account in Google authenticator application and
on client side, use the OTP number as password.


**********************************
OpenVPN Data Channel Offload (DCO)
**********************************

OpenVPN Data Channel Offload (DCO) enables significant performance enhancement
in encrypted OpenVPN data processing. By minimizing context switching for each
packet, DCO effectively reduces overhead. This optimization is achieved by
keeping most data handling tasks within the kernel, avoiding frequent switches
between kernel and user space for encryption and packet handling.

As a result, the processing of each packet becomes more efficient, potentially
leveraging hardware encryption offloading support available in the kernel.

.. note:: OpenVPN DCO is not full OpenVPN features supported , is currently
   considered experimental. Furthermore, there are certain OpenVPN features and
   use cases that remain incompatible with DCO. To get a comprehensive
   understanding of the limitations associated with DCO, refer to the list of
   known limitations in the documentation.

   https://community.openvpn.net/openvpn/wiki/DataChannelOffload/Features


Enabling OpenVPN DCO
====================

DCO support is a per-tunnel option and it is not automatically enabled by 
default for new or upgraded tunnels. Existing tunnels will continue to function 
as they have in the past.

DCO can be enabled for both new and existing tunnels,VyOS adds an option in each 
tunnel configuration where we can enable this function  .The current best 
practice is to create a new tunnel with DCO to minimize the chance of problems 
with existing clients.

.. cfgcmd:: set interfaces openvpn <name> offload dco

  Enable OpenVPN Data Channel Offload feature by loading the appropriate kernel
  module.

  Disabled by default - no kernel module loaded.

  .. note:: Enable this feature causes an interface reset.


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 the specified OpenVPN client.

.. opcmd:: reset openvpn interface <interface>

   Use this command to reset the OpenVPN process on a specific interface.



.. include:: /_include/common-references.txt