Update to 2021-12-01 19:13

This commit is contained in:
Daniel Berteaud
2021-12-01 19:13:34 +01:00
commit 4c4556c660
2153 changed files with 60999 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
map $upstream_http_content_type $is_cacheable {
default 0;
~image/ 1;
~audio/ 1;
~video/ 1;
text/css 1;
application/javascript 1;
application/x-javascript 1;
application/pdf 1;
application/font-sfnt 1;
font/ttf 1;
font/opentype 1;
application/font-woff 1;
application/vnd.ms-fontobject 1;
application/vnd.ms-opentype 1;
}

View File

@@ -0,0 +1,11 @@
proxy_cache_path /var/cache/nginx
levels=1:2
keys_zone=cache_std:5m
max_size={{ nginx_cache_size }}
inactive=300m
use_temp_path=off;
map $is_cacheable $no_cache {
default 1;
1 0;
}

View File

@@ -0,0 +1,18 @@
geo $limit {
default 1;
127.0.0.1 0;
{% for ip in trusted_ip | default([]) %}
{{ ip }} 0;
{% endfor %}
{% for ip in nginx_dos_whitelisted_ip | default([])%}
{{ ip }} 0;
{% endfor %}
}
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=limit_req_std:3m rate={{ nginx_req_per_sec }}r/s;
limit_conn_zone $limit_key zone=limit_conn_std:3m;

View File

@@ -0,0 +1 @@
include /etc/nginx/naxsi_core.rules;

View File

@@ -0,0 +1,8 @@
map $is_cacheable $custom_expires {
default epoch;
1 7d;
}
map $is_cacheable $custom_cache_control {
default "no-cache, no-store, private";
1 "public, max-age=604800, must-revalidate, proxy-revalidate";
}

View File

@@ -0,0 +1,12 @@
ssl_certificate {{ nginx_cert_path }};
ssl_certificate_key {{ nginx_key_path }};
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_ciphers {{ nginx_ssl_ciphers_modern }};
ssl_protocols {{ nginx_ssl_protocols | join(' ') }};
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1h;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/pki/tls/cert.pem;

View File

@@ -0,0 +1,4 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

View File

