Refactoring + SSL support

pull/14/head
Emilien Mantel 2016-01-11 18:20:42 +01:00
parent f64e1f1106
commit 49f11751e6
13 changed files with 186 additions and 89 deletions

View File

@ -8,15 +8,19 @@ nginx_backports: false
# #
nginx_root: "/srv/www" nginx_root: "/srv/www"
nginx_log_dir: '/var/log/nginx' nginx_log_dir: '/var/log/nginx'
nginx_ssl_dir: '/etc/nginx/ssl'
nginx_pid: '/run/nginx.pid' nginx_pid: '/run/nginx.pid'
nginx_resolver: nginx_resolver_hosts: ['8.8.8.8', '8.8.4.4']
hosts: ['8.8.8.8', '8.8.4.4'] nginx_resolver_valid: '300s'
valid: '300' nginx_resolver_timeout: '5s'
timeout: '5'
nginx_error_log_level: 'warn' # http://nginx.org/en/docs/ngx_core_module.html#error_log nginx_error_log_level: 'warn' # http://nginx.org/en/docs/ngx_core_module.html#error_log
nginx_dh_length: 2048 nginx_dh_length: 2048
#
# Nginx directories
#
nginx_htpasswd_dir: '/etc/nginx/htpasswd'
nginx_ssl_dir: '/etc/nginx/ssl'
nginx_helper_dir: '/etc/nginx/helper'
# #
# Load upstream # Load upstream
@ -88,3 +92,8 @@ nginx_vhosts: []
# htpasswd # htpasswd
# #
nginx_htpasswd: [] nginx_htpasswd: []
#
# SSL pairs
#
nginx_ssl_pairs: []

21
tasks/config.yml 100644
View File

@ -0,0 +1,21 @@
---
- name: TEMPLATE | Deploy nginx.conf
template: >
src=etc/nginx/nginx.conf.j2
dest=/etc/nginx/nginx.conf
notify: reload nginx
- name: TEMPLATE | Deploy all helpers
template: >
src={{ item }}
dest={{ nginx_helper_dir }}/{{ item | basename | regex_replace('\.j2$','') }}
with_fileglob: '../templates/etc/nginx/helper/*.j2'
notify: reload nginx
- name: TEMPLATE | Deploy custom http configuration
template: >
src=etc/nginx/conf.d/custom.conf.j2
dest=/etc/nginx/conf.d/custom.conf
notify: reload nginx

13
tasks/install.yml 100644
View File

@ -0,0 +1,13 @@
---
- name: APT | Install nginx and dependencies
apt: >
pkg={{ nginx_apt_package }}
state=present
update_cache=yes
cache_valid_time=3600
default_release={{ ansible_distribution_release + '-backports' if nginx_backports else ansible_distribution_release }}
- name: APT | Install python-passlib
apt: pkg=python-passlib state=present

View File

@ -1,4 +0,0 @@
---
- name: FILE | Remove old directories
file: path=/etc/nginx/helpers state=absent

View File

@ -1,51 +1,13 @@
--- ---
- name: APT | Install nginx and dependencies - name: INCLUDE | Install
apt: > include: install.yml
pkg={{ nginx_apt_package }}
state=present
update_cache=yes
cache_valid_time=3600
default_release={{ ansible_distribution_release + '-backports' if nginx_backports else ansible_distribution_release }}
- name: APT | Install python-passlib - name: INCLUDE | Prepare
apt: pkg=python-passlib state=present include: prepare.yml
- name: SHELL | Get Nginx version - name: INCLUDE | Install
shell: nginx -v 2>&1 | sed -r 's#.*/##;' | cut -d ' ' -f 1 include: config.yml
register: nginx_version
changed_when: false
- name: TEMPLATE | Deploy nginx.conf
template: >
src=etc/nginx/nginx.conf.j2
dest=/etc/nginx/nginx.conf
notify: reload nginx
- name: INCLUDE | Fix legacy
include: legacy.yml
- name: FILE | Create folders
file: dest={{ item }} owner=root mode=0755 state=directory
with_items: "{{ nginx_dirs }}"
#- name: COMMAND | Creates DH file
# command: openssl dhparam -out {{ nginx_dh_path }} {{ nginx_dh_length }}
# args:
# creates: "{{ nginx_dh_path }}"
- name: TEMPLATE | Deploy all helpers
template: >
src={{ item }}
dest={{ nginx_helper_dir }}/{{ item | basename | regex_replace('\.j2$','') }}
with_fileglob: '../templates/etc/nginx/helper/*.j2'
notify: reload nginx
- name: TEMPLATE | Deploy custom http configuration
template: >
src=etc/nginx/conf.d/custom.conf.j2
dest=/etc/nginx/conf.d/custom.conf
notify: reload nginx
- name: INCLUDE | Upstream configuration - name: INCLUDE | Upstream configuration
include: upstream.yml include: upstream.yml
@ -54,6 +16,9 @@
- name: INCLUDE | htpasswd configuration - name: INCLUDE | htpasswd configuration
include: htpasswd.yml include: htpasswd.yml
- name: INCLUDE | Vhosts configuration
include: ssl.yml
- name: INCLUDE | Vhosts configuration - name: INCLUDE | Vhosts configuration
include: vhost.yml include: vhost.yml

