mirror of
https://github.com/DO1JLR/ansible_role_nginx.git
synced 2024-08-16 16:19:48 +02:00
try to merge with r3l
This commit is contained in:
parent
0144eb1c02
commit
ccb3688a8a
21 changed files with 275 additions and 56 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*~
|
|
@ -1,40 +1,30 @@
|
|||
---
|
||||
# enable version check for this role? (true is recomended)
|
||||
submodules_versioncheck: false
|
||||
nginx__packages:
|
||||
- 'nginx'
|
||||
|
||||
|
||||
# Length of DH parameters
|
||||
nginx__dhparam_size: 2048
|
||||
|
||||
|
||||
# Configuration of virtual hosts
|
||||
nginx_sites: {}
|
||||
|
||||
#nginx_sites:
|
||||
# - name: 'example.org' # required
|
||||
# altnames: # Optional alternative names
|
||||
# - name: 'example.org'
|
||||
# altnames: Optional, for acmetool
|
||||
# - 'www.example.org'
|
||||
# - 'ftp.example.org'
|
||||
# logging: false # Optional enable nginx logging
|
||||
# robots: 'robots_allow_all.txt' # Optional, unimplemented
|
||||
# htaccess: 'htpasswd.example.org' # Optional, unimplemented
|
||||
# webroot: # Optional, for use with 'webhost' role
|
||||
# path # Optional, for use with 'webhost' role
|
||||
# user # Optional, for use with 'webhost' role
|
||||
# group # Optional, for use with 'webhost' role
|
||||
# mode # Optional, for use with 'webhost' role
|
||||
|
||||
nginx__snippet_path: 'files/nginx/snippets/'
|
||||
nginx__snippet_files:
|
||||
- 'acmetool.snippet.conf'
|
||||
- 'tls_parameters.snippet.conf'
|
||||
# robots: 'robots_allow_all.txt' Optional, unimplemented
|
||||
# htaccess: 'htpasswd.example.org' Optional, unimplemented
|
||||
# webroot: Optional, for use with 'webhost' role
|
||||
# path Optional, for use with 'webhost' role
|
||||
# user Optional, for use with 'webhost' role
|
||||
# group Optional, for use with 'webhost' role
|
||||
# mode Optional, for use with 'webhost' role
|
||||
|
||||
|
||||
# default_robots_file: 'robots_disallow_all.txt'
|
||||
|
||||
# nginx logging default for all sites
|
||||
nginx__default_enable_logging: false
|
||||
|
||||
nginx__dhparam_size: 4096
|
||||
|
||||
nxinx__state: 'present'
|
||||
|
||||
# disable it if you do not want a autogenerated infrastructure domain config
|
||||
nginx__infrastructure_domain__enabled: true
|
||||
|
||||
# disable this variable if you don't want to use our acmetool role to manage tls certificates
|
||||
nginx__acmetool_enabled: true
|
||||
# Optionally disable acme support within this role
|
||||
nginx__disable_acmetool: false
|
||||
|
|
13
files/nginx/sites-available/default_http.conf.j2
Normal file
13
files/nginx/sites-available/default_http.conf.j2
Normal file
|
@ -0,0 +1,13 @@
|
|||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
access_log /var/log/nginx/log_{{ inventory_hostname }}.access.log;
|
||||
error_log /var/log/nginx/log_{{ inventory_hostname }}.error.log;
|
||||
|
||||
include snippets/acmetool_global.snippet.conf;
|
||||
|
||||
location ^~ / {
|
||||
return 403;
|
||||
}
|
||||
}
|
16
files/nginx/sites-available/default_tls.conf.j2
Normal file
16
files/nginx/sites-available/default_tls.conf.j2
Normal file
|
@ -0,0 +1,16 @@
|
|||
server {
|
||||
listen 443 ssl http2 default_server;
|
||||
listen [::]:443 ssl http2 default_server;
|
||||
|
||||
include snippets/tls-parameters_global.snippet.conf;
|
||||
|
||||
ssl_certificate /var/lib/acme/live/{{ inventory_hostname }}/fullchain;
|
||||
ssl_certificate_key /var/lib/acme/live/{{ inventory_hostname }}/privkey;
|
||||
|
||||
access_log /var/log/nginx/log_{{ inventory_hostname }}.access.log;
|
||||
error_log /var/log/nginx/log_{{ inventory_hostname }}.error.log;
|
||||
|
||||
location ^~ / {
|
||||
return 403;
|
||||
}
|
||||
}
|
14
files/nginx/sites-available/vhost_http_redirect.conf.j2
Normal file
14
files/nginx/sites-available/vhost_http_redirect.conf.j2
Normal file
|
@ -0,0 +1,14 @@
|
|||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name {{ site.name }};
|
||||
|
||||
include snippets/{{ site.name }}_logging_site.snippet.conf;
|
||||
|
||||
include snippets/acmetool_global.snippet.conf;
|
||||
|
||||
location ^~ / {
|
||||
return 308 https://{{ site.name }}$request_uri;
|
||||
}
|
||||
}
|
14
files/nginx/sites-available/vhost_tls.conf.j2
Normal file
14
files/nginx/sites-available/vhost_tls.conf.j2
Normal file
|
@ -0,0 +1,14 @@
|
|||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name {{ site.name }};
|
||||
|
||||
include snippets/tls-parameters_global.snippet.conf;
|
||||
include snippets/{{ site.name }}_certificate_site.snippet.conf;
|
||||
include snippets/{{ site.name }}_logging_site.snippet.conf;
|
||||
|
||||
location ^~ / {
|
||||
return 403;
|
||||
}
|
||||
}
|
4
files/nginx/snippets/_logging_site.snippet.conf
Normal file
4
files/nginx/snippets/_logging_site.snippet.conf
Normal file
|
@ -0,0 +1,4 @@
|
|||
error_log /var/log/nginx/log_{{ site.name }}.error.log;
|
||||
|
||||
#access_log /var/log/nginx/log_{{ site.name }}.access.log;
|
||||
access_log off;
|
|
@ -0,0 +1,2 @@
|
|||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
||||
add_header Content-Security-Policy "default-src 'self'; object-src 'none'";
|
2
files/nginx/snippets/header-hsts_global.snippet.conf
Normal file
2
files/nginx/snippets/header-hsts_global.snippet.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
123
readme.md
Normal file
123
readme.md
Normal file
|
@ -0,0 +1,123 @@
|
|||
Nginx Webserver
|
||||
===============
|
||||
|
||||
Ansible role to configure the `nginx` webserver and manage TLS certificates
|
||||
by the help of the `acmetool` LE client. This role is designed to work together
|
||||
with the `acmetool` role.
|
||||
|
||||
|
||||
Variables
|
||||
---------
|
||||
|
||||
* `nginx__dhparam_size` (Default 2048):
|
||||
The DH parameters bit length.
|
||||
|
||||
* `nginx_sites` (Default `{}`):
|
||||
The virtual hosts configurations for this webserver.
|
||||
|
||||
* `nginx__disable_acmetool` (Default `False`):
|
||||
Optionally disable acme support within this role.
|
||||
|
||||
|
||||
Note: If you do not intent to use `acmetool` or LE at all, it is possible to disable
|
||||
support for it. However, in that case *all* TLS certificates and private keys
|
||||
loaded by the nginx configuration must be present on the destination host *before*
|
||||
running this role. Additionally you need to provide own replacement templates
|
||||
for `files/nginx/sites-available/*j2` (see point 3 in the next section).
|
||||
|
||||
|
||||
Files
|
||||
-----
|
||||
|
||||
Note: Path segments `<host_files>` when resolved by the `hf`/`hfg` lookup plugins always
|
||||
include full `hf`/`hfg` functionality, for example also search the `group_files`
|
||||
directory as apropriate. (See also note on dependencies below.)
|
||||
|
||||
|
||||
* Main `nginx` configuration file template `nginx/nginx.conf`
|
||||
Lookup path:
|
||||
- `<playbook_dir> / files / <host_files> / <inventory_hostname> / nginx / nginx.conf` [via `hf` lookup]
|
||||
- `<playbook_dir> / files / nginx / nginx.conf` [via `hf` lookup]
|
||||
- `<role_dir> / files / nginx / nginx.conf` [default role fallback]
|
||||
|
||||
|
||||
* Global (default and vhost independent) configuration snippets
|
||||
Lookup path:
|
||||
- `<playbook_dir> / files / <host_files> / <inventory_hostname> / nginx / snippets / <snippetname>_global.snippet.conf` [via `hfg` lookup]
|
||||
- `<playbook_dir> / files / nginx / snippets / <snippetname>_global.snippet.conf` [via `hfg` lookup]
|
||||
- `<role_dir> / files / nginx / snippets / <snippetname>_global.snippet.conf` [default role fallback]
|
||||
Note: The `<snippetname>` may not contain a `_`.
|
||||
|
||||
|
||||
* Main configuration file for each virtual host (usually contains corresponding nginx `server` block)
|
||||
Lookup path (tls):
|
||||
- `<playbook_dir> / files / nginx / sites / <vhostname>_tls.conf`
|
||||
- `<role_dir> / files / nginx / sites-available / vhost_tls.conf.j2` [default role fallback]
|
||||
Lookup path (http):
|
||||
- `<playbook_dir> / files / nginx / sites / <vhostname>_http.conf` [via `first_found` lookup]
|
||||
- `<role_dir> / files / nginx / sites-available / vhost_http_redirect.conf.j2` [default role fallback]
|
||||
|
||||
|
||||
* Per virtual host templated snippets
|
||||
Lookup path:
|
||||
- `<playbook_dir> / files / <host_files> / <inventory_hostname> / nginx / snippets / _<snippetname>_site.snippet.conf` [via `hfg` lookup]
|
||||
- `<playbook_dir> / files / nginx / snippets / _<snippetname>_site.snippet.conf` [via `hfg` lookup]
|
||||
- `<role_dir> / files / nginx / snippets / _<snippetname>_site.snippet.conf` [default role fallback]
|
||||
Note 1: The file name is expanded on the server per each virtual host to `<vhostname>_<snippetname>_site.snippet.conf`.
|
||||
Note 2: The `<snippetname>` may not contain a `_`.
|
||||
|
||||
|
||||
* Per virtual host custom individual snippet files
|
||||
Lookup path:
|
||||
- `<playbook_dir> / files / <host_files> / <inventory_hostname> / nginx / snippets / <vhostname>_<snippetname>_site.snippet.conf` [via `hfg` lookup]
|
||||
- `<playbook_dir> / files / nginx / snippets / <vhostname>_<snippetname>_site.snippet.conf` [via `hfg` lookup]
|
||||
- `<role_dir> / files / nginx / snippets / <vhostname>_<snippetname>_site.snippet.conf` [default role fallback]
|
||||
Note 1: In general, content of such snippets could be merged with main vhost configuration file.
|
||||
Note 2: The `<snippetname>` may not contain a `_`.
|
||||
|
||||
|
||||
* Per virtual host basic auth file
|
||||
Lookup path:
|
||||
- unimplemented
|
||||
|
||||
* Per virtual host robots file
|
||||
Lookup path:
|
||||
- unimplemented
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
Configuration of the virtual hosts in the `host_vars` of the webserver:
|
||||
|
||||
```
|
||||
nginx_sites:
|
||||
- name: 'example.org'
|
||||
altnames: Optional, for acmetool
|
||||
- 'www.example.org'
|
||||
- 'ftp.example.org'
|
||||
robots: 'robots_allow_all.txt' Optional, unimplemented
|
||||
htaccess: 'htpasswd.example.org' Optional, unimplemented
|
||||
webroot: Optional, for use with 'webhost' role
|
||||
path Optional, for use with 'webhost' role
|
||||
user Optional, for use with 'webhost' role
|
||||
group Optional, for use with 'webhost' role
|
||||
mode Optional, for use with 'webhost' role
|
||||
```
|
||||
|
||||
Alternatively, put this data into a suitable `group_vars` file.
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
This role depends on the `host_file` (`hf`) and `host_files_glob` (`hfg`) lookup plugins.
|
||||
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
* [Nginx documentation](https://nginx.org/en/docs/)
|
||||
|
||||
* [acmetool](https://github.com/hlandau/acmetool)
|
||||
* [acmetool user's guide](https://hlandau.github.io/acmetool/userguide)
|
|
@ -2,22 +2,31 @@
|
|||
- name: Create default site plain http configuration
|
||||
become: true
|
||||
ansible.builtin.template:
|
||||
src: 'templates/nginx/sites-available/default_http.j2'
|
||||
src: '{{ item }}'
|
||||
dest: '/etc/nginx/sites-available/{{ inventory_hostname }}_http'
|
||||
owner: root
|
||||
group: root
|
||||
mode: 'u=rw,g=r,o=r'
|
||||
with_first_found:
|
||||
- files:
|
||||
- 'files/nginx/sites/default_http.conf'
|
||||
- 'files/nginx/sites-available/default_http.conf.j2'
|
||||
notify:
|
||||
- systemctl reload nginx
|
||||
|
||||
- name: Create default site tls https configuration
|
||||
become: true
|
||||
ansible.builtin.template:
|
||||
src: 'templates/nginx/sites-available/default_tls.j2'
|
||||
template:
|
||||
src: '{{ item }}'
|
||||
dest: '/etc/nginx/sites-available/{{ inventory_hostname }}_tls'
|
||||
owner: root
|
||||
group: root
|
||||
mode: 'u=rw,g=r,o=r'
|
||||
with_first_found:
|
||||
- files:
|
||||
- 'files/nginx/sites/default_tls.conf'
|
||||
- 'files/nginx/sites-available/default_tls.conf.j2'
|
||||
notify:
|
||||
- systemctl reload nginx
|
||||
|
||||
|
@ -39,4 +48,8 @@
|
|||
state: link
|
||||
notify:
|
||||
- systemctl reload nginx
|
||||
when: not nginx__acmetool_enabled
|
||||
when: nginx__disable_acmetool
|
||||
tags:
|
||||
- configuration
|
||||
- nginx
|
||||
- sites
|
||||
|
|
|
@ -11,5 +11,7 @@
|
|||
become: true
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- 'nginx'
|
||||
state: "{{ nxinx__state }}"
|
||||
package: '{{ nginx__packages }}'
|
||||
state: present
|
||||
tags:
|
||||
- installation
|
||||
|
|
|
@ -31,4 +31,7 @@
|
|||
|
||||
- name: Configure acmetool and obtain certificates
|
||||
ansible.builtin.include_tasks: acme.yml
|
||||
when: nginx__acmetool_enabled
|
||||
when: not nginx__disable_acmetool
|
||||
tags:
|
||||
- configuration
|
||||
- acme
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
- name: Copy main nginx configuration file
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: 'nginx/nginx.conf'
|
||||
copy:
|
||||
#src: 'files/nginx/nginx.conf'
|
||||
src: '{{ lookup("hf", "nginx/nginx.conf") }}'
|
||||
dest: '/etc/nginx/'
|
||||
owner: root
|
||||
group: root
|
||||
|
@ -64,14 +66,13 @@
|
|||
group: root
|
||||
mode: 'u=rwx,g=rx,o=rx'
|
||||
|
||||
- name: Copy nginx snippet files
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: '{{ nginx__snippet_path }}{{ item }}'
|
||||
dest: '/etc/nginx/snippets/{{ item }}'
|
||||
- name: Copy nginx global configuration snippet files
|
||||
copy:
|
||||
src: '{{ item }}'
|
||||
dest: '/etc/nginx/snippets/{{ item | basename }}'
|
||||
owner: root
|
||||
group: root
|
||||
mode: 'u=rw,g=r,o=r'
|
||||
with_items: '{{ nginx__snippet_files }}'
|
||||
with_items: "{{ lookup('hfg', 'nginx/snippets/[!_]*_global.snippet.conf', wantlist=True) }}"
|
||||
notify:
|
||||
- systemctl reload nginx
|
||||
|
|
|
@ -2,44 +2,56 @@
|
|||
- name: Create '{{ site.name }}' site plain http configuration
|
||||
become: true
|
||||
ansible.builtin.template:
|
||||
src: 'templates/nginx/sites-available/http_plain_redirect.conf.j2'
|
||||
src: '{{ item }}'
|
||||
dest: '/etc/nginx/sites-available/{{ site.name }}_http'
|
||||
owner: root
|
||||
group: root
|
||||
mode: 'u=rw,g=r,o=r'
|
||||
with_first_found:
|
||||
- files:
|
||||
- 'files/nginx/sites/{{ site.name }}_http.conf'
|
||||
- 'files/nginx/sites-available/vhost_http_redirect.conf.j2'
|
||||
notify:
|
||||
- systemctl reload nginx
|
||||
|
||||
- name: Create '{{ site.name }}' site tls https configuration
|
||||
become: true
|
||||
ansible.builtin.template:
|
||||
src: 'files/nginx/sites/{{ site.name }}_tls.conf'
|
||||
template:
|
||||
src: '{{ item }}'
|
||||
dest: '/etc/nginx/sites-available/{{ site.name }}_tls'
|
||||
owner: root
|
||||
group: root
|
||||
mode: 'u=rw,g=r,o=r'
|
||||
with_first_found:
|
||||
- files:
|
||||
- 'files/nginx/sites/{{ site.name }}_tls.conf'
|
||||
- 'files/nginx/sites-available/vhost_tls.conf.j2'
|
||||
notify:
|
||||
- systemctl reload nginx
|
||||
|
||||
- name: Create '{{ site.name }}' site tls parameter configuration
|
||||
become: true
|
||||
ansible.builtin.template:
|
||||
src: 'files/nginx/snippets/tls_parameters.snippet.conf'
|
||||
dest: '/etc/nginx/snippets/tls_parameters_{{ site.name }}.snippet.conf'
|
||||
src: '{{ item }}'
|
||||
dest: '/etc/nginx/snippets/{{ site.name }}{{ item | basename }}'
|
||||
owner: root
|
||||
group: root
|
||||
mode: 'u=rw,g=r,o=r'
|
||||
with_items: "{{ lookup('hfg', 'nginx/snippets/_*_site.snippet.conf', wantlist=True) }}"
|
||||
notify:
|
||||
- systemctl reload nginx
|
||||
|
||||
- name: Create '{{ site.name }}' site tls certificate configuration
|
||||
become: true
|
||||
ansible.builtin.template:
|
||||
src: 'files/nginx/snippets/tls_certificate.snippet.conf'
|
||||
dest: '/etc/nginx/snippets/tls_certificate_{{ site.name }}.snippet.conf'
|
||||
template:
|
||||
src: '{{ item }}'
|
||||
dest: '/etc/nginx/snippets/{{ item | basename }}'
|
||||
owner: root
|
||||
group: root
|
||||
mode: 'u=rw,g=r,o=r'
|
||||
with_items: "{{ lookup('hfg', 'nginx/snippets/' + site.name + '_*_site.snippet.conf', wantlist=True) }}"
|
||||
notify:
|
||||
- systemctl reload nginx
|
||||
|
||||
|
@ -57,14 +69,19 @@
|
|||
- name: Enable '{{ site.name }}' site plain http configuration
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
file:
|
||||
src: '/etc/nginx/sites-available/{{ site.name }}_http'
|
||||
dest: '/etc/nginx/sites-enabled/{{ site.name }}_http'
|
||||
state: link
|
||||
when: site.http_plain_template | default(True)
|
||||
notify:
|
||||
- systemctl reload nginx
|
||||
tags:
|
||||
- configuration
|
||||
- nginx
|
||||
- sites
|
||||
|
||||
# Note: done by acmetool after sucessfully obtaining a suitable certificate
|
||||
|
||||
# Note: Normally done by acmetool after sucessfully obtaining a suitable certificate
|
||||
- name: Enable '{{ site.name }}' site tls configuration
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
|
@ -73,4 +90,8 @@
|
|||
state: link
|
||||
notify:
|
||||
- systemctl reload nginx
|
||||
when: not nginx__acmetool_enabled
|
||||
when: nginx__disable_acmetool
|
||||
tags:
|
||||
- configuration
|
||||
- nginx
|
||||
- sites
|
||||
|
|
|
@ -5,7 +5,7 @@ server {
|
|||
access_log /var/log/nginx/log_{{ inventory_hostname }}.access.log;
|
||||
error_log /var/log/nginx/log_{{ inventory_hostname }}.error.log;
|
||||
|
||||
include snippets/acmetool.snippet.conf;
|
||||
include snippets/acmetool_global.snippet.conf;
|
||||
|
||||
location ^~ / {
|
||||
return 403;
|
||||
|
|
|
@ -2,7 +2,7 @@ server {
|
|||
listen 443 ssl http2 default_server;
|
||||
listen [::]:443 ssl http2 default_server;
|
||||
|
||||
include snippets/tls_parameters.snippet.conf;
|
||||
include snippets/tls-parameters_global.snippet.conf;
|
||||
|
||||
ssl_certificate /var/lib/acme/live/{{ inventory_hostname }}/fullchain;
|
||||
ssl_certificate_key /var/lib/acme/live/{{ inventory_hostname }}/privkey;
|
||||
|
|
|
@ -4,9 +4,9 @@ server {
|
|||
|
||||
server_name {{ site.name }};
|
||||
|
||||
include snippets/logging_{{ site.name }}.snippet.conf;
|
||||
include snippets/{{ site.name }}_logging_site.snippet.conf;
|
||||
|
||||
include snippets/acmetool.snippet.conf;
|
||||
include snippets/acmetool_global.snippet.conf;
|
||||
|
||||
location ^~ / {
|
||||
return 308 https://{{ site.name }}$request_uri;
|
||||
|
|
Loading…
Reference in a new issue