├── CONTRIBUTING.md
├── CONTRIBUTING_fr.md
├── LICENSE
├── README.md
├── nginx.conf
└── nginx.conf-debian-extras
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | #Contributing
2 |
3 | ##General Guidelines
4 | Test your patches first.
5 |
6 | As a general rule, if you're replacing lines of code with new lines of code, don't comment them out, just delete them EXCEPT for breaking change.
7 |
8 |
9 | ###Compatibility
10 | The code in the nginx.conf
file must work for:
11 |
12 | * Latest NGINX mainline release built against OpenSSL 1.1.0 (or latest OpenSSL stable).
13 |
14 | This is necessary to have latest security and performance improvements like:
15 |
16 | * HTTP2 with ALPN
17 | * Threads AIO
18 | * CHACHA20_POLY1305
19 | * x25519 support
20 | * Multiple ssl_ecdh_curve
support
21 | * Dual certificate support for RSA/ECDSA combo
22 | * And much more ...
23 |
24 |
25 | ##Security Goals
26 |
27 | At least, we need the following results on some major test tools available online:
28 |
29 | * **A** on https://securityheaders.io/
30 | * **A+** on https://tls.imirhil.fr/
31 | * **A+** on https://www.ssllabs.com/
32 |
33 | ##Pull requests
34 | Anyone can commit here.
35 |
36 | Just think than your configuration must me compatible with the largest range of apps possible.
37 |
--------------------------------------------------------------------------------
/CONTRIBUTING_fr.md:
--------------------------------------------------------------------------------
1 | #contribuer
2 |
3 | ##Directives
4 | Testez vos configurations avant un commit.
5 |
6 | En règle générale, si vous remplacez des lignes, supprimez-les au lieu de les commenter SAUF pour les changements qui cassent la rétrocompatibilité.
7 |
8 | ###Compatibilité
9 | Le fichier de configuration nginx.conf
doit fonctionner pour :
10 |
11 | * La dernière mainline de NGINX et OpenSSL 1.1.0 (ou la dernière version stable de OpenSSL).
12 |
13 | C'est nécessaire pour avoir les derniers ajouts en termes de sécurité et de performance comme :
14 |
15 | * HTTP2 with ALPN
16 | * Threads AIO
17 | * CHACHA20_POLY1305
18 | * x25519 support
19 | * Multiple ssl_ecdh_curve
support
20 | * Dual certificate support for RSA/ECDSA combo
21 | * And much more ...
22 |
23 |
24 | ##Objectifs au niveau de la sécurité
25 |
26 | Il est nécessaire d'avoir au minimum les résultats suivants sur différents tests en ligne :
27 |
28 | * **A** on https://securityheaders.io/
29 | * **A+** on https://tls.imirhil.fr/
30 | * **A+** on https://www.ssllabs.com/
31 |
32 | ##Pull requests
33 | Tout le monde peut participer.
34 |
35 | Vous devez simplement essayer de trouver le meilleur compromis entre sécurité, performance et compatibilité.
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Nicolas Simond
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Secure Configuration for NGINX
2 |
3 | The goal of this project is to provide the most secure and supported nginx.conf
file with support for very latest improvements like:
4 |
5 | * HTTP2 with ALPN
6 | * Threads AIO
7 | * CHACHA20_POLY1305
8 | * x25519 support
9 | * TLS 1.3 support
10 | * Multiple ssl_ecdh_curve
support
11 | * 0-RTT support for TLS 1.3
12 | * Crowdsec NGINX bouncer (Don't forget to uncomment the line at the beginning for LUA support)
13 | * And much more ...
14 |
15 | Results :
16 |
17 | * A+ on SSL Labs
18 | * A on Security Headers (.io)
19 |
20 | If you want to use a NGINX release that support every of this, you need to use the package **nginx-extras** on Debian 11 that support every feature listed here.
21 |
22 | --------
23 |
24 | > :warning: **If you were using custom Nginx and want to go back to nginx-extras package**: Like this one: https://github.com/stylersnico/nginx-openssl-chacha-naxsi
25 | ```bash
26 | #stop nginx
27 | systemctl stop nginx
28 |
29 | #clean old stuff
30 | rm -rf /usr/local/etc/nginx/
31 | rm /usr/sbin/nginx
32 | rm /etc/nginx/naxsi_core.rules
33 | rm /etc/init.d/nginx && rm /etc/init.d/nginx-debug
34 | rm /lib/systemd/system/nginx.service
35 |
36 | #Install Nginx-extras and overwrite all configs
37 | apt -o Dpkg::Options::="--force-confnew" install nginx-extras -y
38 |
39 | #Grab latest nginx.conf file and restart
40 | cd /etc/nginx/
41 | rm nginx.conf && wget https://raw.githubusercontent.com/stylersnico/nginx-secure-config/master/nginx.conf
42 | systemctl restart nginx
43 | ```
44 |
--------------------------------------------------------------------------------
/nginx.conf:
--------------------------------------------------------------------------------
1 | #This config is made for user with the basic "nginx-extras" package available on Debian Buster
2 |
3 | #Uncomment these two lines for Crowdsec support (tested on Debian 11 - NGINX Extras)
4 | #load_module modules/ndk_http_module.so;
5 | #load_module modules/ngx_http_lua_module.so;
6 |
7 |
8 | user www-data;
9 | worker_processes auto;
10 | worker_cpu_affinity auto;
11 | pid /run/nginx.pid;
12 |
13 | load_module modules/ngx_http_headers_more_filter_module.so;
14 |
15 | events {
16 | worker_connections 16384;
17 | multi_accept on;
18 | use epoll;
19 | }
20 |
21 | # worker_rlimit_nofile = (worker_connections * 1) + 500
22 | # worker_rlimit_nofile = (worker_connections * 2) + 500 if you use nginx as reverse proxy
23 |
24 | worker_rlimit_nofile 16884;
25 |
26 |
27 | http {
28 | ##
29 | # Basic Settings
30 | ##
31 |
32 | server_names_hash_bucket_size 64;
33 | # server_name_in_redirect off;
34 |
35 | include /etc/nginx/mime.types;
36 | default_type application/octet-stream;
37 |
38 | ##VirtualHosts and configs includes
39 | include /etc/nginx/conf.d/*.conf;
40 | include /etc/nginx/sites-enabled/*;
41 |
42 | ##
43 | # TLS
44 | ##
45 |
46 | ssl_protocols TLSv1.2 TLSv1.3;
47 | ssl_ecdh_curve X25519:sect571r1:secp521r1:secp384r1;
48 | ssl_session_timeout 1d;
49 | ssl_session_cache shared:SSL:50m;
50 | ssl_session_tickets off;
51 | ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:!AES128';
52 | ssl_prefer_server_ciphers off;
53 |
54 |
55 | ##
56 | # Headers
57 | #
58 | ##Less Verbose for Nginx headers
59 | server_tokens off;
60 |
61 | ##Common headers for security
62 | ## You need to adapt the configuration to your website need, It may break some shitty content management system or poorly build websites.
63 | more_set_headers "Content-Security-Policy : default-src https: data: 'unsafe-inline' 'unsafe-eval' always";
64 | more_set_headers "Permissions-Policy: geolocation=();midi=();notifications=();push=();sync-xhr=();microphone=();camera=();magnetometer=();gyroscope=();speaker self;vibrate=();fullscreen self;payment=();;"
65 | more_set_headers "Strict-Transport-Security : max-age=15768000; includeSubDomains; preload";
66 | more_set_headers "X-Frame-Options : SAMEORIGIN";
67 | more_set_headers "X-Xss-Protection : 1; mode=block";
68 | more_set_headers "X-Content-Type-Options : nosniff";
69 | more_set_headers "Referrer-Policy : strict-origin-when-cross-origin";
70 | more_set_headers "Server : Follow the white rabbit.";
71 | more_set_headers "Cross-Origin-Opener-Policy : same-origin"
72 | more_set_headers "Cross-Origin-Embedder-Policy : unsafe-none"
73 | more_set_headers "Origin-Agent-Cluster : ?1"
74 | more_set_headers "Permissions-Policy : accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), clipboard-read=(), clipboard-write=(), display-capture=(), document-domain=(), encrypted-media=(), fullscreen=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), speaker-selection=(), sync-xhr=(), usb=(), xr-spatial-tracking=()";
75 |
76 | ##OCSP settings
77 | ssl_stapling on;
78 | ssl_stapling_verify on;
79 | #ssl_trusted_certificate /etc/ssl/private/ocsp-certs.pem; # <- Add signing certs here
80 | resolver 1.0.0.1 8.8.4.4 valid=300s;
81 | resolver_timeout 5s;
82 |
83 | ##
84 | # Logging
85 | ##
86 |
87 | #access_log /var/log/nginx/access.log; #Disabled for performance
88 |
89 | access_log off;
90 | error_log /var/log/nginx/error.log;
91 |
92 | ##
93 | # Gzip
94 | ##
95 |
96 | gzip on;
97 | gzip_disable "msie6";
98 | gzip_vary on;
99 | gzip_proxied any;
100 | gzip_comp_level 6;
101 | gzip_buffers 16 8k;
102 | gzip_http_version 1.1;
103 | gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
104 |
105 |
106 | ##
107 | # GeoIP
108 | ##
109 |
110 | #GeoIP (optional)
111 | #geoip_country /usr/local/share/GeoIP/GeoIP.dat;
112 | #geoip_city /usr/local/share/GeoIP/GeoLiteCity.dat;
113 |
114 |
115 | ##
116 | # Performance and Cache
117 | ##
118 |
119 | #See - https://www.nginx.com/blog/thread-pools-boost-performance-9x/
120 | aio threads;
121 |
122 | #Enable 0-RTT support for TLS 1.3
123 | ssl_early_data on;
124 | proxy_set_header Early-Data $ssl_early_data;
125 |
126 | #Simple DOS mitigation
127 | ##Max c/s by ip
128 | limit_conn_zone $binary_remote_addr zone=limit_per_ip:10m;
129 | limit_conn limit_per_ip 40;
130 |
131 | ##Max rq/s by ip
132 | limit_req_zone $binary_remote_addr zone=allips:10m rate=400r/s;
133 | limit_req zone=allips burst=400 nodelay;
134 |
135 | #PHP
136 | fastcgi_buffers 256 32k;
137 | fastcgi_buffer_size 256k;
138 | fastcgi_connect_timeout 4s;
139 | fastcgi_send_timeout 120s;
140 | fastcgi_read_timeout 120s;
141 | fastcgi_busy_buffers_size 512k;
142 | fastcgi_temp_file_write_size 512K;
143 | reset_timedout_connection on;
144 |
145 | #Others
146 | open_file_cache max=2000 inactive=20s;
147 | open_file_cache_valid 60s;
148 | open_file_cache_min_uses 5;
149 | open_file_cache_errors off;
150 |
151 | client_max_body_size 50M;
152 | client_body_buffer_size 1m;
153 | client_body_timeout 15;
154 | client_header_timeout 15;
155 | keepalive_timeout 65;
156 | send_timeout 15;
157 | sendfile on;
158 | tcp_nopush on;
159 | tcp_nodelay on;
160 | }
161 |
--------------------------------------------------------------------------------
/nginx.conf-debian-extras:
--------------------------------------------------------------------------------
1 | #This config is made for user with the basic "nginx-extras" package available on Debian Buster
2 |
3 | #Uncomment these two lines for Crowdsec support (tested on Debian 11 - NGINX Extras)
4 | #load_module modules/ndk_http_module.so;
5 | #load_module modules/ngx_http_lua_module.so;
6 |
7 |
8 | user www-data;
9 | worker_processes auto;
10 | worker_cpu_affinity auto;
11 | pid /run/nginx.pid;
12 |
13 | load_module modules/ngx_http_headers_more_filter_module.so;
14 |
15 | events {
16 | worker_connections 16384;
17 | multi_accept on;
18 | use epoll;
19 | }
20 |
21 | # worker_rlimit_nofile = (worker_connections * 1) + 500
22 | # worker_rlimit_nofile = (worker_connections * 2) + 500 if you use nginx as reverse proxy
23 |
24 | worker_rlimit_nofile 16884;
25 |
26 |
27 | http {
28 | ##
29 | # Basic Settings
30 | ##
31 |
32 | server_names_hash_bucket_size 64;
33 | # server_name_in_redirect off;
34 |
35 | include /etc/nginx/mime.types;
36 | default_type application/octet-stream;
37 |
38 | ##VirtualHosts and configs includes
39 | include /etc/nginx/conf.d/*.conf;
40 | include /etc/nginx/sites-enabled/*;
41 |
42 | ##
43 | # TLS
44 | ##
45 |
46 | ssl_protocols TLSv1.2 TLSv1.3;
47 | ssl_ecdh_curve X25519:sect571r1:secp521r1:secp384r1;
48 | ssl_session_timeout 1d;
49 | ssl_session_cache shared:SSL:50m;
50 | ssl_session_tickets off;
51 | ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:!AES128';
52 | ssl_prefer_server_ciphers off;
53 |
54 |
55 | ##
56 | # Headers
57 | #
58 | ##Less Verbose for Nginx headers
59 | server_tokens off;
60 |
61 | ##Common headers for security
62 | ## You need to adapt the configuration to your website need, It may break some shitty content management system or poorly build websites.
63 | more_set_headers "Content-Security-Policy : default-src https: data: 'unsafe-inline' 'unsafe-eval' always";
64 | more_set_headers "Permissions-Policy: geolocation=();midi=();notifications=();push=();sync-xhr=();microphone=();camera=();magnetometer=();gyroscope=();speaker self;vibrate=();fullscreen self;payment=();;"
65 | more_set_headers "Strict-Transport-Security : max-age=15768000; includeSubDomains; preload";
66 | more_set_headers "X-Frame-Options : SAMEORIGIN";
67 | more_set_headers "X-Xss-Protection : 1; mode=block";
68 | more_set_headers "X-Content-Type-Options : nosniff";
69 | more_set_headers "Referrer-Policy : strict-origin-when-cross-origin";
70 | more_set_headers "Server : Follow the white rabbit.";
71 | more_set_headers "Cross-Origin-Opener-Policy : same-origin"
72 | more_set_headers "Cross-Origin-Embedder-Policy : unsafe-none"
73 | more_set_headers "Origin-Agent-Cluster : ?1"
74 | more_set_headers "Permissions-Policy : accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), clipboard-read=(), clipboard-write=(), display-capture=(), document-domain=(), encrypted-media=(), fullscreen=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), speaker-selection=(), sync-xhr=(), usb=(), xr-spatial-tracking=()";
75 |
76 | ##OCSP settings
77 | ssl_stapling on;
78 | ssl_stapling_verify on;
79 | #ssl_trusted_certificate /etc/ssl/private/ocsp-certs.pem; # <- Add signing certs here
80 | resolver 1.0.0.1 8.8.4.4 valid=300s;
81 | resolver_timeout 5s;
82 |
83 | ##
84 | # Logging
85 | ##
86 |
87 | #access_log /var/log/nginx/access.log; #Disabled for performance
88 |
89 | access_log off;
90 | error_log /var/log/nginx/error.log;
91 |
92 | ##
93 | # Gzip
94 | ##
95 |
96 | gzip on;
97 | gzip_disable "msie6";
98 | gzip_vary on;
99 | gzip_proxied any;
100 | gzip_comp_level 6;
101 | gzip_buffers 16 8k;
102 | gzip_http_version 1.1;
103 | gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
104 |
105 |
106 | ##
107 | # GeoIP
108 | ##
109 |
110 | #GeoIP (optional)
111 | #geoip_country /usr/local/share/GeoIP/GeoIP.dat;
112 | #geoip_city /usr/local/share/GeoIP/GeoLiteCity.dat;
113 |
114 |
115 | ##
116 | # Performance and Cache
117 | ##
118 |
119 | #See - https://www.nginx.com/blog/thread-pools-boost-performance-9x/
120 | aio threads;
121 |
122 | #Enable 0-RTT support for TLS 1.3
123 | ssl_early_data on;
124 | proxy_set_header Early-Data $ssl_early_data;
125 |
126 | #Simple DOS mitigation
127 | ##Max c/s by ip
128 | limit_conn_zone $binary_remote_addr zone=limit_per_ip:10m;
129 | limit_conn limit_per_ip 40;
130 |
131 | ##Max rq/s by ip
132 | limit_req_zone $binary_remote_addr zone=allips:10m rate=400r/s;
133 | limit_req zone=allips burst=400 nodelay;
134 |
135 | #PHP
136 | fastcgi_buffers 256 32k;
137 | fastcgi_buffer_size 256k;
138 | fastcgi_connect_timeout 4s;
139 | fastcgi_send_timeout 120s;
140 | fastcgi_read_timeout 120s;
141 | fastcgi_busy_buffers_size 512k;
142 | fastcgi_temp_file_write_size 512K;
143 | reset_timedout_connection on;
144 |
145 | #Others
146 | open_file_cache max=2000 inactive=20s;
147 | open_file_cache_valid 60s;
148 | open_file_cache_min_uses 5;
149 | open_file_cache_errors off;
150 |
151 | client_max_body_size 50M;
152 | client_body_buffer_size 1m;
153 | client_body_timeout 15;
154 | client_header_timeout 15;
155 | keepalive_timeout 65;
156 | send_timeout 15;
157 | sendfile on;
158 | tcp_nopush on;
159 | tcp_nodelay on;
160 | }
161 |
--------------------------------------------------------------------------------