11
tasks/prepare.yml 100644
View File

@ -0,0 +1,11 @@
---
- name: SHELL | Get Nginx version
shell: nginx -v 2>&1 | sed -r 's#.*/##;' | cut -d ' ' -f 1
register: nginx_version
changed_when: false
- name: FILE | Create folders
file: dest={{ item }} owner=root mode=0755 state=directory
with_items: "{{ nginx_dirs }}"

33
tasks/ssl.yml 100644
View File

@ -0,0 +1,33 @@
---
- name: COMMAND | Creates DH file
command: openssl dhparam -out {{ nginx_dh_path }} {{ nginx_dh_length }}
args:
creates: "{{ nginx_dh_path }}"
- name: FILE | Create SSL directories
file: >
path="{{ nginx_ssl_dir + '/' + item.name }}"
state=directory
with_items: nginx_ssl_pairs
- name: COPY | Deploy SSL keys
copy: >
content="{{ item.key }}"
dest="{{ nginx_ssl_dir + '/' + item.name + '/' + item.name + '.key' }}"
with_items: nginx_ssl_pairs
notify: reload nginx
- name: COPY | Deploy SSL certs
copy: >
content="{{ item.cert }}"
dest="{{ nginx_ssl_dir + '/' + item.name + '/' + item.name + '.crt' }}"
with_items: nginx_ssl_pairs
notify: reload nginx
#- name: FAIL | Missmatch vhost SSL configuration
# fail: msg="FUCK {{ item.name }}"
#
#
#
# nginx_ssl_dir + '/' + ssl_name + '/' + ssl_name + '.key'

View File

@ -69,19 +69,3 @@
notify: reload nginx notify: reload nginx
when: (item.enable is defined and not item.enable) or (item.delete is defined and item.delete) when: (item.enable is defined and not item.enable) or (item.delete is defined and item.delete)
#- name: FILE | Create ssl dir per vhost (if needed)
# file: dest=/etc/nginx/ssl/{{ item.name }} owner=root mode=0750 state=directory
# with_items: nginx_vhosts
# when: item.ssl.use is defined and item.ssl.use
# TODO...
#- name: COPY | Deploy SSL keys if needed
# copy: src=keys/{{ item.name }}/{{ item.name }}.crt dest=/etc/nginx/ssl/{{ item.name }} mode=660
# copy: src=keys/{{ item.name }}/{{ item.name }}.key dest=/etc/nginx/ssl/{{ item.name }} mode=660
# with_items: nginx_vhosts
# when: item.ssl.use and not generatekey
# TODO:
# - deploy defaults files (index.html/index.php) allready in files/
# - work with role "ssl_autosign"

View File

@ -11,8 +11,8 @@ add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff; add_header X-Content-Type-Options nosniff;
ssl_stapling on; ssl_stapling on;
ssl_stapling_verify on; ssl_stapling_verify on;
resolver {{ nginx_resolver.hosts | default(['208.67.222.222', '208.67.220.220']) | join(' ') }} valid={{ nginx_resolver.valid}}s; resolver {{ nginx_resolver_hosts | join(' ') }} valid={{ nginx_resolver_valid }};
resolver_timeout {{ nginx_resolver.timeout }}s; resolver_timeout {{ nginx_resolver_timeout }};
# vim:filetype=nginx # vim:filetype=nginx

View File

