From 4c65e9c8b4ff4b9928684139b7e8d494c7a64c4f Mon Sep 17 00:00:00 2001 From: Ludovic Cartier Date: Tue, 17 Dec 2024 17:20:50 +0100 Subject: [PATCH] initial commit --- README.md | 17 ++++++- files/conf.d/custom/acme.conf | 4 ++ files/conf.d/custom/hidden_files.conf | 6 +++ files/conf.d/custom/robots.conf | 6 +++ files/conf.d/custom/wordpress.conf | 68 +++++++++++++++++++++++++++ files/conf.d/gzip.conf | 7 +++ files/conf.d/log_format.conf | 1 + files/conf.d/proxy.conf | 4 ++ files/conf.d/real_ip.conf | 2 + files/conf.d/server_name.conf | 1 + files/status.conf | 32 +++++++++++++ handlers/main.yml | 12 +++++ tasks/configure.yml | 34 ++++++++++++++ tasks/install.yml | 30 ++++++++++++ tasks/main.yml | 12 +++++ tasks/status.yml | 15 ++++++ tasks/vhost.yml | 66 ++++++++++++++++++++++++++ 17 files changed, 315 insertions(+), 2 deletions(-) create mode 100644 files/conf.d/custom/acme.conf create mode 100644 files/conf.d/custom/hidden_files.conf create mode 100644 files/conf.d/custom/robots.conf create mode 100644 files/conf.d/custom/wordpress.conf create mode 100644 files/conf.d/gzip.conf create mode 100644 files/conf.d/log_format.conf create mode 100644 files/conf.d/proxy.conf create mode 100644 files/conf.d/real_ip.conf create mode 100644 files/conf.d/server_name.conf create mode 100644 files/status.conf create mode 100644 handlers/main.yml create mode 100644 tasks/configure.yml create mode 100644 tasks/install.yml create mode 100644 tasks/main.yml create mode 100644 tasks/status.yml create mode 100644 tasks/vhost.yml diff --git a/README.md b/README.md index f17ba80..ccc4a9f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ -# nginx - +vhost definition: +nginx_vhosts: + domain.com: + template: '../data/nginx/vhost.j2' + servername: domain.fr + aliases: + - domain.fr + index: index.php + documentroot: + path: /var/www/domain.com + user: www-data + group: www-data + php_socket: /run/php/php8.1-fpm-www.sock + custom_config: + - wordpress.conf diff --git a/files/conf.d/custom/acme.conf b/files/conf.d/custom/acme.conf new file mode 100644 index 0000000..f405b2f --- /dev/null +++ b/files/conf.d/custom/acme.conf @@ -0,0 +1,4 @@ + location ~ /.well-known { + try_files $uri $uri/ =404; + root /var/www; + } diff --git a/files/conf.d/custom/hidden_files.conf b/files/conf.d/custom/hidden_files.conf new file mode 100644 index 0000000..ecee353 --- /dev/null +++ b/files/conf.d/custom/hidden_files.conf @@ -0,0 +1,6 @@ + # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac). + location ~ /\. { + deny all; + access_log off; + log_not_found off; + } diff --git a/files/conf.d/custom/robots.conf b/files/conf.d/custom/robots.conf new file mode 100644 index 0000000..60061ef --- /dev/null +++ b/files/conf.d/custom/robots.conf @@ -0,0 +1,6 @@ + location = /robots.txt { + auth_basic off; + allow all; + log_not_found off; + access_log off; + } diff --git a/files/conf.d/custom/wordpress.conf b/files/conf.d/custom/wordpress.conf new file mode 100644 index 0000000..9e95477 --- /dev/null +++ b/files/conf.d/custom/wordpress.conf @@ -0,0 +1,68 @@ + # rate limiting : defined in /etc/nginx/conf.d/limits.conf + #limit_req zone=flood burst=30 nodelay; + #limit_req_status 444; + + client_body_buffer_size 128M; + client_max_body_size 128M; # set max upload size + fastcgi_buffers 512 32K; + #fastcgi_buffers 64 4K; + + location / { + try_files $uri $uri/ /index.php?q=$uri&$args; + } + +# location ~* ^.+\.(xml|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { +# access_log off; log_not_found off; expires 1m; +# } + + # SECURITY : Deny all attempts to access PHP Files in the uploads directory + location ~* /(?:uploads|files)/.*\.php$ { + deny all; + } + + location /favicon.ico { + log_not_found off; access_log off; + } + + location /robots.txt { + allow all; log_not_found off; access_log off; + } + + # SECURITY : Deny all attempts to access hidden files .abcde + location ~ /\. { + deny all; + } + + # BEGIN W3TC Browser Cache + gzip on; + gzip_types text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/bmp application/java application/msword application/vnd.ms-fontobject application/x-msdownload image/x-icon image/webp application/json application/vnd.ms-access application/vnd.ms-project application/x-font-otf application/vnd.ms-opentype application/vnd.oasis.opendocument.database application/vnd.oasis.opendocument.chart application/vnd.oasis.opendocument.formula application/vnd.oasis.opendocument.graphics application/vnd.oasis.opendocument.spreadsheet application/vnd.oasis.opendocument.text audio/ogg application/pdf application/vnd.ms-powerpoint application/x-shockwave-flash image/tiff application/x-font-ttf audio/wav application/vnd.ms-write application/font-woff application/font-woff2 application/vnd.ms-excel; + location ~ \.(css|htc|less|js|js2|js3|js4)$ { + expires 31536000s; + etag on; + if_modified_since exact; + try_files $uri $uri/ $uri.html /index.php?$args; + } + + location ~ \.(html|htm|rtf|rtx|svg|txt|xsd|xsl|xml)$ { + etag on; + if_modified_since exact; + try_files $uri $uri/ $uri.html /index.php?$args; + } + + location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|webp|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|_otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|_ttf|wav|wma|wri|woff|woff2|xla|xls|xlsx|xlt|xlw|zip)$ { + expires 31536000s; + etag on; + if_modified_since exact; + try_files $uri $uri/ $uri.html /index.php?$args; + } + + location ~ \.(bmp|class|doc|docx|eot|exe|ico|webp|json|mdb|mpp|otf|_otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|pot|pps|ppt|pptx|svg|svgz|swf|tif|tiff|ttf|ttc|_ttf|wav|wri|woff|woff2|xla|xls|xlsx|xlt|xlw)$ { + etag off; + if_modified_since off; + try_files $uri $uri/ $uri.html /index.php?$args; + } + # END W3TC Browser Cache + + # BEGIN W3TC Minify core + rewrite ^/wp-content/cache/minify/ /index.php last; + # END W3TC Minify core diff --git a/files/conf.d/gzip.conf b/files/conf.d/gzip.conf new file mode 100644 index 0000000..aaa1b88 --- /dev/null +++ b/files/conf.d/gzip.conf @@ -0,0 +1,7 @@ + gzip_disable "msie6"; # Do people still use Internet Explorer 6? In that case, disable gzip and hope for the best! + gzip_vary on; # Also compress content with other MIME types than "text/html" + gzip_types application/json text/css application/javascript; # We only want to compress json, css and js. Compressing images and such isn't worth it + gzip_proxied any; + gzip_comp_level 6; # Set desired compression ratio, higher is better compression, but slower + gzip_buffers 16 8k; # Gzip buffer size + gzip_http_version 1.0; # Compress every type of HTTP request diff --git a/files/conf.d/log_format.conf b/files/conf.d/log_format.conf new file mode 100644 index 0000000..b7605f3 --- /dev/null +++ b/files/conf.d/log_format.conf @@ -0,0 +1 @@ +log_format custom '$remote_addr;$time_local;"$request";$status;$bytes_sent;"$http_referer";"$http_user_agent";"$gzip_ratio";$request_time'; diff --git a/files/conf.d/proxy.conf b/files/conf.d/proxy.conf new file mode 100644 index 0000000..7e4bc00 --- /dev/null +++ b/files/conf.d/proxy.conf @@ -0,0 +1,4 @@ + proxy_connect_timeout 600; + proxy_send_timeout 600; + proxy_read_timeout 600; + send_timeout 600; diff --git a/files/conf.d/real_ip.conf b/files/conf.d/real_ip.conf new file mode 100644 index 0000000..74bccc6 --- /dev/null +++ b/files/conf.d/real_ip.conf @@ -0,0 +1,2 @@ + set_real_ip_from 127.0.0.1; # Load Balancer Internal IP + real_ip_header X-Forwarded-For; diff --git a/files/conf.d/server_name.conf b/files/conf.d/server_name.conf new file mode 100644 index 0000000..e900e1e --- /dev/null +++ b/files/conf.d/server_name.conf @@ -0,0 +1 @@ + server_names_hash_bucket_size 128; diff --git a/files/status.conf b/files/status.conf new file mode 100644 index 0000000..d66c9ac --- /dev/null +++ b/files/status.conf @@ -0,0 +1,32 @@ +server { + listen 127.0.0.1:80; + server_name _; + + access_log /var/log/nginx/localhost.access.log; + error_log /var/log/nginx/localhost.error.log; + + location ~ /.well-known/acme-challenge/ { + alias /var/www/challenges/; + try_files $uri =404; + allow 127.0.0.1; + deny all; + } + + location /stub_status { + stub_status on; + access_log off; + allow 127.0.0.1; + deny all; + } + +# location /php_status { +# access_log off; +# include /etc/nginx/fastcgi_params; +# fastcgi_pass unix:/run/php/php7.0-fpm.sock; +# fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; +# } + + location / { + deny all; + } +} diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..9a8f32f --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,12 @@ +--- +- name: 'nginx reload' + systemd: + name: nginx + state: reloaded + tags: ['nginx'] + +- name: 'nginx restart' + systemd: + name: nginx + state: restarted + tags: ['nginx'] diff --git a/tasks/configure.yml b/tasks/configure.yml new file mode 100644 index 0000000..ed5a50c --- /dev/null +++ b/tasks/configure.yml @@ -0,0 +1,34 @@ +--- +- name: 'nginx | push configuration' + copy: + src: '{{ item }}' + dest: /etc/nginx/conf.d/ + owner: root + mode: 600 + with_fileglob: + - conf.d/* + notify: + - 'nginx restart' + tags: + - nginx + - nginx_configure + +- name: 'nginx | push custom configuration' + copy: + src: '{{ item }}' + dest: /etc/nginx/conf.d/custom/ + owner: root + mode: 600 + with_fileglob: + - conf.d/custom/* + notify: + - 'nginx restart' + tags: + - nginx + - nginx_configure + +#- name: 'nginx | disable general gzip' +# replace: +# path: /etc/nginx/nginx.conf +# regexp: 'gzip on;' +# replace: 'gzip off;' diff --git a/tasks/install.yml b/tasks/install.yml new file mode 100644 index 0000000..fa068bf --- /dev/null +++ b/tasks/install.yml @@ -0,0 +1,30 @@ +--- +- name: "nginx | apt update cache" + apt: + update_cache: yes + cache_valid_time: 86400 #One day + tags: + - nginx + - nginx_install + +- name: "nginx | install packages" + apt: + name: "{{ item }}" + update_cache: true + state: present + with_items: + - nginx-common + - nginx-full + register: is_nginx + tags: + - nginx + - nginx_install + +- name: "nginx | remove default vhost" + file: + path: "/etc/nginx/sites-enabled/default" + state: absent + tags: + - nginx + - nginx_install + diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..44addd4 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- name: "nginx | installation" + include: install.yml + +- name: "nginx | custom configuration" + include: configure.yml + +- name: "nginx | status page" + include: status.yml + +- name: "nginx | configure vhost" + include: vhost.yml diff --git a/tasks/status.yml b/tasks/status.yml new file mode 100644 index 0000000..ef8b405 --- /dev/null +++ b/tasks/status.yml @@ -0,0 +1,15 @@ +--- +- name: "nginx | copy status vhost" + copy: + src: "status.conf" + dest: "/etc/nginx/sites-available/00-status.conf" + mode: "0644" + force: yes + backup: yes + when: is_nginx + +- name: "nginx | activate the status vhost" + file: + src: "/etc/nginx/sites-available/00-status.conf" + dest: "/etc/nginx/sites-enabled/00-status.conf" + state: link diff --git a/tasks/vhost.yml b/tasks/vhost.yml new file mode 100644 index 0000000..2572ae6 --- /dev/null +++ b/tasks/vhost.yml @@ -0,0 +1,66 @@ +--- + +- name: 'nginx | configure vhosts' + template: + src: "{{ item.value.template | default('vhost.conf.j2') }}" + dest: "/etc/nginx/sites-available/{{ item.key }}.conf" + owner: root + group: root + mode: 0644 + loop: "{{ nginx_vhosts | dict2items }}" + notify: + - nginx reload + tags: + - nginx + - nginx_vhost + +- name: 'nginx | enable vhosts' + file: + src: "/etc/nginx/sites-available/{{ item.key }}.conf" + dest: "/etc/nginx/sites-enabled/{%if item.value.priority is defined%}{{ item.value.priority }}-{%endif%}{{ item.key }}.conf" + state: link + loop: "{{ nginx_vhosts | dict2items }}" + when: item.value.enabled is not defined or item.value.enabled + notify: + - nginx reload + tags: + - nginx + - nginx_vhost + +- name: 'nginx | configure DocumentRoot' + file: + path: "{{ item.value.documentroot.path | default(nginx_documentroot_default) }}" + state: directory + owner: "{{ item.value.documentroot.user | default(nginx_user) }}" + group: "{{ item.value.documentroot.group | default(nginx_group) }}" + loop: "{{ nginx_vhosts | dict2items }}" + loop_control: + label: "{{ item.value.documentroot | default([]) }}" + when: + - item.value.enabled is undefined or item.value.enabled + - item.value.documentroot is defined + - item.value.documentroot != False + notify: + - nginx reload + tags: + - nginx + - nginx_vhost + +- name: 'nginx | configure nginx logs' + file: + path: "/var/log/nginx/{{ item.value.servername }}" + state: directory + owner: root + group: adm + loop: "{{ nginx_vhosts | dict2items }}" + loop_control: + label: "{{ item.value.servername | default([]) }}" + when: + - item.value.enabled is undefined or item.value.enabled + - item.value.documentroot is defined + - item.value.documentroot != False + notify: + - nginx reload + tags: + - nginx + - nginx_vhost