diff --git a/manifests/ca.pp b/manifests/ca.pp index e2087b6d..e779fb42 100644 --- a/manifests/ca.pp +++ b/manifests/ca.pp @@ -112,6 +112,12 @@ group => $group_to_set, } + # directory shared with openvpn::server + ensure_resource(file, "/etc/openvpn/${name}", { + ensure => directory, + mode => '0750', + }) + exec { "copy easy-rsa to openvpn config folder ${name}": command => "/bin/cp -r ${openvpn::params::easyrsa_source} /etc/openvpn/${name}/easy-rsa", creates => "/etc/openvpn/${name}/easy-rsa", diff --git a/manifests/client.pp b/manifests/client.pp index dfea4a3d..69eea2e9 100644 --- a/manifests/client.pp +++ b/manifests/client.pp @@ -109,6 +109,10 @@ # Integer, Set the TCP/UDP socket receive buffer size. # Default: undef # +# [*shared_ca*] +# String, The name of an openssl::ca resource to use. +# Default: undef +# # === Examples # # openvpn::client { @@ -167,6 +171,7 @@ $down = '', $sndbuf = undef, $rcvbuf = undef, + $shared_ca = undef, ) { if $pam { @@ -176,11 +181,15 @@ Openvpn::Server[$server] -> Openvpn::Client[$name] + $ca_name = pick($shared_ca, $server) + Openvpn::Ca[$ca_name] -> + Openvpn::Client[$name] + exec { - "generate certificate for ${name} in context of ${server}": + "generate certificate for ${name} in context of ${ca_name}": command => ". ./vars && ./pkitool ${name}", - cwd => "/etc/openvpn/${server}/easy-rsa", - creates => "/etc/openvpn/${server}/easy-rsa/keys/${name}.crt", + cwd => "/etc/openvpn/${ca_name}/easy-rsa", + creates => "/etc/openvpn/${ca_name}/easy-rsa/keys/${name}.crt", provider => 'shell'; } @@ -192,20 +201,20 @@ file { "/etc/openvpn/${server}/download-configs/${name}/keys/${name}/${name}.crt": ensure => link, - target => "/etc/openvpn/${server}/easy-rsa/keys/${name}.crt", - require => Exec["generate certificate for ${name} in context of ${server}"], + target => "/etc/openvpn/${ca_name}/easy-rsa/keys/${name}.crt", + require => Exec["generate certificate for ${name} in context of ${ca_name}"], } file { "/etc/openvpn/${server}/download-configs/${name}/keys/${name}/${name}.key": ensure => link, - target => "/etc/openvpn/${server}/easy-rsa/keys/${name}.key", - require => Exec["generate certificate for ${name} in context of ${server}"], + target => "/etc/openvpn/${ca_name}/easy-rsa/keys/${name}.key", + require => Exec["generate certificate for ${name} in context of ${ca_name}"], } file { "/etc/openvpn/${server}/download-configs/${name}/keys/${name}/ca.crt": ensure => link, - target => "/etc/openvpn/${server}/easy-rsa/keys/ca.crt", - require => Exec["generate certificate for ${name} in context of ${server}"], + target => "/etc/openvpn/${ca_name}/easy-rsa/keys/ca.crt", + require => Exec["generate certificate for ${name} in context of ${ca_name}"], } file { "/etc/openvpn/${server}/download-configs/${name}/${name}.conf": diff --git a/manifests/server.pp b/manifests/server.pp index 55c20959..88cda0e6 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -281,6 +281,10 @@ # Integer, Set the TCP/UDP socket receive buffer size. # Default: undef # +# [*shared_ca*] +# String. Name of a openssl::ca resource to use config with +# Default: undef +# # === Examples # # openvpn::client { @@ -382,6 +386,7 @@ $ping_timer_rem = false, $sndbuf = undef, $rcvbuf = undef, + $shared_ca = undef, ) { include openvpn @@ -403,18 +408,43 @@ group => $group_to_set, } - file { "/etc/openvpn/${name}": + # directory shared with openvpn::ca + ensure_resource(file, "/etc/openvpn/${name}", { ensure => directory, mode => '0750', - } + }) if $remote == undef { - # 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") } + if $shared_ca == undef { + # 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_name = $name + $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, + } + } else { + $ca_name = $shared_ca + $ca_common_name = getparam(Openvpn::Ca[$ca_name], 'common_name') + Openvpn::Ca[$shared_ca] -> Openvpn::Server[$name] + } file { [ "/etc/openvpn/${name}/auth", @@ -425,21 +455,6 @@ recurse => true, } - ::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, - } } else { # VPN Client Mode diff --git a/spec/defines/openvpn_client_spec.rb b/spec/defines/openvpn_client_spec.rb index 0aeffb3d..7362acf3 100644 --- a/spec/defines/openvpn_client_spec.rb +++ b/spec/defines/openvpn_client_spec.rb @@ -111,4 +111,49 @@ it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^sndbuf\s+393216$/)} it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^rcvbuf\s+393215$/)} end + + context "when using shared ca" do + let(:params) { { + 'server' => 'test_server', + 'shared_ca' => 'my_already_existing_ca', + } } + before do + pre_condition << ' + openvpn::ca{ "my_already_existing_ca": + common_name => "custom_common_name", + country => "CO", + province => "ST", + city => "Some City", + organization => "example.org", + email => "testemail@example.org" + } + ' + end + + it { should contain_openvpn__ca('my_already_existing_ca') } + + it { should contain_exec('generate certificate for test_client in context of my_already_existing_ca') } + [ 'test_client.crt', 'test_client.key', 'ca.crt' ].each do |file| + it { should contain_file("/etc/openvpn/test_server/download-configs/test_client/keys/test_client/#{file}").with( + 'ensure' => 'link', + 'target' => "/etc/openvpn/my_already_existing_ca/easy-rsa/keys/#{file}" + )} + end + + # Check that certificate files point to the provide CA + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^client$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^ca\s+keys\/test_client\/ca\.crt$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^cert\s+keys\/test_client\/test_client.crt$/)} + it { should contain_file('/etc/openvpn/test_server/download-configs/test_client/test_client.conf').with_content(/^key\s+keys\/test_client\/test_client\.key$/)} + end + + context "when using not existed shared ca" do + let(:params) { { + 'server' => 'test_server', + 'shared_ca' => 'my_already_existing_ca', + } } + it { expect { should compile }.to raise_error } + end + + end diff --git a/spec/defines/openvpn_server_spec.rb b/spec/defines/openvpn_server_spec.rb index 39ec1299..55974e13 100644 --- a/spec/defines/openvpn_server_spec.rb +++ b/spec/defines/openvpn_server_spec.rb @@ -260,6 +260,38 @@ it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^rcvbuf\s+393215$/) } end + context "when using shared ca" do + let(:params) { { + 'shared_ca' => 'my_already_existing_ca', + } } + let(:pre_condition) { ' + openvpn::ca{ "my_already_existing_ca": + common_name => "custom_common_name", + country => "CO", + province => "ST", + city => "Some City", + organization => "example.org", + email => "testemail@example.org" + }' } + + it { should contain_openvpn__ca('my_already_existing_ca') } + + # Check that certificate files point to the provide CA + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^mode\s+server$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^client\-config\-dir\s+\/etc\/openvpn\/test_server\/client\-configs$/) } + + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^ca\s+\/etc\/openvpn\/my_already_existing_ca\/keys\/ca.crt$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^cert\s+\/etc\/openvpn\/my_already_existing_ca\/keys\/custom_common_name.crt$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^key\s+\/etc\/openvpn\/my_already_existing_ca\/keys\/custom_common_name.key$/) } + it { should contain_file('/etc/openvpn/test_server.conf').with_content(/^dh\s+\/etc\/openvpn\/my_already_existing_ca\/keys\/dh1024.pem$/) } + end + + context "when using not existed shared ca" do + let(:params) { { + 'shared_ca' => 'my_already_existing_ca', + } } + it { expect { should compile }.to raise_error } + end context "when RedHat based machine" do let(:params) { { diff --git a/templates/server.erb b/templates/server.erb index 2ec6134d..44f27a84 100644 --- a/templates/server.erb +++ b/templates/server.erb @@ -11,14 +11,14 @@ remote <%= rem %> server-poll-timeout <%= @server_poll_timeout %> <% end -%> <% end -%> -ca /etc/openvpn/<%= @name %>/keys/ca.crt -cert /etc/openvpn/<%= @name %>/keys/<%= @common_name %>.crt -key /etc/openvpn/<%= @name %>/keys/<%= @common_name %>.key +ca /etc/openvpn/<%= @ca_name %>/keys/ca.crt +cert /etc/openvpn/<%= @ca_name %>/keys/<%= @ca_common_name %>.crt +key /etc/openvpn/<%= @ca_name %>/keys/<%= @ca_common_name %>.key <% unless @remote -%> -dh /etc/openvpn/<%= @name %>/keys/dh<%= @ssl_key_size %>.pem +dh /etc/openvpn/<%= @ca_name %>/keys/dh<%= @ssl_key_size %>.pem <% end -%> <% unless @remote -%> -crl-verify /etc/openvpn/<%= @name %>/crl.pem +crl-verify /etc/openvpn/<%= @ca_name %>/crl.pem <% end -%> <% if @proto == 'tcp' -%> proto <%= @proto %>-server