@@ -0,0 +1,244 @@
# {{ ansible_managed }}
{% for vhost in nginx_vhosts %}
#####################################
## Begin vhost for {{ vhost.name }}
#####################################
{{ vhost.custom_pre }}
server {
{% if vhost.port is iterable %}
{% for port in vhost.port %}
listen {{ port }}{% if vhost.name == '_' %} default_server{% endif %};
{% endfor %}
{% else %}
listen {{ vhost.port }}{% if vhost.name == '_' %} default_server{% endif %};
{% endif %}
{% if vhost.ssl.enabled %}
{% if vhost.ssl.port is iterable %}
{% for port in vhost.ssl.port %}
listen {{ port }} ssl http2{% if vhost.name == '_' %} default_server{% endif %};
{% endfor %}
{% else %}
listen {{ vhost.ssl.port }} ssl http2{% if vhost.name == '_' %} default_server{% endif %};
{% endif %}
{% if vhost.ssl.cert is defined and vhost.ssl.key is defined %}
ssl_certificate {{ vhost.ssl.cert }};
ssl_certificate_key {{ vhost.ssl.key }};
{% elif vhost.ssl.letsencrypt_cert is defined %}
ssl_certificate /var/lib/dehydrated/certificates/certs/{{ vhost.ssl.letsencrypt_cert }}/fullchain.pem;
ssl_certificate_key /var/lib/dehydrated/certificates/certs/{{ vhost.ssl.letsencrypt_cert }}/privkey.pem;
{% elif nginx_auto_letsencrypt_cert %}
ssl_certificate /var/lib/dehydrated/certificates/certs/{{ vhost.name }}/fullchain.pem;
ssl_certificate_key /var/lib/dehydrated/certificates/certs/{{ vhost.name }}/privkey.pem;
{% endif %}
{% if vhost.ssl.compat %}
ssl_ciphers {{ nginx_ssl_ciphers_compat }};
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
{% else %}
ssl_ciphers {{ nginx_ssl_ciphers_modern }};
ssl_protocols TLSv1.2 TLSv1.3;
{% endif %}
{% endif %}
ssl_prefer_server_ciphers on;
server_name {{ vhost.name }} {{ vhost.aliases | join(' ') }};
access_log /var/log/nginx/access.log {{ nginx_log_format + (vhost.auth is string and vhost.auth is search('^llng')) | ternary('_llng','') }};
{% if vhost.full_config is defined %}
{{ vhost.full_config | indent(2, true) }}
{% else %}
root {{ vhost.document_root }};
{{ vhost.custom_begin | indent(2, true) }}
client_max_body_size {{ vhost.max_body_size }};
{% if vhost.maintenance %}
include /etc/nginx/ansible_conf.d/maintenance.inc;
{% endif %}
{% if vhost.acme_http %}
include /etc/nginx/ansible_conf.d/acme.inc;
{% endif %}
# Include a custom fragment. Can be used to insert ACME challenges support during
# dehydrated hooks for example
include /etc/nginx/ansible_conf.d/custom.inc;
{% if vhost.ssl.forced and vhost.ssl.enabled %}
include /etc/nginx/ansible_conf.d/force_ssl.inc;
{% endif %}
{% if vhost.auth == 'llng' or vhost.auth == 'llng_basic' %}
## lmauth endpoint for llng authentication
location = /lmauth {
internal;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/llng-fastcgi-server/llng-fastcgi.sock;
# Drop post datas
fastcgi_pass_request_body off;
fastcgi_param CONTENT_LENGTH "";
# Keep original hostname
fastcgi_param HOST $http_host;
# Keep original request (LLNG server will received /llauth)
fastcgi_param X_ORIGINAL_URI $request_uri;
# Use bigger buffers (see GLPI #49915)
fastcgi_buffers 16 32k;
fastcgi_buffer_size 64k;
{% if vhost.auth == 'llng_basic' %}
# Use basic auth on this vhost
fastcgi_param VHOSTTYPE AuthBasic;
{% endif %}
}
{% endif %}
if ($request_method !~ ^({{ vhost.allowed_methods | join('|') }})$ ) {
return 405;
}
location {{ vhost.location }} {
{{ vhost.custom_location_begin | indent(4, True) }}
{% if vhost.redirect_aliases and vhost.aliases | length > 0 %}
set $redirect_alias 0;
if ($host != '{{ vhost.name }}'){
set $redirect_alias 1;
}
# Only GET and HEAD should be redirected
if ($request_method !~ ^(GET|HEAD)$){
set $redirect_alias 0;
}
if ($redirect_alias = 1){
rewrite ^/(.*)$ http{{ vhost.ssl.enabled | ternary('s','') }}://{{ vhost.name }}{% if vhost.ssl.enabled and vhost.ssl.port | int != 443 %}:{{ vhost.ssl.port }}{% elif not vhost.ssl.enabled and vhost.port | int != 80 %}:{{ vhost.port }}{% endif %}/$1 permanent;
}
{% endif %}
{% if vhost.limits %}
limit_req zone=limit_req_std burst=200 nodelay;
limit_conn limit_conn_std 80;
{% endif %}
{% if vhost.perf %}
include /etc/nginx/ansible_conf.d/perf.inc;
{% endif %}
{% for header in vhost.headers.keys() %}
{% if vhost.headers[header] != False %}
add_header {{ header }} "{{ vhost.headers[header] }}";
{% endif %}
{% endfor %}
{% if vhost.csp %}
add_header Content-Security-Policy "{{ vhost.csp + (vhost.csp is search('connect-src') and vhost.proxy.websocket) | ternary('', '; connect-src \'self\' wss://' + vhost.name) }}";
{% endif %}
{% if vhost.auth == 'llng' or vhost.auth == 'llng_basic' %}
auth_request /lmauth;
auth_request_set $lmremote_user $upstream_http_lm_remote_user;
auth_request_set $lmlocation $upstream_http_location;
auth_request_set $lmlocation $upstream_http_location;
auth_request_set $cookie_value $upstream_http_set_cookie;
{% if vhost.auth != 'llng_basic' %}
error_page 401 $lmlocation;
{% endif %}
{% if nginx_llng_headers.stat.exists %}
include /etc/nginx/ansible_conf.d/llng_headers.inc;
{% endif %}
fastcgi_param REMOTE_USER $lmremote_user;
{% elif vhost.auth == 'basic' and vhost.htpasswd_file is defined %}
auth_basic "Authentication required for {{ vhost.name }}";
auth_basic_user_file {{ vhost.htpasswd_file }};
{% endif %}
{% if vhost.proxy.backend is string %}
{% if vhost.proxy.cache %}
include /etc/nginx/ansible_conf.d/cache.inc;
{% endif %}
# Send info about the original request to the backend
{% for header in vhost.proxy.headers.keys() %}
{% if vhost.proxy.headers[header] != False %}
proxy_set_header {{ header }} "{{ vhost.proxy.headers[header] }}";
{% endif %}
{% endfor %}
{% if vhost.proxy.websocket %}
# Handle websocket proxying
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
{% endif %}
# Hide some headers sent by the backend
proxy_hide_header X-Powered-By;
proxy_hide_header Content-Security-Policy;
{% if vhost.perf %}
# Cache control and expiration is managed by the proxy
proxy_hide_header Cache-Control;
proxy_hide_header Pragma;
proxy_hide_header Expires;
{% endif %}
{% for header in vhost.headers.keys() %}
proxy_hide_header {{ header }};
{% endfor %}
# Set the timeout to read responses from the backend
proxy_read_timeout {{ vhost.proxy.timeout }};
# Enable Keep Alive to the backend
proxy_socket_keepalive on;
# Disable buffering large files
proxy_max_temp_file_size 5m;
# Proxy requests to the backend
proxy_pass {{ vhost.proxy.backend }};
{% endif %}
{% if vhost.deny_ip | length > 0 %}
# per vhost IP blacklist
{% for ip in vhost.deny_ip %}
deny {{ ip }};
{% endfor %}
{% endif %}
{% if vhost.src_ip | length > 0 %}
# per vhost IP restriction
{% for ip in vhost.src_ip | flatten %}
allow {{ ip }};
{% endfor %}
deny all;
{% endif %}
{{ vhost.custom_location_end | indent(4, True) }}
}
location = /RequestDenied {
return 403;
}
{% if vhost.location != '/' %}
location / {
return 403;
}
{% endif %}
{{ vhost.custom_end | indent(2, true) }}
{% endif %}
}
#####################################
## End vhost for {{ vhost.name }}
#####################################
{% endfor %}

