Skip to content

Commit

Permalink
Add ssl default settings in http context. (#13)
Browse files Browse the repository at this point in the history
The ssl settings that are done in the http context used as default for
all server within the http conext. So with this new option we can manage
ssl settings in a single place. The settings can be set via pillar. If
needed the configuration values can be override in each server.

Co-authored-by: Daniel Goeke <[email protected]>
Co-authored-by: Chris Aumann <[email protected]>
  • Loading branch information
3 people authored Jan 27, 2023
1 parent b3b9545 commit 5a60749
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .salt-lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
skip_list:
# Allows 3-digit unquoted codes to still be used, such as `644` and `755`
- 207 # File modes should always be encapsulated in quotation marks
- 208 # File modes should always contain a leading zero
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Install and configure nginx.

Install the `nginx` package from the official PPA.

Set default ssl settings in the `http` context. This settings can be overwritten for `server {}` block if needed.

To deploy sites, you need to put your configuration files in `/etc/nginx/conf.d` in another formula.


Expand Down
22 changes: 22 additions & 0 deletions init.sls
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# The cipher suite comes from the Mozilla TLS guide, with the following modifications:
# - Prefer Chacha-Poly over AES
# - Remove less secure DHE based ciphers
# - Prefer SHA384 over SHA256
# See: https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29
{% set ssl_protocols = salt['pillar.get']('nginx:ssl_protocols', 'TLSv1.2 TLSv1.3') %}
{% set ssl_ciphers = salt['pillar.get']('nginx:ssl_ciphers', 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256' ) %} # noqa: 204
{% set ssl_session_cache = salt['pillar.get']('nginx:ssl_session_cache', 'shared:SSL:10m' ) %}
{% set ssl_prefer_server_ciphers = salt['pillar.get']('nginx:ssl_prefer_server_ciphers', 'on') %}
{% set ssl_stapling = salt['pillar.get']('nginx:ssl_stapling', 'off') %}
{% set ssl_stapling_verify = salt['pillar.get']('nginx:ssl_stapling_verify', 'off') %}
{% set ssl_session_tickets = salt['pillar.get']('nginx:ssl_session_tickets', 'off') %}

nginx-repo:
pkgrepo.managed:
- name: deb http://nginx.org/packages/mainline/ubuntu {{ grains['oscodename'] }} nginx
Expand Down Expand Up @@ -33,6 +46,15 @@ validate-nginx-config:
- user: root
- group: root
- mode: 644
- defaults:
ssl_protocols: {{ ssl_protocols }}
ssl_ciphers: {{ ssl_ciphers }}
ssl_session_cache: {{ ssl_session_cache }}
# Quotes are needed, as YAML will interpret on/off as boolean
ssl_prefer_server_ciphers: '{{ ssl_prefer_server_ciphers }}'
ssl_stapling: '{{ ssl_stapling }}'
ssl_stapling_verify: '{{ ssl_stapling_verify }}'
ssl_session_tickets: '{{ ssl_session_tickets }}'
- require:
- pkg: nginx

Expand Down
13 changes: 4 additions & 9 deletions letsencrypt/default_server.nginx.jinja
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
# To prevent host header injection, this file sets the default_server directive and returns
# HTTP 400 for requests with an unknown hostname in Host header
server {
listen *:80 default_server;
listen [::]:80 default_server;

return 400 "Unknown Host $host\n";
}

server {
listen *:443 default_server;
listen [::]:443 default_server;
listen *:80 default_server;
listen [::]:80 default_server;
listen *:443 default_server ssl;
listen [::]:443 default_server ssl;

# SSL certificate
ssl_dhparam {{ acme_certificate_dir }}/dhparam.pem;
Expand Down
22 changes: 11 additions & 11 deletions letsencrypt/init.sls
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ nginx-generate-dhparam:
generate-dummy-cert:
cmd.run:
- names:
- openssl req -x509 -nodes -batch -newkey rsa:2048 -keyout {{ acme_certificate_dir }}/{{ domain }}/dummy.key -out {{ acme_certificate_dir }}/{{ domain }}/dummy.crt -days 1
- openssl req -x509 -nodes -batch -newkey rsa:2048 -keyout {{ acme_certificate_dir }}/{{ domain }}/dummy.key -out {{ acme_certificate_dir }}/{{ domain }}/dummy.crt -days 1 # noqa: 204
- ln -s {{ acme_certificate_dir }}/{{ domain }}/dummy.key {{ acme_certificate_dir }}/{{ domain }}/privkey.pem
- ln -s {{ acme_certificate_dir }}/{{ domain }}/dummy.crt {{ acme_certificate_dir }}/{{ domain }}/fullchain.pem
- creates: {{ acme_certificate_dir }}/{{ domain }}/fullchain.pem
Expand All @@ -49,8 +49,8 @@ generate-dummy-cert:
- source: salt://{{ tpldir }}/letsencrypt.nginx.jinja
- template: jinja
- defaults:
fqdn: {{ domain }} {{ altnames }}
acme_challenge_dir: {{ acme_challenge_dir }}
fqdn: {{ domain }} {{ altnames }}
acme_challenge_dir: {{ acme_challenge_dir }}
- require:
- file: /etc/nginx/conf.d

Expand All @@ -63,8 +63,8 @@ generate-dummy-cert:
- source: salt://{{ tpldir }}/default_server.nginx.jinja
- template: jinja
- defaults:
fqdn: {{ domain }}
acme_certificate_dir: {{ acme_certificate_dir }}
fqdn: {{ domain }}
acme_certificate_dir: {{ acme_certificate_dir }}
- require:
- file: /etc/nginx/conf.d

Expand All @@ -79,11 +79,11 @@ dehydrated:
- source: salt://{{ tpldir }}/dehydrated.conf.jinja
- template: jinja
- defaults:
acme_certificate_dir: {{ acme_certificate_dir }}
acme_challenge_dir: {{ acme_challenge_dir }}
contact_email: {{ contact_email }}
hook: /etc/dehydrated/hook.sh
ca: {{ ca }}
acme_certificate_dir: {{ acme_certificate_dir }}
acme_challenge_dir: {{ acme_challenge_dir }}
contact_email: {{ contact_email }}
hook: /etc/dehydrated/hook.sh
ca: {{ ca }}
cmd.run:
- name: /usr/bin/dehydrated --register --accept-terms
- onchanges:
Expand All @@ -109,7 +109,7 @@ dehydrated:
- source: salt://{{ tpldir }}/hook.sh.jinja
- template: jinja
- defaults:
services: {{ salt['pillar.get']('letsencrypt:services', ['nginx']) }}
services: {{ salt['pillar.get']('letsencrypt:services', ['nginx']) }}
- require:
- pkg: dehydrated

Expand Down
9 changes: 9 additions & 0 deletions nginx.conf.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,14 @@ http {

server_tokens off;

# Global TLS settings
ssl_protocols {{ ssl_protocols }};
ssl_ciphers {{ ssl_ciphers }};
ssl_session_cache {{ ssl_session_cache }};
ssl_prefer_server_ciphers {{ ssl_prefer_server_ciphers }};
ssl_stapling {{ ssl_stapling }};
ssl_stapling_verify {{ ssl_stapling_verify }};
ssl_session_tickets {{ ssl_session_tickets }};

include /etc/nginx/conf.d/*.conf;
}
15 changes: 15 additions & 0 deletions pillar.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# vim: ft=sls

nginx:

# Default SSL values which will be written to the http context.
# This values can be overwritten in each server context individually.
ssl_protocols: 'TLSv1.2 TLSv1.3'
ssl_ciphers: 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256' # noqa: 204

ssl_session_cache: 'shared:SSL:10m'
ssl_prefer_server_ciphers: 'on'

ssl_stapling: 'off'
ssl_stapling_verify: 'off'
ssl_session_tickets: 'off'


letsencrypt:
domain: example.com
altnames: www.example.com alt.example.com
Expand Down
1 change: 1 addition & 0 deletions tests/integration/nginx/nginx_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
describe file('/etc/nginx/nginx.conf') do
its('mode') { should cmp '0644' }
its('content') { should match /^\s*worker_processes/ }
its('content') { should match /^\s*ssl_prefer_server_ciphers\s*on;$/ }
end

describe file('/etc/nginx/conf.d/default.conf') do
Expand Down

0 comments on commit 5a60749

Please sign in to comment.