From 88cf4a501e5bcf47f9a11886d0f8108416ad1b8e Mon Sep 17 00:00:00 2001 From: Josh Gitlin Date: Fri, 14 May 2021 15:05:01 -0400 Subject: [PATCH] Match client and server conf; improve docs (#189) As described in issue #198, make settings in the client configs (E.G. `auth`, `cipher`, `compress`, etc) match their server counterparts. This eliminates warnings in the OpenVPN log about inconsistent option usage. In addition, document how the `openvpn_user` resource works, including showing how additional configuration options can be added to client conf files (using `additional_vars` and `cookbook_user_conf`) Squashed commit of the following: commit 91542b9b62d7d16d2578685afe12150c26eefaf1 Author: Josh Gitlin Date: Fri May 14 15:04:28 2021 -0400 Add changelog entry commit 858f41c496b8bdc5da5a3bfbc06c8ce4bfbf988b Author: Josh Gitlin Date: Fri May 14 15:00:21 2021 -0400 Bugfix node name commit dab2949b9006f9e43a641dac623c38030c2c50f4 Author: Josh Gitlin Date: Fri May 14 14:33:29 2021 -0400 Cookstyle fixes commit d587ae1d98fc28499b6f6b996d849cac7c6ddd3d Author: Josh Gitlin Date: Fri May 14 14:31:33 2021 -0400 MDL fixes commit eda83e5e616a96cad250d3f6271c48fca092cf5a Author: Josh Gitlin Date: Fri May 14 12:05:37 2021 -0400 Added documentation for vpn_user resource commit 61172d84100cf7ac0a8d9ada76ff2e6c7a35a073 Author: Josh Gitlin Date: Thu May 13 21:48:09 2021 -0400 Make client settings match server settings commit c14d15a5e2bca338cd1c4630c517e79af907925d Author: Josh Gitlin Date: Tue May 11 21:36:18 2021 -0400 Add compression to client configs Signed-off-by: Josh Gitlin --- CHANGELOG.md | 3 ++ README.md | 51 ++++++++++++++++++++++++++++++-- resources/user.rb | 10 +++++-- templates/client-inline.conf.erb | 12 +++++++- templates/client.conf.erb | 16 ++++++++-- 5 files changed, 84 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56c67d09..f66b8462 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This file is used to list changes made in each version of the openvpn cookbook. ## Unreleased +- Make client config match server config (fixes [#189](https://github.com/sous-chefs/openvpn/issues/189)) +- Document usage of `openvpn_user` with examples for `additional_vars` + ## 5.3.0 - *2021-03-16* - Fix openvpn_conf template handling diff --git a/README.md b/README.md index 27c03933..617b3fa8 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ These attributes are set by the cookbook by default. - `node['openvpn']['configure_default_server']` - Boolean. Set this to false if you want to create all of your "conf" files with the LWRP. - `node['openvpn']['git_package']` - Boolean. Whether to use the `openvpn-git` package (Arch Linux only, default false). - `node['openvpn']['client_prefix']` - String. Name of the config that is created for clients. When imported into most vpn clients, this is the name that will be displayed for the connection. Default is 'vpn-prod'. -- `node['openvpn']['cookbook_user_conf']` - String. The cookbook used by the `openvpn::users` recipe for the `client.conf.erb` template. You can override this to your own, such as your wrapper cookbook. Default is `'openvpn'`. +- `node['openvpn']['cookbook_user_conf']` - String. The cookbook used by the `openvpn::users` recipe for the `client.conf.erb` template. You can override this to your own, such as your wrapper cookbook. Default is `'openvpn'`. See [Customizing user configuration](#customizing-user-configuration) under the [openvpn_user resource](#openvpn_user) section - `node['openvpn']['key_dir']` - Location to store keys, certificates and related files. Default `/etc/openvpn/keys`. - `node['openvpn']['signing_ca_cert']` - CA certificate for signing, default `/etc/openvpn/keys/ca.crt` - `node['openvpn']['signing_ca_key']` - CA key for signing, default `/etc/openvpn/keys/ca.key` @@ -198,7 +198,54 @@ This cookbook also provides an 'up' script that runs when OpenVPN is started. Th ### openvpn_user -Implements a resource for creation of users and bundles. +Implements a resource for creation of users and bundles. User configuration will attempt to match the server configuration as best as possible, +by matching node attributes like `node['openvpn']['config']['compress']` and `node['openvpn']['config']['cipher']`. Reasonable default configuration +for the user bundle is specified otherwise. + +By default, an OpenVPN user _bundle_ is created, which is a gzipped TAR file (`.tgz` archive) containing the user configuration and the public/private +keys. This is controlled by the `create_bundle` attribute of the `openvpn_user` resource; pass `create_bundle false` if you prefer to have inline `.ovpn` +files created, containing the public and private keys all inside one OpenVPN config file. + +#### Customizing user configuration + +If the provided OpenVPN configuration does not meet your needs, either because you need different configuration directives, or you want to add directives which +are not present, you can use the node attribute `node['openvpn']['cookbook_user_conf']` to look for the template files in a different cookbook, E.G. in your +wrapper cookbook. + +If you only need _additional_ directives, you can use the `additional_vars` attribute of the `openvpn_user` resource to pass additional template variables to your +custom template. This way, you can render the user configuration from this cookbook using a partial, and append (or prepend) your own config inside your template. + +#### Example + +Adding a 2FA via a hardware token + +`cookbooks/vpn_wrapper/recipes/user.rb`: + +```ruby +override["openvpn"]["cookbook_user_conf"] => "vpn_wrapper" +openvpn_user "VPN User Bundle" do + client_name "my_user" + additional_vars( + static_challenge: %{"Touch your hardware token now:" 0} + ) +end +``` + +`cookbooks/vpn_wrapper/templates/client.conf.erb`: + +```ruby +<%= render "client.conf.erb", cookbook: "openvpn" %> +auth-user-pass +static-challenge <%= @static_challenge %> +``` + +`cookbooks/vpn_wrapper/templates/client-inline.conf.erb`: + +```ruby +<%= render "client-inline.conf.erb", cookbook: "openvpn" %> +auth-user-pass +static-challenge <%= @static_challenge %> +``` ### openvpn_config diff --git a/resources/user.rb b/resources/user.rb index baa0eaa4..1221dcc2 100644 --- a/resources/user.rb +++ b/resources/user.rb @@ -22,6 +22,11 @@ destination_path = ::File.expand_path(new_resource.destination || key_dir) bundle_filename = "#{new_resource.client_name}.tar.gz" bundle_full_path = ::File.expand_path(::File.join(destination_path, bundle_filename)) + compression = if node['openvpn']['config']['compress'] + node['openvpn']['config']['compress'] + elsif node['openvpn']['config']['comp-lzo'] + 'lzo' + end execute "generate-openvpn-#{new_resource.client_name}" do command "./pkitool #{new_resource.client_name}" @@ -46,7 +51,7 @@ template "#{destination_path}/#{client_file_basename}.conf" do source 'client.conf.erb' - cookbook node['openvpn']['cookbook_user_conf'] + cookbook lazy { node['openvpn']['cookbook_user_conf'] } variables(client_cn: new_resource.client_name) notifies :delete, "file[#{cleanup_name}]", :immediately only_if { new_resource.create_bundle } @@ -54,7 +59,7 @@ template "#{destination_path}/#{client_file_basename}.ovpn" do source new_resource.create_bundle ? 'client.conf.erb' : 'client-inline.conf.erb' - cookbook node['openvpn']['cookbook_user_conf'] + cookbook lazy { node['openvpn']['cookbook_user_conf'] } if new_resource.create_bundle variables(client_cn: new_resource.client_name) else @@ -66,6 +71,7 @@ ca: IO.read(ca_cert_path), cert: IO.read(cert_path), key: IO.read(key_path), + compression: compression, }.merge(new_resource.additional_vars) { |key, oldval, newval| oldval } # rubocop:disable Lint/UnusedBlockArgument end ) diff --git a/templates/client-inline.conf.erb b/templates/client-inline.conf.erb index 0b7e4eb9..49fb1d97 100644 --- a/templates/client-inline.conf.erb +++ b/templates/client-inline.conf.erb @@ -12,7 +12,17 @@ resolv-retry infinite nobind persist-key persist-tun -comp-lzo +<% if @compression -%> +compress <%= @compression %> +<% end %> +<% +%w(cipher tls-cipher auth keysize link-mtu).each do |conf| + if node['openvpn']['config'][conf] +%><%= "#{conf} #{node['openvpn']['config'][conf]}" %> +<% + end +end +-%> verb 3 <%= @ca -%> diff --git a/templates/client.conf.erb b/templates/client.conf.erb index e75eff6a..fbb0c825 100644 --- a/templates/client.conf.erb +++ b/templates/client.conf.erb @@ -15,8 +15,18 @@ persist-tun ca ca.crt cert <%= @client_cn %>.crt key <%= @client_cn %>.key -comp-lzo +<% if @compression -%> +<%= @compression %> +<% end %> +<% +%w(cipher tls-cipher auth keysize link-mtu).each do |conf| + if node['openvpn']['config'][conf] +%><%= "#{conf} #{node['openvpn']['config'][conf]}" %> +<% + end +end +-%> verb 3 -<% if node['openvpn']['server_verification'] %> +<% if node['openvpn']['server_verification'] -%> <%= node['openvpn']['server_verification'] %> -<% end %> +<% end -%>