diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 8af810ef..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -version: 2.1 -orbs: - kitchen: sous-chefs/kitchen@2 -workflows: - danger: - jobs: - - kitchen/danger: - name: danger - context: Danger-Minimal diff --git a/.delivery/project.toml b/.delivery/project.toml deleted file mode 100644 index 6d5e3617..00000000 --- a/.delivery/project.toml +++ /dev/null @@ -1 +0,0 @@ -remote_file = "https://raw.githubusercontent.com/chef-cookbooks/community_cookbook_tools/master/delivery/project.toml" diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 60bf5fdb..7cc52a97 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @sous-chefs/openvpn +* @sous-chefs/maintainers diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 651e753a..00000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,20 +0,0 @@ -### Cookbook version -[Version of the cookbook where you are encountering the issue] - -### Chef-client version -[Version of chef-client in your environment] - -### Platform Details -[Operating system distribution and release version. Cloud provider if running in the cloud] - -### Scenario: -[What you are trying to achieve and you can't?] - -### Steps to Reproduce: -[If you are filing an issue what are the things we need to do in order to repro your problem? How are you using this cookbook or any resources it includes?] - -### Expected Result: -[What are you expecting to happen as the consequence of above reproduction steps?] - -### Actual Result: -[What actually happens after the reproduction steps? Include the error output or a link to a gist if possible.] diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 9771a4a7..00000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,13 +0,0 @@ -### Description - -[Describe what this change achieves] - -### Issues Resolved - -[List any existing issues this PR resolves] - -### Check List - -- [ ] All tests pass. See -- [ ] New functionality includes testing. -- [ ] New functionality has been documented in the README if applicable diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b5a4ba6e..79bd7bdf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,74 +1,54 @@ --- name: ci -on: +"on": pull_request: push: branches: - - master + - main jobs: - delivery: - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@master - - name: Run Chef Delivery - uses: actionshub/chef-delivery@master - env: - CHEF_LICENSE: accept-no-persist - - yamllint: - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@master - - name: Run yaml Lint - uses: actionshub/yamllint@master + lint-unit: + uses: sous-chefs/.github/.github/workflows/lint-unit.yml@3.1.1 + permissions: + actions: write + checks: write + pull-requests: write + statuses: write + issues: write - mdl: - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@master - - name: Run Markdown Lint - uses: actionshub/markdownlint@master - - dokken: - needs: [mdl, yamllint, delivery] + integration: + needs: "lint-unit" runs-on: ubuntu-latest strategy: matrix: os: - - 'amazonlinux-2' - - 'centos-7' - - 'centos-8' - - 'debian-9' - - 'ubuntu-1604' - - 'ubuntu-1804' + - "almalinux-8" + - "amazonlinux-2023" + - "centos-7" + - "centos-stream-8" + - "debian-10" + - "debian-11" + - "fedora-latest" + - "rockylinux-8" + - "ubuntu-1804" + - "ubuntu-2004" suite: - - 'server' - - 'server-verification' - - 'server-verify-no-databag' + - "server" + - "server-verification" + - "server-verify-no-databag" fail-fast: false steps: - name: Check out code - uses: actions/checkout@master + uses: actions/checkout@v4 - name: Install Chef - uses: actionshub/chef-install@master + uses: actionshub/chef-install@3.0.0 - name: Dokken - uses: actionshub/kitchen-dokken@master + uses: actionshub/test-kitchen@3.0.0 env: CHEF_LICENSE: accept-no-persist KITCHEN_LOCAL_YAML: kitchen.dokken.yml with: suite: ${{ matrix.suite }} os: ${{ matrix.os }} - - final: - needs: [dokken] - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@master diff --git a/.github/workflows/md-links.yml b/.github/workflows/md-links.yml deleted file mode 100644 index d3a2e2b2..00000000 --- a/.github/workflows/md-links.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: md-links - -"on": - pull_request: - push: - branches: [master] - -jobs: - md-links: - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@main - - name: markdown-link-check - uses: gaurav-nelson/github-action-markdown-link-check@v1 - with: - use-verbose-mode: "yes" - folder-path: "documentation" diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 9e2ff38e..d4dae8fc 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -8,7 +8,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v3 + - uses: actions/stale@v9 with: repo-token: ${{ secrets.GITHUB_TOKEN }} close-issue-message: > diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml new file mode 100644 index 00000000..6fa8e776 --- /dev/null +++ b/.markdownlint-cli2.yaml @@ -0,0 +1,5 @@ +config: + ul-indent: false # MD007 + line-length: false # MD013 + no-duplicate-heading: false # MD024 + reference-links-images: false # MD052 diff --git a/.overcommit.yml b/.overcommit.yml index 1d27ed8d..0e89a3c1 100644 --- a/.overcommit.yml +++ b/.overcommit.yml @@ -4,17 +4,21 @@ PreCommit: enabled: true YamlLint: enabled: true - Rspec: + required_executable: "yamllint" + ChefSpec: enabled: true - required_executable: 'rspec' + required_executable: "chef" + command: ["chef", "exec", "rspec"] Cookstyle: enabled: true - required_executable: 'cookstyle' + required_executable: "cookstyle" command: ["cookstyle"] - Delivery: - enabled: true - required_executable: 'delivery' - flags: ['local', 'all'] + MarkdownLint: + enabled: false + required_executable: "npx" + command: ["npx", "markdownlint-cli2", "'**/*.md'"] + include: ["**/*.md"] + CommitMsg: HardTabs: enabled: true diff --git a/.vscode/extensions.json b/.vscode/extensions.json index cd777250..51d0ae7a 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,7 +1,8 @@ { "recommendations": [ - "chef-software.chef", - "rebornix.ruby", - "editorconfig.editorconfig" + "chef-software.chef", + "rebornix.ruby", + "editorconfig.editorconfig", + "DavidAnson.vscode-markdownlint" ] } diff --git a/.yamllint b/.yamllint index 1b5cea09..0046b237 100644 --- a/.yamllint +++ b/.yamllint @@ -11,3 +11,5 @@ rules: max-spaces-inside: 1 min-spaces-inside-empty: -1 max-spaces-inside-empty: -1 + comments: + min-spaces-from-content: 1 diff --git a/CHANGELOG.md b/CHANGELOG.md index f66b8462..aeb1a7ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,99 @@ This file is used to list changes made in each version of the openvpn cookbook. - 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` +## 7.0.20 - *2024-05-06* + +## 7.0.19 - *2024-05-06* + +## 7.0.18 - *2023-10-03* + +## 7.0.17 - *2023-10-03* + +- Added idempotency checks on CI + +## 7.0.16 - *2023-09-29* + +## 7.0.15 - *2023-09-11* + +## 7.0.14 - *2023-05-16* + +## 7.0.13 - *2023-04-17* + +## 7.0.12 - *2023-04-07* + +Standardise files with files in sous-chefs/repo-management + +## 7.0.11 - *2023-04-01* + +## 7.0.10 - *2023-04-01* + +## 7.0.9 - *2023-04-01* + +Standardise files with files in sous-chefs/repo-management + +## 7.0.8 - *2023-03-20* + +Standardise files with files in sous-chefs/repo-management + +## 7.0.7 - *2023-03-15* + +Standardise files with files in sous-chefs/repo-management + +## 7.0.6 - *2023-03-01* + +- Switch from mdl to markdownlint-cli2 +- Update workflows + +## 7.0.5 - *2023-02-16* + +## 7.0.4 - *2023-02-16* + +Standardise files with files in sous-chefs/repo-management + +## 7.0.3 - *2023-02-15* + +Standardise files with files in sous-chefs/repo-management + +## 7.0.2 - *2022-12-09* + +Standardise files with files in sous-chefs/repo-management + +## 7.0.1 - *2022-05-16* + +- Standardise files with files in sous-chefs/repo-management + +## 7.0.0 - *2022-05-07* + +- Remove comp-lzo as a default option + +## 6.1.0 - *2022-02-24* + +- Add certificate properties to user resource + +## 6.0.0 - *2022-02-08* + +- Remove delivery and move to calling RSpec directly via a reusable workflow +- Update tested platforms +- Fix Fedora +- Standardize kitchen settings +- Enable unified_mode and require Chef >= 15.3 +- Fix various idempotency issues + - Set umask to 077 to match file permissions we expect + - Trigger various resources to run during first converge phase + +## 5.4.0 - *2022-01-18* + +- resolved cookstyle error: recipes/server.rb:88:3 refactor: `Chef/RedundantCode/UseCreateIfMissing` +- resolved cookstyle error: recipes/server.rb:98:3 refactor: `Chef/RedundantCode/UseCreateIfMissing` + +## 5.3.2 - *2021-08-30* + +- Standardise files with files in sous-chefs/repo-management + +## 5.3.1 - *2021-06-01* + +- Standardise files with files in sous-chefs/repo-management + ## 5.3.0 - *2021-03-16* - Fix openvpn_conf template handling @@ -92,17 +185,17 @@ Locking yum dependency to '< 3' ### Bug -- **[COOK-3317](https://tickets.chef.io/browse/COOK-3317)** - Fix and make `server.up.sh` useful and customizable +- [COOK-3317] - Fix and make `server.up.sh` useful and customizable ### New Feature -- **[COOK-3315](https://tickets.chef.io/browse/COOK-3315)** - Remove hardcoded variables in configuration file +- [COOK-3315] - Remove hardcoded variables in configuration file ## v1.1.2 ### Improvement -- **[COOK-2820](https://tickets.chef.io/browse/COOK-2820)** - Update metadata.rb for all attributes and recipes +- [COOK-2820] - Update metadata.rb for all attributes and recipes ## v1.1.0 diff --git a/Dangerfile b/Dangerfile deleted file mode 100644 index bc08b7ae..00000000 --- a/Dangerfile +++ /dev/null @@ -1,47 +0,0 @@ -# Reference: http://danger.systems/reference.html - -# A pull request summary is required. Add a description of the pull request purpose. -# Changelog must be updated for each pull request that changes code. -# Warnings will be issued for: -# Pull request with more than 400 lines of code changed -# Pull reqest that change more than 5 lines without test changes -# Failures will be issued for: -# Pull request without summary -# Pull requests with code changes without changelog entry - -def code_changes? - code = %w(libraries attributes recipes resources files templates) - code.each do |location| - return true unless git.modified_files.grep(/#{location}/).empty? - end - false -end - -def test_changes? - tests = %w(spec test kitchen.yml kitchen.dokken.yml) - tests.each do |location| - return true unless git.modified_files.grep(/#{location}/).empty? - end - false -end - -failure 'Please provide a summary of your Pull Request.' if github.pr_body.length < 10 - -warn 'This is a big Pull Request.' if git.lines_of_code > 400 - -warn 'This is a Table Flip.' if git.lines_of_code > 2000 - -# Require a CHANGELOG entry for non-test changes. -if !git.modified_files.include?('CHANGELOG.md') && code_changes? - failure 'Please include a CHANGELOG entry.' -end - -# Require Major Minor Patch version labels -unless github.pr_labels.grep /minor|major|patch/i - warn 'Please add a release label to this pull request' -end - -# A sanity check for tests. -if git.lines_of_code > 5 && code_changes? && !test_changes? - warn 'This Pull Request is probably missing tests.' -end diff --git a/attributes/default.rb b/attributes/default.rb index 252a58fc..4eec575c 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -91,7 +91,6 @@ default['openvpn']['config']['up'] = [node['openvpn']['fs_prefix'], '/etc/openvpn/server.up.sh'].join default['openvpn']['config']['persist-key'] = '' default['openvpn']['config']['persist-tun'] = '' -default['openvpn']['config']['comp-lzo'] = '' default['openvpn']['config']['ca'] = node['openvpn']['signing_ca_cert'] default['openvpn']['config']['key'] = "#{node['openvpn']['key_dir']}/server.key" diff --git a/chefignore b/chefignore index cc170ea7..a27b0b25 100644 --- a/chefignore +++ b/chefignore @@ -61,7 +61,7 @@ Dangerfile examples/* features/* Guardfile -kitchen.yml* +kitchen*.yml mlc_config.json Procfile Rakefile diff --git a/kitchen.dokken.yml b/kitchen.dokken.yml new file mode 100644 index 00000000..47eff95d --- /dev/null +++ b/kitchen.dokken.yml @@ -0,0 +1,113 @@ +driver: + name: dokken + privileged: true + chef_version: <%= ENV['CHEF_VERSION'] || 'current' %> + +transport: { name: dokken } +provisioner: { name: dokken } + +platforms: + - name: almalinux-8 + driver: + image: dokken/almalinux-8 + pid_one_command: /usr/lib/systemd/systemd + + - name: almalinux-9 + driver: + image: dokken/almalinux-9 + pid_one_command: /usr/lib/systemd/systemd + + - name: amazonlinux-2023 + driver: + image: dokken/amazonlinux-2023 + pid_one_command: /usr/lib/systemd/systemd + + - name: centos-7 + driver: + image: dokken/centos-7 + pid_one_command: /usr/lib/systemd/systemd + + - name: centos-stream-8 + driver: + image: dokken/centos-stream-8 + pid_one_command: /usr/lib/systemd/systemd + + - name: centos-stream-9 + driver: + image: dokken/centos-stream-9 + pid_one_command: /usr/lib/systemd/systemd + + - name: debian-9 + driver: + image: dokken/debian-9 + pid_one_command: /bin/systemd + + - name: debian-10 + driver: + image: dokken/debian-10 + pid_one_command: /bin/systemd + + - name: debian-11 + driver: + image: dokken/debian-11 + pid_one_command: /bin/systemd + + - name: debian-12 + driver: + image: dokken/debian-12 + pid_one_command: /bin/systemd + + - name: fedora-latest + driver: + image: dokken/fedora-latest + pid_one_command: /usr/lib/systemd/systemd + + - name: opensuse-leap-15 + driver: + image: dokken/opensuse-leap-15 + pid_one_command: /usr/lib/systemd/systemd + + - name: oraclelinux-7 + driver: + image: dokken/oraclelinux-7 + pid_one_command: /usr/lib/systemd/systemd + + - name: oraclelinux-8 + driver: + image: dokken/oraclelinux-8 + pid_one_command: /usr/lib/systemd/systemd + + - name: oraclelinux-9 + driver: + image: dokken/oraclelinux-9 + pid_one_command: /usr/lib/systemd/systemd + + - name: rockylinux-8 + driver: + image: dokken/rockylinux-8 + pid_one_command: /usr/lib/systemd/systemd + + - name: rockylinux-9 + driver: + image: dokken/rockylinux-9 + pid_one_command: /usr/lib/systemd/systemd + + - name: ubuntu-18.04 + driver: + image: dokken/ubuntu-18.04 + pid_one_command: /bin/systemd + + - name: ubuntu-20.04 + driver: + image: dokken/ubuntu-20.04 + pid_one_command: /bin/systemd + + - name: ubuntu-22.04 + driver: + image: dokken/ubuntu-22.04 + pid_one_command: /bin/systemd + + - name: ubuntu-23.04 + driver: + image: dokken/ubuntu-23.04 + pid_one_command: /bin/systemd diff --git a/kitchen.exec.yml b/kitchen.exec.yml new file mode 100644 index 00000000..ba7b2a96 --- /dev/null +++ b/kitchen.exec.yml @@ -0,0 +1,7 @@ +--- +driver: { name: exec } +transport: { name: exec } + +platforms: + - name: macos-latest + - name: windows-latest diff --git a/kitchen.global.yml b/kitchen.global.yml new file mode 100644 index 00000000..a382fcd0 --- /dev/null +++ b/kitchen.global.yml @@ -0,0 +1,38 @@ +--- +provisioner: + name: chef_infra + product_name: chef + product_version: <%= ENV['CHEF_VERSION'] || 'latest' %> + channel: stable + install_strategy: once + chef_license: accept + enforce_idempotency: <%= ENV['ENFORCE_IDEMPOTENCY'] || true %> + multiple_converge: <%= ENV['MULTIPLE_CONVERGE'] || 2 %> + deprecations_as_errors: true + log_level: <%= ENV['CHEF_LOG_LEVEL'] || 'auto' %> + +verifier: + name: inspec + +platforms: + - name: almalinux-8 + - name: almalinux-9 + - name: amazonlinux-2023 + - name: centos-7 + - name: centos-stream-8 + - name: centos-stream-9 + - name: debian-9 + - name: debian-10 + - name: debian-11 + - name: debian-12 + - name: fedora-latest + - name: opensuse-leap-15 + - name: oraclelinux-7 + - name: oraclelinux-8 + - name: oraclelinux-9 + - name: rockylinux-8 + - name: rockylinux-9 + - name: ubuntu-18.04 + - name: ubuntu-20.04 + - name: ubuntu-22.04 + - name: ubuntu-23.04 diff --git a/kitchen.yml b/kitchen.yml index 0fb973a8..20d1f7d0 100644 --- a/kitchen.yml +++ b/kitchen.yml @@ -1,77 +1,29 @@ ---- driver: - name: dokken - privileged: true # because Docker and SystemD/Upstart - chef_version: <%= ENV['CHEF_VERSION'] || 'current' %> - -transport: - name: dokken - require_chef_omnibus: <%= ENV['CHEF_VERSION'] || 'latest' %> + name: vagrant provisioner: - name: dokken + name: chef_infra + enforce_idempotency: true + multiple_converge: 2 + deprecations_as_errors: true chef_license: accept-no-persist + enforce_idempotency: true + multiple_converge: 2 verifier: name: inspec - deprecations_as_errors: true -# currently only support 2 last major revs of distros (at the most) platforms: - name: amazonlinux-2 - driver: - image: dokken/amazonlinux-2 - pid_one_command: /usr/lib/systemd/systemd - - - name: debian-8 - driver: - image: dokken/debian-8 - pid_one_command: /bin/systemd - intermediate_instructions: - - RUN /usr/bin/apt-get update - - - name: debian-9 - driver: - image: dokken/debian-9 - pid_one_command: /bin/systemd - intermediate_instructions: - - RUN /usr/bin/apt-get update - - - name: debian-10 - driver: - image: dokken/debian-10 - pid_one_command: /bin/systemd - intermediate_instructions: - - RUN /usr/bin/apt-get update - - name: centos-7 - driver: - image: dokken/centos-7 - pid_one_command: /usr/lib/systemd/systemd - - - name: centos-8 - driver: - image: dokken/centos-8 - pid_one_command: /usr/lib/systemd/systemd - + - name: centos-stream-8 + - name: debian-10 + - name: debian-10 + - name: freebsd-12 - name: fedora-latest - driver: - image: dokken/fedora-latest - pid_one_command: /usr/lib/systemd/systemd - - - name: ubuntu-16.04 - driver: - image: dokken/ubuntu-16.04 - pid_one_command: /bin/systemd - intermediate_instructions: - - RUN /usr/bin/apt-get update - + - name: opensuse-leap-15 - name: ubuntu-18.04 - driver: - image: dokken/ubuntu-18.04 - pid_one_command: /bin/systemd - intermediate_instructions: - - RUN /usr/bin/apt-get update + - name: ubuntu-20.04 suites: - name: server @@ -82,15 +34,15 @@ suites: config: verb: 1 mute: 10 - route: - - '192.168.4.0 255.255.255.0' + route: ["192.168.4.0 255.255.255.0"] push_routes: - 192.168.10.0 255.255.255.0 - 10.12.10.0 255.255.255.0 push_options: dhcp-option: - - 'DOMAIN local' - - 'DOMAIN-SEARCH local' + - "DOMAIN local" + - "DOMAIN-SEARCH local" + - name: server_verification run_list: - recipe[openvpn::server] @@ -98,6 +50,7 @@ suites: attributes: openvpn: server_verification: "remote-cert-tls server" + - name: server_verify_no_databag run_list: - recipe[openvpn::server] diff --git a/metadata.rb b/metadata.rb index d8582c4a..a072c380 100644 --- a/metadata.rb +++ b/metadata.rb @@ -1,12 +1,12 @@ name 'openvpn' -version '5.3.0' maintainer 'Sous Chefs' maintainer_email 'help@sous-chefs.org' license 'Apache-2.0' description 'Installs and configures openvpn and includes rake tasks for managing certs.' source_url 'https://github.com/sous-chefs/openvpn' issues_url 'https://github.com/sous-chefs/openvpn/issues' -chef_version '>= 14' +version '7.0.20' +chef_version '>= 15.3' supports 'arch' supports 'centos' diff --git a/recipes/server.rb b/recipes/server.rb index 46114268..0177f609 100644 --- a/recipes/server.rb +++ b/recipes/server.rb @@ -85,7 +85,7 @@ file "#{key_dir}/serial" do content '01' - not_if { ::File.exist?("#{key_dir}/serial") } + action :create_if_missing end require 'openssl' @@ -95,32 +95,50 @@ owner 'root' group node['root_group'] mode '0600' - not_if { ::File.exist?(node['openvpn']['config']['dh']) } -end - -bash 'openvpn-initca' do - environment('KEY_CN' => "#{node['openvpn']['key']['org']} CA") - code <<-EOF - openssl req -batch -days #{node['openvpn']['key']['ca_expire']} \ - -nodes -new -newkey rsa:#{key_size} -#{message_digest} -x509 \ - -keyout #{node['openvpn']['signing_ca_key']} \ - -out #{node['openvpn']['signing_ca_cert']} \ - -config #{key_dir}/openssl.cnf - EOF + action :create_if_missing +end + +execute 'openvpn-initca' do + environment( + 'KEY_CN' => "#{node['openvpn']['key']['org']} CA", + 'KEY_EMAIL' => "#{node['openvpn']['key']['email']}", + 'KEY_COUNTRY' => "#{node['openvpn']['key']['country']}", + 'KEY_CITY' => "#{node['openvpn']['key']['city']}", + 'KEY_PROVINCE' => "#{node['openvpn']['key']['province']}", + 'KEY_DIR' => '/etc/openvpn/keys', + 'KEY_SIZE' => "#{node['openvpn']['key']['size']}", + 'KEY_ORG' => "#{node['openvpn']['key']['org']}", + 'KEY_OU' => 'OpenVPN Server' + ) + command 'umask 077 && ' \ + "openssl req -batch -days #{node['openvpn']['key']['ca_expire']} " \ + "-nodes -new -newkey rsa:#{key_size} -#{message_digest} -x509 " \ + "-keyout #{node['openvpn']['signing_ca_key']} " \ + "-out #{node['openvpn']['signing_ca_cert']} " \ + "-config #{key_dir}/openssl.cnf" not_if { ::File.exist?(node['openvpn']['signing_ca_cert']) } end -bash 'openvpn-server-key' do - environment('KEY_CN' => 'server') - code <<-EOF - openssl req -batch -days #{node['openvpn']['key']['expire']} \ - -nodes -new -newkey rsa:#{key_size} -keyout #{key_dir}/server.key \ - -out #{key_dir}/server.csr -extensions server \ - -config #{key_dir}/openssl.cnf && \ - openssl ca -batch -days #{node['openvpn']['key']['ca_expire']} \ - -out #{key_dir}/server.crt -in #{key_dir}/server.csr \ - -extensions server -md #{message_digest} -config #{key_dir}/openssl.cnf - EOF +execute 'openvpn-server-key' do + environment( + 'KEY_CN' => 'server', + 'KEY_EMAIL' => "#{node['openvpn']['key']['email']}", + 'KEY_COUNTRY' => "#{node['openvpn']['key']['country']}", + 'KEY_CITY' => "#{node['openvpn']['key']['city']}", + 'KEY_PROVINCE' => "#{node['openvpn']['key']['province']}", + 'KEY_DIR' => '/etc/openvpn/keys', + 'KEY_SIZE' => "#{node['openvpn']['key']['size']}", + 'KEY_ORG' => "#{node['openvpn']['key']['org']}", + 'KEY_OU' => 'OpenVPN Server' + ) + command 'umask 077 && ' \ + "openssl req -batch -days #{node['openvpn']['key']['expire']} " \ + "-nodes -new -newkey rsa:#{key_size} -keyout #{key_dir}/server.key " \ + "-out #{key_dir}/server.csr -extensions server " \ + "-config #{key_dir}/openssl.cnf && " \ + "openssl ca -batch -days #{node['openvpn']['key']['ca_expire']} " \ + "-out #{key_dir}/server.crt -in #{key_dir}/server.csr " \ + "-extensions server -md #{message_digest} -config #{key_dir}/openssl.cnf" not_if { ::File.exist?("#{key_dir}/server.crt") } end @@ -135,8 +153,19 @@ end execute 'gencrl' do - environment('KEY_CN' => "#{node['openvpn']['key']['org']} CA") - command "openssl ca -config #{[node['openvpn']['fs_prefix'], '/etc/openvpn/easy-rsa/openssl.cnf'].join} " \ + environment( + 'KEY_CN' => "#{node['openvpn']['key']['org']} CA", + 'KEY_EMAIL' => "#{node['openvpn']['key']['email']}", + 'KEY_COUNTRY' => "#{node['openvpn']['key']['country']}", + 'KEY_CITY' => "#{node['openvpn']['key']['city']}", + 'KEY_PROVINCE' => "#{node['openvpn']['key']['province']}", + 'KEY_DIR' => '/etc/openvpn/keys', + 'KEY_SIZE' => "#{node['openvpn']['key']['size']}", + 'KEY_ORG' => "#{node['openvpn']['key']['org']}", + 'KEY_OU' => 'OpenVPN Server' + ) + command 'umask 077 && ' \ + "openssl ca -config #{[node['openvpn']['fs_prefix'], '/etc/openvpn/easy-rsa/openssl.cnf'].join} " \ '-gencrl ' \ '-crlexts crl_ext ' \ "-md #{node['openvpn']['key']['message_digest']} " \ @@ -158,6 +187,7 @@ generate end action :run + notifies :create, "remote_file[#{[node['openvpn']['fs_prefix'], '/etc/openvpn/crl.pem'].join}]" end # Make a world readable copy of the CRL diff --git a/recipes/service.rb b/recipes/service.rb index 6274af60..38d12125 100644 --- a/recipes/service.rb +++ b/recipes/service.rb @@ -36,10 +36,10 @@ service_name = 'openvpn' end when 'fedora' - link "/etc/systemd/system/multi-user.target.wants/openvpn@#{node['openvpn']['type']}.service" do + link "/etc/systemd/system/multi-user.target.wants/openvpn-#{node['openvpn']['type']}@#{node['openvpn']['type']}.service" do to '/usr/lib/systemd/system/openvpn@.service' end - service_name = "openvpn@#{node['openvpn']['type']}.service" + service_name = "openvpn-#{node['openvpn']['type']}@#{node['openvpn']['type']}.service" when 'amazon' case node['platform_version'].to_i when 2 diff --git a/recipes/users.rb b/recipes/users.rb index cdc5ffa4..8986fcda 100644 --- a/recipes/users.rb +++ b/recipes/users.rb @@ -20,6 +20,15 @@ if node['openvpn']['use_databag'] search(node['openvpn']['user_databag'], node['openvpn']['user_query']) do |u| openvpn_user u['id'] do + key_vars({ + 'key_country' => u['key_country'], + 'key_province' => u['key_province'], + 'key_city' => u['key_city'], + 'key_email' => u['key_email'], + 'key_size' => u['key_size'], + 'key_org' => u['key_org'], + 'key_org_unit' => u['key_org_unit'], + }) create_bundle true end end diff --git a/renovate.json b/renovate.json new file mode 100644 index 00000000..a0b29c85 --- /dev/null +++ b/renovate.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:base"], + "packageRules": [ + { + "groupName": "Actions", + "matchUpdateTypes": ["minor", "patch", "pin"], + "automerge": true, + "addLabels": ["Release: Patch", "Skip: Announcements"] + }, + { + "groupName": "Actions", + "matchUpdateTypes": ["major"], + "automerge": false, + "addLabels": ["Release: Patch", "Skip: Announcements"] + } + ] +} diff --git a/resources/conf.rb b/resources/conf.rb index 1d66082c..59e0c551 100644 --- a/resources/conf.rb +++ b/resources/conf.rb @@ -21,9 +21,10 @@ property :template_source, String, default: 'server.conf.erb' property :push_routes, Array property :push_options, Array +unified_mode true action :create do - conf_location = if platform_family?('rhel') && node['platform_version'].to_i >= 8 + conf_location = if (platform_family?('rhel') && node['platform_version'].to_i >= 8) || platform_family?('fedora') "/etc/openvpn/#{new_resource.name}/#{new_resource.name}.conf" else "/etc/openvpn/#{new_resource.name}.conf" diff --git a/resources/user.rb b/resources/user.rb index 1221dcc2..66559781 100644 --- a/resources/user.rb +++ b/resources/user.rb @@ -7,13 +7,15 @@ property :create_bundle, [true, false], default: true property :force, [true, false] property :destination, String +property :key_vars, Hash, default: {} property :additional_vars, Hash, default: {} +unified_mode true + # TODO: this action will not recreate if the client configuration data has # changed. Requires manual intervention. action :create do - # Setup some variables key_dir = node['openvpn']['key_dir'] cert_path = ::File.join(key_dir, "#{new_resource.client_name}.crt") ca_cert_path = ::File.join(key_dir, 'ca.crt') @@ -29,22 +31,25 @@ end execute "generate-openvpn-#{new_resource.client_name}" do - command "./pkitool #{new_resource.client_name}" + command "umask 077 && ./pkitool #{new_resource.client_name}" cwd '/etc/openvpn/easy-rsa' environment( - 'EASY_RSA' => '/etc/openvpn/easy-rsa', - 'KEY_CONFIG' => '/etc/openvpn/easy-rsa/openssl.cnf', - 'KEY_DIR' => key_dir, - 'CA_EXPIRE' => node['openvpn']['key']['ca_expire'].to_s, - 'KEY_EXPIRE' => node['openvpn']['key']['expire'].to_s, - 'KEY_SIZE' => node['openvpn']['key']['size'].to_s, - 'KEY_COUNTRY' => node['openvpn']['key']['country'], - 'KEY_PROVINCE' => node['openvpn']['key']['province'], - 'KEY_CITY' => node['openvpn']['key']['city'], - 'KEY_ORG' => node['openvpn']['key']['org'], - 'KEY_EMAIL' => node['openvpn']['key']['email'] + 'EASY_RSA' => '/etc/openvpn/easy-rsa', + 'KEY_CONFIG' => '/etc/openvpn/easy-rsa/openssl.cnf', + 'KEY_DIR' => key_dir, + 'CA_EXPIRE' => (new_resource.key_vars['ca_expire'] || node['openvpn']['key']['ca_expire']).to_s, + 'KEY_EXPIRE' => (new_resource.key_vars['key_expire'] || node['openvpn']['key']['expire']).to_s, + 'KEY_SIZE' => (new_resource.key_vars['key_size'] || node['openvpn']['key']['size']).to_s, + 'KEY_COUNTRY' => (new_resource.key_vars['key_country'] || node['openvpn']['key']['country']), + 'KEY_PROVINCE' => (new_resource.key_vars['key_province'] || node['openvpn']['key']['province']), + 'KEY_CITY' => (new_resource.key_vars['key_city'] || node['openvpn']['key']['city']), + 'KEY_ORG' => (new_resource.key_vars['key_org'] || node['openvpn']['key']['org']), + 'KEY_EMAIL' => (new_resource.key_vars['key_email'] || node['openvpn']['key']['email']), + 'KEY_OU' => (new_resource.key_vars['key_org_unit'] || 'OpenVPN Server') ) creates cert_path unless new_resource.force + notifies :run, 'execute[gencrl]', :immediately + notifies :create, "remote_file[#{[node['openvpn']['fs_prefix'], '/etc/openvpn/crl.pem'].join}]", :immediately end cleanup_name = "cleanup-old-bundle-#{new_resource.client_name}" @@ -89,7 +94,7 @@ cwd destination_path filelist = "ca.crt #{new_resource.client_name}.crt #{new_resource.client_name}.key #{client_file_basename}.ovpn" filelist += " #{client_file_basename}.conf" if new_resource.create_bundle - command "tar zcf #{bundle_filename} #{filelist}" + command "umask 077 && tar zcf #{bundle_filename} #{filelist}" creates bundle_full_path unless new_resource.force end end diff --git a/spec/unit/recipes/server_spec.rb b/spec/unit/recipes/server_spec.rb index 776957e8..1559ba27 100644 --- a/spec/unit/recipes/server_spec.rb +++ b/spec/unit/recipes/server_spec.rb @@ -38,8 +38,18 @@ it 'executes gencrl with correction parameters' do expect(chef_run).to run_execute('gencrl').with( - environment: { 'KEY_CN' => 'Fort Funston CA' }, - command: 'openssl ca -config /etc/openvpn/easy-rsa/openssl.cnf ' \ + environment: { + 'KEY_CITY' => 'San Francisco', + 'KEY_CN' => 'Fort Funston CA', + 'KEY_COUNTRY' => 'US', + 'KEY_DIR' => '/etc/openvpn/keys', + 'KEY_EMAIL' => 'admin@foobar.com', + 'KEY_ORG' => 'Fort Funston', + 'KEY_OU' => 'OpenVPN Server', + 'KEY_PROVINCE' => 'CA', + 'KEY_SIZE' => '2048', + }, + command: 'umask 077 && openssl ca -config /etc/openvpn/easy-rsa/openssl.cnf ' \ '-gencrl ' \ '-crlexts crl_ext ' \ '-md sha256 ' \ diff --git a/templates/Rakefile.erb b/templates/Rakefile.erb index d5ba6bb0..4b7d9374 100644 --- a/templates/Rakefile.erb +++ b/templates/Rakefile.erb @@ -56,7 +56,6 @@ persist-tun ca ca.crt cert #{usercn}.crt key #{usercn}.key -comp-lzo verb 3 <% if node['openvpn']['server_verification'] %> <%= node['openvpn']['server_verification'] %> diff --git a/templates/openssl.cnf.erb b/templates/openssl.cnf.erb index 52e239f6..a6cd1739 100644 --- a/templates/openssl.cnf.erb +++ b/templates/openssl.cnf.erb @@ -9,7 +9,7 @@ engines = engine_section [ ca ] default_ca = CA_default [ CA_default ] -dir = <%= node['openvpn']['key_dir'] %> +dir = $ENV::KEY_DIR certs = $dir crl_dir = $dir database = $dir/index.txt @@ -42,7 +42,7 @@ organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] -default_bits = <%= node['openvpn']['key']['size'] %> +default_bits = $ENV::KEY_SIZE default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes @@ -50,22 +50,22 @@ x509_extensions = v3_ca string_mask = nombstr [ req_distinguished_name ] countryName = Country Name (2 letter code) -countryName_default = <%= node['openvpn']['key']['country'] %> +countryName_default = $ENV::KEY_COUNTRY countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = <%= node['openvpn']['key']['province'] %> +stateOrProvinceName_default = $ENV::KEY_PROVINCE localityName = Locality Name (eg, city) -localityName_default = <%= node['openvpn']['key']['city'] %> +localityName_default = $ENV::KEY_CITY 0.organizationName = Organization Name (eg, company) -0.organizationName_default = <%= node['openvpn']['key']['org'] %> +0.organizationName_default = $ENV::KEY_ORG organizationalUnitName = Organizational Unit Name (eg, section) commonName = Common Name (eg, your name or your server\'s hostname) commonName_max = 64 emailAddress = Email Address -emailAddress_default = <%= node['openvpn']['key']['email'] %> +emailAddress_default = $ENV::KEY_EMAIL emailAddress_max = 40 -organizationalUnitName_default = "OpenVPN Server" +organizationalUnitName_default = $ENV::KEY_OU commonName_default = $ENV::KEY_CN [ req_attributes ] challengePassword = A challenge password diff --git a/test/integration/data_bags/users/vpn_user.json b/test/integration/data_bags/users/vpn_user.json index 280c88a9..7d01da90 100644 --- a/test/integration/data_bags/users/vpn_user.json +++ b/test/integration/data_bags/users/vpn_user.json @@ -1,3 +1,10 @@ { - "id": "vpn_user" + "id": "vpn_user", + "key_country": "CA", + "key_province": "Ontario", + "key_city": "Ottawa", + "key_org": "Test Org", + "key_org_unit": "Test Org Unit", + "key_email": "vpn_user@test.com", + "key_size": "1024" } diff --git a/test/integration/server/server_test.rb b/test/integration/server/server_test.rb index 1bdae1ee..b2874a35 100644 --- a/test/integration/server/server_test.rb +++ b/test/integration/server/server_test.rb @@ -1,17 +1,15 @@ # this is done in a similar fashion to # https://github.com/xhost-cookbooks/openvpn/blob/master/recipes/service.rb -if (os[:name] == 'redhat' && os[:release] >= '7') || - (os[:name] == 'centos' && os[:release] < '8') || - (os[:name] == 'debian' && os[:release] >= '8') || - (os[:name] == 'ubuntu' && os[:release] >= '15.04') || - (os[:name] == 'amazon' && os[:release] >= '2') || - (os[:name] == 'fedora') +if (os[:family] == 'redhat' && os[:release].to_i < 8) || + (os[:name] == 'debian') || + (os[:name] == 'ubuntu') || + (os[:name] == 'amazon') describe service('openvpn@server') do it { is_expected.to be_enabled } it { is_expected.to be_running } end -elsif os[:name] == 'centos' && os[:release] >= '8' +elsif (os[:family] == 'redhat' && os[:release] >= '8') || os[:family] == 'fedora' describe service('openvpn-server@server') do it { is_expected.to be_enabled } it { is_expected.to be_running } @@ -23,7 +21,7 @@ end end -conf_location = if os[:name] == 'centos' && os[:release] >= '8' +conf_location = if (os[:family] == 'redhat' && os[:release] >= '8') || os[:family] == 'fedora' '/etc/openvpn/server/server.conf' else '/etc/openvpn/server.conf' diff --git a/test/integration/server_verification/default_test.rb b/test/integration/server_verification/default_test.rb index f33ce512..fda64509 100644 --- a/test/integration/server_verification/default_test.rb +++ b/test/integration/server_verification/default_test.rb @@ -10,3 +10,13 @@ end end end + +describe file('/etc/openvpn/keys/vpn_user.crt') do + its('content') { should match /C=CA/ } + its('content') { should match /ST=Ontario/ } + its('content') { should match /L=Ottawa/ } + its('content') { should match /O=Test Org/ } + its('content') { should match /OU=Test Org Unit/ } + its('content') { should match %r{CN=vpn_user/emailAddress=vpn_user@test.com} } + its('content') { should match /Public-Key: \(1024 bit\)/ } +end