View File

@@ -0,0 +1,8 @@
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
alias /var/lib/dehydrated/challenges/;
allow all;
}
location = /.well-known/acme-challenge/ {
return 404;
}

View File

@@ -0,0 +1,9 @@
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_cache cache_std;
proxy_cache_valid 200 120m;
proxy_cache_valid 404 500 502 503 504 20s;
proxy_no_cache $no_cache;
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
add_header X-Proxy-Cache $upstream_cache_status;

View File

@@ -0,0 +1 @@
# {{ ansible_managed }}

View File

@@ -0,0 +1,15 @@
set $ssl 1;
if ($scheme = 'https') {
set $ssl 0;
}
if ($remote_addr = '127.0.0.1'){
set $ssl 0;
}
{% for ip in ansible_all_ipv4_addresses %}
if ($remote_addr = '{{ ip }}'){
set $ssl 0;
}
{% endfor %}
if ($ssl = 1){
return 301 https://$host$request_uri;
}

View File

@@ -0,0 +1,4 @@
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security $hsts_header;

View File

@@ -0,0 +1,9 @@
set $maintenance 1;
{% for ip in nginx_maintenance_ip %}
if ($remote_addr ~ "^{{ ip | replace('.','\.') }}") {
set $maintenance 0;
}
{% endfor %}
if ($maintenance = 1) {
rewrite (.*) https://downtime.{{ nginx_primary_domain | default(ansible_domain) }}/ redirect;
}

View File

@@ -0,0 +1,9 @@
SecRulesEnabled;
DeniedUrl "/RequestDenied";
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$EVADE >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
# This rule blocks unkown Content-Type which is just too common
BasicRule wl:11 "mz:BODY";

View File

@@ -0,0 +1,18 @@
gzip on;
gzip_types
text/plain
text/css
text/xml
text/json
image/svg+xml
application/xml
application/json
application/xhtml+xml
application/rss+xml
application/atom_xml
application/x-javascript
application/javascript;
gzip_vary on;
gzip_disable "msie6";
expires $custom_expires;
add_header Cache-Control $custom_cache_control;

View File

@@ -0,0 +1,6 @@
location /nginx-status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}

View File

