From 0653dfd8d0a3e20c42dc9d022ba9112707e16458 Mon Sep 17 00:00:00 2001 From: Andrea Dell'Amico Date: Sun, 3 Jul 2016 12:19:12 +0200 Subject: [PATCH] library/roles/nginx: First steps to a unified virtualhost template management. --- nginx/defaults/main.yml | 56 +++++++++-- nginx/tasks/main.yml | 14 +++ nginx/tasks/nginx-letsencrypt.yml | 9 -- nginx/tasks/nginx-virtualhosts.yml | 12 +++ nginx/templates/nginx-virthost.j2 | 156 +++++++++++++++++++++++++++++ 5 files changed, 232 insertions(+), 15 deletions(-) create mode 100644 nginx/tasks/nginx-virtualhosts.yml create mode 100644 nginx/templates/nginx-virthost.j2 diff --git a/nginx/defaults/main.yml b/nginx/defaults/main.yml index b3bdb9c4..2121a727 100644 --- a/nginx/defaults/main.yml +++ b/nginx/defaults/main.yml @@ -1,9 +1,10 @@ --- -nginx_use_ldap_pam_auth: False -nginx_pam_svc_name: nginx -nginx_ldap_uri: "ldap://ldap.example.org" -nginx_ldap_base_dn: "dc=example,dc=org" nginx_enabled: True +nginx_use_ppa: False +nginx_ppa_repo: ppa:nginx/stable +nginx_package_state: installed + +#nginx_virthosts: [] nginx_enable_compression: True nginx_gzip_vary: "on" @@ -24,6 +25,49 @@ nginx_proxy_send_timeout: 120s nginx_client_max_body_size: 32000M nginx_client_body_timeout: 240s -nginx_letsencrypt_managed: True -nginx_letsencrypt_proxy_conf: letsencrypt-proxy.conf +# Find a set of acceptable defaults for the cache setup +nginx_cache_enabled: False +nginx_use_ldap_pam_auth: False +nginx_pam_svc_name: nginx +nginx_ldap_uri: "ldap://ldap.example.org" +nginx_ldap_base_dn: "dc=example,dc=org" + +nginx_letsencrypt_managed: True + +# Virtualhost example +# nginx_virthosts: +# - virthost_name: '{{ ansible_fqdn }}' +# listen: '{{ http_port }}' +# server_name: '{{ ansible_fqdn }}' +# server_aliases: '' +# index: index.html +# error_page: /path_to_error_page.html +# ssl_enabled: False +# ssl_only: False +# ssl_letsencrypt_certs: '{{ nginx_letsencrypt_managed }}' +# root: /usr/share/nginx/html/ +# server_tokens: 'off' +# proxy_standard_setup: True +# proxy_additional_options: +# - 'proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache:30m max_size=250m;' +# proxies: +# - location: / +# target: http://localhost:{{ local_http_port }}; +# +# extra_parameters: | +# location ~ \.php$ { +# fastcgi_split_path_info ^(.+\.php)(/.+)$; +# fastcgi_pass unix:/var/run/php5-fpm.sock; +# fastcgi_index index.php; +# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; +# include fastcgi_params; +# } + +# TODO: ckan, ssl with 80 -> 443 redirection, ssl only (no listening on 80). +# If nginx via ppa, proxy_protocol e http/2 too +# php, rewrite rules, acls, ldap auth +# More robust rules +# log format personalization (global, inside conf.d) +# +# Special cases: mediawiki,... diff --git a/nginx/tasks/main.yml b/nginx/tasks/main.yml index f8cfbaee..001b4d1b 100644 --- a/nginx/tasks/main.yml +++ b/nginx/tasks/main.yml @@ -1,5 +1,19 @@ --- - include: nginx.yml +#- include: nginx-virtualhosts.yml +# when: nginx_virthosts|length > 0 - include: nginx-letsencrypt.yml when: letsencrypt_acme_install is defined and letsencrypt_acme_install - include: pam-ldap.yml + +- name: Ensure that the webserver is running and enabled at boot time + service: name=nginx state=started enabled=yes + when: nginx_enabled + ignore_errors: True + tags: nginx + +- name: Ensure that the webserver is stopped and disabled + service: name=nginx state=stopped enabled=no + when: not nginx_enabled + ignore_errors: True + tags: nginx diff --git a/nginx/tasks/nginx-letsencrypt.yml b/nginx/tasks/nginx-letsencrypt.yml index c9b0b6da..2c57d94a 100644 --- a/nginx/tasks/nginx-letsencrypt.yml +++ b/nginx/tasks/nginx-letsencrypt.yml @@ -1,10 +1,5 @@ --- - block: - - name: Install the letsencrypt conf - template: src={{ item }}.j2 dest=/etc/nginx/conf.d/{{ item }} owner=root group=root mode=0644 - with_items: '{{ nginx_letsencrypt_proxy_conf }}' - notify: Reload nginx - - name: Create the acme hooks directory if it does not yet exist file: dest={{ letsencrypt_acme_services_scripts_dir }} state=directory owner=root group=root @@ -17,10 +12,6 @@ tags: [ 'nginx', 'letsencrypt' ] - block: - - name: Disable the letsencrypt conf - file: dest=/etc/nginx/conf.d/letsencrypt-proxy.conf state=absent - notify: nginx2 reload - - name: Remove the letsencrypt hook for nginx file: path={{ letsencrypt_acme_services_scripts_dir }}/nginx state=absent diff --git a/nginx/tasks/nginx-virtualhosts.yml b/nginx/tasks/nginx-virtualhosts.yml new file mode 100644 index 00000000..f5877b76 --- /dev/null +++ b/nginx/tasks/nginx-virtualhosts.yml @@ -0,0 +1,12 @@ +--- +- name: Install the nginx virtualhost files + template: src=nginx-virthost.j2 dest=/etc/nginx/sites-available/{{ item.virthost_name }} owner=root group=root mode=0444 + with_items: '{{ nginx_virthosts }}' + notify: Reload nginx + tags: [ 'nginx', 'virtualhost' ] + +- name: Enable the nginx virtualhosts + file: src=/etc/nginx/sites-available/{{ item.virthost_name }} dest=/etc/nginx/sites-enabled/{{ item.virthost_name }} state=link + with_items: '{{ nginx_virthosts }}' + notify: Reload nginx + tags: [ 'nginx', 'virtualhost' ] diff --git a/nginx/templates/nginx-virthost.j2 b/nginx/templates/nginx-virthost.j2 new file mode 100644 index 00000000..29aafc44 --- /dev/null +++ b/nginx/templates/nginx-virthost.j2 @@ -0,0 +1,156 @@ +server { + listen {{ item.http_port }}; + server_name {{ item.server_name }} {% if item.serveraliases is defined %}{{ item.serveraliases }}{% endif %}; + {% if item.access_log is defined %} + access_log {{ item.access_log }}; + {% else %} + access_log /var/log/nginx/{{ item.server_name }}_access.log; + {% endif %} + {% if item.error_log is defined %} + error_log {{ item.error_log }}; + {% else %} + error_log /var/log/nginx/{{ item.server_name }}_error.log; + {% endif %} + +{% if not item.ssl_enabled %} + # This is the default for nginx on Ubuntu 14.04 + {% if item.root is defined %} + root {{ item.root }}; + {% else %} + root /usr/share/nginx/html; + {% endif %} + {% if item.index is defined %} + index {{ item.index }}; + {% else %} + index index.html index.htm; + {% endif %} + {% if item.error_page is defined %} + error_page 500 502 503 504 {{ item.error_page }}; + {% else %} + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + {% endif %} + location = /favicon.ico { + log_not_found off; + access_log off; + } + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + {% if item.max_body is defined %} + client_max_body_size {{ item.max_body }}; + {% else %} + client_max_body_size {{ nginx_client_max_body_size }}; + {% endif %} + {% if item.body_timeout is defined %} + client_body_timeout {{ item.body_timeout }}; + {% else %} + client_body_timeout {{ nginx_client_body_timeout }}; + {% endif %} + {% if item.server_tokens is defined %} + server_tokens {{ item.server_tokens }}; + {% else %} + # don't send the nginx version number in error pages and Server header + server_tokens off; + {% endif %} + + {% if item.proxy_standard_setup is defined and item.proxy_standard_setup %} + # Proxy stuff + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_buffer_size {{ nginx_proxy_buffer_size }}; + proxy_buffers {{ nginx_proxy_buffers }}; + proxy_busy_buffers_size {{ nginx_proxy_busy_buffers_size }}; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_http_version 1.1; + proxy_redirect {{ nginx_proxy_redirect }}; + proxy_buffering {{ nginx_proxy_buffering }}; + proxy_connect_timeout {{ nginx_proxy_connect_timeout }}; + proxy_read_timeout {{ nginx_proxy_read_timeout }}; + proxy_send_timeout {{ nginx_proxy_send_timeout }}; + {% endif %} + {% if item.proxy_additional_options is defined %} + {% for popt in item.proxy_additional_options %} + {{ popt }} + {% endfor %} + location / { + proxy_pass http://localhost:{{ grafana_http_port }}/; + } +{% else %} + location / { + return 301 https://{{ ansible_fqdn }}$request_uri; + } +{% endif %} + +} + +{% if http_ssl_enabled %} +server { + listen {{ https_port }} ssl; + + server_name {{ ansible_fqdn }}; + client_max_body_size 100M; + access_log /var/log/nginx/access_ssl.log; + error_log /var/log/nginx/error_ssl.log; + # This is the default for nginx on Ubuntu 14.04 + root /usr/share/nginx/html/; + + ssl_certificate {{ letsencrypt_acme_certs_dir }}/fullchain; + ssl_certificate_key {{ letsencrypt_acme_certs_dir }}/privkey; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"; + ssl_prefer_server_ciphers on; + ssl_stapling on; + ssl_stapling_verify on; + add_header Strict-Transport-Security max-age=15768000; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/www; + } + + location = /favicon.ico { + log_not_found off; + access_log off; + } + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + # don't send the nginx version number in error pages and Server header + server_tokens off; + + # Proxy stuff + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_buffer_size {{ nginx_proxy_buffer_size }}; + proxy_buffers {{ nginx_proxy_buffers }}; + proxy_busy_buffers_size {{ nginx_proxy_busy_buffers_size }}; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_http_version 1.1; + proxy_redirect {{ nginx_proxy_redirect }}; + proxy_buffering {{ nginx_proxy_buffering }}; + proxy_connect_timeout {{ nginx_proxy_connect_timeout }}; + proxy_read_timeout {{ nginx_proxy_read_timeout }}; + proxy_send_timeout {{ nginx_proxy_send_timeout }}; + location / { + proxy_pass http://localhost:{{ grafana_http_port }}/; + } +} + +{% endif %}