Skip to content

Commit

Permalink
Make client settings match server settings and improve docs (#189)
Browse files Browse the repository at this point in the history
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 aditional configuration options can be added to client conf
files (using `additional_vars` and `cookbook_user_conf`)

Squashed commit of the following:

commit dab2949
Author: Josh Gitlin <[email protected]>
Date:   Fri May 14 14:33:29 2021 -0400

    Cookstyle fixes

commit d587ae1
Author: Josh Gitlin <[email protected]>
Date:   Fri May 14 14:31:33 2021 -0400

    MDL fixes

commit eda83e5
Author: Josh Gitlin <[email protected]>
Date:   Fri May 14 12:05:37 2021 -0400

    Added documentation for vpn_user resource

commit 61172d8
Author: Josh Gitlin <[email protected]>
Date:   Thu May 13 21:48:09 2021 -0400

    Make client settings match server settings

commit c14d15a
Author: Josh Gitlin <[email protected]>
Date:   Tue May 11 21:36:18 2021 -0400

    Add compression to client configs

Signed-off-by: Josh Gitlin <[email protected]>
  • Loading branch information
jgitlin-p21 committed May 14, 2021
1 parent 433d725 commit b69bfeb
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 8 deletions.
51 changes: 49 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down Expand Up @@ -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

Expand Down
10 changes: 8 additions & 2 deletions resources/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 default['openvpn']['config']['comp-lzo']
'lzo'
end

execute "generate-openvpn-#{new_resource.client_name}" do
command "./pkitool #{new_resource.client_name}"
Expand All @@ -46,15 +51,15 @@

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 }
end

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
Expand All @@ -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
)
Expand Down
12 changes: 11 additions & 1 deletion templates/client-inline.conf.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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>
<%= @ca -%>
Expand Down
16 changes: 13 additions & 3 deletions templates/client.conf.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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 -%>

0 comments on commit b69bfeb

Please sign in to comment.