79 Commits

Author SHA1 Message Date
Emilien Mantel
6891b29c94 🔥 Drop Debian 10 support 2025-06-02 17:45:15 +02:00
Emilien Mantel
b1997d56c6 🔧 Bypass namespace name in Galaxy 2025-06-02 17:42:47 +02:00
Emilien M
9983636f37 Merge pull request #45 from HanXHX/modernize
Modernize
2025-06-02 15:55:47 +02:00
Emilien Mantel
da4e9dfc4f 🎨 Fix imports in Ansible Galaxy 2025-06-02 13:08:49 +02:00
Emilien Mantel
bf37be22f7 🚀 Support Ubuntu 24.04 + Debian 13 2025-06-02 11:00:11 +02:00
Emilien Mantel
277cf7fe74 👷 Change ansible-lint in CI 2025-06-02 10:50:12 +02:00
Emilien Mantel
40d14922b9 📝 Update docs 2025-06-02 10:43:10 +02:00
Emilien Mantel
8ec630284a 🔥 Drop legacy test suite 2025-06-02 10:42:54 +02:00
Emilien Mantel
1aaf0351b4 🔥 Drop FreeBSD support 2025-06-02 10:35:34 +02:00
Emilien Mantel
9a52e83315 ⚗️ Modernize role
- Drop ngrok support
- Do not link legacy tests files
2025-06-02 10:30:32 +02:00
Emilien Mantel
591f2c6bcb 🔨 Modernize lint config 2025-05-28 17:56:58 +02:00
Emilien Mantel
a5325d7d54 🔥 Drop Ubuntu 18.04 support and hack CI 2023-05-31 12:10:40 +02:00
Emilien Mantel
c61fb86cc0 💚 Allow CI job Ubuntu 20.04 to fail 2023-05-31 12:10:40 +02:00
Emilien Mantel
c2e0fc241f ✏️ Fix doc typo 2023-05-31 12:10:40 +02:00
Emilien Mantel
1debe40739 💚 Fix Ubuntu 20.04 build
- Prevent segfault on nginx-extra package
2023-05-31 12:10:40 +02:00
Emilien Mantel
c9e1aa2848 Skip checks for Ubuntu 18.04
Curl does not manage proxy protocol...
2023-05-31 12:10:40 +02:00
Emilien Mantel
0fd16bdd1e 🚀 Manage Ubuntu 2023-05-31 12:10:40 +02:00
Emilien Mantel
424160f9d4 🐛 Fix load vars for Debian based OS 2023-05-31 12:10:40 +02:00
Emilien Mantel
6abee22d23 Add missing collection dependencies 2023-05-31 12:10:40 +02:00
Emilien Mantel
3b3f1cb3e0 🔥 Remove useless code 2023-05-31 12:10:40 +02:00
Emilien Mantel
955857ac4f 📝 Add github action badge 2023-05-31 12:10:40 +02:00
Emilien Mantel
170046480a 🔥 Remove TravisCI 2023-05-31 12:10:40 +02:00
Emilien Mantel
c8344201a8 Add Debian 12 and CI 2023-05-31 12:10:40 +02:00
Emilien Mantel
c552dd3642 🚀 Add core options 2023-05-31 12:10:40 +02:00
Emilien Mantel
d262ddd79e 🚨 Fix linter 2023-05-31 12:10:40 +02:00
Emilien Mantel
257437731a 🔒 Modernize TLS helpers 2023-05-31 12:10:40 +02:00
Emilien Mantel
3b69a4f700 🙈 Ignore pycharm files 2023-05-31 12:10:40 +02:00
Emilien Mantel
9f727adcb5 Fix linter 2022-11-25 10:11:19 +01:00
Emilien Mantel
55e075ac2b Drop Debian Stretch support 2021-09-10 17:05:53 +02:00
Emilien Mantel
26543001f3 Quickfix on invalid FQDN 2021-09-10 16:44:08 +02:00
Emilien Mantel
815e39162a Fix passlib install
- Do not break idempotence on Debian Stretch
- Python 2 must not be used now...
2021-09-10 16:43:32 +02:00
Emilien Mantel
7135bc68e7 Code refactoring on tests 2021-09-10 16:25:01 +02:00
Emilien Mantel
0622f8ab87 Some changes on acme.sh install process
- Remove useless git directory
- Force use letsencrypt as default CA
2021-09-10 16:02:24 +02:00
Emilien Mantel
8de557346e Some code refactoring on install process 2021-09-10 15:52:29 +02:00
Emilien Mantel
297dc1f669 Fix ansible lint 2021-09-03 12:19:32 +02:00
Emilien Mantel
5e2f988beb Merge branch 'master' into debian_11 2021-09-03 12:08:30 +02:00
Emilien Mantel
6aea2bcb5f Migrate to new TravisCI version 2021-09-01 12:05:07 +02:00
Emilien Mantel
8c6c4dc813 Fix Ansible Lint 2021-09-01 11:58:39 +02:00
Emilien Mantel
a2780d3d95 Fix Ansible Lint 2021-09-01 11:45:44 +02:00
Emilien Mantel
6c7e0c2a47 Fix yaml lint 2021-09-01 11:21:12 +02:00
Emilien Mantel
bdddb06fcc Add Debian Bullseye (11) support 2021-09-01 11:07:54 +02:00
Emilien Mantel
6e5fce00e7 Drop Backuppc support 2021-09-01 11:06:02 +02:00
Emilien Mantel
8268eb266a Fix no_log call crashes on Ansible 2.11 2021-09-01 11:02:45 +02:00
Emilien Mantel
8b73a835c6 Fix ngrok task to get hostname 2021-09-01 11:02:12 +02:00
Emilien Mantel
40ebe61c57 Add doc for custom site templates 2020-08-24 09:08:57 +02:00
Emilien Mantel
0f8688f290 Travis: don't install ansible buggy versions 2020-08-24 09:08:57 +02:00
Emilien Mantel
204e95725e Manage custom templates for sites
Issue #12 related
2020-08-24 09:08:57 +02:00
Emilien Mantel
da08953a27 Drop Backuppc support 2020-08-24 09:08:57 +02:00
Emilien Mantel
4c63efa588 Compat python3 2020-05-18 16:10:42 +02:00
Emilien Mantel
3e228d0812 Typofix 2020-02-04 13:08:48 +01:00
Emilien Mantel
1e7a0fc855 Change HSTS header per site or globally 2020-02-04 13:06:26 +01:00
Emilien Mantel
93b90c748f Fix redirect_ssl cannot be a default_site 2020-02-04 11:31:21 +01:00
Emilien Mantel
d8f6088362 Fix SSL with multiple names 2020-02-04 11:07:21 +01:00
Emilien Mantel
8c3b1c7f13 Compat with python3 2020-01-01 22:56:08 +01:00
Emilien Mantel
5cdd1a8b37 Skip tests on proxy protocol on Debian Stretch 2019-12-31 13:16:42 +01:00
Emilien Mantel
0363a37e06 Changeis for proxy_protocol and apply default values 2019-12-31 13:07:13 +01:00
Emilien Mantel
a1e76453cf DH length 4096 -> 2048 2019-12-31 12:46:02 +01:00
Emilien Mantel
729173c46c Better SSL management
- Use filter plugins
- Acme: can use proxy protocol
- Acme: uses all sites name
- Acme: add more tests while crashing
2019-12-31 12:43:43 +01:00
Emilien Mantel
2f8ce00067 Add tests on proxy protocol 2019-12-30 17:43:18 +01:00
Emilien Mantel
9b286f9b96 Fix some issues:
- "main_name" is name/name[0] not filename
- improve some tests
- better proxy protocol handling (not necessary to declare ports twice)
2019-12-30 17:28:34 +01:00
Emilien Mantel
4a2478a4fb [WIP] Working on FreeBSD tests
Replace ngrok by serveo.net?
2019-12-29 18:18:24 +01:00
Emilien Mantel
a9a72dd25f Drop PHP version support (useless) + fix some bugs 2019-12-29 16:29:18 +01:00
Emilien Mantel
2a612a55b9 Ajout symfony template 2019-12-26 17:55:07 +01:00
Emilien Mantel
1280a441ee Fix tests on Sury 2019-12-26 17:35:00 +01:00
Emilien Mantel
21edb6b584 Fix install role 2019-12-26 17:23:36 +01:00
Emilien Mantel
c524b97b0f Use upstream config from HanXHX.php role 2019-12-26 17:16:13 +01:00
Emilien Mantel
993310641a Fix "always" management in add_header directive 2019-08-20 10:35:51 +02:00
Emilien Mantel
f5885c5c55 Cache fonts 2019-08-07 21:11:00 +02:00
Emilien Mantel
bb5e00d6f5 Don't remove acme.sh keys if acme.sh fails 2019-05-03 14:16:23 +02:00
Emilien Mantel
cf010e4a4b Reload nginx with acme.sh
Sometimes fu****** systemd don't want you to restart nginx in a loop. I
t crashes the role.
2019-04-30 16:45:14 +02:00
Emilien M
39d3f5f06a Fix lints warnings (#40)
* Add new filter plugins related to SSL
* Ignore lint on few tasks
2019-04-26 13:29:06 +02:00
Emilien M
247f849b86 Remove obsolete code (php 5.6 support) (#41)
Closes #39
2019-04-26 13:28:04 +02:00
Emilien Mantel
a03a656b18 Prevent crash on Docker+Buster 2019-04-25 16:14:43 +02:00
Emilien Mantel
1239219d90 Add buster to travis 2019-04-25 14:37:15 +02:00
Emilien Mantel
4f94fc2211 acme.sh fixes
- fix acme.sh home directory
- Clean crash when acme.sh fails (EXPERIMENTAL)
2019-04-25 13:59:19 +02:00
Emilien M
e89a154bb5 Support Debian Buster (#37) 2019-04-23 09:28:00 +02:00
Emilien Mantel
c9bda9e95a Force Python2.7 on travis 2019-04-19 14:38:47 +02:00
Emilien Mantel
4efc975770 Remove obsolete doc 2019-04-10 10:01:32 +02:00
Emilien M
20d04015c1 Remove newlines+tab on server_name. Bypass acme.sh limitations (#38) 2019-03-20 19:37:55 +01:00
71 changed files with 1626 additions and 1389 deletions

14
.config/ansible-lint.yml Normal file
View File

@@ -0,0 +1,14 @@
---
profile: production
warn_list:
- role-name
- schema[meta]
skip_list: []
exclude_paths:
- .github/
- .venv/
- venv/

17
.github/workflows/ansible_galaxy.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
---
name: Deploy on Ansible Galaxy
'on':
- push
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
- name: galaxy
uses: robertdebock/galaxy-action@1.2.0
with:
galaxy_api_key: ${{ secrets.galaxy_api_key }}

39
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
---
name: ci
'on':
pull_request:
push:
branches:
- master
jobs:
yaml-lint:
name: YAML Lint
runs-on: ubuntu-latest
steps:
- name: Fetch code
uses: actions/checkout@v3
- name: Set up Python 3.
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install test dependencies.
run: pip3 install yamllint
- name: Lint code.
run: |
yamllint .
ansible-lint:
name: Ansible Lint
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Run ansible-lint
uses: ansible/ansible-lint@main

43
.github/workflows/molecule.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
---
name: Molecule
'on':
pull_request:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
scenario:
- debian-11
- debian-12
- ubuntu-20.04
- ubuntu-22.04
- ubuntu-24.04
allowed-to-fail:
- false
include:
- scenario: debian-13
allowed-to-fail: true
steps:
- name: Checkout
uses: actions/checkout@v3
with:
path: "${{ github.repository }}"
- name: Molecule
uses: gofrolist/molecule-action@v2.7.62
with:
molecule_options: --base-config molecule/_shared/base.yml
molecule_args: --scenario-name ${{ matrix.scenario }}
continue-on-error: ${{ matrix.allowed-to-fail }}
- name: Fake command
run: echo "End of job"

5
.gitignore vendored
View File

@@ -2,3 +2,8 @@
*.swp *.swp
*.retry *.retry
*.pyc *.pyc
/tests/hanxhx.php
/.idea
/.venv
/venv
/.ansible

View File

@@ -1,37 +0,0 @@
env:
- PLATFORM='docker-debian-stretch' ANSIBLE_VERSION='ansible>=2.6,<2.7'
- PLATFORM='docker-debian-stretch-sury' ANSIBLE_VERSION='ansible>=2.6,<2.7'
- PLATFORM='docker-debian-stretch' ANSIBLE_VERSION='ansible>=2.7,<2.8'
- PLATFORM='docker-debian-stretch-sury' ANSIBLE_VERSION='ansible>=2.7,<2.8'
matrix:
fast_finish: true
sudo: required
dist: trusty
language: python
services:
- docker
before_install:
- wget https://releases.hashicorp.com/vagrant/2.0.1/vagrant_2.0.1_x86_64.deb
- sudo dpkg -i vagrant_2.0.1_x86_64.deb
install:
- pip install "$ANSIBLE_VERSION"
script:
- VAGRANT_DEFAULT_PROVIDER=docker vagrant up $PLATFORM
- >
VAGRANT_DEFAULT_PROVIDER=docker vagrant provision $PLATFORM
| grep -q 'changed=0.*failed=0'
&& (echo 'Idempotence test: pass' && exit 0)
|| (echo 'Idempotence test: fail' && exit 1)
- VAGRANT_DEFAULT_PROVIDER=docker vagrant status
notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/

8
.yamllint.yml Normal file
View File

@@ -0,0 +1,8 @@
---
extends: default
rules:
line-length: disable
ignore-from-file: .gitignore

View File

@@ -1,9 +1,9 @@
Nginx for Debian/FreeBSD Ansible role Nginx for Debian/Ubuntu Ansible role
===================================== =====================================
[![Ansible Galaxy](http://img.shields.io/badge/ansible--galaxy-HanXHX.nginx-blue.svg)](https://galaxy.ansible.com/HanXHX/nginx/) [![Build Status](https://travis-ci.org/HanXHX/ansible-nginx.svg?branch=master)](https://travis-ci.org/HanXHX/ansible-nginx) [![Ansible Galaxy](http://img.shields.io/badge/ansible--galaxy-HanXHX.nginx-blue.svg)](https://galaxy.ansible.com/HanXHX/nginx/) ![GitHub Workflow Status (master branch)](https://img.shields.io/github/actions/workflow/status/hanxhx/ansible-nginx/molecule.yml?branch=master)
Install and configure Nginx on Debian/FreeBSD. Install and configure Nginx on Debian/Ubuntu.
Features: Features:
@@ -20,17 +20,23 @@ Features:
Supported OS: Supported OS:
| OS | Working | Stable (active support) | | OS | Working | Stable (active support) |
| ------------------ | ------- | ----------------------- | |----------------------|---------|--------------------------------------------------------------------------------------------------------|
| Debian Jessie (8) | Yes | Check latest supported version ([1.5.0](https://github.com/HanXHX/ansible-nginx/releases/tag/1.5.0)) | | Debian Jessie (8) | Yes | Check latest supported version ([1.5.0](https://github.com/HanXHX/ansible-nginx/releases/tag/1.5.0)) |
| Debian Stretch (9) | Yes | Yes | | Debian Stretch (9) | Yes | Check latest supported version ([1.9.0](https://github.com/HanXHX/ansible-nginx/releases/tag/1.9.0)) |
| FreeBSD 11 | Yes | No | | Debian Buster (10) | Yes | Check latest supported version ([1.10.0](https://github.com/HanXHX/ansible-nginx/releases/tag/1.10.0)) |
| FreeBSD 12 | Yes | No | | Debian Bullseye (11) | Yes | Yes |
| Debian Bookworm (12) | Yes | Yes |
| Debian Trixie (13) | WIP | Not yet |
| Ubuntu 20.04 | Yes | Yes |
| Ubuntu 22.04 | Yes | Yes |
| Ubuntu 24.04 | Yes | Yes |
Requirements Requirements
------------ ------------
Ansible 2.6+. If you set true to `nginx_backports`, you must install backports repository before lauching this role. - Ansible >=2.11
- If you set true to `nginx_backports`, you must install backports repository before lauching this role.
Role Variables Role Variables
-------------- --------------
@@ -42,10 +48,6 @@ Debian:
- `nginx_apt_package`: APT nginx package (try: apt-cache search ^nginx) - `nginx_apt_package`: APT nginx package (try: apt-cache search ^nginx)
- `nginx_backports`: Install nginx from backport repository (bool) - `nginx_backports`: Install nginx from backport repository (bool)
FreeBSD:
- `nginx_pkgng_package`: PKGNG nginx package (should be "nginx" or "nginx-devel")
### Shared ### Shared
- `nginx_root`: root directory where you want to have your files - `nginx_root`: root directory where you want to have your files
@@ -54,6 +56,7 @@ FreeBSD:
- `nginx_error_log_level`: default log level - `nginx_error_log_level`: default log level
- `nginx_auto_config_httpv2`: boolean, auto configure HTTP2 where possible - `nginx_auto_config_httpv2`: boolean, auto configure HTTP2 where possible
- `nginx_fastcgi_fix_realpath`: boolean, use realpath for fastcgi (fix problems with symlinks and PHP opcache) - `nginx_fastcgi_fix_realpath`: boolean, use realpath for fastcgi (fix problems with symlinks and PHP opcache)
- `nginx_default_hsts`: string, default header sent for HSTS
### Nginx Configuration ### Nginx Configuration
@@ -62,13 +65,13 @@ FreeBSD:
- `nginx_pid`: daemon pid file - `nginx_pid`: daemon pid file
- `nginx_events_*`: all variables in events block - `nginx_events_*`: all variables in events block
- `nginx_http_*`: all variables in http block - `nginx_http_*`: all variables in http block
- `nginx_custom_core`: instructions list (for core, will put data in `/etc/nginx/nginx.conf`)
- `nginx_custom_http`: instructions list (will put data in `/etc/nginx/conf.d/custom.conf`) - `nginx_custom_http`: instructions list (will put data in `/etc/nginx/conf.d/custom.conf`)
- `nginx_module_packages`: package list module to install (Debian) - `nginx_module_packages`: package list module to install (Debian)
- `nginx_load_modules`: module list to load (full path), should be used only on FreeBSD
### Misc ### Misc
- `nginx_debug_role`: set _true_ if you need to see output of no\_log tasks - `nginx_debug_role`: set _true_ if you need to see output of no\_log tasks
About modules About modules
------------- -------------
@@ -88,26 +91,29 @@ Fine configuration
[Basic Auth](doc/auth.md) [Basic Auth](doc/auth.md)
[FreeBSD](doc/freebsd.md)
[acme.sh](doc/acme.md) [acme.sh](doc/acme.md)
Note Note
---- ----
- Active support for Debian. - Active support for Debian/Ubuntu.
- FreeBSD support is experimental (no Travis). I only test (for the moment) 10.2 (but it can work on other versions).
- I don't manage BackupPC for FreeBSD (PR welcome).
Dependencies Dependencies
------------ ------------
None See: [requirements.yml](requirements.yml).
Example Playbook
----------------
See [tests/test.yml](tests/test.yml). If you need to dev this role locally with molecule
--------------------------------------------------
Check available scenarios in [molecule](molecule) directory.
With `debian-12` scenario:
```commandline
molecule -v -c molecule/_shared/base.yml verify -s debian-12
```
License License
------- -------

77
Vagrantfile vendored
View File

@@ -1,77 +0,0 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# vi: set tabstop=2 :
# vi: set shiftwidth=2 :
Vagrant.configure("2") do |config|
vms_debian = [
{ :name => "debian-stretch", :box => "debian/stretch64", :vars => { "nginx_php": [{"version": "7.0"}] }},
{ :name => "debian-stretch-sury", :box => "debian/stretch64", :vars => { "nginx_php": [{"version": "7.1"}], "sury": true }}
]
vms_freebsd = [
{ :name => "freebsd-11", :box => "freebsd/FreeBSD-11.1-STABLE", :vars => {} },
{ :name => "freebsd-12", :box => "freebsd/FreeBSD-12.0-CURRENT", :vars => {} }
]
conts = [
{ :name => "docker-debian-stretch", :docker => "hanxhx/vagrant-ansible:debian9", :vars => { "nginx_php": [{"version": "7.0"}] }},
{ :name => "docker-debian-stretch-sury", :docker => "hanxhx/vagrant-ansible:debian9", :vars => { "nginx_php": [{"version": "7.1"}], "sury": true }}
]
config.vm.network "private_network", type: "dhcp"
config.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true
conts.each do |opts|
config.vm.define opts[:name] do |m|
m.vm.provider "docker" do |d|
d.image = opts[:docker]
d.remains_running = true
d.has_ssh = true
end
m.vm.provision "ansible" do |ansible|
ansible.playbook = "tests/test.yml"
ansible.verbose = 'vv'
ansible.become = true
ansible.extra_vars = opts[:vars].merge({ "nginx_debug_role": true })
end
end
end
vms_debian.each do |opts|
config.vm.define opts[:name] do |m|
m.vm.box = opts[:box]
m.vm.provider "virtualbox" do |v|
v.cpus = 1
v.memory = 256
end
m.vm.provision "ansible" do |ansible|
ansible.playbook = "tests/test.yml"
ansible.verbose = 'vv'
ansible.become = true
ansible.extra_vars = opts[:vars].merge({ "nginx_debug_role": true })
end
end
end
vms_freebsd.each do |opts|
config.vm.base_mac = "080027D14C66"
config.vm.define opts[:name] do |m|
m.vm.box = opts[:box]
m.vm.provider "virtualbox" do |v, override|
override.ssh.shell = "csh"
v.cpus = 2
v.memory = 512
end
m.vm.provision "shell", inline: "pkg install -y python bash"
m.vm.provision "ansible" do |ansible|
ansible.playbook = "tests/test.yml"
ansible.verbose = 'vv'
ansible.become = true
ansible.extra_vars = opts[:vars].merge({ "nginx_debug_role": true, "ansible_python_interpreter": '/usr/local/bin/python' })
end
end
end
end

View File

@@ -3,8 +3,6 @@
# Debian # Debian
nginx_apt_package: nginx-full nginx_apt_package: nginx-full
nginx_backports: false nginx_backports: false
# FreeBSD
nginx_pkgng_package: nginx
# #
# Nginx shared variables # Nginx shared variables
@@ -14,18 +12,19 @@ nginx_log_dir: '/var/log/nginx'
nginx_resolver_hosts: ['8.8.8.8', '8.8.4.4'] nginx_resolver_hosts: ['8.8.8.8', '8.8.4.4']
nginx_resolver_valid: '300s' nginx_resolver_valid: '300s'
nginx_resolver_timeout: '5s' nginx_resolver_timeout: '5s'
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_auto_config_httpv2: true nginx_auto_config_httpv2: true
nginx_default_site: null nginx_default_site: null
nginx_default_site_ssl: null nginx_default_site_ssl: null
nginx_fastcgi_fix_realpath: true nginx_fastcgi_fix_realpath: true
nginx_default_hsts: 'max-age=63072000; includeSubDomains'
# #
# Nginx directories # Nginx directories
# #
nginx_htpasswd_dir: '{{ nginx_etc_dir }}/htpasswd' nginx_htpasswd_dir: '{{ nginx_etc_dir }}/htpasswd'
nginx_ssl_dir: '{{ nginx_etc_dir }}/ssl' nginx_ssl_dir: '{{ nginx_etc_dir }}/ssl'
nginx_helper_dir: '{{ nginx_etc_dir}}/helper' nginx_helper_dir: '{{ nginx_etc_dir }}/helper'
# #
# Load upstream # Load upstream
@@ -83,6 +82,19 @@ nginx_http_gzip_disable: '"msie6"'
# Custom global configuration # Custom global configuration
# #
nginx_custom_http: [] nginx_custom_http: []
nginx_custom_core: []
#
# Nginx default
#
nginx_default_listen:
- '80'
- '[::]:80'
nginx_default_listen_ssl:
- '443'
- '[::]:443'
nginx_default_listen_proxy_protocol: []
nginx_default_listen_proxy_protocol_ssl: []
# #
# Sites # Sites
@@ -115,7 +127,7 @@ nginx_load_modules: []
# #
nginx_dh: null nginx_dh: null
nginx_dh_path: '{{ nginx_ssl_dir }}/dhparam.pem' nginx_dh_path: '{{ nginx_ssl_dir }}/dhparam.pem'
nginx_dh_length: 4096 nginx_dh_length: 2048
# #
# acme.sh # acme.sh

View File

@@ -1,11 +1,6 @@
Auth Basic management Auth Basic management
===================== =====================
IMPORTANT
---------
If you use this feature with Debian Stretch, you *MUST* use ansible >= 2.3.2! See: [https://github.com/HanXHX/ansible-nginx/issues/28](#28).
Description Description
----------- -----------
@@ -25,12 +20,12 @@ Example
```yaml ```yaml
nginx_sites: nginx_sites:
# htpasswd on all site # htpasswd on all site
- name: test.local - name: test.local
htpasswd: 'hello' htpasswd: 'hello'
template: '_base' template: '_base'
# htpasswd only in /hello # htpasswd only in /hello
- name: test-location.local - name: test-location.local
template: '_base' template: '_base'
location: location:

View File

@@ -1,17 +0,0 @@
Freebsd
=======
Limitations
-----------
Due to Ansible + FreeBSD limitations (`ansible_processor_vcpus`), You must explicitely set `nginx_worker_processes`.
About modules
-------------
Dynamic modules must be set with full path (see `nginx_load_modules` path).
Sites not tested
----------------
- BackupPC

View File

@@ -2,8 +2,7 @@ PHP
=== ===
`nginx_php`: `nginx_php`:
- `version`: (M) PHP version - `upstream_name` (M)
- `upstream_name` (O)
- `sockets`: (O) socket list - `sockets`: (O) socket list
If `sockets` is not provided, if uses local unix socket (based on PHP version). If `sockets` is not provided, if uses local unix socket (based on PHP version).
@@ -16,8 +15,8 @@ Each socket have:
XOR XOR
- `host` - `host` (M)
- `port` - `port` (M)
- `weight` - `weight` (O)
- `max_fails` - `max_fails` (O)
- `fail_timeout` - `fail_timeout` (O)

View File

@@ -1,7 +1,7 @@
Site management Site management
=============== ===============
You can see many examples in: [tests/test.yml](../tests/test.yml). You can see many examples in: [molecule/_shared/group_vars/all/main.yml](../molecule/_shared/group_vars/all/main.yml).
`nginx_sites`: List of dict. A site has few keys. See bellow. `nginx_sites`: List of dict. A site has few keys. See bellow.
@@ -9,16 +9,32 @@ Common
------ ------
- `name`: (M) Domain or list of domain used. - `name`: (M) Domain or list of domain used.
- `template`: (D) template used to create site. Optional if you set `state`=`absent` or using `redirect_to`.
- `filename`: (O) Specify filename in /etc/nginx/sites-*. Do NOT specify default (reserved keyword). It will be used for log filenames and directories creation.
- `state`: (O) Site status. Can be "present" (default), "absent" and "disabled". - `state`: (O) Site status. Can be "present" (default), "absent" and "disabled".
- `filename`: (O) Specify filename in `/etc/nginx/sites-*`. Do NOT specify default (reserved keyword). It will be used for log filenames and directories creation.
(O): Optional
(M): Mandatory
(D): Depends other keys...
You can use 2 config (at the same time time):
- pre-built: Some configuration are templated (Wordpress, Symfony...), auto create root dir, perform an "A+" on ssllabs for https... etc
- custom: Push your own site config template. Usefull when you have a complex configuration.
Pre-built site config
---------------------
# Keys
- `template`: (M) template used to create site. Optional if you set `state`=`absent` or using `redirect_to`.
- `redirect_from`: (O) Domain list to redirect to the first `name`. You can use this key to redirect non-www to www - `redirect_from`: (O) Domain list to redirect to the first `name`. You can use this key to redirect non-www to www
- `redirect_to`: (O) Redirect all requests to this domain. Please set scheme (http:// or https:// or $sheme). - `redirect_to`: (O) Redirect all requests to this domain. Please set scheme (http:// or https:// or $sheme).
- `headers`: (O) Set additionals header as key/value list. You can append "always" to the value. Show [nginx doc](http://nginx.org/en/docs/http/ngx_http_headers_module.html). - `headers`: (O) Set additionals header as key/value list. You can append "always" to the value. Show [nginx doc](http://nginx.org/en/docs/http/ngx_http_headers_module.html).
- `redirect_to_code`: Redirect code (default: 302) - `redirect_to_code`: Redirect code (default: 302)
- `redirect_https`: (O) Boolean. Redirect HTTP to HTTPS. If "true", you _MUST_ set `proto` to ```['https']```. - `redirect_https`: (O) Boolean. Redirect HTTP to HTTPS. If "true", you _MUST_ set `proto` to `['https']`.
- `location`: (O) Add new custom locations (it does not overwrite!) - `location`: (O) Add new custom locations (it does not overwrite!)
- `location_order`: (O) Due to non preditive `location` order, you can provide the good order (see test-location.local in [tests/test.yml](../tests/test.yml)). - `location_order`: (O) Due to non preditive `location` order, you can provide the good order (see test-location.local in [molecule/_shared/group_vars/all/main.yml](../molecule/_shared/group_vars/all/main.yml)).
- `location_before`: (O) Add new custom locations before generated location by template - `location_before`: (O) Add new custom locations before generated location by template
- `location_order_before`: (O) Manages location order for `location_before` - `location_order_before`: (O) Manages location order for `location_before`
- `more`: (O) Add more custom infos. - `more`: (O) Add more custom infos.
@@ -29,19 +45,13 @@ Common
- `proto`: (O) list of protocol used. Default is a list with "http". If you need http and https, you must set a list with "http" and "https". You can only set "https" without http support. - `proto`: (O) list of protocol used. Default is a list with "http". If you need http and https, you must set a list with "http" and "https". You can only set "https" without http support.
- `ssl_name`: (D) name of the key used when using TLS/SSL. Optional when `proto` contains "https". If you don't set this value, it will search by `name`. - `ssl_name`: (D) name of the key used when using TLS/SSL. Optional when `proto` contains "https". If you don't set this value, it will search by `name`.
- `ssl_template` (O) "strong" (default) or "legacy". You can disable SSL helpers and add your own directives by setting "false". - `ssl_template` (O) "strong" (default) or "legacy". You can disable SSL helpers and add your own directives by setting "false".
- `php_version` (O) Sepecify PHP version (5 or 7) - `listen_proxy_protocol` (O) Enable proxy protocol on http port.
- `http_proxy_protocol_port` (O) Enable proxy protocol on http port. - `listen_proxy_protocol_ssl` (O) Enable proxy protocol on https port.
- `https_proxy_protocol_port` (O) Enable proxy protocol on https port. - `hsts` (O) overwrite default header for hsts
(O): Optional ### Templates
(M): Mandatory
(D): Depends other keys...
Templates
---------
- `_base`: static template - `_base`: static template
- `_backuppc`: access to [BackupPC](http://backuppc.sourceforge.net/) (be careful: you need to install [fcgiwrap](https://packages.debian.org/stretch/fcgiwrap))
- `_dokuwiki` - `_dokuwiki`
- `_redirect`: should not be called explicitly - `_redirect`: should not be called explicitly
- `_phalcon`: Phalcon PHP Framework - `_phalcon`: Phalcon PHP Framework
@@ -52,8 +62,7 @@ Templates
Templates works as parent-child. Templates works as parent-child.
About proxy template ### About proxy template
--------------------
Proxy template allow you to use Nginx as reverse proxy. Usefull when you have an application service such as Redmine, Jenkins... Proxy template allow you to use Nginx as reverse proxy. Usefull when you have an application service such as Redmine, Jenkins...
@@ -64,10 +73,67 @@ You have many key added to site key:
(O) : Optional (O) : Optional
Default sites ### Default sites
--------------
You can manage default site by setting domain name to these variables. You can manage default site by setting domain name to these variables.
- `nginx_default_site` - `nginx_default_site`
- `nginx_default_site_ssl` - `nginx_default_site_ssl`
*IT WORKS ONLY WITH PRE-BUIT SITES*
### Example
```yaml
nginx_sites:
- name: 'mywebsite.com'
template: '_wordpress'
headers:
x-ansibled: '1'
manage_local_content: false
```
Custom site config
------------------
### Keys
- `custom_template`: (M) template path used
You can add some extra infos if needed.
### Example:
```yaml
nginx_sites:
- name: 'mycustom-website.com'
custom_template: 'my/template_dir/the-template.conf.j2'
allow_admin: '192.168.0.0/24'
```
In `my/template_dir/the-template.conf.j2`:
```
#
# {{ ansible_managed }} - {{ item.name }}
#
server {
listen 8080 http2 proxy_protocol;
server_name {{ item.name }};
index index.html;
root /var/www/{{ item.name }};
location / {
try_files $uri $uri/ =404;
}
location /admin {
allow {{ item.allow_admin }};
deny all;
}
}
```

View File

@@ -8,7 +8,7 @@ Variables
- `nginx_dh`: DH content - `nginx_dh`: DH content
- `nginx_dh_length`: DH key length (default is 2048) - `nginx_dh_length`: DH key length (default is 2048)
- `nginx_dh_path`: file localation - `nginx_dh_path`: file location
- `nginx_ssl_dir`: directory where you install your SSL/TLS keys - `nginx_ssl_dir`: directory where you install your SSL/TLS keys
- `nginx_ssl_pairs` - `nginx_ssl_pairs`
@@ -20,7 +20,7 @@ Note: `name` is used to deploy key/cert. With defaults values dans `name` = "foo
### Content mode ### Content mode
Key/Cert content is stored in variable. Usefull with vault. Key/Cert content is stored in variable. Useful with vault.
- `key`: content of the private key - `key`: content of the private key
- `cert`: content of the public key - `cert`: content of the public key
@@ -32,11 +32,11 @@ You can use these variables if you use another task/role to manages your certifi
- `dest_cert`: remote path where certificate is located - `dest_cert`: remote path where certificate is located
- `dest_key`: remote path where key is located - `dest_key`: remote path where key is located
### Self signed ### Self-signed
Create a self-signed pair and deploy it. Do not use this feature in production. Create a self-signed pair and deploy it. Do not use this feature in production.
- `self_signed`: set true to use this featrure - `self_signed`: set true to use this feature
- `force`: optional feature (default: false), force regen pair (not idempotent) - `force`: optional feature (default: false), force regen pair (not idempotent)
### Acme ### Acme
@@ -45,7 +45,7 @@ Uses acme.sh to create free certificates. It uses HTTP-01 challenge. Use this fe
- `acme`: set true to use this feature. It uses `name` (can be a string or string list). - `acme`: set true to use this feature. It uses `name` (can be a string or string list).
Have a look to [acme configuratuion](acme.md configuration). Have a look to [acme configuration](acme.md).
Tips Tips
---- ----
@@ -61,7 +61,7 @@ Example
------- -------
```yaml ```yaml
nginx_sites; nginx_sites:
- name: 'test-ssl.local' - name: 'test-ssl.local'
proto: ['http', 'https'] proto: ['http', 'https']
template: '_base' template: '_base'

View File

@@ -1,5 +1,5 @@
def nginx_site_filename(site): def nginx_site_filename(site):
if site.has_key('filename'): if 'filename' in site:
return site['filename'] return site['filename']
else: else:
return nginx_site_name(site) return nginx_site_name(site)
@@ -10,11 +10,59 @@ def nginx_site_name(site):
else: else:
return site['name'] return site['name']
def nginx_ssl_dir(pair, ssl_dir):
return ssl_dir + '/' + nginx_site_filename(pair)
def nginx_key_path(pair, ssl_dir):
if 'dest_key' in pair:
return pair['dest_key']
else:
return nginx_ssl_dir(pair, ssl_dir) + '/' + nginx_site_filename(pair) + '.key'
def nginx_cert_path(pair, ssl_dir):
if 'dest_cert' in pair:
return pair['dest_cert']
else:
return nginx_ssl_dir(pair, ssl_dir) + '/' + nginx_site_filename(pair) + '.crt'
def nginx_all_site_names(site):
all_sites = []
if isinstance(site['name'], list):
all_sites = all_sites + site['name']
else:
all_sites.append(site['name'])
if 'redirect_from' in site:
if isinstance(site['redirect_from'], list):
all_sites = all_sites + site['redirect_from']
else:
all_sites.append(site['redirect_from'])
return all_sites
def nginx_search_by_ssl_name(sites, ssl_name):
if isinstance(ssl_name, list):
comp_ssl_name = ssl_name[0]
else:
comp_ssl_name = ssl_name
res = None
for site in sites:
if 'ssl_name' in site and site['ssl_name'] == comp_ssl_name:
res = site
break
return res
class FilterModule(object): class FilterModule(object):
''' Nginx module ''' ''' Nginx module '''
def filters(self): def filters(self):
return { return {
'nginx_site_filename': nginx_site_filename, 'nginx_site_filename': nginx_site_filename,
'nginx_site_name': nginx_site_name 'nginx_site_name': nginx_site_name,
'nginx_ssl_dir': nginx_ssl_dir,
'nginx_key_path': nginx_key_path,
'nginx_cert_path': nginx_cert_path,
'nginx_all_site_names': nginx_all_site_names,
'nginx_search_by_ssl_name': nginx_search_by_ssl_name
} }

View File

@@ -1,17 +1,5 @@
def php_default_upstream_socket(php_version): def php_default_upstream_socket(php_version):
if php_version == '5.6': return '/run/php/php%s-fpm.sock' % php_version
return '/run/php5-fpm.sock'
else:
return '/run/php/php%s-fpm.sock' % php_version
def php_default_upstream_name(php_version):
return 'default_php_%s' % php_version
def php_fpm_service(php_version):
if php_version == '5.6':
return 'php5-fpm'
else:
return 'php%s-fpm' % php_version
class FilterModule(object): class FilterModule(object):
''' PHP module ''' ''' PHP module '''
@@ -19,7 +7,4 @@ class FilterModule(object):
def filters(self): def filters(self):
return { return {
'php_default_upstream_socket': php_default_upstream_socket, 'php_default_upstream_socket': php_default_upstream_socket,
'php_default_upstream_name': php_default_upstream_name,
'php_fpm_service': php_fpm_service,
'php_fpm_package': php_fpm_service
} }

View File

@@ -1,46 +1,14 @@
--- ---
- name: reload nginx - name: Reload nginx
command: nginx -t ansible.builtin.service:
notify:
- real-reload nginx
- docker reload nginx
- name: restart nginx
command: nginx -t
notify:
- real-restart nginx
- docker restart nginx
- name: real-reload nginx
service:
name: nginx name: nginx
state: reloaded state: reloaded
when: ansible_virtualization_type != 'docker'
- name: real-restart nginx - name: Restart nginx
service: ansible.builtin.service:
name: nginx name: nginx
state: restarted state: restarted
when: ansible_virtualization_type != 'docker'
- name: docker reload nginx - name: Setup
command: service nginx reload ansible.builtin.setup:
args:
warn: false
when: ansible_virtualization_type == 'docker'
- name: docker restart nginx
command: service nginx restart
args:
warn: false
when: ansible_virtualization_type == 'docker'
- name: restart nginx freebsd
service:
name: nginx
state: restarted
when: ansible_distribution == "FreeBSD"
- name: setup
action: setup

View File

@@ -1,28 +1,32 @@
--- ---
galaxy_info: galaxy_info:
author: Emilien Mantel author: Emilien Mantel
description: Nginx for Debian / FreeBSD namespace: HanXHX
company: role_name: nginx
description: Nginx for Debian / Ubuntu
company: TripleStack
license: GPLv2 license: GPLv2
min_ansible_version: 2.6 min_ansible_version: '2.11'
platforms: platforms:
- name: Debian - name: Debian
versions: versions:
- stretch - buster
- name: FreeBSD - bullseye
versions: - bookworm
- 11.0 - name: Ubuntu
- 11.1 versions:
- 12.0 - focal
- jammy
galaxy_tags: galaxy_tags:
- web - web
- proxy - debian
- http - proxy
- http2 - http
- https - http2
- ssl - https
- tls - ssl
- nginx - tls
- cdn - nginx
- cdn
dependencies: [] dependencies: []

View File

@@ -0,0 +1,19 @@
# Molecule managed
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
{% if item.env is defined %}
{% for var, value in item.env.items() %}
{% if value %}
ENV {{ var }} {{ value }}
{% endif %}
{% endfor %}
{% endif %}
RUN apt-get update && \
apt-get install -y python3 sudo bash ca-certificates iproute2 python-apt-common \
&& apt-get clean

42
molecule/_shared/base.yml Normal file
View File

@@ -0,0 +1,42 @@
---
scenario:
test_sequence:
- dependency
- syntax
- create
- prepare
- converge
- idempotence
- verify
- destroy
dependency:
name: galaxy
options:
requirements-file: ./molecule/_shared/requirements.yml
role-file: ./molecule/_shared/requirements.yml
driver:
name: docker
role_name_check: 1
provisioner:
name: ansible
env:
ANSIBLE_FILTER_PLUGINS: "../../filter_plugins"
config_options:
defaults:
deprecation_warnings: false
callback_whitelist: timer,profile_tasks
fact_caching: jsonfile
fact_caching_connection: ./cache
forks: 100
connection:
pipelining: true
playbooks:
converge: ../_shared/converge.yml
prepare: ../_shared/prepare.yml
verify: ../_shared/verify.yml
inventory:
links:
group_vars: ../_shared/group_vars
verifier:
name: ansible

View File

@@ -0,0 +1,9 @@
---
- name: Converge # noqa: role-name[path]
hosts: all
gather_facts: true
vars:
nginx_debug_role: true
roles:
- ../../../

View File

@@ -0,0 +1,250 @@
---
# Internal vars
int_ansible_ssl_dir: '/etc/ansible-ssl'
# Role vars
nginx_worker_processes: 1 # Ansible can't detect CPU count
nginx_apt_package: 'nginx-extras'
nginx_module_packages: ['libnginx-mod-http-headers-more-filter']
nginx_custom_core:
- 'worker_rlimit_nofile 4242;'
nginx_upstreams:
- name: 'test'
servers:
- path: '127.0.0.1:80'
max_conns: 150
weight: 10
down: false
- name: 'test-absent'
servers:
- path: '127.0.0.1:80'
max_conns: 150
weight: 10
down: false
state: 'absent'
nginx_htpasswd:
- name: 'hello'
description: 'Please login!'
users:
- name: 'hx'
password: 'asdfg'
state: 'absent'
- name: 'hanx'
password: 'qwerty'
- name: 'deleteme'
description: 'Please login!'
users: []
state: 'absent'
nginx_acmesh: true
nginx_acmesh_test: true
nginx_ssl_pairs:
- name: 'test-ssl-selfsigned.local'
self_signed: true
force: false
- name:
- 'test-ssl-predeployed.local'
- 'test-multiple-name.local' # Hack: tests for acme with multiple name, without using acme
dest_key: "{{ int_ansible_ssl_dir }}/test.key"
dest_cert: "{{ int_ansible_ssl_dir }}/test.crt"
- 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:
- 'add_header X-ansible 1;'
- 'geoip_country {% if ansible_os_family == "Debian" %}/usr/share/GeoIP/GeoIP.dat{% else %}/usr/local/share/GeoIP/GeoIP.dat{% endif %};'
- 'map $geoip_country_code $allowed_country {'
- ' default yes;'
- ' MA no;'
- ' DZ no;'
- ' TN no;'
- '}'
nginx_default_site: 'test.local'
nginx_default_site_ssl: 'test-ssl-predeployed.local'
nginx_sites:
- name:
- 'test.local'
- 'test-alias.local'
- 'test2-alias.local'
template: '_base'
filename: 'first-test'
override_try_files: '$uri/ $uri =404'
headers:
'X-Frame-Options': 'deny always'
'X-ansible-default': '1'
manage_local_content: false
use_error_log: true
more:
- 'autoindex off;'
location:
'/test':
- 'return 403;'
'/gunther':
- 'return 404;'
'/status':
- 'stub_status on;'
- 'access_log off;'
- 'allow 127.0.0.1;'
- 'deny all;'
- name: 'test-htpasswd.local'
template: '_base'
location_before:
'/hello':
- htpasswd: 'hello'
location:
'/public':
- htpasswd: false
use_error_log: true
- name: 'test-htpasswd-all.local'
template: '_base'
htpasswd: 'hello'
- name: 'test-location.local'
template: '_base'
location_before:
'/b':
- 'alias /var/tmp;'
'/c':
- 'alias /var/tmp;'
location:
'/':
- 'alias /var/tmp;'
'/a':
- 'alias /var/tmp;'
location_order_before:
- '/b'
- '/c'
location_order:
- '/'
- '/a'
- name: 'test-php.local'
php_upstream: "manual"
upstream_params:
- 'fastcgi_param FOO bar;'
redirect_from:
- 'www.test-php.local'
template: '_php'
use_error_log: true
use_access_log: true
- name: 'test-php-index.local'
template: '_php_index'
php_upstream: 'hx_unix'
- name: 'test-php-index2.local'
template: '_php_index2'
php_upstream: 'hx_ip'
- name: 'test-proxy.local'
listen:
- 8080
template: '_proxy'
upstream_name: 'test'
headers:
'X-proxyfied': '1'
- name: 'deleted.local'
state: 'absent'
- name: 'redirect-to.local'
redirect_to: 'http://test.local'
- name: 'test-ssl.local'
proto: ['http', 'https']
template: '_base'
- name:
- 'test-ssl-selfsigned.local'
- 'www.test-ssl-selfsigned.local'
proto: ['http', 'https']
template: '_base'
hsts: 'max-age=1664;'
- name: 'test-ssl-predeployed.local'
proto: ['http', 'https']
template: '_base'
ssl_name: 'test-ssl-predeployed.local'
headers:
'X-ansible-default': '1'
ssl_template: false
- name: 'test-ssl-redirect.local'
proto: ['https']
template: '_base'
ssl_name: 'test-ssl.local'
redirect_https: true
- name:
- 'test-ssl-redirect-many.local'
- 'test-ssl-redirect-many2.local'
listen_ssl: [8443]
proto: ['https']
template: '_base'
ssl_name: 'test-ssl.local'
redirect_https: true
redirect_from:
- 'www.test-ssl-redirect-many.local'
- 'www.test-ssl-redirect-many2.local'
- name: 'test-ssl-proxy-protocol.local'
proto: ['http', 'https']
listen_proxy_protocol: [20080]
listen_proxy_protocol_ssl: [20443]
template: '_base'
ssl_name: 'test-ssl.local'
headers:
'X-Proxy-Protocol': '1'
# - name: '{{ ngrok.stdout }}'
# proto: ['http', 'https']
# listen_proxy_protocol: [21080]
# listen_proxy_protocol_ssl: [21443]
# template: '_base'
# ssl_name: '{{ ngrok.stdout }}'
# headers:
# 'X-acme': '1'
# - name: 'test-custom-template.local'
# custom_template: 'templates/custom_template.conf.j2'
# root: '/tmp/custom-template'
nginx_php: "{{ [{'upstream_name': 'manual', 'sockets': [{'host': '127.0.0.1', 'port': '9636'}]}] }}"
nginx_dh_length: 1024

View File

@@ -0,0 +1,109 @@
---
- name: Prepare
hosts: all
gather_facts: true
tasks:
- name: APT_REPOSITORY | Install backports
ansible.builtin.apt_repository:
repo: 'deb http://httpredir.debian.org/debian {{ ansible_distribution_release }}-backports main'
state: present
when: nginx_backports is defined and nginx_backports
- name: APT | Install needed packages
ansible.builtin.apt:
pkg: "{{ packages }}"
update_cache: true
cache_valid_time: 3600
state: present
vars:
packages:
- cron
- curl
- daemonize
- jq
- nghttp2
- strace
- vim
- unzip
- name: APT | Install PHP
ansible.builtin.apt:
pkg: "{{ pkgs }}"
update_cache: true
cache_valid_time: 3600
state: present
vars:
pkgs:
- php-cli
- php-fpm
- name: SHELL | Get current PHP version # noqa: risky-shell-pipe
ansible.builtin.shell: php --version | awk '/^PHP/ { print $2 }' | grep -o -E '^.{3}'
changed_when: false
register: cur_php_version
- name: SERVICE | Ensure PHP-FPM is started
ansible.builtin.service:
name: "php{{ cur_php_version.stdout }}-fpm"
state: started
- name: USER | Create PHP User foo
ansible.builtin.user:
name: foo
system: true
- name: INCLUDE_ROLE | hanxhx.php
ansible.builtin.include_role:
name: "hanxhx.php"
vars:
php_version: "{{ cur_php_version.stdout }}"
php_autoremove_default_pool: false
php_fpm_poold:
- name: 'hx_unix'
user: 'foo'
php_value:
display_errors: 'Off'
php_admin_value:
memory_limit: '98M'
- name: 'hx_ip'
listen: '127.0.0.1:9636'
- name: FILE | Create an internal SSL dir
ansible.builtin.file:
path: "{{ int_ansible_ssl_dir }}"
state: directory
mode: "0750"
owner: root
group: root
- name: COPY | Deploy test cert/key
ansible.builtin.copy:
src: "file/{{ item }}"
dest: "{{ int_ansible_ssl_dir }}/{{ item }}"
mode: "0640"
owner: root
group: root
loop:
- 'test.key'
- 'test.crt'
- name: COPY | Add all hosts in /etc/hosts
ansible.builtin.copy:
content: |
127.0.0.1 localhost
{% for s in nginx_sites %}
{% if s.name is string %}
127.0.0.1 {{ s.name }}
{% else %}
127.0.0.1 {% for n in s.name %}{{ n }} {% endfor %}
{% endif %}
{% if s.redirect_from is defined %}
127.0.0.1 {% for rf in s.redirect_from %}{{ rf }} {% endfor %}
{% endif %}
{% endfor %}
dest: "/etc/hosts"
mode: "0644"
owner: root
group: root
unsafe_writes: true

View File

@@ -0,0 +1,7 @@
---
roles:
- name: hanxhx.php
collections:
- community.general

View File

@@ -0,0 +1,16 @@
# {{ ansible_managed }} - custom template
server {
listen 80;
listen 8888 http2;
listen 9999 http2 proxy_protocol;
server_name {{ item.name }};
index index.html index.htm;
root {{ item.root }};
location / {
try_files $uri $uri/ =404;
}
}

266
molecule/_shared/verify.yml Normal file
View File

@@ -0,0 +1,266 @@
---
- name: Verify
hosts: all
gather_facts: true
vars:
nginx_root: "/srv/www"
tasks:
# --------------------------------
# Deploy index files
# --------------------------------
- name: -- Add PHP file --
ansible.builtin.copy:
dest: "{{ nginx_root }}/{{ item }}/public/index.php"
content: "<?php phpinfo();"
mode: "0644"
owner: root
group: root
loop:
- 'test-php.local'
- 'test-php-index.local'
- 'test-php-index2.local'
- name: -- Add Directories --
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "0755"
loop:
- "{{ nginx_root }}/test-htpasswd.local/public/hello"
- "/tmp/custom-template"
- name: -- Add HTML file --
ansible.builtin.copy:
dest: "{{ item }}/index.html"
content: "Index HTML test OK\n"
mode: "0644"
owner: root
group: root
loop:
- '{{ nginx_root }}/first-test/public'
- '/var/tmp'
- '{{ nginx_root }}/test-htpasswd-all.local/public'
- '{{ nginx_root }}/test-ssl.local/public'
- '{{ nginx_root }}/test-ssl-selfsigned.local/public'
- '{{ nginx_root }}/test-ssl-predeployed.local/public'
- '{{ nginx_root }}/test-ssl-proxy-protocol.local/public'
- name: -- Create directory --
ansible.builtin.file:
path: "{{ nginx_root }}/test-htpasswd.local/public/hello"
state: directory
mode: "0755"
owner: root
group: root
- name: -- Add HTML file hello --
ansible.builtin.copy:
dest: "{{ nginx_root }}/test-htpasswd.local/public/hello/index.html"
content: "hello\n"
mode: "0644"
owner: root
group: root
# --------------------------------
# Test custom facts
# --------------------------------
- name: -- CHECK FACTS --
ansible.builtin.assert:
that: "ansible_local.nginx.fact_nginx_sites[0].name[0] == 'test.local'"
# --------------------------------
# Simple sites tests
# --------------------------------
- name: -- VERIFY SITES --
ansible.builtin.uri:
url: "http://{{ item | nginx_site_name }}{% if item.listen is defined %}:{{ item.listen[0] }}{% endif %}/"
status_code: '200,301,302,401,403'
follow_redirects: none
loop: "{{ nginx_sites }}"
when: item.state is undefined or item.state != "absent"
changed_when: false
- name: -- VERIFY FORBIDDEN --
ansible.builtin.uri:
url: "http://test-php-index.local/phpinfo.php"
status_code: 403
- name: -- VERIFY REDIRECT SITES --
ansible.builtin.uri:
url: "http://{{ item.redirect_from[0] }}/"
status_code: 301
follow_redirects: none
loop: "{{ nginx_sites }}"
when: item.redirect_from is defined and (item.state is undefined or item.state != "absent") and (item.proto is not defined or 'https' not in item.proto)
changed_when: false
- name: -- VERIFY REDIRECT HTTPS SITES --
ansible.builtin.uri:
url: "https://{{ item.redirect_from[0] }}:{{ item.listen_ssl[0] | default(443) }}/"
status_code: 301
follow_redirects: none
validate_certs: false
loop: "{{ nginx_sites }}"
when: item.redirect_from is defined and (item.state is undefined or item.state != "absent") and item.proto is defined and 'https' in item.proto
changed_when: false
# --------------------------------
# PHP
# --------------------------------
- name: -- VERIFY PHP SITES --
ansible.builtin.uri:
url: "http://{{ item.name }}/"
return_content: true
register: p
loop: "{{ nginx_sites }}"
when: >
item.template is defined and
(item.template == '_php' or item.template == '_php_index' or item.template == '_php_index2')
failed_when: p.content.find('PHP Version') == -1
- name: -- VERIFY INDEX2 --
ansible.builtin.uri:
url: "http://test-php-index2.local/lorem.php?ipsum=sit&dolor=amet"
return_content: true
register: p2
failed_when: p2.content.find('PHP Version') == -1
# --------------------------------
# Basic Auth
# --------------------------------
- name: -- VERIFY AUTH BASIC NONE --
ansible.builtin.uri:
url: "http://test-htpasswd.local/hello/"
status_code: 401
- name: -- VERIFY AUTH BASIC FAIL --
ansible.builtin.uri:
url: "http://test-htpasswd.local/hello/"
status_code: 401
user: "fail"
password: "fail"
force_basic_auth: true
- name: -- VERIFY AUTH BASIC OK --
ansible.builtin.uri:
url: "http://test-htpasswd.local/hello/"
user: "hanx"
password: "qwerty"
force_basic_auth: true
- name: -- VERIFY AUTH BASIC FAIL GLOBAL --
ansible.builtin.uri:
url: "http://test-htpasswd-all.local/"
status_code: 401
user: "fail"
password: "fail"
force_basic_auth: true
- name: -- VERIFY AUTH BASIC OK GLOBAL --
ansible.builtin.uri:
url: "http://test-htpasswd-all.local/"
user: "hanx"
password: "qwerty"
force_basic_auth: true
# --------------------------------
# SSL
# --------------------------------
- name: -- VERIFY SSL --
ansible.builtin.uri:
url: "https://{{ item }}/"
return_content: true
validate_certs: false
register: sslok
failed_when: sslok.content.find('Index HTML test OK') == -1
loop:
- 'test-ssl-predeployed.local'
- 'test-ssl-selfsigned.local'
- 'test-ssl.local'
- name: -- VERIFY SSL REDIRECT --
ansible.builtin.uri:
url: "http://{{ item.name }}/"
validate_certs: false
status_code: 301
return_content: true
follow_redirects: none
register: sslredirok
failed_when: '"https://%s%s" % (item.name, ":" + item.port if item.port is defined else "") not in sslredirok.location'
loop:
- name: 'test-ssl-redirect.local'
- name: 'test-ssl-redirect-many.local'
port: '8443'
- name: 'test-ssl-redirect-many2.local'
port: '8443'
# --------------------------------
# Default sites
# --------------------------------
- name: -- VERIFY DEFAULT SITE --
ansible.builtin.uri:
url: 'http://127.0.0.1/'
return_content: true
register: vdefault
failed_when: >
vdefault.content.find('Index HTML test OK') == -1 or
vdefault.x_ansible_default is not defined
- name: -- VERIFY DEFAULT SITE + STUB STATUS--
ansible.builtin.uri:
url: 'http://127.0.0.1/status'
return_content: true
register: vdefault_status
failed_when: >
vdefault_status.content.find('Active connections') == -1 or
vdefault_status.x_ansible_default is not defined
- name: -- VERIFY DEFAULT SSL SITE --
ansible.builtin.uri:
url: 'https://127.0.0.1/'
return_content: true
validate_certs: false
register: vdefault
failed_when: >
vdefault.content.find('Index HTML test OK') == -1 or
vdefault.x_ansible_default is not defined
- name: -- VERIFY NOT DEFAULT SITE --
ansible.builtin.uri:
url: 'http://test-php.local/'
return_content: true
register: vphp
failed_when: vphp.x_ansible_default is defined
- name: -- VERIFY NOT DEFAULT SSL SITE --
ansible.builtin.uri:
url: 'https://test-ssl.local/'
return_content: true
validate_certs: false
register: notdefaultssl
failed_when: notdefaultssl.x_ansible_default is defined
# --------------------------------
# Check Proxy protocol
# --------------------------------
- name: SHELL | Check HTTP proxy protocol
ansible.builtin.shell: set -o pipefail && curl -I --haproxy-protocol http://test-ssl-proxy-protocol.local:20080 | grep -qi 'X-Proxy-Protocol'
args:
executable: /bin/bash
changed_when: false
- name: SHELL | Check HTTPS proxy protocol
ansible.builtin.shell: set -o pipefail && curl -I --haproxy-protocol -k https://test-ssl-proxy-protocol.local:20443 | grep -qi 'X-Proxy-Protocol'
args:
executable: /bin/bash
changed_when: false
# --------------------------------
# Check HTTP2
# --------------------------------
- name: SHELL | Check HTTP2
ansible.builtin.shell: set -o pipefail && nghttp -nv https://localhost 2> /dev/null | grep -q h2
args:
executable: /bin/bash
changed_when: false

View File

@@ -0,0 +1,13 @@
---
platforms:
- name: debian-11
image: dokken/debian-11
command: /lib/systemd/systemd
dockerfile: ../_shared/Dockerfile.j2
capabilities:
- SYS_ADMIN
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true

View File

@@ -0,0 +1,13 @@
---
platforms:
- name: debian-13
image: dokken/debian-13
command: /lib/systemd/systemd
dockerfile: ../_shared/Dockerfile.j2
capabilities:
- SYS_ADMIN
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true

View File

@@ -0,0 +1,13 @@
---
platforms:
- name: debian-12
image: dokken/debian-13
command: /lib/systemd/systemd
dockerfile: ../_shared/Dockerfile.j2
capabilities:
- SYS_ADMIN
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true

View File

View File

@@ -0,0 +1,20 @@
---
platforms:
- name: ubuntu-20.04
image: dokken/ubuntu-20.04
command: /lib/systemd/systemd
dockerfile: ../_shared/Dockerfile.j2
capabilities:
- SYS_ADMIN
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true
# Segfault on Ubuntu 20.04 with `nginx-extras` package...
provisioner:
inventory:
host_vars:
ubuntu-20.04:
nginx_apt_package: 'nginx-full'

View File

@@ -0,0 +1,13 @@
---
platforms:
- name: ubuntu-22.04
image: dokken/ubuntu-22.04
command: /lib/systemd/systemd
dockerfile: ../_shared/Dockerfile.j2
capabilities:
- SYS_ADMIN
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true

View File

@@ -0,0 +1,13 @@
---
platforms:
- name: ubuntu-24.04
image: dokken/ubuntu-24.04
command: /lib/systemd/systemd
dockerfile: ../_shared/Dockerfile.j2
capabilities:
- SYS_ADMIN
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true

4
requirements.yml Normal file
View File

@@ -0,0 +1,4 @@
---
collections:
- community.general

View File

@@ -1,26 +1,35 @@
--- ---
- name: TEMPLATE | Deploy nginx.conf - name: TEMPLATE | Deploy nginx.conf
template: ansible.builtin.template:
src: "etc/nginx/nginx.conf.j2" src: "etc/nginx/nginx.conf.j2"
dest: "{{ nginx_etc_dir }}/nginx.conf" dest: "{{ nginx_etc_dir }}/nginx.conf"
notify: reload nginx mode: "0644"
owner: root
group: root
notify: Reload nginx
- name: TEMPLATE | Deploy all helpers - name: TEMPLATE | Deploy all helpers
template: ansible.builtin.template:
src: "{{ item }}" src: "{{ item }}"
dest: "{{ nginx_helper_dir }}/{{ item | basename | regex_replace('.j2$','') }}" dest: "{{ nginx_helper_dir }}/{{ item | basename | regex_replace('.j2$', '') }}"
mode: "0644"
owner: root
group: root
with_fileglob: '../templates/etc/nginx/helper/*.j2' with_fileglob: '../templates/etc/nginx/helper/*.j2'
notify: reload nginx notify: Reload nginx
- name: TEMPLATE | Deploy custom http configuration - name: TEMPLATE | Deploy custom http configuration
template: ansible.builtin.template:
src: "etc/nginx/conf.d/custom.conf.j2" src: "etc/nginx/conf.d/custom.conf.j2"
dest: "{{ nginx_etc_dir }}/conf.d/custom.conf" dest: "{{ nginx_etc_dir }}/conf.d/custom.conf"
notify: reload nginx mode: "0644"
owner: root
group: root
notify: Reload nginx
- name: LINEINFILE | Fix path - name: LINEINFILE | Fix path
lineinfile: ansible.builtin.lineinfile:
regexp: '{{ item.0.regexp }}' regexp: '{{ item.0.regexp }}'
line: '{{ item.0.line }}' line: '{{ item.0.line }}'
dest: '{{ item.1 }}' dest: '{{ item.1 }}'
@@ -36,10 +45,13 @@
when: nginx_fastcgi_fix_realpath when: nginx_fastcgi_fix_realpath
- name: COPY | Add modules manually - name: COPY | Add modules manually
copy: ansible.builtin.copy:
content: | content: |
{% for m in nginx_load_modules %} {% for m in nginx_load_modules %}
load_module {{ m }}; load_module {{ m }};
{% endfor %} {% endfor %}
dest: "{{ nginx_etc_dir }}/modules-enabled/000-modules.conf" dest: "{{ nginx_etc_dir }}/modules-enabled/000-modules.conf"
notify: reload nginx mode: "0644"
owner: root
group: root
notify: Reload nginx

View File

@@ -1,18 +1,21 @@
--- ---
- name: FILE | Delete htpasswd file - name: FILE | Delete htpasswd file
file: ansible.builtin.file:
path: "{{ nginx_htpasswd_dir }}/{{ item.name }}" path: "{{ nginx_htpasswd_dir }}/{{ item.name }}"
state: absent state: absent
loop: "{{ nginx_htpasswd }}" loop: "{{ nginx_htpasswd }}"
when: item.state is defined and item.state == 'absent' when: item.state is defined and item.state == 'absent'
no_log: not nginx_debug_role no_log: "{{ not nginx_debug_role }}"
- name: HTPASSWD | Manage files - name: HTPASSWD | Manage files
htpasswd: community.general.htpasswd:
name: "{{ item.1.name }}" name: "{{ item.1.name }}"
password: "{{ item.1.password }}" password: "{{ item.1.password }}"
path: "{{ nginx_htpasswd_dir }}/{{ item.0.name }}" path: "{{ nginx_htpasswd_dir }}/{{ item.0.name }}"
mode: "0644"
owner: root
group: root
loop: "{{ nginx_htpasswd | subelements('users') }}" loop: "{{ nginx_htpasswd | subelements('users') }}"
when: item.0.state is not defined or item.0.state == 'present' when: item.0.state is not defined or item.0.state == 'present'
no_log: not nginx_debug_role no_log: "{{ not nginx_debug_role }}"

27
tasks/install/Debian.yml Normal file
View File

@@ -0,0 +1,27 @@
---
- name: SET_FACT | Bypass https://github.com/ansible/ansible/issues/19874
ansible.builtin.set_fact:
ansible_distribution_release: 'buster'
when: ansible_facts.distribution_major_version == "buster/sid"
- name: APT | Update cache
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
changed_when: false
- name: APT | Install nginx and dependencies
ansible.builtin.apt:
pkg: "{{ nginx_apt_package }}"
default_release: "{{ ansible_distribution_release + '-backports' if (nginx_backports and ansible_distribution == 'Debian') else ansible_distribution_release }}"
- name: APT | Install nginx modules
ansible.builtin.apt:
pkg: "{{ nginx_module_packages }}"
state: present
- name: APT | Install passlib lib
ansible.builtin.apt:
pkg: "python3-passlib"
state: present

36
tasks/install/acme.yml Normal file
View File

@@ -0,0 +1,36 @@
---
- name: STAT | Check acme.sh is installed
ansible.builtin.stat:
path: "{{ nginx_acmesh_dir }}"
register: acme
- name: Install acme.sh if needed
when: not acme.stat.exists
block:
- name: APT | Install git
ansible.builtin.apt:
pkg: git
- name: GIT | Get acme.sh
ansible.builtin.git:
repo: 'https://github.com/Neilpang/acme.sh.git'
dest: '{{ nginx_acmesh_git_dir }}'
update: false
version: master
- name: COMMAND | Install acme.sh
ansible.builtin.command: ./acme.sh --install --home "{{ nginx_acmesh_dir }}"
args:
chdir: "{{ nginx_acmesh_git_dir }}"
creates: "{{ nginx_acmesh_dir }}"
- name: COMMAND | Force acme.sh to use letsencrypt (instead of zerossl)
ansible.builtin.command: '{{ nginx_acmesh_dir }}/acme.sh --set-default-ca --server letsencrypt --home "{{ nginx_acmesh_dir }}"'
changed_when: true
- name: FILE | Remove temp acme.sh dir
ansible.builtin.file:
path: '{{ nginx_acmesh_git_dir }}'
state: absent

8
tasks/install/main.yml Normal file
View File

@@ -0,0 +1,8 @@
---
- name: INCLUDE_TASKS | Install
ansible.builtin.include_tasks: "{{ ansible_os_family }}.yml"
- name: IMPORT_TASKS | acme
ansible.builtin.import_tasks: "acme.yml"
when: nginx_acmesh

View File

@@ -1,55 +0,0 @@
---
- name: APT | Update cache
apt:
update_cache: yes
cache_valid_time: 3600
changed_when: false
- name: APT | Force OpenSSL from backports (fix dependency break)
apt:
pkg: openssl
state: latest
default_release: "{{ ansible_distribution_release + '-backports' }}"
when: nginx_backports
- name: APT | Install nginx and dependencies
apt:
pkg: "{{ nginx_apt_package }}"
state: present
default_release: "{{ ansible_distribution_release + '-backports' if nginx_backports else ansible_distribution_release }}"
- name: APT | Install nginx modules
apt:
pkg: "{{ nginx_module_packages }}"
state: present
- name: APT | Install python-passlib
apt:
pkg: python-passlib
state: present
- name: STAT | Check acme.sh is installed
stat:
path: "{{ nginx_acmesh_dir }}"
register: acme
- block:
- name: APT | Install git
apt:
pkg: git
- name: GIT | Get acme.sh
git:
repo: 'https://github.com/Neilpang/acme.sh.git'
dest: '{{ nginx_acmesh_git_dir }}'
update: no
- name: SHELL | Install acme.sh
shell: ./acme.sh --install --home {{ nginx_acmesh_dir }} --cert-home {{ nginx_acmesh_dir }}
args:
chdir: "{{ nginx_acmesh_git_dir }}"
creates: "{{ nginx_acmesh_dir }}"
when: not acme.stat.exists

View File

@@ -1,59 +0,0 @@
---
- name: PKGNG | Install nginx and related tools
pkgng:
name: "{{ item }}"
state: present
loop:
- acme.sh
- "{{ nginx_pkgng_package }}"
- py27-passlib
- curl
#
# Bypass https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=224166#c1
#
- block:
- name: COMMAND | Create /usr/local/etc/fdfs/http.conf
command: touch /usr/local/etc/fdfs/http.conf
args:
creates: /usr/local/etc/fdfs/http.conf
register: fd1
- name: LINEINFILE | Tune fdfs
lineinfile:
regexp: ^load_fdfs_parameters_from_tracker
line: load_fdfs_parameters_from_tracker=false
path: /usr/local/etc/fdfs/mod_fastdfs.conf
register: fd2
- name: SERVICE | Restart nginx when fdfs is tuned
service:
name: nginx
state: restarted
when: fd1.changed or fd2.changed
when: true
- name: FILE | Create configuration dir (like Debian)
file:
path: "{{ nginx_etc_dir }}/{{ item }}"
state: directory
loop:
- conf.d
- sites-available
- sites-enabled
- name: FILE | Create log directory
file:
path: "{{ nginx_log_dir }}"
owner: "{{ nginx_user }}"
group: wheel
mode: 0755
state: directory
- name: SERVICE | Enable nginx
service:
name: nginx
enabled: yes

View File

@@ -1,30 +1,30 @@
--- ---
- name: INCLUDE_VARS | Related to OS - name: INCLUDE_VARS | Related to OS
include_vars: "{{ ansible_distribution }}.yml" ansible.builtin.include_vars: "{{ ansible_os_family }}.yml"
tags: ['nginx::site', 'nginx::ssl'] tags: ['nginx::site', 'nginx::ssl']
- name: INCLUDE_TASKS | Install - name: INCLUDE_TASKS | Install
include_tasks: "install_{{ ansible_distribution }}.yml" ansible.builtin.import_tasks: "install/main.yml"
tags: ['nginx::site', 'nginx::ssl'] tags: ['nginx::site', 'nginx::ssl']
- name: IMPORT_TASKS| Prepare - name: IMPORT_TASKS| Prepare
import_tasks: prepare.yml ansible.builtin.import_tasks: prepare.yml
tags: ['nginx::site', 'nginx::ssl'] tags: ['nginx::site', 'nginx::ssl']
- name: IMPORT_TASKS| Install - name: IMPORT_TASKS| Install
import_tasks: config.yml ansible.builtin.import_tasks: config.yml
- name: IMPORT_TASKS| Upstream configuration - name: IMPORT_TASKS| Upstream configuration
import_tasks: upstream.yml ansible.builtin.import_tasks: upstream.yml
- name: IMPORT_TASKS| htpasswd configuration - name: IMPORT_TASKS| htpasswd configuration
import_tasks: htpasswd.yml ansible.builtin.import_tasks: htpasswd.yml
- name: IMPORT_TASKS| SSL configuration - name: IMPORT_TASKS| SSL configuration
import_tasks: ssl/main.yml ansible.builtin.import_tasks: ssl/main.yml
tags: ['nginx::ssl'] tags: ['nginx::ssl']
- name: IMPORT_TASKS| Sites configuration - name: IMPORT_TASKS| Sites configuration
import_tasks: site.yml ansible.builtin.import_tasks: site.yml
tags: ['nginx::site'] tags: ['nginx::site']

View File

@@ -1,27 +1,37 @@
--- ---
- name: SHELL | Get Nginx version - name: SHELL | Get Nginx version
shell: nginx -v 2>&1 | sed -r 's#.*/##;' | cut -d ' ' -f 1 ansible.builtin.shell: nginx -v 2>&1 | sed -r 's#.*/##;' | cut -d ' ' -f 1
args: args:
executable: /bin/sh executable: /bin/sh
register: nginx_version register: nginx_version
changed_when: false changed_when: false
check_mode: no check_mode: false
tags:
- skip_ansible_lint
- name: SHELL | Get module list - name: SHELL | Get module list
shell: nginx -V 2>&1 | tr -- - '\n' | grep -A 1 with | grep _module | sed -r 's/_module//g; s/\s+//g' | sort ansible.builtin.shell: |
nginx -V 2>&1 |
tr -- - '\n' |
grep -A 1 with |
grep _module |
sed -r 's/_module//g; s/\s+//g' |
sort
args: args:
executable: /bin/sh executable: /bin/sh
register: shell_modules register: shell_modules
changed_when: false changed_when: false
check_mode: no check_mode: false
tags:
- skip_ansible_lint
- name: SET_FACT | Save modules - name: SET_FACT | Save modules
set_fact: ansible.builtin.set_fact:
nginx_modules: "{{ shell_modules.stdout_lines }}" nginx_modules: "{{ shell_modules.stdout_lines }}"
- name: FILE | Create folders - name: FILE | Create folders
file: ansible.builtin.file:
dest: "{{ item.dir }}" dest: "{{ item.dir }}"
owner: "{{ item.owner }}" owner: "{{ item.owner }}"
mode: "{{ item.mode }}" mode: "{{ item.mode }}"
@@ -29,6 +39,9 @@
loop: "{{ nginx_dirs }}" loop: "{{ nginx_dirs }}"
- name: FILE | Create ansible facts dir - name: FILE | Create ansible facts dir
file: ansible.builtin.file:
path: /etc/ansible/facts.d path: /etc/ansible/facts.d
state: directory state: directory
mode: "0755"
owner: root
group: root

View File

@@ -1,7 +1,7 @@
--- ---
- name: FAIL | Check filenames - name: FAIL | Check filenames
fail: ansible.builtin.fail:
msg: "Forbidden keyword default on site {{ item | nginx_site_name }}" msg: "Forbidden keyword default on site {{ item | nginx_site_name }}"
when: item.filename is defined and item.filename == 'default' when: item.filename is defined and item.filename == 'default'
loop: "{{ nginx_sites }}" loop: "{{ nginx_sites }}"
@@ -9,7 +9,7 @@
label: "{{ item | nginx_site_name }}" label: "{{ item | nginx_site_name }}"
- name: FAIL | Check HTTPS redir and proto - name: FAIL | Check HTTPS redir and proto
fail: ansible.builtin.fail:
msg: "You can't have HTTP proto and HTTPS redirection at the same time" msg: "You can't have HTTP proto and HTTPS redirection at the same time"
when: when:
((item.proto is defined and 'http' in item.proto) or (item.proto is not defined)) and ((item.proto is defined and 'http' in item.proto) or (item.proto is not defined)) and
@@ -19,12 +19,15 @@
label: "{{ item | nginx_site_name }}" label: "{{ item | nginx_site_name }}"
- name: FILE | Create root directory - name: FILE | Create root directory
file: ansible.builtin.file:
path: "{{ nginx_root }}" path: "{{ nginx_root }}"
state: directory state: directory
mode: "0755"
owner: root
group: root
- name: FILE | Create root public folders (foreach nginx_sites) - name: FILE | Create root public folders (foreach nginx_sites)
file: ansible.builtin.file:
path: "{{ nginx_root }}/{{ item | nginx_site_filename }}/public" path: "{{ nginx_root }}/{{ item | nginx_site_filename }}/public"
state: directory state: directory
owner: "{{ item.owner | default(nginx_user) }}" owner: "{{ item.owner | default(nginx_user) }}"
@@ -40,21 +43,37 @@
label: "{{ item | nginx_site_name }}" label: "{{ item | nginx_site_name }}"
- name: TEMPLATE | Create sites - name: TEMPLATE | Create sites
template: ansible.builtin.template:
src: "etc/nginx/sites-available/{{ item.template if item.redirect_to is not defined else '_redirect' }}.j2" src: "etc/nginx/sites-available/{{ item.template if item.redirect_to is not defined else '_redirect' }}.j2"
dest: "{{ nginx_etc_dir }}/sites-available/{{ item | nginx_site_filename }}" dest: "{{ nginx_etc_dir }}/sites-available/{{ item | nginx_site_filename }}"
notify: ['reload nginx', 'restart nginx freebsd'] mode: "0644"
when: item.state is not defined or item.state != 'absent' owner: root
group: root
notify: 'Reload nginx'
when: (item.state is not defined or item.state != 'absent') and item.custom_template is not defined
loop: "{{ nginx_sites }}"
loop_control:
label: "{{ item | nginx_site_name }}"
- name: TEMPLATE | Create sites with preconfigured template
ansible.builtin.template:
src: "{{ item.custom_template }}"
dest: "{{ nginx_etc_dir }}/sites-available/{{ item | nginx_site_filename }}"
mode: "0644"
owner: root
group: root
notify: 'Reload nginx'
when: (item.state is not defined or item.state != 'absent') and item.custom_template is defined
loop: "{{ nginx_sites }}" loop: "{{ nginx_sites }}"
loop_control: loop_control:
label: "{{ item | nginx_site_name }}" label: "{{ item | nginx_site_name }}"
- name: FILE | Delete sites - name: FILE | Delete sites
file: ansible.builtin.file:
path: "{{ nginx_etc_dir }}/{{ item.1 }}/{{ item.0 | nginx_site_filename }}" path: "{{ nginx_etc_dir }}/{{ item.1 }}/{{ item.0 | nginx_site_filename }}"
state: absent state: absent
loop: "{{ nginx_sites | product(dirs) | list }}" loop: "{{ nginx_sites | product(dirs) | list }}"
notify: ['reload nginx', 'restart nginx freebsd'] notify: 'Reload nginx'
when: item.0.state is defined and item.0.state == 'absent' when: item.0.state is defined and item.0.state == 'absent'
vars: vars:
dirs: ['sites-available', 'sites-enabled'] dirs: ['sites-available', 'sites-enabled']
@@ -62,45 +81,45 @@
label: "{{ nginx_etc_dir }}/{{ item.1 }}/{{ item.0 | nginx_site_filename }}" label: "{{ nginx_etc_dir }}/{{ item.1 }}/{{ item.0 | nginx_site_filename }}"
- name: FILE | Enable sites - name: FILE | Enable sites
file: ansible.builtin.file:
src: "{{ nginx_etc_dir }}/sites-available/{{ item | nginx_site_filename }}" src: "{{ nginx_etc_dir }}/sites-available/{{ item | nginx_site_filename }}"
dest: "{{ nginx_etc_dir }}/sites-enabled/{{ item | nginx_site_filename }}" dest: "{{ nginx_etc_dir }}/sites-enabled/{{ item | nginx_site_filename }}"
state: link state: link
loop: "{{ nginx_sites }}" loop: "{{ nginx_sites }}"
notify: ['reload nginx', 'restart nginx freebsd'] notify: 'Reload nginx'
when: > when: >
item.state is not defined or item.state == 'present' item.state is not defined or item.state == 'present'
loop_control: loop_control:
label: "{{ item | nginx_site_name }}" label: "{{ item | nginx_site_name }}"
- name: FILE | Disable sites - name: FILE | Disable sites
file: ansible.builtin.file:
path: "{{ nginx_etc_dir}}/sites-enabled/{{ item | nginx_site_filename }}" path: "{{ nginx_etc_dir }}/sites-enabled/{{ item | nginx_site_filename }}"
state: absent state: absent
loop: "{{ nginx_sites }}" loop: "{{ nginx_sites }}"
notify: ['reload nginx', 'restart nginx freebsd'] notify: 'Reload nginx'
when: item.state is defined and item.state == 'disabled' when: item.state is defined and item.state == 'disabled'
loop_control: loop_control:
label: "{{ item | nginx_site_name }}" label: "{{ item | nginx_site_name }}"
- name: FILE | Delete default site when explicitely defined - name: FILE | Delete default site when explicitely defined
file: ansible.builtin.file:
path: "{{ nginx_etc_dir }}/sites-enabled/default" path: "{{ nginx_etc_dir }}/sites-enabled/default"
state: absent state: absent
notify: ['reload nginx', 'restart nginx freebsd'] notify: 'Reload nginx'
when: nginx_default_site is not none when: nginx_default_site is not none
- name: FILE | Auto set default site - name: FILE | Auto set default site
file: ansible.builtin.file:
src: "{{ nginx_etc_dir }}/sites-available/default" src: "{{ nginx_etc_dir }}/sites-available/default"
dest: "{{ nginx_etc_dir }}/sites-enabled/default" dest: "{{ nginx_etc_dir }}/sites-enabled/default"
state: link state: link
notify: ['reload nginx', 'restart nginx freebsd'] notify: 'Reload nginx'
when: nginx_default_site is none when: nginx_default_site is none
- name: TEMPLATE | Deploy facts - name: TEMPLATE | Deploy facts
template: ansible.builtin.template:
src: etc/ansible/facts.d/nginx.fact.j2 src: etc/ansible/facts.d/nginx.fact.j2
dest: /etc/ansible/facts.d/nginx.fact dest: /etc/ansible/facts.d/nginx.fact
mode: 0644 mode: "0644"
notify: ['setup'] notify: ['Setup']

View File

@@ -1,72 +1,103 @@
--- ---
- name: SET_FACT | Assign default.. - name: SET_FACT | Assign default...
set_fact: ansible.builtin.set_fact:
acme_create: [] acme_create: []
- name: STAT | Check if certificates are already installed - name: STAT | Check if certificates are already installed
stat: ansible.builtin.stat:
path: "{{ nginx_ssl_dir }}/{{ item | nginx_site_name }}/{{ item | nginx_site_name }}.crt" path: "{{ item | nginx_cert_path(nginx_ssl_dir) }}"
loop: "{{ nginx_ssl_pairs }}" loop: "{{ nginx_ssl_pairs }}"
when: item.acme is defined and item.acme when: item.acme is defined and item.acme
register: acme_installed_certs register: acme_installed_certs
- name: SET_FACT | Assign var with certificates to create - name: SET_FACT | Assign var with certificates to create
set_fact: ansible.builtin.set_fact:
acme_create: "{{ acme_create | default([]) + [ (item.item) ] }}" acme_create: "{{ acme_create | default([]) + [item.item] }}"
loop: "{{ acme_installed_certs.results }}" loop: "{{ acme_installed_certs.results }}"
when: item.skipped is not defined and not item.stat.exists when: item.skipped is not defined and (not item.stat.exists or item.stat.size == 0)
- name: TEMPLATE | Create fake site - name: BLOCK | Start acme
template: block:
src: "etc/nginx/conf.d/FAKESITE.conf.j2"
dest: "{{ nginx_etc_dir }}/conf.d/FAKESITE_{{ item | nginx_site_name }}.conf"
loop: "{{ acme_create }}"
register: fake_site
- name: FILE | Delete current site if needed - name: TEMPLATE | Create fake site
file: ansible.builtin.template:
path: "{{ nginx_etc_dir }}/sites-enabled/{{ item | nginx_site_name }}" src: "etc/nginx/conf.d/FAKESITE.conf.j2"
state: absent dest: "{{ nginx_etc_dir }}/conf.d/FAKESITE_{{ item | nginx_site_name }}.conf"
loop: "{{ acme_create }}" mode: "0644"
when: fake_site.changed owner: root
group: root
loop: "{{ acme_create }}"
register: fake_site
notify: Restart nginx
- name: SERVICE | Restart nginx - name: TEMPLATE | Create fake site
service: ansible.builtin.template:
name: nginx src: "etc/nginx/conf.d/FAKESITE.conf.j2"
state: restarted dest: "/tmp/FAKESITE_{{ item | nginx_site_name }}.conf"
when: fake_site.changed and ansible_virtualization_type != 'docker' mode: "0644"
owner: root
group: root
loop: "{{ acme_create }}"
- name: COMMAND | Restart nginx - name: FILE | Delete current site if needed # noqa: no-handler
command: service nginx restart ansible.builtin.file:
args: path: "{{ nginx_etc_dir }}/sites-enabled/{{ item | nginx_site_name }}"
warn: false state: absent
when: fake_site.changed and ansible_virtualization_type == 'docker' loop: "{{ acme_create }}"
when: fake_site.changed
notify: Restart nginx
- name: SHELL | Get certificates - name: META | Ensure nginx is restarted if needed
shell: '{{ nginx_acmesh_bin }} --issue{% if item.name is string %} -d {{ item.name }}{% else %}{% for name in item.name %} -d {{ name }}{% endfor %}{% endif %} --nginx {% if nginx_acmesh_test %}--test{% endif %}' ansible.builtin.meta: flush_handlers
args:
creates: "/root/.acme.sh/{{ item | nginx_site_name }}/{{ item | nginx_site_name }}.key"
loop: "{{ acme_create }}"
register: acme_get
failed_when: acme_get.rc != 0 and acme_get.rc != 2
no_log: not nginx_debug_role
- name: FILE | Create SSL dir per site - name: COMMAND | Get certificates
file: ansible.builtin.command: |
path: "{{ nginx_ssl_dir }}/{{ item | nginx_site_name }}" {{ nginx_acmesh_bin }}
loop: "{{ acme_create }}" --home {{ nginx_acmesh_dir }}
--issue{% for s in nginx_sites | nginx_search_by_ssl_name(item.name) | nginx_all_site_names %} -d {{ s }}{% endfor %}
--nginx
{% if nginx_acmesh_test %}--test --log{% endif %}
args:
creates: "{{ nginx_acmesh_dir }}/{{ item | nginx_site_name }}/fullchain.cer"
loop: "{{ acme_create }}"
register: acme_get
failed_when: acme_get.rc != 0 and acme_get.rc != 2
no_log: "{{ not nginx_debug_role }}"
- name: SHELL | Install certificates - name: FILE | Create SSL dir per site
shell: '{{ nginx_acmesh_bin }} --install-cert -d {{ item | nginx_site_name }} --fullchain-file {{ nginx_ssl_dir }}/{{ item | nginx_site_name }}/{{ item | nginx_site_name }}.crt --key-file {{ nginx_ssl_dir }}/{{ item | nginx_site_name }}/{{ item | nginx_site_name }}.key --reloadcmd "service nginx restart"' ansible.builtin.file:
args: path: "{{ nginx_ssl_dir }}/{{ item | nginx_site_name }}"
creates: "{{ nginx_ssl_dir }}/{{ item | nginx_site_name }}/{{ item | nginx_site_name }}.key" loop: "{{ acme_create }}"
loop: "{{ nginx_ssl_pairs }}"
when: item.acme is defined and item.acme
notify: restart nginx
- name: FILE | Delete fake sites - name: COMMAND | Install certificates
file: ansible.builtin.command: |
path: "{{ nginx_etc_dir }}/conf.d/FAKESITE_{{ item | nginx_site_name }}.conf" {{ nginx_acmesh_bin }}
state: absent --home {{ nginx_acmesh_dir }}
loop: "{{ acme_create }}" --install-cert -d {{ nginx_sites | nginx_search_by_ssl_name(item | nginx_site_name) | nginx_site_name }}
--fullchain-file {{ item | nginx_cert_path(nginx_ssl_dir) }}
--key-file {{ item | nginx_key_path(nginx_ssl_dir) }}
--reloadcmd "service nginx reload"
args:
creates: "{{ item | nginx_cert_path(nginx_ssl_dir) }}"
loop: "{{ nginx_ssl_pairs }}"
when: item.acme is defined and item.acme
notify: Restart nginx
rescue:
- name: FAIL | Explicit
ansible.builtin.fail:
msg: "Something is bad... Auto crash!"
always:
- name: FILE | Delete fake sites
ansible.builtin.file:
path: "{{ nginx_etc_dir }}/conf.d/FAKESITE_{{ item | nginx_site_name }}.conf"
state: absent
loop: "{{ acme_create }}"
notify: Restart nginx
- name: META | Flush handlers
ansible.builtin.meta: flush_handlers

View File

@@ -1,8 +1,8 @@
--- ---
- name: IMPORT_TASKS | standard.yml - name: IMPORT_TASKS | standard.yml
import_tasks: standard.yml ansible.builtin.import_tasks: standard.yml
- name: IMPORT_TASKS | acme.yml - name: IMPORT_TASKS | acme.yml
import_tasks: acme.yml ansible.builtin.import_tasks: acme.yml
when: nginx_acmesh when: nginx_acmesh

View File

@@ -1,67 +1,86 @@
--- ---
- block: - name: Generate DH if needed
- name: STAT | Get info ajout DH file
stat:
path: "{{ nginx_dh_path }}"
get_checksum: no
register: stat_dh_file
- name: SHELL | Get info about DH file
shell: openssl dhparam -in {{ nginx_dh_path }} -text -noout 2>&1 | awk '/DH Parameters/ { print substr($3, 2) }'
changed_when: false
register: dh_info
when: stat_dh_file.stat.exists
- name: COMMAND | Generate DH file
command: openssl dhparam -out {{ nginx_dh_path }} {{ nginx_dh_length }}
when: not stat_dh_file.stat.exists or (dh_info.stdout | int != nginx_dh_length | int)
notify: restart nginx
when: nginx_dh is not string when: nginx_dh is not string
block:
- name: STAT | Get info about DH file
ansible.builtin.stat:
path: "{{ nginx_dh_path }}"
get_checksum: false
register: stat_dh_file
- name: SHELL | Get info about DH file
ansible.builtin.shell: |
set -o pipefail &&
openssl dhparam -in {{ nginx_dh_path }} -text -noout 2>&1 | awk '/DH Parameters/ { print substr($3, 2) }'
args:
executable: /bin/bash
changed_when: false
register: dh_info
when: stat_dh_file.stat.exists
- name: COMMAND | Generate DH file # noqa: no-changed-when
ansible.builtin.command: openssl dhparam -out {{ nginx_dh_path }} {{ nginx_dh_length }}
when: not stat_dh_file.stat.exists or (dh_info.stdout | int != nginx_dh_length | int)
notify: Restart nginx
- name: COPY | Deploy DH file from vars - name: COPY | Deploy DH file from vars
copy: ansible.builtin.copy:
content: "{{ nginx_dh }}" content: "{{ nginx_dh }}"
dest: "{{ nginx_dh_path }}" dest: "{{ nginx_dh_path }}"
owner: root
group: root
mode: "0640"
when: nginx_dh is string when: nginx_dh is string
notify: restart nginx notify: Restart nginx
- name: FILE | Create SSL directories - name: FILE | Create SSL directories
file: ansible.builtin.file:
path: "{{ nginx_ssl_dir + '/' + item | nginx_site_name }}" path: "{{ item | nginx_ssl_dir(nginx_ssl_dir) }}"
state: directory state: directory
owner: root
group: root
mode: "0750"
loop: "{{ nginx_ssl_pairs }}" loop: "{{ nginx_ssl_pairs }}"
when: item.dest_key is not defined or item.dest_cert is not defined when: item.dest_key is not defined or item.dest_cert is not defined
no_log: not nginx_debug_role no_log: "{{ not nginx_debug_role }}"
- name: COPY | Deploy SSL keys - name: COPY | Deploy SSL keys
copy: ansible.builtin.copy:
content: "{{ item.key }}" content: "{{ item.key }}"
dest: "{{ nginx_ssl_dir + '/' + item | nginx_site_name + '/' + item | nginx_site_name + '.key' if item.dest_key is not defined else item.dest_key }}" dest: "{{ item | nginx_key_path(nginx_ssl_dir) }}"
mode: 0640 owner: root
group: root
mode: "0640"
loop: "{{ nginx_ssl_pairs }}" loop: "{{ nginx_ssl_pairs }}"
when: item.key is defined when: item.key is defined
notify: restart nginx notify: Restart nginx
no_log: not nginx_debug_role no_log: "{{ not nginx_debug_role }}"
- name: COPY | Deploy SSL certs - name: COPY | Deploy SSL certs
copy: ansible.builtin.copy:
content: "{{ item.cert }}" content: "{{ item.cert }}"
dest: "{{ nginx_ssl_dir + '/' + item | nginx_site_name + '/' + item | nginx_site_name + '.crt' if item.dest_cert is not defined else item.dest_cert }}" dest: "{{ item | nginx_cert_path(nginx_ssl_dir) }}"
mode: 0644 owner: root
group: root
mode: "0644"
loop: "{{ nginx_ssl_pairs }}" loop: "{{ nginx_ssl_pairs }}"
when: item.cert is defined when: item.cert is defined
notify: restart nginx notify: Restart nginx
no_log: not nginx_debug_role no_log: "{{ not nginx_debug_role }}"
- name: COMMAND | Create self-signed certificates - name: COMMAND | Create self-signed certificates
command: "openssl req -new -newkey rsa:2048 -sha256 -days 3650 -nodes -x509 -subj '/CN={{ item | nginx_site_name }}' -keyout {{ item | nginx_site_name + '.key' }} -out {{ item | nginx_site_name + '.crt' }}" ansible.builtin.command: |
openssl req
-new -newkey rsa:2048 -sha256 -days 3650 -nodes -x509
-subj '/CN={{ item | nginx_site_name }}'
-keyout {{ item | nginx_key_path(nginx_ssl_dir) }}
-out {{ item | nginx_cert_path(nginx_ssl_dir) }}
args: args:
chdir: "{{ nginx_ssl_dir + '/' + item | nginx_site_name }}" chdir: "{{ item | nginx_ssl_dir(nginx_ssl_dir) }}"
creates: "{% if item.force is defined and item.force %}/tmp/dummy{% else %}{{ nginx_ssl_dir + '/' + item | nginx_site_name + '/' + item | nginx_site_name + '.crt' }}{% endif %}" creates: "{{ '/tmp/dummy' if item.force is defined and item.force else item | nginx_cert_path(nginx_ssl_dir) }}"
loop: "{{ nginx_ssl_pairs }}" loop: "{{ nginx_ssl_pairs }}"
when: item.self_signed is defined when: item.self_signed is defined
notify: restart nginx notify: Restart nginx
no_log: not nginx_debug_role no_log: "{{ not nginx_debug_role }}"

View File

@@ -1,30 +1,29 @@
--- ---
- name: TEMPLATE | Deploy PHP upstream to Nginx - name: TEMPLATE | Deploy PHP upstream to Nginx
template: ansible.builtin.template:
src: "etc/nginx/conf.d/php.conf.j2" src: "etc/nginx/conf.d/php.conf.j2"
dest: "{{ nginx_etc_dir }}/conf.d/php.conf" dest: "{{ nginx_etc_dir }}/conf.d/php.conf"
when: nginx_php | length > 0 mode: "0644"
notify: reload nginx owner: root
group: root
- name: FILE | Delete PHP upstream notify: Reload nginx
file:
path: "{{ nginx_etc_dir }}/conf.d/php.conf"
state: absent
when: nginx_php | length == 0
- name: TEMPLATE | Deploy other upstreams - name: TEMPLATE | Deploy other upstreams
template: ansible.builtin.template:
src: "etc/nginx/conf.d/_upstream.conf.j2" src: "etc/nginx/conf.d/_upstream.conf.j2"
dest: "{{ nginx_etc_dir }}/conf.d/upstream-{{ item.name }}.conf" dest: "{{ nginx_etc_dir }}/conf.d/upstream-{{ item.name }}.conf"
mode: "0644"
owner: root
group: root
loop: "{{ nginx_upstreams }}" loop: "{{ nginx_upstreams }}"
when: item.state is not defined or item.state == 'present' when: item.state is not defined or item.state == 'present'
notify: reload nginx notify: Reload nginx
- name: FILE | Delete other upstreams - name: FILE | Delete other upstreams
file: ansible.builtin.file:
path: "{{ nginx_etc_dir }}/conf.d/upstream-{{ item.name }}.conf" path: "{{ nginx_etc_dir }}/conf.d/upstream-{{ item.name }}.conf"
state: absent state: absent
loop: "{{ nginx_upstreams }}" loop: "{{ nginx_upstreams }}"
when: item.state is defined and item.state == 'absent' when: item.state is defined and item.state == 'absent'
notify: reload nginx notify: Reload nginx

View File

@@ -1,8 +1,16 @@
server { {% set site = nginx_sites | nginx_search_by_ssl_name(item.name) %}
listen {{ item.acme_port | default('80') }}; {% set __listen = item.listen | default(nginx_default_listen) %}
listen [::]:{{ item.acme_port | default('80') }}; {% set __listen_proxy_protocol = item.listen_proxy_protocol | default(nginx_default_listen_proxy_protocol) %}
server_name {% if item.name is string %}{{ item.name }}{% else %}{{ item.name | join(" ") }}{% endif %}{% if item.redirect_from is defined %} {% if item.redirect_from is string %}{{ item.redirect_from }}{% else %}{{ item.redirect_from | join(" ") }}{% endif %}{% endif %}; server {
{% for port in __listen %}
listen {{ port }};
{% endfor %}
{% for port in __listen_proxy_protocol %}
listen {{ port }} proxy_protocol;
{% endfor %}
server_name {{ site | nginx_all_site_names | join(" ") }};
location / { location / {
return 503; return 503;

View File

@@ -3,18 +3,27 @@
# #
{% for php in nginx_php %} {% for php in nginx_php %}
upstream {{ php.upstream_name | default((php.version | php_default_upstream_name)) }} { upstream {{ php.upstream_name }} {
{% for sock in php.sockets | default([]) %} {% for sock in php.sockets | default([]) %}
{% if sock.host is defined %} {% if sock.host is defined %}
server {{ sock.host }}:{{ sock.port }} weight={{ sock.weight | default('1') }} max_fails={{ sock.max_fails | default('5') }} fail_timeout={{ sock.fail_timeout | default('10s') }}; server {{ sock.host }}:{{ sock.port }} weight={{ sock.weight | default('1') }} max_fails={{ sock.max_fails | default('5') }} fail_timeout={{ sock.fail_timeout | default('10s') }};
{% else %} {% else %}
server unix:{{ sock.unix | default((php.version | php_default_upstream_socket)) }} weight={{ sock.weight | default('1') }}; server unix:{{ sock.unix }} weight={{ sock.weight | default('1') }};
{% endif %} {% endif %}
{% else %}
server unix:{{ php.version | php_default_upstream_socket }} weight=1;
{% endfor %} {% endfor %}
} }
{% endfor %} {% endfor %}
{% if ansible_local.hanxhx_php.fpm_pool is defined%}
# -------------------------------------------------------
# Auto-detected PHP config for HanXHX.php ansible role
# -------------------------------------------------------
{% for php in ansible_local.hanxhx_php.fpm_pool %}
upstream {{ php.name }} {
server {% if php.listen.startswith('/') %}unix:{{ php.listen }}{% else %}{{ php.listen }}{% endif %};
}
{% endfor %}
{% endif %}
# vim:filetype=nginx # vim:filetype=nginx

View File

@@ -1,17 +1,23 @@
# #
# {{ ansible_managed }} # {{ ansible_managed }}
# # See: https://ssl-config.mozilla.org/#server=nginx&version=1.18.0&config=intermediate&openssl=1.1.1n&hsts=false&guideline=5.7
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA128:DHE-RSA-AES128-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA128:ECDHE-RSA-AES128-SHA384:ECDHE-RSA-AES128-SHA128:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA384:AES128-GCM-SHA128:AES128-SHA128:AES128-SHA128:AES128-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; ssl_session_timeout 1d;
ssl_protocols TLSv1.1 TLSv1.2{% if nginx_version.stdout is version('1.13.0', 'ge') %} TLSv1.3{% endif %}; ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
resolver {{ nginx_resolver_hosts | join(' ') }} valid={{ nginx_resolver_valid }};
resolver_timeout {{ nginx_resolver_timeout }};
ssl_dhparam {{ nginx_dh_path }}; ssl_dhparam {{ nginx_dh_path }};
# intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# Replace with the IP address of your resolver
resolver {{ nginx_resolver_hosts | join(' ') }} valid={{ nginx_resolver_valid }};
# vim:filetype=nginx # vim:filetype=nginx

View File

@@ -1,19 +1,21 @@
# #
# {{ ansible_managed }} # {{ ansible_managed }}
# # See: https://ssl-config.mozilla.org/#server=nginx&version=1.18.0&config=modern&openssl=1.1.1n&hsts=false&guideline=5.7
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384"; ssl_session_timeout 1d;
ssl_protocols TLSv1.2{% if nginx_version.stdout is version('1.13.0', 'ge') %} TLSv1.3{% endif %}; ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_prefer_server_ciphers on;
ssl_ecdh_curve secp384r1;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; ssl_session_tickets off;
# modern configuration
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
# OCSP stapling
ssl_stapling on; ssl_stapling on;
ssl_stapling_verify on; ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
# Replace with the IP address of your resolver
resolver {{ nginx_resolver_hosts | join(' ') }} valid={{ nginx_resolver_valid }}; resolver {{ nginx_resolver_hosts | join(' ') }} valid={{ nginx_resolver_valid }};
resolver_timeout {{ nginx_resolver_timeout }}; resolver_timeout {{ nginx_resolver_timeout }};
ssl_dhparam {{ nginx_dh_path }};
# vim:filetype=nginx # vim:filetype=nginx

View File

@@ -5,6 +5,9 @@
user {{ nginx_user }}; user {{ nginx_user }};
worker_processes {{ nginx_worker_processes }}; worker_processes {{ nginx_worker_processes }};
pid {{ nginx_pid }}; pid {{ nginx_pid }};
{% for i in nginx_custom_core %}
{{ i }}
{% endfor %}
include {{ nginx_etc_dir }}/modules-enabled/*.conf; include {{ nginx_etc_dir }}/modules-enabled/*.conf;
events { events {

View File

@@ -1,33 +0,0 @@
{% extends "_base.j2" %}
{% block root %}
root /usr/share/backuppc/cgi-bin;
{% endblock %}
{% block template_try_files %}
{% endblock %}
{% block template_index %}
index index.cgi;
{% endblock %}
{% block template_local_content %}
location ~ /\.ht {
deny all;
}
location /backuppc/image {
alias /usr/share/backuppc/image;
expires 60d;
}
{% endblock %}
{% block template_upstream_location %}
location ~ \.cgi$ {
gzip off;
include fastcgi.conf;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
fastcgi_index BackupPC_Admin;
fastcgi_param SCRIPT_FILENAME /usr/share/backuppc/cgi-bin$fastcgi_script_name;
}
{% endblock %}

View File

@@ -1,15 +1,21 @@
{% set __proto = item.proto | default(['http']) %} {% set __proto = item.proto | default(['http']) %}
{% set __main_name = item | nginx_site_filename %} {% set __main_name = item | nginx_site_name %}
{% set __listen = item.listen | default(['80', '[::]:80']) %} {% set __listen = item.listen | default(nginx_default_listen) %}
{% set __listen_ssl = item.listen_ssl | default(['443', '[::]:443']) %} {% set __listen_ssl = item.listen_ssl | default(nginx_default_listen_ssl) %}
{% set __http_proxy_protocol_port = item.http_proxy_protocol_port | default([]) %} {% set __listen_proxy_protocol = item.listen_proxy_protocol | default(nginx_default_listen_proxy_protocol) %}
{% set __https_proxy_protocol_port = item.https_proxy_protocol_port | default([]) %} {% set __listen_proxy_protocol_ssl = item.listen_proxy_protocol_ssl | default(nginx_default_listen_proxy_protocol_ssl) %}
{% set __location = item.location | default({}) %} {% set __location = item.location | default({}) %}
{% set __location_before = item.location_before | default({}) %} {% set __location_before = item.location_before | default({}) %}
{% set __headers = item.headers | default(nginx_servers_default_headers) %} {% set __headers = item.headers | default(nginx_servers_default_headers) %}
{% set __ssl_name = item.ssl_name | default(item.name if item.name is string else item.name[0]) %} {% set __ssl_name = item.ssl_name | default(__main_name) %}
{% set __location_order = item.location_order | default(__location.keys()) %} {% set __location_order = item.location_order | default(__location.keys()) %}
{% set __location_order_before = item.location_order_before | default(__location_before.keys()) %} {% set __location_order_before = item.location_order_before | default(__location_before.keys()) %}
{% set __http2 = nginx_auto_config_httpv2 and 'http_v2' in nginx_modules %}
{% macro listen_http() %}
{% endmacro %}
{% macro server_name(name) %}
{% if name is string %}{{ name }}{% else %}{{ name | join(" ") }}{% endif %}
{% endmacro %}
{% macro locations(list, order) %} {% macro locations(list, order) %}
{% if order | length > 0 %} {% if order | length > 0 %}
# --> Custom locations # --> Custom locations
@@ -37,17 +43,20 @@
{%- endif %} {%- endif %}
{%- endmacro %} {%- endmacro %}
{% macro ssl(ssl_name) %} {% macro ssl(ssl_name) %}
{% for sn in nginx_ssl_pairs if ((sn.name is string and sn.name == ssl_name) or (sn.name.0 == ssl_name)) %} {% for sn in nginx_ssl_pairs if (sn.name is defined and (sn | nginx_site_name) == ssl_name) %}
ssl_certificate {{ nginx_ssl_dir + '/' + ssl_name + '/' + ssl_name + '.crt' if sn.dest_cert is not defined else sn.dest_cert }}; ssl_certificate {{ sn | nginx_cert_path(nginx_ssl_dir) }};
ssl_certificate_key {{ nginx_ssl_dir + '/' + ssl_name + '/' + ssl_name + '.key' if sn.dest_key is not defined else sn.dest_key }}; ssl_certificate_key {{ sn | nginx_key_path(nginx_ssl_dir) }};
{% endfor %} {% endfor %}
{%- endmacro %} {%- endmacro %}
{% macro httpsredirect(name) %} {% macro httpsredirect(name) %}
server { server {
{% for port in __listen %} {% for port in __listen %}
listen {{ port }}{% if port | int in __http_proxy_protocol_port %} proxy_protocol{% endif %}; listen {{ port }};
{% endfor %} {% endfor %}
server_name {{ name }}; {% for port in __listen_proxy_protocol %}
listen {{ port }} proxy_protocol;
{% endfor %}
server_name {{ server_name(name) }};
location / { location / {
return 301 https://{{ name }}{% if '443' not in __listen_ssl and 443 not in __listen_ssl %}:{{ __listen_ssl[0] }}{% endif %}$request_uri; return 301 https://{{ name }}{% if '443' not in __listen_ssl and 443 not in __listen_ssl %}:{{ __listen_ssl[0] }}{% endif %}$request_uri;
} }
@@ -64,24 +73,31 @@ server {
server { server {
{% if 'http' in __proto %} {% if 'http' in __proto %}
{% for port in __listen %} {% for port in __listen %}
listen {{ port }}{% if nginx_default_site == __main_name %} default_server{% endif %}{% if port | int in __http_proxy_protocol_port %} proxy_protocol{% endif %}; listen {{ port }}{% if nginx_default_site == __main_name %} default_server{% endif %};
{% endfor %}
{% for port in __listen_proxy_protocol %}
listen {{ port }}{% if nginx_default_site == __main_name %} default_server{% endif %} proxy_protocol;
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if 'https' in __proto %} {% if 'https' in __proto %}
{% for port in __listen_ssl %} {% for port in __listen_ssl %}
listen {{ port }}{% if nginx_default_site_ssl == __main_name %} default_server{% endif %} ssl{% if nginx_auto_config_httpv2 and 'http_v2' in nginx_modules %} http2{% endif %}{% if port | int in __https_proxy_protocol_port %} proxy_protocol{% endif %}; listen {{ port }}{% if nginx_default_site_ssl == __main_name %} default_server{% endif %} ssl{% if __http2 %} http2{% endif %};
{% endfor %}
{% for port in __listen_proxy_protocol_ssl %}
listen {{ port }}{% if nginx_default_site_ssl == __main_name %} default_server{% endif %} ssl{% if __http2 %} http2{% endif %} proxy_protocol;
{% endfor %} {% endfor %}
{{ ssl(__ssl_name) }} {{ ssl(__ssl_name) }}
{% if item.ssl_template is not defined or item.ssl_template != false %} {% if item.ssl_template is not defined or item.ssl_template != false %}
include {{ nginx_helper_dir + '/ssl-' + item.ssl_template | default('strong') }}; include {{ nginx_helper_dir + '/ssl-' + item.ssl_template | default('strong') }};
add_header Strict-Transport-Security "{{ item.hsts | default(nginx_default_hsts) }}" always;
{% endif %} {% endif %}
{% endif %} {% endif %}
server_name {% if item.name is string %}{{ item.name }}{% else %}{{ "\n\t\t" }}{{ item.name | join("\n\t\t") }}{% endif %}; server_name {{ server_name(item.name) }};
{% block root %} {% block root %}
{% if item.root is defined %} {% if item.root is defined %}
root {{ item.root }}; root {{ item.root }};
{% else %} {% else %}
root {{ nginx_root }}/{{ __main_name }}/public; root {{ nginx_root }}/{{ item | nginx_site_filename }}/public;
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block template_index %} {% block template_index %}
@@ -102,15 +118,15 @@ server {
{% block template_headers %} {% block template_headers %}
# --> Custom headers # --> Custom headers
{% for key, value in __headers.iteritems() %} {% for key, value in __headers.items() %}
add_header {{ key }} "{{ value }}"; add_header {{ key }} "{{ value | regex_replace('\s+always$', '') }}"{% if value | regex_search('\s+always$') %} always{% endif %};
{% endfor %} {% endfor %}
# <-- Custom headers # <-- Custom headers
{% endblock %} {% endblock %}
{{ locations(__location_before, __location_order_before) }} {{ locations(__location_before, __location_order_before) }}
{% if not __location.has_key('/') %} {% if not '/' in __location %}
location / { location / {
{% block template_try_files %} {% block template_try_files %}
try_files {{ item.override_try_files | default('$uri $uri/ =404') }}; try_files {{ item.override_try_files | default('$uri $uri/ =404') }};
@@ -137,7 +153,7 @@ server {
log_not_found off; log_not_found off;
} }
location ~* \.(txt|js|css|png|jpe?g|gif|ico|svg)$ { location ~* \.(txt|js|css|png|jpe?g|gif|ico|svg|(o|t)tf|woff2?|eot)$ {
expires 30d; expires 30d;
log_not_found off; log_not_found off;
} }
@@ -179,26 +195,34 @@ server {
# #
server { server {
{% for port in __listen %} {% for port in __listen %}
listen {{ port }}{% if port | int in __http_proxy_protocol_port %} proxy_protocol{% endif %}; listen {{ port }};
{% endfor %} {% endfor %}
server_name {% if item.redirect_from is string %}{{ item.redirect_from }}{% else %}{{ "\n\t\t" }}{{ item.redirect_from | join("\n\t\t") }}{% endif %}; {% for port in __listen_proxy_protocol %}
listen {{ port }} proxy_protocol;
{% endfor %}
server_name {{ server_name(item.redirect_from) }};
location / { location / {
return 301 $scheme://{{ item.name if item.name is string else item.name[0] }}$request_uri; return 301 $scheme://{{ __main_name }}$request_uri;
} }
} }
{% if 'https' in __proto %} {% if 'https' in __proto %}
server { server {
{% for port in __listen_ssl %} {% for port in __listen_ssl %}
listen {{ port }}{% if nginx_default_site_ssl == __main_name %} default_server{% endif %} ssl{% if nginx_auto_config_httpv2 and 'http_v2' in nginx_modules %} http2{% endif %}{% if port | int in __https_proxy_protocol_port %} proxy_protocol{% endif %}; listen {{ port }} ssl{% if __http2 %} http2{% endif %};
{% endfor %}
{% for port in __listen_proxy_protocol_ssl %}
listen {{ port }} ssl{% if __http2 %} http2{% endif %} proxy_protocol;
{% endfor %} {% endfor %}
{{ ssl(__ssl_name) }} {{ ssl(__ssl_name) }}
{% if item.ssl_template is not defined or item.ssl_template != false %} {% if item.ssl_template is not defined or item.ssl_template != false %}
include {{ nginx_helper_dir + '/ssl-' + item.ssl_template | default('strong') }}; include {{ nginx_helper_dir + '/ssl-' + item.ssl_template | default('strong') }};
add_header Strict-Transport-Security "{{ item.hsts | default(nginx_default_hsts) }}" always;
{% endif %} {% endif %}
server_name {% if item.redirect_from is string %}{{ item.redirect_from }}{% else %}{{ "\n\t\t" }}{{ item.redirect_from | join("\n\t\t") }}{% endif %}; server_name {{ server_name(item.redirect_from) }};
location / { location / {
return 301 https://{{ item.name if item.name is string else item.name[0] }}{% if '443' not in __listen_ssl and 443 not in __listen_ssl %}:{{ __listen_ssl[0] }}{% endif %}$request_uri; return 301 https://{{ __main_name }}{% if '443' not in __listen_ssl and 443 not in __listen_ssl %}:{{ __listen_ssl[0] }}{% endif %}$request_uri;
} }
} }
{% endif %} {% endif %}

View File

@@ -1,16 +1,5 @@
{% extends "_base.j2" %} {% extends "_base.j2" %}
{% if item.php_version is defined %}
{% set php_info = 'Explicit PHP version on site' %}
{% set php_upstream = (nginx_php|selectattr('version', 'equalto', item.php_version)|first).upstream_name | default(item.php_version | php_default_upstream_name) %}
{% elif item.php_upstream is defined %}
{% set php_info = 'Explicit Nginx/PHP upstream on site' %}
{% set php_upstream = item.php_upstream %}
{% else %}
{% set php_info = 'Warning: using first PHP version on config' %}
{% set php_upstream = nginx_php.0.upstream_name | default(nginx_php.0.version | php_default_upstream_name) %}
{% endif %}
{% block template_index %} {% block template_index %}
index {{ item.index | default('index.html index.htm index.php') }}; index {{ item.index | default('index.html index.htm index.php') }};
{% endblock %} {% endblock %}
@@ -21,8 +10,7 @@
{% block template_upstream_location %} {% block template_upstream_location %}
location ~ \.php$ { location ~ \.php$ {
# {{ php_info }} fastcgi_pass {{ item.php_upstream }};
fastcgi_pass {{ php_upstream }};
fastcgi_index index.php; fastcgi_index index.php;
{% if item.upstream_params is defined and item.upstream_params is iterable %} {% if item.upstream_params is defined and item.upstream_params is iterable %}
{% for param in item.upstream_params %} {% for param in item.upstream_params %}

View File

@@ -2,8 +2,7 @@
{% block template_upstream_location %} {% block template_upstream_location %}
location = /index.php { location = /index.php {
# {{ php_info }} fastcgi_pass {{ item.php_upstream }};
fastcgi_pass {{ php_upstream }};
fastcgi_index index.php; fastcgi_index index.php;
{% if item.upstream_params is defined and item.upstream_params is iterable %} {% if item.upstream_params is defined and item.upstream_params is iterable %}
{% for param in item.upstream_params %} {% for param in item.upstream_params %}

View File

@@ -6,8 +6,7 @@
{% block template_upstream_location %} {% block template_upstream_location %}
location = /index.php { location = /index.php {
# {{ php_info }} fastcgi_pass {{ item.php_upstream }};
fastcgi_pass {{ php_upstream }};
fastcgi_index index.php; fastcgi_index index.php;
{% if item.upstream_params is defined and item.upstream_params is iterable %} {% if item.upstream_params is defined and item.upstream_params is iterable %}
{% for param in item.upstream_params %} {% for param in item.upstream_params %}

View File

@@ -0,0 +1,27 @@
{% extends "_php.j2" %}
{% block template_try_files %}
try_files $uri /index.php$is_args$args;
{% endblock %}
{% block template_upstream_location %}
location /bundles {
try_files $uri =404;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass {{ item.php_upstream }};
fastcgi_index index.php;
{% if item.upstream_params is defined and item.upstream_params is iterable %}
{% for param in item.upstream_params %}
{{ param }}
{% endfor %}
{% endif %}
include fastcgi.conf;
internal;
}
location ~ \.php$ {
return 404;
}
{% endblock %}

View File

@@ -1,15 +0,0 @@
---
- name: APT | Install webapps
apt:
pkg: "{{ packages }}"
state: present
install_recommends: no
vars:
packages:
- backuppc
- name: SERVICE | Ensure backuppc is started
service:
name: backuppc
state: started

View File

@@ -1,23 +0,0 @@
---
#- name: APT | Install web apps
# pkgng:
# name: "backuppc"
# state: present
#
#- name: COMMAND | Activate backuppc config
# command: >
# cp /usr/local/etc/backuppc/config.pl.sample /usr/local/etc/backuppc/config.pl
# creates=/usr/local/etc/backuppc/config.pl
#
#- name: FILE | Fix backuppc permissions
# file:
# path: /usr/local/etc/backuppc/config.pl
# owner: backuppc
# group: backuppc
#
#
# We don't manage BackupPC on FreeBSD... too dirty. :/
#
#- name: SERVICE | Ensure backuppc is started
# service: name=backuppc state=started enabled=yes

View File

@@ -1,80 +0,0 @@
---
- name: APT_REPOSITORY | Install backports
apt_repository:
repo: 'deb http://httpredir.debian.org/debian {{ ansible_distribution_release }}-backports main'
state: present
when: nginx_backports
- block:
- name: APT | Install apt-transport-https
apt:
pkg: apt-transport-https
update_cache: yes
cache_valid_time: 3600
- name: APT_KEY | Install GPG key
apt_key:
url: 'https://packages.sury.org/php/apt.gpg'
- name: APT_REPOSITORY | Add APT repository
apt_repository:
repo: 'deb https://packages.sury.org/php {{ ansible_distribution_release }} main'
when: sury | default(false)
- name: APT | Install needed packages
apt:
pkg: "{{ packages }}"
update_cache: yes
cache_valid_time: 3600
state: present
vars:
packages:
- cron
- curl
- daemonize
- fcgiwrap
- jq
- nghttp2
- strace
- vim
- unzip
- name: APT | Install PHP
apt:
pkg: "{{ item.version | php_fpm_package }}"
update_cache: yes
cache_valid_time: 3600
state: present
loop: "{{ nginx_php }}"
register: apt_php
- name: SERVICE | Force start fcgiwrap
service:
name: "fcgiwrap"
state: started
# Bypasses Ansible+Docker issue. With service module... php is not really started!
- name: COMMAND | Force start PHP
command: "service {{ item.version | php_fpm_service }} start"
args:
creates: "{{ item.version | php_default_upstream_socket }}"
warn: false
loop: "{{ nginx_php }}"
- name: GET_URL | Download ngrok
get_url:
url: "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip"
dest: "/tmp/ngrok.zip"
- name: UNARCHIVE | Uncompress ngrok
unarchive:
src: "/tmp/ngrok.zip"
dest: "/tmp"
remote_src: yes
- name: SET_FACT | ngrok_path
set_fact:
ngrok_path: '/tmp/ngrok'

View File

@@ -1,66 +0,0 @@
---
- name: SET_FACT | FreeBSD web user
set_fact:
nginx_pkgng_package: 'nginx-full'
nginx_user: 'www'
nginx_php:
- version: '7.2'
sockets:
- host: '127.0.0.1'
port: 9000
nginx_load_modules:
- /usr/local/libexec/nginx/ngx_http_geoip_module.so
ngrok_path: '/usr/local/bin/ngrok'
- name: PKGNG | Install needed packages
pkgng:
pkg: "{{ packages }}"
state: present
vars:
packages:
- curl
- daemonize
- fcgiwrap
- GeoIP
- jq
- nghttp2
- php72
- vim
- name: COMMAND | Get geoip database
command: geoipupdate.sh
args:
creates: /usr/local/share/GeoIP/GeoIP.dat
- name: SERVICE | Force start services
service:
name: "{{ item }}"
state: started
enabled: yes
register: sf
loop:
- php-fpm
- fcgiwrap
- name: STAT | Check ports
stat:
path: /usr/ports
register: ports
- block:
- name: COMMAND | Get ports
command: portsnap fetch --interactive
- name: COMMAND | Extract ports
command: portsnap extract
no_log: true
when: not ports.stat.exists
- name: SHELL | Install ngrok
shell: make install clean DISABLE_LICENSES=yes
args:
chdir: /usr/ports/security/ngrok
creates: "{{ ngrok_path }}"

View File

@@ -1,29 +0,0 @@
---
- name: SHELL | Start ngrok
shell: daemonize -l /tmp/ngrok.lock {{ ngrok_path }} http 8888 -bind-tls=false
failed_when: false
changed_when: ngrok.stderr.find("Can't lock the lock file") == -1
register: ngrok
- name: WAIT_FOR | ngrok started
wait_for:
delay: 2
port: 4040
when: ngrok.changed
- name: SHELL | Get ngrok public address
shell: curl 'http://127.0.0.1:4040/api/tunnels/command_line' | jq '.public_url' | grep -oE '[[:alnum:]]+\.ngrok\.io'
args:
warn: false
register: ngrok
changed_when: false
- name: LINEINFILE | Tune vimrc
lineinfile:
line: "set mouse="
dest: "{{ item }}/.vimrc"
create: yes
loop:
- /root
- /home/vagrant

View File

@@ -1,512 +0,0 @@
---
- hosts: all
pre_tasks:
- name: INCLUDE_TASKS | Pre_tasks related to OS version
include_tasks: "includes/pre_{{ ansible_distribution }}.yml"
- name: IMPORT_TASKS | Pre_tasks common
import_tasks: "includes/pre_common.yml"
- name: FILE | Create an internal SSL dir
file:
path: "{{ int_ansible_ssl_dir }}"
state: directory
- name: COPY | Deploy test certificate
copy:
src: "file/test.crt"
dest: "{{ int_ansible_ssl_dir }}/test.crt"
- name: COPY | Deploy test key
copy:
src: "file/test.key"
dest: "{{ int_ansible_ssl_dir }}/test.key"
- name: LINEINFILE | Add all hosts in /etc/hosts
lineinfile:
line: "127.0.0.1\tlocalhost {% for s in nginx_sites %}{% if s.name is string %}{{ s.name }}{% else %}{% for n in s.name %}{{ n }} {% endfor %}{% endif %} {% if s.redirect_from is defined %}{% for rf in s.redirect_from %}{{ rf }} {% endfor %}{% endif %}{% endfor %}"
regexp: '^127\.0\.0\.1'
dest: "/etc/hosts"
unsafe_writes: yes
vars:
# Internal vars
int_ansible_ssl_dir: '/etc/ansible-ssl'
# Role vars
nginx_worker_processes: 1 # Ansible+FreeBSD can't detect CPU number
nginx_apt_package: 'nginx-extras'
nginx_module_packages: ['libnginx-mod-http-headers-more-filter']
nginx_upstreams:
- name: 'test'
servers:
- path: '127.0.0.1:80'
max_conns: 150
weight: 10
down: false
- name: 'test-absent'
servers:
- path: '127.0.0.1:80'
max_conns: 150
weight: 10
down: false
state: 'absent'
nginx_htpasswd:
- name: 'hello'
description: 'Please login!'
users:
- name: 'hx'
password: 'asdfg'
state: 'absent'
- name: 'hanx'
password: 'qwerty'
- name: 'deleteme'
description: 'Please login!'
users: []
state: 'absent'
nginx_acmesh: true
nginx_acmesh_test: true
nginx_ssl_pairs:
- name:
- '{{ ngrok.stdout }}'
acme: true
acme_port: 8888
- name: 'test-ssl-selfsigned.local'
self_signed: true
force: false
- name: 'test-ssl-predeployed.local'
dest_key: "{{ int_ansible_ssl_dir }}/test.key"
dest_cert: "{{ int_ansible_ssl_dir }}/test.crt"
- 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:
- 'add_header X-ansible 1;'
- 'geoip_country {% if ansible_distribution == "Debian" %}/usr/share/GeoIP/GeoIP.dat{% else %}/usr/local/share/GeoIP/GeoIP.dat{% endif %};'
- 'map $geoip_country_code $allowed_country {'
- ' default yes;'
- ' MA no;'
- ' DZ no;'
- ' TN no;'
- '}'
nginx_default_site: 'first-test'
nginx_default_site_ssl: 'test-ssl-predeployed.local'
nginx_sites:
- name:
- 'test.local'
- 'test-alias.local'
- 'test2-alias.local'
template: '_base'
filename : 'first-test'
override_try_files: '$uri $uri /index.htm /index.html'
headers:
'X-Frame-Options': 'deny always'
'X-ansible-default': '1'
manage_local_content: false
use_error_log: true
more:
- 'autoindex off;'
location:
'/test':
- 'return 403;'
'/gunther':
- 'return 404;'
'/status':
- 'stub_status on;'
- 'access_log off;'
- 'allow 127.0.0.1;'
- 'deny all;'
- name: 'test-htpasswd.local'
template: '_base'
location_before:
'/hello':
- htpasswd: 'hello'
location:
'/public':
- htpasswd: false
use_error_log: true
- name: 'test-htpasswd-all.local'
template: '_base'
htpasswd: 'hello'
- name: 'test-location.local'
template: '_base'
location_before:
'/b':
- 'alias /var/tmp;'
'/c':
- 'alias /var/tmp;'
location:
'/':
- 'alias /var/tmp;'
'/a':
- 'alias /var/tmp;'
location_order_before:
- '/b'
- '/c'
location_order:
- '/'
- '/a'
- name: 'test-php.local'
php_version: "{{ nginx_php.1.version if nginx_php.1 is defined else nginx_php.0.version }}"
upstream_params:
- 'fastcgi_param FOO bar;'
redirect_from:
- 'www.test-php.local'
template: '_php'
use_error_log: true
use_access_log: true
- name: 'test-php-index.local'
template: '_php_index'
- name: 'test-php-index2.local'
template: '_php_index2'
- name: 'test-proxy.local'
listen:
- 8080
template: '_proxy'
upstream_name: 'test'
headers:
'X-proxyfied': '1'
- name: 'deleted.local'
state: 'absent'
- name: 'redirect-to.local'
redirect_to: 'http://test.local'
- name: 'backuppc.local'
template: '_backuppc'
htpasswd: 'hello'
- name: 'test-ssl.local'
proto: ['http', 'https']
template: '_base'
- name: 'test-ssl-selfsigned.local'
proto: ['http', 'https']
template: '_base'
- name: 'test-ssl-predeployed.local'
proto: ['http', 'https']
template: '_base'
ssl_name: 'test-ssl-predeployed.local'
headers:
'X-ansible-default': '1'
ssl_template: false
- name: 'test-ssl-redirect.local'
proto: ['https']
template: '_base'
ssl_name: 'test-ssl.local'
redirect_https: true
- name:
- 'test-ssl-redirect-many.local'
- 'test-ssl-redirect-many2.local'
listen_ssl: [8443]
proto: ['https']
template: '_base'
ssl_name: 'test-ssl.local'
redirect_https: true
redirect_from:
- 'www.test-ssl-redirect-many.local'
- 'www.test-ssl-redirect-many2.local'
- name: 'test-ssl-proxy-protocol.local'
proto: ['http', 'https']
listen: [80, 20080]
listen_ssl: [443, 20443]
http_proxy_protocol_port: [20080]
https_proxy_protocol_port: [20443]
template: '_base'
ssl_name: 'test-ssl.local'
- name: '{{ ngrok.stdout }}'
proto: ['http', 'https']
template: '_base'
ssl_name: '{{ ngrok.stdout }}'
headers:
'X-acme': '1'
nginx_dh_length: 1024
roles:
- ../../
post_tasks:
# --------------------------------
# Apps
# --------------------------------
- name: INCLUDE_TASKS | Post_tasks related to OS version
include_tasks: "includes/post_{{ ansible_distribution }}.yml"
# --------------------------------
# Deploy index files
# --------------------------------
- name: -- Add PHP file --
copy:
dest: "{{ nginx_root }}/{{ item }}/public/index.php"
content: "<?php phpinfo();"
loop:
- 'test-php.local'
- 'test-php-index.local'
- 'test-php-index2.local'
- name: -- Add HTML file --
copy:
dest: "{{ item }}/index.html"
content: "Index HTML test OK\n"
loop:
- '{{ nginx_root }}/first-test/public'
- '/var/tmp'
- '{{ nginx_root }}/test-htpasswd-all.local/public'
- '{{ nginx_root }}/test-ssl.local/public'
- '{{ nginx_root }}/test-ssl-selfsigned.local/public'
- '{{ nginx_root }}/test-ssl-predeployed.local/public'
- '{{ nginx_root }}/test-ssl-proxy-protocol.local/public'
- '{{ nginx_root }}/{{ ngrok.stdout }}/public'
- name: -- Create directory --
file:
path: "{{ nginx_root }}/test-htpasswd.local/public/hello"
state: directory
- name: -- Add HTML file hello --
copy:
dest: "{{ nginx_root }}/test-htpasswd.local/public/hello/index.html"
content: "hello\n"
# --------------------------------
# Test custom facts
# --------------------------------
- name: -- CHECK FACTS --
assert:
that: "'{{ ansible_local.nginx.fact_nginx_sites[0].name[0] }}' == 'test.local'"
# --------------------------------
# Simple sites tests
# --------------------------------
- name: -- VERIFY SITES --
uri:
url: "http://{{ item | nginx_site_name }}{% if item.listen is defined %}:{{ item.listen[0] }}{% endif %}/"
status_code: '200,301,302,401,403'
follow_redirects: none
loop: "{{ nginx_sites }}"
when: item.state is undefined or item.state != "absent"
changed_when: false
- name: -- VERIFY FORBIDDEN --
uri:
url: "http://test-php-index.local/phpinfo.php"
status_code: 403
- name: -- VERIFY REDIRECT SITES --
uri:
url: "http://{{ item.redirect_from[0] }}/"
status_code: 301
follow_redirects: none
loop: "{{ nginx_sites }}"
when: item.redirect_from is defined and (item.state is undefined or item.state != "absent") and (item.proto is not defined or 'https' not in item.proto)
changed_when: false
- name: -- VERIFY REDIRECT HTTPS SITES --
uri:
url: "https://{{ item.redirect_from[0] }}:{{ item.listen_ssl[0] | default(443) }}/"
status_code: 301
follow_redirects: none
validate_certs: no
loop: "{{ nginx_sites }}"
when: item.redirect_from is defined and (item.state is undefined or item.state != "absent") and item.proto is defined and 'https' in item.proto
changed_when: false
# --------------------------------
# PHP
# --------------------------------
- name: -- VERIFY PHP SITES --
uri:
url: "http://{{ item.name}}/"
return_content: yes
register: p
loop: "{{ nginx_sites }}"
when: >
item.template is defined and
(item.template == '_php' or item.template == '_php_index' or item.template == '_php_index2')
failed_when: p.content.find('PHP Version ' + item.php_version if 'php_version' in item else nginx_php.0.version) == -1
- name: -- VERIFY INDEX2 --
uri:
url: "http://test-php-index2.local/lorem.php?ipsum=sit&dolor=amet"
return_content: yes
register: p2
failed_when: p2.content.find('PHP Version') == -1
# --------------------------------
# Basic Auth
# --------------------------------
- name: -- VERIFY AUTH BASIC NONE --
uri:
url: "http://test-htpasswd.local/hello/"
status_code: 401
- name: -- VERIFY AUTH BASIC FAIL --
uri:
url: "http://test-htpasswd.local/hello/"
status_code: 401
user: "fail"
password: "fail"
force_basic_auth: yes
- name: -- VERIFY AUTH BASIC OK --
uri:
url: "http://test-htpasswd.local/hello/"
user: "hanx"
password: "qwerty"
force_basic_auth: yes
- name: -- VERIFY AUTH BASIC FAIL GLOBAL --
uri:
url: "http://test-htpasswd-all.local/"
status_code: 401
user: "fail"
password: "fail"
force_basic_auth: yes
- name: -- VERIFY AUTH BASIC OK GLOBAL --
uri:
url: "http://test-htpasswd-all.local/"
user: "hanx"
password: "qwerty"
force_basic_auth: yes
# --------------------------------
# BackupPC
# --------------------------------
- name: -- VERIFY BACKUPPC --
uri:
url: "http://backuppc.local/"
user: "hanx"
password: "qwerty"
force_basic_auth: yes
return_content: yes
register: authbpc
when: ansible_distribution != 'FreeBSD'
failed_when: authbpc.content.find('BackupPC Server Status') == -1
# --------------------------------
# SSL
# --------------------------------
- name: -- VERIFY SSL --
uri:
url: "https://{{ item }}/"
return_content: yes
validate_certs: no
register: sslok
failed_when: sslok.content.find('Index HTML test OK') == -1
loop:
- 'test-ssl-predeployed.local'
- 'test-ssl-selfsigned.local'
- 'test-ssl.local'
- '{{ ngrok.stdout }}'
- name: -- VERIFY SSL REDIRECT --
uri:
url: "http://{{ item.name }}/"
validate_certs: no
status_code: 301
return_content: yes
follow_redirects: none
register: sslredirok
failed_when: '"https://%s%s" % (item.name, ":" + item.port if item.port is defined else "") not in sslredirok.location'
loop:
- name: 'test-ssl-redirect.local'
- name: 'test-ssl-redirect-many.local'
port: '8443'
- name: 'test-ssl-redirect-many2.local'
port: '8443'
# --------------------------------
# Default sites
# --------------------------------
- name: -- VERIFY DEFAULT SITE --
uri:
url: 'http://127.0.0.1/'
return_content: yes
register: vdefault
failed_when: >
vdefault.content.find('Index HTML test OK') == -1 or
vdefault.x_ansible_default is not defined
- name: -- VERIFY DEFAULT SITE + STUB STATUS--
uri:
url: 'http://127.0.0.1/status'
return_content: yes
register: vdefault_status
failed_when: >
vdefault_status.content.find('Active connections') == -1 or
vdefault_status.x_ansible_default is not defined
- name: -- VERIFY DEFAULT SSL SITE --
uri:
url: 'https://127.0.0.1/'
return_content: yes
validate_certs: no
register: vdefault
failed_when: >
vdefault.content.find('Index HTML test OK') == -1 or
vdefault.x_ansible_default is not defined
- name: -- VERIFY NOT DEFAULT SITE --
uri:
url: 'http://test-php.local/'
return_content: yes
register: vphp
failed_when: vphp.x_ansible_default is defined
- name: -- VERIFY NOT DEFAULT SSL SITE --
uri:
url: 'https://test-ssl.local/'
return_content: yes
validate_certs: no
register: notdefaultssl
failed_when: notdefaultssl.x_ansible_default is defined
# --------------------------------
# Check HTTP2
# --------------------------------
- name: SHELL | Check HTTP2
shell: nghttp -nv https://localhost 2> /dev/null | grep -q h2
args:
executable: /bin/sh
changed_when: false
when: nginx_auto_config_httpv2 and 'http_v2' in nginx_modules

View File

@@ -1,6 +1,5 @@
---
nginx_events_use: 'epoll' nginx_events_use: 'epoll'
nginx_pid: '/run/nginx.pid' nginx_pid: '/run/nginx.pid'
nginx_etc_dir: '/etc/nginx' nginx_etc_dir: '/etc/nginx'
# Specific sites
nginx_fcgiwrap_sock: '/var/run/fcgiwrap.socket'

View File

@@ -1,8 +0,0 @@
nginx_events_use: 'kqueue'
nginx_pid: '/var/run/nginx.pid'
nginx_etc_dir: '/usr/local/etc/nginx'
# Specific sites
nginx_fcgiwrap_sock: '/var/run/fcgiwrap/fcgiwrap.sock'
nginx_acmesh_bin: '/usr/local/sbin/acme.sh'

View File

@@ -1,3 +1,5 @@
---
nginx_upstream_server_params: nginx_upstream_server_params:
- key: 'weight' - key: 'weight'
default: 1 default: 1
@@ -40,12 +42,11 @@ nginx_dirs:
owner: "root" owner: "root"
nginx_templates_no_dir: nginx_templates_no_dir:
- '_backuppc'
- '_proxy' - '_proxy'
nginx_servers_default_headers: nginx_servers_default_headers:
'X-Frame-Options': 'DENY always' 'X-Frame-Options': 'DENY always'
'X-Content-Type-Options': 'nosniff always' 'X-Content-Type-Options': 'nosniff always'
'X-XSS-Protection': '1; mode=block' 'X-XSS-Protection': '1; mode=block always'
nginx_acmesh_bin: "{{ nginx_acmesh_dir }}/acme.sh" nginx_acmesh_bin: "{{ nginx_acmesh_dir }}/acme.sh"