@@ -0,0 +1,3 @@
{% for module in nginx_modules %}
load_module "/usr/lib64/nginx/modules/{{ (module is search('\.so$')) | ternary(module,'ngx_' + module + '_module.so') }}";
{% endfor %}

View File

@@ -0,0 +1,10 @@
- module: nginx
access:
enabled: True
input:
exclude_files: [ '\.[gx]z$' ]
error:
enabled: True
input:
exclude_files: [ '\.[gx]z$' ]

View File

@@ -0,0 +1,12 @@
/var/log/nginx/*log {
create 0644 nginx nginx
daily
rotate 60
missingok
notifempty
compress
sharedscripts
postrotate
/bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
endscript
}

View File

@@ -0,0 +1,98 @@
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
application/rss+xml rss;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
image/png png;
image/svg+xml svg svgz;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/webp webp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
font/woff woff;
font/woff2 woff2;
application/java-archive jar war ear;
application/json json;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.apple.mpegurl m3u8;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/vnd.ms-excel xls;
application/vnd.ms-fontobject eot;
application/vnd.ms-powerpoint ppt;
application/vnd.oasis.opendocument.graphics odg;
application/vnd.oasis.opendocument.presentation odp;
application/vnd.oasis.opendocument.spreadsheet ods;
application/vnd.oasis.opendocument.text odt;
application/vnd.openxmlformats-officedocument.presentationml.presentation
pptx;
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
xlsx;
application/vnd.openxmlformats-officedocument.wordprocessingml.document
docx;
application/vnd.wap.wmlc wmlc;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-xpinstall xpi;
application/xhtml+xml xhtml;
application/xspf+xml xspf;
application/zip zip;
application/octet-stream bin exe dll;
application/octet-stream deb;
application/octet-stream dmg;
application/octet-stream iso img;
application/octet-stream msi msp msm;
audio/midi mid midi kar;
audio/mpeg mp3;
audio/ogg ogg;
audio/x-m4a m4a;
audio/x-realaudio ra;
video/3gpp 3gpp 3gp;
video/mp2t ts;
video/mp4 mp4;
video/mpeg mpeg mpg;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-m4v m4v;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
application/wasm wasm;
}

View File

@@ -0,0 +1,105 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
{% if nginx_openresty %}
# Openresty uses builtin modules, not dynamic ones
{% else %}
include /etc/nginx/ansible_modules.d/*.conf;
{% endif %}
events {
worker_connections 1024;
}
http {
{% if nginx_openresty %}
# Set nginx compatible paths for openresty
client_body_temp_path /var/lib/nginx/tmp/client_body;
fastcgi_temp_path /var/lib/nginx/tmp/fastcgi;
proxy_temp_path /var/lib/nginx/tmp/proxy;
scgi_temp_path /var/lib/nginx/tmp/scgi;
uwsgi_temp_path /var/lib/nginx/tmp/uwsgi;
{% endif %}
log_format combined_virtual
'$server_name $remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" scheme="$scheme"';
log_format combined_virtual_backend
'$server_name $http_x_forwarded_for - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" scheme="$scheme"';
{% if nginx_llng.stat.exists %}
log_format combined_virtual_llng
'$server_name $remote_addr - $lmremote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" scheme="$scheme"';
log_format combined_virtual_backend_llng
'$server_name $http_x_forwarded_for - $lmremote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" scheme="$scheme"';
{% else %}
# LL::NG not installed, just make those log formats aliases of the non llng formats
log_format combined_virtual_llng
'$server_name $remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" scheme="$scheme"';
log_format combined_virtual_backend_llng
'$server_name $http_x_forwarded_for - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" scheme="$scheme"';
{% endif %}
access_log /var/log/nginx/access.log {{ nginx_log_format }};
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
client_max_body_size 10m;
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/ansible_conf.d/*.conf;
map $scheme $hsts_header {
https 'max-age=31536000';
}
{% if '_' not in nginx_vhosts | map(attribute='name') | list %}
server {
listen 80 default_server;
listen 443 default_server ssl http2;
server_name _;
root /usr/share/nginx/html;
# Load location fragments in the default vhost
include /etc/nginx/ansible_location.d/*.conf;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security $hsts_header;
include /etc/nginx/ansible_conf.d/acme.inc;
location / {
}
location ~ \.ht {
deny all;
}
}
{% endif %}
}