@ -11,8 +11,7 @@ add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff; add_header X-Content-Type-Options nosniff;
ssl_stapling on; ssl_stapling on;
ssl_stapling_verify on; ssl_stapling_verify on;
resolver {{ nginx_resolver.hosts | default(['208.67.222.222', '208.67.220.220']) | join(' ') }} valid={{ nginx_resolver.valid}}s; resolver {{ nginx_resolver_hosts | join(' ') }} valid={{ nginx_resolver_valid }};
resolver_timeout {{ nginx_resolver.timeout }}s; resolver_timeout {{ nginx_resolver_timeout }};
# vim:filetype=nginx # vim:filetype=nginx

View File

@ -1,11 +1,19 @@
{% set __proto = item.proto | default(['http']) %}
{% set __main_name = item.name if item.name is string else item.name[0] %}
{% set __listen = item.listen | default(['80']) %} {% set __listen = item.listen | default(['80']) %}
{% set __listen_ssl = item.listen_ssl | default(['443']) %} {% set __listen_ssl = item.listen_ssl | default(['443']) %}
{% set __location = item.location | default({}) %} {% set __location = item.location | default({}) %}
{% macro htpasswd(htpasswd_name, indent=1) -%} {% macro htpasswd(htpasswd_name, indent=1) -%}
{% for ht in nginx_htpasswd %}{% if ht.name == htpasswd_name %} {% for ht in nginx_htpasswd if ht.name == htpasswd_name %}
{{ "\t" * indent }}auth_basic "{{ ht.description }}"; {{ "\t" * indent }}auth_basic "{{ ht.description }}";
{{ "\t" * indent }}auth_basic_user_file {{ nginx_htpasswd_dir }}/{{ ht.name }}; {{ "\t" * indent }}auth_basic_user_file {{ nginx_htpasswd_dir }}/{{ ht.name }};
{% endif %}{% endfor%} {% endfor%}
{%- endmacro %}
{% macro ssl(ssl_name) %}
{% for sn in nginx_ssl_pairs if sn.name == ssl_name %}
ssl_certificate {{ nginx_ssl_dir + '/' + ssl_name + '/' + ssl_name + '.crt' }};
ssl_certificate_key {{ nginx_ssl_dir + '/' + ssl_name + '/' + ssl_name + '.key' }};
{% endfor %}
{%- endmacro %} {%- endmacro %}
# #
# {{ ansible_managed }} # {{ ansible_managed }}
@ -15,9 +23,18 @@
# HTTP # HTTP
# #
server { server {
{% if 'http' in __proto %}
{% for port in __listen %} {% for port in __listen %}
listen {{ port }}; listen {{ port }};
{% endfor %} {% endfor %}
{% endif %}
{% if 'https' in __proto %}
{% for port in __listen_ssl %}
listen {{ port }} ssl;
{% endfor %}
{{ ssl(item.ssl_name) }}
include {{ nginx_helper_dir + '/ssl-' + item.ssl_template | default('strong') }};
{% endif %}
server_name {% if item.name is string %}{{ item.name }}{% else %}{{ item.name | join(' ') }}{% endif %}; server_name {% if item.name is string %}{{ item.name }}{% else %}{{ item.name | join(' ') }}{% endif %};
{% block root %} {% block root %}
{% if item.root is defined %} {% if item.root is defined %}
@ -97,15 +114,6 @@ server {
{% endif %} {% endif %}
} }
{#
# HTTPS
#server {
ssl on;
ssl_certificate {{ nginx_ssl_dir }}/{{ item.name }}/{{ item.name }}.crt;
ssl_certificate_key {{ nginx_ssl_dir }}/{{ item.name }}/{{ item.name }}.key;
include {{ nginx_helper_dir }}/ssl-{{ item.ssl.template | default('strong') }};
#}
{% if item.redirect_from is defined and item.redirect_from is iterable %} {% if item.redirect_from is defined and item.redirect_from is iterable %}
# #
# Redirect from # Redirect from

View File

@ -9,7 +9,9 @@
- curl - curl
- fcgiwrap - fcgiwrap
- service: name=fcgiwrap state=started - service: name=fcgiwrap state=started
register: sf
- pause: seconds=5 - pause: seconds=5
when: sf.changed
vars: vars:
nginx_backports: true nginx_backports: true
nginx_php: true nginx_php: true
@ -33,6 +35,56 @@
description: 'Please login!' description: 'Please login!'
users: [] users: []
state: 'absent' state: 'absent'
nginx_ssl_pairs:
- name: 'test-ssl.local'
key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvavrJWFp3Al2VwRgKx+4Y2mbRRvoxvyd2pyN0xMJ/tCJscaG
8s60v6WZ9FcCOeMkSI2DXsk4z7pbQdQn0h2GDr/5MOJkPAVWSWEN46tpaLZ3v0zp
88ZIbnEk1G0PsdFuW/pnLsakPlAMrl1VArFsV6YsatLt30UIYYcRO97StkoOehCx
A5w+XqtfHZeQZ0/DS81633gwYUcMuSTUFZ60r7ge1/m77DTSKg3rTVk5sebP8cjS
+aWHvxP/GyvvDsT+3gjRJx2/5O3JkfH0zaOsaU2Avj0PR0c5rhynrNO/l1k+GJJB
cbBrM+yA8Ofzp4oXUrCfaIq3RuL3Pd+khcKsiwIDAQABAoIBAQCPpAMQ7BUfbosQ
m1+5SOx7XR8Z12kSSX3CcY12rJSFRakB2TeZ6rE38lIFmV82N67iw0kaH4nGx3sU
/3aoyXMc+IXfX5RJYEFYkQfTw5ywkH9fgQAsfZ2dBlK+DVo1cEYDoj9CTW1VQ4pX
Ape+0l8agd5hiBxdWgpe0ctbbARnx584viLiA/iPBDNxKi9zEYw+WP7hSj5QWahr
a09tubcC4L6tjvv8CoZTRSKfCW64vWRDvE6vmA+zJN9Arc1WTYzF1KO1Gybwf8h7
stJb191smAgGDFhKo0j58ncyAnrS1k4mapm86QQhlfIA6DKvvC0qm3KdQns5b7HM
PyzW0hwBAoGBAO2mTVTOsziom9vtBwM0nRMMEgynR2X3EKMJz2mjcCf66f1F+aQ5
DvQFM2V8S2s1nGnPh8NKKZ8DxW1NKuR4qx82zeAXpUs9ibHxOnw4YRC485zqc2Wt
fSO1OEDYeKyzWP1nGGtCntYUXzJnWn/wz0mBGKzLKTuLwyFIKx1b7bybAoGBAMxR
N+lT57rX6d4GUqcgNOuWMZ/D8egnE5+hsoiFnHOisRLOgUgBBSy4rwAZx+rdHYT+
RO11L1PLYEzyvnO0f13R+N7aqKwNXDSzZGA+jb4pjkVidIC2smG/JYKJH5Z+kakw
mwMKP0wdRZJsCaMgScHmWJS8d6Ox/XJJoWrTWTbRAoGAWJlEgVaiaIArwz1F/QLz
gHNik0cWDkSi9jWlFxwwpycbbypUXM5M7dq2g6JoN6sACk6trbgLdlYgl5RKZm06
VuPGs0H9hOSHXkix5jfasDJT2G9r4D9ixRo9w6cwriobBjYWW3612tgzeYYgrkwn
655uhZUkZSfA8rqGIGbyZfsCgYAf5WH8G+wmIATTc1s92epJCOZwUY+XNVp75itP
4sPczX4lOHW4PuiG5cH0GxI5mRE9rNAn3c5on2xGNvMCbyAfDmNyruH8Eg3d8E9w
MvO/xw79x/P2EA9i8QszCKMUxGeK6RqZ6+SbxkoRJKqQe77n9UTI228179hoGhSH
77ySsQKBgQC8SSZn6a8PpSIIFXB9WCFMwfGFYbUz0wvpaeZP8GKx3BEzMeJqSUaJ
hrQgpwQXkueeamlCQcvV3AUCoBRWTYRLDrWiUIXuIgikDWBFp6TBvTnVRI7iktly
fNED7jXOSjJqnFmdkZlAI5V8dM++mVYVykJD6jcaVRQvxqFLrhSaRg==
-----END RSA PRIVATE KEY-----
cert: |
-----BEGIN CERTIFICATE-----
MIIDBTCCAe2gAwIBAgIJALKJfbk5vuieMA0GCSqGSIb3DQEBBQUAMBkxFzAVBgNV
BAMMDnRlc3Qtc3NsLmxvY2FsMB4XDTE2MDExMTE2NDI0NFoXDTI2MDEwODE2NDI0
NFowGTEXMBUGA1UEAwwOdGVzdC1zc2wubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQC9q+slYWncCXZXBGArH7hjaZtFG+jG/J3anI3TEwn+0Imx
xobyzrS/pZn0VwI54yRIjYNeyTjPultB1CfSHYYOv/kw4mQ8BVZJYQ3jq2lotne/
TOnzxkhucSTUbQ+x0W5b+mcuxqQ+UAyuXVUCsWxXpixq0u3fRQhhhxE73tK2Sg56
ELEDnD5eq18dl5BnT8NLzXrfeDBhRwy5JNQVnrSvuB7X+bvsNNIqDetNWTmx5s/x
yNL5pYe/E/8bK+8OxP7eCNEnHb/k7cmR8fTNo6xpTYC+PQ9HRzmuHKes07+XWT4Y
kkFxsGsz7IDw5/OnihdSsJ9oirdG4vc936SFwqyLAgMBAAGjUDBOMB0GA1UdDgQW
BBRaSF1L+ivPhmIVGQjtviBqZWDS9DAfBgNVHSMEGDAWgBRaSF1L+ivPhmIVGQjt
viBqZWDS9DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCjrgB9+Zuq
Rx7T2mRUl4jf75dLabuBQD0ePALTtvNyBSghhzSr90mE7GlFOYAv0JsmEa3R1LVF
wLPIdrIhNHpt7hN0PkhUlfgmxBnRSCfhpiq4xxsDVFM7ehtDz4+dv1LUDMXo07+E
f24g9aqmypiFzHisUQrYIhtQmHxRpKyGp6kDAW9qNxg6k/Um00aHdYfuD9ER4ksR
f8Hto7f+vssKxCRY2OZXqq13PxEwC5+hgAUkTdrycA/moXFuHJi3lCnCND7sSzvG
tXBggOusyFZFC4bs2m+V+Z+RN+tK2c/c0nq5HR8MV5HwIm4Z8GoT2/0BfJ00cgWL
lVz0gDBfdH8f
-----END CERTIFICATE-----
nginx_custom_http: nginx_custom_http:
- 'add_header X-ansible 1;' - 'add_header X-ansible 1;'
nginx_vhosts: nginx_vhosts:
@ -85,6 +137,10 @@
- name: 'backuppc.local' - name: 'backuppc.local'
template: '_backuppc' template: '_backuppc'
htpasswd: 'hello' htpasswd: 'hello'
- name: 'test-ssl.local'
proto: ['http', 'https']
template: '_base'
ssl_name: 'test-ssl.local'
roles: roles:
- ../../ - ../../
post_tasks: post_tasks:
@ -95,7 +151,7 @@
with_items: ['test-php.local', 'test-php-index.local'] with_items: ['test-php.local', 'test-php-index.local']
- name: -- Add HTML file -- - name: -- Add HTML file --
copy: dest="{{ item }}/index.html" content="Index HTML test OK\n" copy: dest="{{ item }}/index.html" content="Index HTML test OK\n"
with_items: ['{{ nginx_root }}/test.local/public', '/var/tmp', '{{ nginx_root }}/test-htpasswd-all.local/public'] with_items: ['{{ nginx_root }}/test.local/public', '/var/tmp', '{{ nginx_root }}/test-htpasswd-all.local/public', '{{ nginx_root }}/test-ssl.local/public']
- name: -- VERIFY VHOSTS -- - name: -- VERIFY VHOSTS --
command: "curl -H 'Host: {{ item.name if item.name is string else item.name[0] }}' http://127.0.0.1{% if item.listen is defined %}:{{ item.listen[0] }}{% endif %}/" command: "curl -H 'Host: {{ item.name if item.name is string else item.name[0] }}' http://127.0.0.1{% if item.listen is defined %}:{{ item.listen[0] }}{% endif %}/"
with_items: nginx_vhosts with_items: nginx_vhosts
@ -143,3 +199,8 @@
changed_when: false changed_when: false
register: authbpc register: authbpc
failed_when: authbpc.stdout.find('BackupPC Server Status') == -1 failed_when: authbpc.stdout.find('BackupPC Server Status') == -1
- name: -- VERIFY SSL --
command: "curl --insecure -H 'Host: test-ssl.local' https://127.0.0.1/"
changed_when: false
failed_when: authok.stdout.find('Index HTML test OK') != -1

View File

@ -29,7 +29,4 @@ nginx_dirs:
- "{{ nginx_ssl_dir }}" - "{{ nginx_ssl_dir }}"
- "{{ nginx_helper_dir }}" - "{{ nginx_helper_dir }}"
nginx_htpasswd_dir: '/etc/nginx/htpasswd'
nginx_ssl_dir: '/etc/nginx/ssl'
nginx_helper_dir: '/etc/nginx/helper'