Defined Type: openvpn::server

Defined in:
manifests/server.pp

Summary

This define creates the openvpn server instance which can run in server or client mode.

Overview

Examples:

install

openvpn::server { 'winterthur':
    country      => 'CH',
    province     => 'ZH',
    city         => 'Winterthur',
    organization => 'example.org',
    email        => 'root@example.org',
    server       => '10.200.200.0 255.255.255.0',
}

a server in client mode

file {
  '/etc/openvpn/zurich/keys/ca.crt':
    source => 'puppet:///path/to/ca.crt';
  '/etc/openvpn/zurich/keys/zurich.crt':
    source => 'puppet:///path/to/zurich.crt';
  '/etc/openvpn/zurich/keys/zurich.key':
    source => 'puppet:///path/to/zurich.key';
}
openvpn::server { 'zurich':
  remote  => [ 'mgmtnet3.nine.ch 1197', 'mgmtnet2.nine.ch 1197' ],
  require => [ File['/etc/openvpn/zurich/keys/ca.crt'],
               File['/etc/openvpn/zurich/keys/zurich.crt'],
               File['/etc/openvpn/zurich/keys/zurich.key'] ];
}

Parameters:

  • country (Optional[String]) (defaults to: undef)

    Country to be used for the SSL certificate, mandatory for server mode.

  • province (Optional[String]) (defaults to: undef)

    Province to be used for the SSL certificate, mandatory for server mode.

  • city (Optional[String]) (defaults to: undef)

    City to be used for the SSL certificate, mandatory for server mode.

  • organization (Optional[String]) (defaults to: undef)

    Organization to be used for the SSL certificate, mandatory for server mode.

  • email (Optional[String]) (defaults to: undef)

    Email address to be used for the SSL certificate, mandatory for server mode.

  • remote (Optional[Array]) (defaults to: undef)

    List of OpenVPN endpoints to connect to.

  • remote_random_hostname (Boolean) (defaults to: false)

    OpenVPN will prepend a random string (6 bytes, 12 hex characters) to hostname to prevent DNS caching. For example, “foo.example.com” would be modified to “<random-chars>.foo.example.com”.

  • remote_random (Boolean) (defaults to: false)

    When multiple $remote address/ports are specified, initially randomize the order of the list as a kind of basic load-balancing measure.

  • common_name (String) (defaults to: 'server')

    Common name to be used for the SSL certificate

  • compression (String) (defaults to: 'comp-lzo')

    Which compression algorithim to use

  • dev (String) (defaults to: 'tun0')

    TUN/TAP virtual network device

  • user (String) (defaults to: 'nobody')

    Group to drop privileges to after startup

  • group (Optional[String]) (defaults to: undef)

    User to drop privileges to after startup

  • ipp (Boolean) (defaults to: false)

    Persist ifconfig information to a file to retain client IP addresses between sessions

  • duplicate_cn (Boolean) (defaults to: false)

    Allow multiple connections on one cn

  • local (String) (defaults to: $facts['networking']['ip'])

    Interface for openvpn to bind to.

  • logfile (Variant[Boolean, String]) (defaults to: false)

    Logfile for this openvpn server

  • manage_logfile_directory (Boolean) (defaults to: false)

    Manage the directory that the logfile is located in

  • logdirectory_user (String[1]) (defaults to: 'nobody')

    The owner user of the logfile directory

  • logdirectory_group (String[1]) (defaults to: 'nobody')

    The owner group of the logfile directory

  • port (String) (defaults to: '1194')

    The port the openvpn server service is running on#

  • portshare (Optional[String]) (defaults to: undef)

    The address and port to which non openvpn request shall be forwared, e.g. 127.0.0.1 8443

  • proto (Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6']) (defaults to: 'tcp')

    What IP protocol is being used.

  • status_log (String) (defaults to: "/var/log/openvpn/${name}-status.log")

    Logfile for periodic dumps of the vpn service status

  • status_version (Enum['1', '2', '3', '']) (defaults to: '')

    Choose the status file format version number.

  • server (String) (defaults to: '')

    Network to assign client addresses out of. Required in tun mode, not in tap mode

  • server_ipv6 (String) (defaults to: '')

    IPv6 network to assign client addresses out of

  • server_bridge (String) (defaults to: '')

    Server configuration to comply with existing DHCP server

  • push (Array) (defaults to: [])

    Options to push out to the client. This can include routes, DNS servers, DNS search domains, and many other options.

  • route (Array) (defaults to: [])

    Add route to routing table after connection is established. Multiple routes can be specified.

  • route_ipv6 (Array) (defaults to: [])

    Add IPv6 route to routing table after connection is established. Multiple routes can be specified.

  • keepalive (String) (defaults to: '')

    Add keepalive directive (ping and ping-restart) to server. Should match the form “n m”.

  • ssl_key_size (Integer) (defaults to: 2048)

    Length of SSL keys (in bits) generated by this module.

  • topology (String) (defaults to: 'net30')

    Define the network topology type

  • c2c (Boolean) (defaults to: false)

    Enable client to client visibility

  • tcp_nodelay (Boolean) (defaults to: false)

    Enable/Disable.

  • ccd_exclusive (Boolean) (defaults to: false)

    Enable/Disable.

  • pam (Boolean) (defaults to: false)

    Enable/Disable.

  • pam_module_arguments (String) (defaults to: 'login')

    Arguments to pass to the PAM module. For FreeIPA, set this to “openvpn login USERNAME password PASSWORD” and create HBAC Service “openvpn”.

  • management (Boolean) (defaults to: false)

    Enable management interface

  • management_ip (String) (defaults to: 'localhost')

    IP address where the management interface will listen

  • management_port (Variant[Stdlib::Port::Unprivileged,Enum['unix']]) (defaults to: 7505)

    Port where the management interface will listen

  • up (Optional[String[1]]) (defaults to: undef)

    Script which we want to run when openvpn server starts. If the path to the scirpt does not contain a slash, it will be assumed to be in ‘openvpn/$name/scripts` directory.

  • down (Optional[String[1]]) (defaults to: undef)

    Script which we want to run when openvpn server stops. If the path to the scirpt does not contain a slash, it will be assumed to be in ‘openvpn/$name/scripts` directory.

  • client_connect (Optional[String[1]]) (defaults to: undef)

    Script which we want to run when a client connects. If the path to the scirpt does not contain a slash, it will be assumed to be in ‘openvpn/$name/scripts` directory.

  • client_disconnect (Optional[String[1]]) (defaults to: undef)

    Script which we want to run when a client disconnects. If the path to the scirpt does not contain a slash, it will be assumed to be in ‘openvpn/$name/scripts` directory.

  • username_as_common_name (Boolean) (defaults to: false)

    If true then set username-as-common-name

  • client_cert_not_required (Boolean) (defaults to: false)

    If true then set client-cert-not-required

  • ldap_enabled (Boolean) (defaults to: false)

    If ldap is enabled, do stuff

  • ldap_server (String) (defaults to: '')

    URL of LDAP server. ie. ldap://URL:PORT

  • ldap_binddn (String) (defaults to: '')

    LDAP DN to bind as#

  • ldap_bindpass (String) (defaults to: '')

    LDAP password for ldapbinddn

  • ldap_u_basedn (String) (defaults to: '')

    Place in the LDAP tree to look for users

  • ldap_u_filter (String) (defaults to: '')

    User SearchFilter for LDAP accounts

  • ldap_g_basedn (String) (defaults to: '')

    Place in the LDAP tree to look for groups

  • ldap_gmember (Boolean) (defaults to: false)

    If defined use group block in ldap.conf

  • ldap_g_filter (String) (defaults to: '')

    Group SearchFilter for LDAP accounts

  • ldap_memberatr (String) (defaults to: '')

    Attribute for MemberAttribute. Used with ldapfilter

  • ldap_tls_enable (Boolean) (defaults to: false)

    Enable TLS for the LDAP authentication

  • ldap_tls_ca_cert_file (String) (defaults to: '')

    LDAP TLS authentication: path to the CA certificate.

  • ldap_tls_ca_cert_dir (String) (defaults to: '')

    LDAP TLS authentication: path to the CA certificates.

  • ldap_tls_client_cert_file (Optional[Stdlib::Absolutepath]) (defaults to: undef)

    LDAP TLS authentication: path to the tls client certificate

  • ldap_tls_client_key_file (Optional[Stdlib::Absolutepath]) (defaults to: undef)

    LDAP TLS authentication: path to the tls client key

  • verb (String) (defaults to: '')

    Level of logging verbosity

  • cipher (String) (defaults to: 'AES-256-CBC')

    Cipher to use for packet encryption

  • tls_cipher (String) (defaults to: 'TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256')

    TLS Ciphers to use

  • persist_key (Boolean) (defaults to: false)

    Try to retain access to resources that may be unavailable because of privilege downgrades

  • persist_tun (Boolean) (defaults to: false)

    Try to retain access to resources that may be unavailable because of privilege downgrades

  • key_expire (Integer) (defaults to: 3650)

    The number of days to certify the server certificate for

  • ca_expire (Integer) (defaults to: 3650)

    The number of days to certify the CA certificate for

  • key_name (String) (defaults to: '')

    Value for name_default variable in openssl.cnf and KEY_NAME in vars

  • key_ou (String) (defaults to: '')

    Value for organizationalUnitName_default variable in openssl.cnf and KEY_OU in vars

  • key_cn (String) (defaults to: '')

    Value for commonName_default variable in openssl.cnf and KEY_CN in vars

  • tls_auth (Boolean) (defaults to: false)

    Activates tls-auth to Add an additional layer of HMAC authentication on top of the TLS control channel to protect against DoS attacks.

  • tls_crypt (Boolean) (defaults to: false)

    Encrypt and authenticate all control channel packets with the key from keyfile. (See –tls-auth for more background.)

  • tls_server (Boolean) (defaults to: false)

    If proto not tcp it lets you choose if the parameter tls-server is set or not.

  • tls_client (Boolean) (defaults to: false)

    Allows you to set this server up as a tls-client connection.

  • server_poll_timeout (Optional[Integer]) (defaults to: undef)

    Value for timeout before trying the next server.

  • ping_timer_rem (Boolean) (defaults to: false)

    Do not start clocking timeouts until a remote peer connects.

  • sndbuf (Optional[Integer]) (defaults to: undef)

    Set the TCP/UDP socket send buffer size.

  • rcvbuf (Optional[Integer]) (defaults to: undef)

    Set the TCP/UDP socket receive buffer size.

  • shared_ca (Optional[String]) (defaults to: undef)

    Name of a openssl::ca resource to use config with

  • crl_verify (Boolean) (defaults to: true)

    Enable CRL checking. Disabling this is not recommended.

  • crl_auto_renew (Boolean) (defaults to: false)

    Enables automatic renewing of crl.pem.

  • crl_renew_schedule_period (String) (defaults to: 'monthly')

    Sets the “period” Parameter of the schedule for renewing the CRL. Since changing the expiry of 30 days is not possible with easy-rsa2, twice a month should be good

  • crl_renew_schedule_repeat (Integer) (defaults to: 2)

    Sets the “repeat” Parameter of the schedule for renewing the CRL. Since changing the expiry of 30 days is not possible with easy-rsa2, twice a month should be good

  • extca_enabled (Boolean) (defaults to: false)

    Turn this on if you are using an external CA solution, like FreeIPA. Once enabled, you must configure the remaining extca_* parameters.

  • extca_ca_cert_file (Optional[String]) (defaults to: undef)

    External CA: Path to the CA certificate.

  • extca_ca_crl_file (Optional[String]) (defaults to: undef)

    External CA: Path to the CA’s CRL file. For FreeIPA-based CAs, CRLs expire every four hours, which means you may need your own solution for maintaining a local copy of your CA’s CRL. Otherwise, you can set crl_verify to false (not recommended).

  • extca_server_cert_file (Optional[String]) (defaults to: undef)

    External CA: Path to the external CA issued OpenVPN server certificate.

  • extca_server_key_file (Optional[String]) (defaults to: undef)

    External CA: Path to the key file that corresponds to $extca_server_cert_file

  • extca_dh_file (Optional[String]) (defaults to: undef)

    External CA: Path to your Dillie-Hellman parameter file. You will need to create one yourself. Make sure key-size matches the public key size of your CA-issued server certificate. Like this: openssl dhparam -out /path/to/dh.pem 2048 Note: This is only required if you are enabling $tls_server.

  • extca_tls_auth_key_file (Optional[String]) (defaults to: undef)

    External CA: If you are enabling $extca_enabled and $tls_auth, you will also need to create the tls-auth key file and specify its location here. The file can be created like this: openvpn –genkey –secret /path/to/ta.key. Note: you will need to distribute this file to your clients as well.

  • autostart (Optional[Boolean]) (defaults to: undef)

    Enable autostart for server if openvpn::autostart_all is false.

  • ns_cert_type (Boolean) (defaults to: true)

    Enable or disable use of ns-cert-type for the session. Generally used with client configuration Deprecated in OpenVPN 2.4 and replaced with remote-cert-tls

  • remote_cert_tls (Boolean) (defaults to: false)

    Enable or disable use of remote-cert-tls for the session. Generally used with client configuration

  • nobind (Boolean) (defaults to: false)

    Whether or not to bind to a specific port number.#

  • secret (Optional[String]) (defaults to: undef)

    A pre-shared static key.

  • scripts (Hash[String, Hash]) (defaults to: {})

    Hash of scripts to copy with this instance. For example, to put a script in ‘/etc/openvpn/test-site/scripts/add-tap-to-bridge.sh` and use it as an `up` script “` puppet openvpn::server { ’test-site’:

    ....
    up => 'add-tap-to-bridge.sh',
    scripts => {
      "add-tap-to-bridge.sh" => {
        source => 'puppet:///path/to/add-tap-to-bridge.sh',
      },
    },
    

    } “‘

  • custom_options (Hash) (defaults to: {})

    Hash of additional options to append to the configuration file.

  • fragment (Variant[Boolean, Integer]) (defaults to: false)


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
# File 'manifests/server.pp', line 144

define openvpn::server (
  Optional[String] $country                                         = undef,
  Optional[String] $province                                        = undef,
  Optional[String] $city                                            = undef,
  Optional[String] $organization                                    = undef,
  Optional[String] $email                                           = undef,
  Optional[Array] $remote                                           = undef,
  Boolean $remote_random_hostname                                   = false,
  Boolean $remote_random                                            = false,
  String $common_name                                               = 'server',
  String $compression                                               = 'comp-lzo',
  String $dev                                                       = 'tun0',
  String $user                                                      = 'nobody',
  Optional[String] $group                                           = undef,
  Boolean $ipp                                                      = false,
  Boolean $duplicate_cn                                             = false,
  String $local                                                     = $facts['networking']['ip'],
  Variant[Boolean, String] $logfile                                 = false,
  Boolean $manage_logfile_directory                                 = false,
  String[1] $logdirectory_user                                      = 'nobody',
  String[1] $logdirectory_group                                     = 'nobody',
  String $port                                                      = '1194',
  Optional[String] $portshare                                       = undef,
  Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6'] $proto         = 'tcp',
  Enum['1', '2', '3', ''] $status_version                           = '',
  String $status_log                                                = "/var/log/openvpn/${name}-status.log",
  String $server                                                    = '',
  String $server_ipv6                                               = '',
  String $server_bridge                                             = '',
  Array $push                                                       = [],
  Array $route                                                      = [],
  Array $route_ipv6                                                 = [],
  String $keepalive                                                 = '',
  Variant[Boolean, Integer] $fragment                               = false,
  Integer $ssl_key_size                                             = 2048,
  String $topology                                                  = 'net30',
  Boolean $c2c                                                      = false,
  Boolean $tcp_nodelay                                              = false,
  Boolean $ccd_exclusive                                            = false,
  Boolean $pam                                                      = false,
  String $pam_module_arguments                                      = 'login',
  Boolean $management                                               = false,
  String $management_ip                                             = 'localhost',
  Variant[Stdlib::Port::Unprivileged,Enum['unix']] $management_port = 7505,
  Optional[String[1]] $up                                           = undef,
  Optional[String[1]] $down                                         = undef,
  Optional[String[1]] $client_connect                               = undef,
  Optional[String[1]] $client_disconnect                            = undef,
  Boolean $username_as_common_name                                  = false,
  Boolean $client_cert_not_required                                 = false,
  Boolean $ldap_enabled                                             = false,
  String $ldap_server                                               = '',
  String $ldap_binddn                                               = '',
  String $ldap_bindpass                                             = '',
  String $ldap_u_basedn                                             = '',
  String $ldap_g_basedn                                             = '',
  Boolean $ldap_gmember                                             = false,
  String $ldap_u_filter                                             = '',
  String $ldap_g_filter                                             = '',
  String $ldap_memberatr                                            = '',
  Boolean $ldap_tls_enable                                          = false,
  String $ldap_tls_ca_cert_file                                     = '',
  String $ldap_tls_ca_cert_dir                                      = '',
  Optional[Stdlib::Absolutepath] $ldap_tls_client_cert_file         = undef,
  Optional[Stdlib::Absolutepath] $ldap_tls_client_key_file          = undef,
  Integer $ca_expire                                                = 3650,
  Integer $key_expire                                               = 3650,
  String $key_cn                                                    = '',
  String $key_name                                                  = '',
  String $key_ou                                                    = '',
  String $verb                                                      = '',
  String $cipher                                                    = 'AES-256-CBC',
  String $tls_cipher                                                = 'TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256',
  Boolean $persist_key                                              = false,
  Boolean $persist_tun                                              = false,
  Boolean $tls_auth                                                 = false,
  Boolean $tls_crypt                                                = false,
  Boolean $tls_server                                               = false,
  Boolean $tls_client                                               = false,
  Optional[Integer] $server_poll_timeout                            = undef,
  Boolean $ping_timer_rem                                           = false,
  Optional[Integer] $sndbuf                                         = undef,
  Optional[Integer] $rcvbuf                                         = undef,
  Optional[String] $shared_ca                                       = undef,
  Boolean $crl_verify                                               = true,
  Boolean $crl_auto_renew                                           = false,
  String $crl_renew_schedule_period                                 = 'monthly',
  Integer $crl_renew_schedule_repeat                                = 2,
  Boolean $extca_enabled                                            = false,
  Optional[String] $extca_ca_cert_file                              = undef,
  Optional[String] $extca_ca_crl_file                               = undef,
  Optional[String] $extca_server_cert_file                          = undef,
  Optional[String] $extca_server_key_file                           = undef,
  Optional[String] $extca_dh_file                                   = undef,
  Optional[String] $extca_tls_auth_key_file                         = undef,
  Optional[Boolean] $autostart                                      = undef,
  Boolean $ns_cert_type                                             = true,
  Boolean $remote_cert_tls                                          = false,
  Boolean $nobind                                                   = false,
  Optional[String] $secret                                          = undef,
  Hash[String, Hash] $scripts                                       = {},
  Hash $custom_options                                              = {},
) {
  include openvpn
  Class['openvpn::install']
  -> Openvpn::Server[$name]

  if $facts['service_provider'] == 'systemd' and $openvpn::namespecific_rclink {
    fail("Using systemd and namespecific rclink's (BSD-style) is not allowed")
  }

  if $tls_auth and $tls_crypt {
    fail('tls_auth and tls_crypt are mutually exclusive')
  }

  if $openvpn::manage_service {
    if $facts['service_provider'] == 'systemd' {
      $lnotify = Service["${openvpn::server_service_name}@${name}"]
    } elsif $openvpn::namespecific_rclink {
      $lnotify = Service["openvpn_${name}"]
    } else {
      $lnotify = Service['openvpn']
      Openvpn::Server[$name] -> Service['openvpn']
    }
  }
  else {
    $lnotify = undef
  }

  if $manage_logfile_directory {
    $logdir = dirname($logfile)
    file { $logdir:
      ensure => 'directory',
      owner  => $logdirectory_user,
      group  => $logdirectory_group,
    }
  }

  # Selection block to enable or disable tls-server flag
  # Check if we want to run as a client or not
  if !$tls_client {
    if $tls_server and !$extca_enabled {
      $real_tls_server = $tls_server
    } elsif ($extca_enabled and $extca_dh_file) or (!$extca_enabled) {
      $real_tls_server = $proto ? {
        /tcp/   => true,
        default => false
      }
    } else {
      $real_tls_server = false
    }
  }

  $pam_module_path = $openvpn::pam_module_path
  $etc_directory = $openvpn::etc_directory
  $server_directory = $openvpn::server_directory

  $group_to_set = $group ? {
    undef   => $openvpn::group,
    default => $group
  }

  if $shared_ca {
    $ca_name = $shared_ca
  } elsif !$extca_enabled {
    $ca_name = $name
  }

  File {
    group => $group_to_set,
  }

  file { "${server_directory}/${name}":
    ensure => directory,
    mode   => '0750',
    notify => $lnotify,
  }
  file {
    ["${server_directory}/${name}/scripts",]:
      ensure  => directory,
      mode    => '0750',
      recurse => true,
  }
  if $shared_ca {
    ensure_resource(file, "${server_directory}/${ca_name}", {
        ensure => directory,
        mode   => '0750',
    })
  }

  if $extca_enabled {
    # VPN Server or Client with external CA
    if $extca_ca_cert_file == undef { fail('extca_ca_cert_file has to be specified in extca mode') }
    if $extca_ca_crl_file == undef and $crl_verify and !$remote { fail('extca_ca_crl_file has to be specified in extca mode if crl_verify is enabled') }
    if $extca_server_cert_file == undef { fail('extca_server_cert_file has to be specified in extca mode') }
    if $extca_server_key_file == undef { fail('extca_server_key_file has to be specified in extca mode') }
    if $extca_dh_file == undef and !$remote and $tls_server { fail('cant enable tls_server: missing extca_dh_file') }
    if $extca_tls_auth_key_file == undef and !$remote and $tls_auth { fail('cant enable tls_auth: missing extca_tls_auth_key_file') }
  }

  if !$remote {
    if !$shared_ca and !$extca_enabled {
      # VPN Server Mode
      if $country == undef {
        fail('country has to be specified in server mode')
      }
      if $province == undef {
        fail('province has to be specified in server mode')
      }
      if $city == undef { fail('city has to be specified in server mode') }
      if $organization == undef {
        fail('organization has to be specified in server mode')
      }
      if $email == undef { fail('email has to be specified in server mode') }

      $ca_common_name = $common_name
      ::openvpn::ca { $name:
        country        => $country,
        province       => $province,
        city           => $city,
        organization   => $organization,
        email          => $email,
        common_name    => $common_name,
        group          => $group,
        ssl_key_size   => $ssl_key_size,
        ca_expire      => $ca_expire,
        key_expire     => $key_expire,
        key_cn         => $key_cn,
        key_name       => $key_name,
        key_ou         => $key_ou,
        tls_static_key => $tls_auth or $tls_crypt,
      }

      ## Renewal of crl.pem
      if ($crl_auto_renew) {
        schedule { "renew crl.pem schedule on ${name}":
          range  => '1 - 4',
          period => $crl_renew_schedule_period,
          repeat => $crl_renew_schedule_repeat,
        }
        case $openvpn::easyrsa_version {
          '2.0': {
            exec { "renew crl.pem on ${name}":
              command  => ". ./vars && KEY_CN='' KEY_OU='' KEY_NAME='' KEY_ALTNAMES='' openssl ca -gencrl -out ${server_directory}/${name}/crl.pem -config ${server_directory}/${name}/easy-rsa/openssl.cnf",
              cwd      => "${server_directory}/${name}/easy-rsa",
              provider => 'shell',
              schedule => "renew crl.pem schedule on ${name}",
            }
          }
          '3.0': {
            exec { "renew crl.pem on ${name}":
              command  => ". ./vars && EASYRSA_REQ_CN='' EASYRSA_REQ_OU='' openssl ca -gencrl -out ${server_directory}/${name}/crl.pem -config ${server_directory}/${name}/easy-rsa/openssl.cnf",
              cwd      => "${server_directory}/${name}/easy-rsa",
              provider => 'shell',
              schedule => "renew crl.pem schedule on ${name}",
            }
          }
          default: {
            fail("unexepected value for EasyRSA version, got '${openvpn::easyrsa_version}', expect 2.0 or 3.0.")
          }
        }
      }
    } elsif !$extca_enabled {
      if !defined(Openvpn::Ca[$shared_ca]) {
        fail("Openvpn::ca[${name}] is not defined for shared_ca")
      }
      $ca_common_name = getparam(Openvpn::Ca[$shared_ca], 'common_name')
    } else {
      $ca_common_name = undef
    }

    file {
      [
        "${server_directory}/${name}/auth",
        "${server_directory}/${name}/client-configs",
        "${server_directory}/${name}/download-configs",
      ]:
        ensure  => directory,
        mode    => '0750',
        recurse => true,
    }
  } else {
    # VPN Client Mode
    $ca_common_name = $name

    file { "${server_directory}/${name}/keys":
      ensure  => directory,
      mode    => '0750',
      recurse => true,
    }
  }

  if $facts['os']['family'] == 'Debian' and !$openvpn::autostart_all and $autostart {
    concat::fragment { "openvpn.default.autostart.${name}":
      content => "AUTOSTART=\"\$AUTOSTART ${name}\"\n",
      target  => '/etc/default/openvpn',
      order   => '10',
    }
  }

  # template use $_easyrsa_version
  $_easyrsa_version = $openvpn::easyrsa_version

  # Template might need script directory
  $_script_dir = "${server_directory}/${name}/scripts"

  file { "${server_directory}/${name}.conf":
    owner   => root,
    group   => 0,
    mode    => '0440',
    content => template('openvpn/server.erb'),
    notify  => $lnotify,
  }

  $ensure = $secret ? {
    undef   => absent,
    default => present,
  }
  file { "${server_directory}/${name}/keys/pre-shared.secret":
    ensure  => $ensure,
    owner   => root,
    group   => root,
    mode    => '0440',
    content => $secret,
    notify  => $lnotify,
  }

  $scripts.each |String $scriptname, Hash $properties| {
    file { "${_script_dir}/${scriptname}":
      * => $properties,
    }
  }

  if $ldap_enabled == true {
    file {
      "${server_directory}/${name}/auth/ldap.conf":
        ensure  => file,
        owner   => root,
        mode    => '0400',
        content => template('openvpn/ldap.erb'),
        require => Package['openvpn-auth-ldap'],
    }
  }

  if $facts['service_provider'] == 'systemd' {
    if $openvpn::manage_service {
      service { "${openvpn::server_service_name}@${name}":
        ensure   => running,
        enable   => true,
        provider => 'systemd',
        require  => File["${server_directory}/${name}.conf"],
      }
      if !$extca_enabled and !$remote {
        Openvpn::Ca[$ca_name] -> Service["${openvpn::server_service_name}@${name}"]
      }
    }
  }

  if $openvpn::namespecific_rclink {
    file { "/usr/local/etc/rc.d/openvpn_${name}":
      ensure => link,
      target => "${etc_directory}/rc.d/openvpn",
    }

    file { "/etc/rc.conf.d/openvpn_${name}":
      owner   => root,
      group   => 0,
      mode    => '0644',
      content => template('openvpn/etc-rc.d-openvpn.erb'),
    }

    if $openvpn::manage_service {
      service { "openvpn_${name}":
        ensure  => running,
        enable  => true,
        require => [
          File["${server_directory}/${name}.conf"],
          File["/usr/local/etc/rc.d/openvpn_${name}"],
        ],
      }
      if !extca_enabled and !$remote {
        Openvpn::Ca[$ca_name] -> Service["openvpn_${name}"]
      }
    }
  }
}