diff --git a/README.md b/README.md index 6cdd3bd8..c1f3b190 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ nginx based Docker image secure by default. - HTTPS support with transparent Let's Encrypt automation - State-of-the-art web security : HTTP security headers, php.ini hardening, prevent leaks, ... - Integrated ModSecurity WAF with the OWASP Core Rule Set -- Automatic ban of bad behaviors with fail2ban +- Automatic ban of strange behaviors with fail2ban - Block TOR users, bad user-agents, countries, ... - Detect bad files with ClamAV - Based on alpine and compiled from source @@ -56,200 +56,255 @@ Here you have three environment variables : - SERVE_FILES : nginx will not serve files from /www directory - DISABLE_DEFAULT_SERVER : nginx will not respond to requests if Host header is not in the SERVER_NAME list +## Tutorials +TODO : link tutorials from bunkerity website + ## List of environment variables ### nginx -*SERVER_TOKENS* -Values : on | off -Default value : off +`SERVER_TOKENS` +Values : *on* | *off* +Default value : *off* If set to on, nginx will display server version in Server header and default error pages. -*HEADER_SERVER* -Values : yes | no -Default value : no +`HEADER_SERVER` +Values : *yes* | *no* +Default value : *no* If set to no, nginx will remove the Server header in HTTP responses. -*ALLOWED_METHODS* -Values : allowed HTTP methods separated with | char -Default value : GET|POST|HEAD +`ALLOWED_METHODS` +Values : *allowed HTTP methods separated with | char* +Default value : *GET|POST|HEAD* Only the HTTP methods listed here will be accepted by nginx. If not listed, nginx will close the connection. -*DISABLE_DEFAULT_SERVER* -Values : yes | no -Default value : no -If set to yes, nginx will only respond to HTTP request when the Host header match a FQDN specified in the SERVER_NAME environment variable. +`DISABLE_DEFAULT_SERVER` +Values : *yes* | *no* +Default value : *no* +If set to yes, nginx will only respond to HTTP request when the Host header match a FQDN specified in the `SERVER_NAME` environment variable. For example, it will close the connection if a bot access the site with direct ip. -*SERVE_FILES* -Values : yes | no -Default value : yes +`SERVE_FILES` +Values : *yes* | *no* +Default value : *yes* If set to yes, nginx will serve files from /www directory within the container. A use case to not serving files is when you setup bunkerized-nginx as a reverse proxy via a custom configuration. -*MAX_CLIENT_SIZE* -Values : 0 | Xm -Default value : 10m +`MAX_CLIENT_SIZE` +Values : *0* | *Xm* +Default value : *10m* Sets the maximum body size before nginx returns a 413 error code. Setting to 0 means "infinite" body size. -*SERVER_NAME* -Values : ... -Default value : www.bunkerity.com +`SERVER_NAME` +Values : * ...* +Default value : *www.bunkerity.com* Sets the host names of the webserver separated with spaces. This must match the Host header sent by clients. -Useful when used with AUTO_LETSENCRYPT=yes and/or DISABLE_DEFAULT_SERVER=yes. +Useful when used with `AUTO_LETSENCRYPT=yes` and/or `DISABLE_DEFAULT_SERVER=yes`. -*WRITE_ACCESS* -Values : yes | no -Default value : no +`WRITE_ACCESS` +Values : *yes* | *no* +Default value : *no* If set to yes, nginx will be granted write access to the /www directory. Set it to yes if your website uses file upload or creates dynamic files for example. ### HTTPS -*AUTO_LETS_ENCRYPT* -Values : yes | no -Default value : no +`AUTO_LETS_ENCRYPT` +Values : *yes* | *no* +Default value : *no* If set to yes, automatic certificate generation and renewal will be setup through Let's Encrypt. This will enable HTTPS on your website for free. -You will need to redirect both 80 and 443 port to your container and also set the SERVER_NAME environment variable. +You will need to redirect both 80 and 443 port to your container and also set the `SERVER_NAME` environment variable. -*LISTEN_HTTP* -Values : yes | no -Default value : yes +`LISTEN_HTTP` +Values : *yes* | *no* +Default value : *yes* If set to no, nginx will not in listen on HTTP (port 80). Useful if you only want HTTPS access to your website. -*REDIRECT_HTTP_TO_HTTPS* -Values : yes | no -Default value : no +`REDIRECT_HTTP_TO_HTTPS` +Values : *yes* | *no* +Default value : *no* If set to yes, nginx will redirect all HTTP requests to HTTPS. -*HTTP2* -Values : yes | no -Default value : yes +`HTTP2` +Values : *yes* | *no* +Default value : *yes* If set to yes, nginx will use HTTP2 protocol when HTTPS is enabled. ### ModSecurity -*USE_MODSECURITY* -Values : yes | no -Default value : yes -If set to yes, the ModSecurity WAF will be enabled with the OWASP Core Rule Set. +`USE_MODSECURITY` +Values : *yes* | *no* +Default value : *yes* +If set to yes, the ModSecurity WAF will be enabled. +You can include custom rules by adding .conf files into the /modsec-confs/ directory inside the container (i.e : through a volume). + +`USE_MODSECURITY_CRS` +Values: *yes* | *no* +Default value : *yes* +If set to yes, the [OWASP ModSecurity Core Rule Set](https://coreruleset.org/) will be used. It provides generic rules to detect common web attacks. +You can customize the CRS (i.e. : add WordPress exclusions) by adding custom .conf files into the /modsec-crs-confs/ directory inside the container (i.e : through a volume). ### Security headers -*X_FRAME_OPTIONS* -Values : DENY | SAMEORIGIN | ALLOW-FROM https://www.website.net | ALLOWALL -Default value : DENY +`X_FRAME_OPTIONS` +Values : *DENY* | *SAMEORIGIN* | *ALLOW-FROM https://www.website.net* | *ALLOWALL* +Default value : *DENY* Policy to be used when the site is displayed through iframe. Can be used to mitigate clickjacking attacks. More info [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options). -*X_XSS_PROTECTION* -Values : 0 | 1 | 1; mode=block -Default value : 1; mode=block +`X_XSS_PROTECTION` +Values : *0* | *1* | *1; mode=block* +Default value : *1; mode=block* Policy to be used when XSS is detected by the browser. Only works with Internet Explorer. More info [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection). -*X_CONTENT_TYPE_OPTIONS* -Values : nosniff -Default value : nosniff +`X_CONTENT_TYPE_OPTIONS` +Values : *nosniff* +Default value : *nosniff* Tells the browser to be strict about MIME type. More info [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options). -*REFERRER_POLICY* -Values : no-referrer | no-referrer-when-downgrade | origin | origin-when-cross-origin | same-origin | strict-origin | strict-origin-when-cross-origin | unsafe-url -Default value : no-referrer +`REFERRER_POLICY` +Values : *no-referrer* | *no-referrer-when-downgrade* | *origin* | *origin-when-cross-origin* | *same-origin* | *strict-origin* | *strict-origin-when-cross-origin* | *unsafe-url* +Default value : *no-referrer* Policy to be used for the Referer header. More info [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy). -*FEATURE_POLICY* -Values : -Default value : accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; picture-in-picture 'none'; speaker 'none'; sync-xhr 'none'; usb 'none'; vibrate 'none'; vr 'none' +`FEATURE_POLICY` +Values : * * +Default value : *accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; picture-in-picture 'none'; speaker 'none'; sync-xhr 'none'; usb 'none'; vibrate 'none'; vr 'none'* Tells the browser which features can be used on the website. More info [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy). -*COOKIE_FLAGS* -Values : * HttpOnly | MyCookie secure SameSite | ... -Default value : * HttpOnly +`COOKIE_FLAGS` +Values : ** HttpOnly* | *MyCookie secure SameSite* | *...* +Default value : ** HttpOnly* Adds some security to the cookies set by the server. Accepted value can be found [here](https://github.com/AirisX/nginx_cookie_flag_module). -*STRICT_TRANSPORT_POLICY* -Values : max-age=expireTime [; includeSubDomains] [; preload] -Default value : max-age=31536000 +`STRICT_TRANSPORT_POLICY` +Values : *max-age=expireTime [; includeSubDomains] [; preload]* +Default value : *max-age=31536000* Tells the browser to use exclusively HTTPS instead of HTTP when communicating with the server. More info [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security). -*CONTENT_SECURITY_POLICY* -Values : ; ; ... -Default value : default-src 'self'; frame-ancestors 'none'; form-action 'self'; upgrade-insecure-requests; block-all-mixed-content; sandbox allow-forms allow-same-origin allow-scripts; reflected-xss block; base-uri 'self'; referrer no-referrer +`CONTENT_SECURITY_POLICY` +Values : *; ; ...* +Default value : *default-src 'self'; frame-ancestors 'none'; form-action 'self'; upgrade-insecure-requests; block-all-mixed-content; sandbox allow-forms allow-same-origin allow-scripts; reflected-xss block; base-uri 'self'; referrer no-referrer* Policy to be used when loading resources (scripts, forms, frames, ...). More info [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy). ### Blocking -*BLOCK_COUNTRY* -Values : ... +`BLOCK_COUNTRY` +Values : * ...* Default value : Block some countries from accessing your website. Use 2 letters country code separated with space. -*BLOCK_USER_AGENT* -Values : yes | no -Default value : yes +`BLOCK_USER_AGENT` +Values : *yes* | *no* +Default value : *yes* If set to yes, block clients with "bad" user agent. Blacklist can be found [here](https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list). -*BLOCK_TOR_EXIT_NODE* -Values : yes | no -Default value : no +`BLOCK_TOR_EXIT_NODE` +Values : *yes* | *no* +Default value : *no* Is set to yes, will block TOR clients. ### PHP -*USE_PHP* -Values : yes | no -Default value : yes +`USE_PHP` +Values : *yes* | *no* +Default value : *yes* If set to yes, PHP files will be executed by the server. -*PHP_DISPLAY_ERRORS* -Values : yes | no -Default value : no +`PHP_DISPLAY_ERRORS` +Values : *yes* | *no* +Default value : *no* If set to yes, PHP errors will be shown to clients. -*PHP_EXPOSE* -Values : yes | no -Default value : no +`PHP_EXPOSE` +Values : *yes* | *no* +Default value : *no* If set to yes, the PHP version will be sent within the X-Powered-By header. -*PHP_OPEN_BASEDIR* -Values : -Default value : /www/ +`PHP_OPEN_BASEDIR` +Values : ** +Default value : */www/* Limits access to files within the given directory. For example include() or fopen() calls outside the directory will fail. -*PHP_ALLOW_URL_FOPEN* -Values : yes | no -Default value : no +`PHP_ALLOW_URL_FOPEN` +Values : *yes* | *no* +Default value : *no* If set to yes, allows using url in fopen() calls (i.e. : ftp://, http://, ...). -*PHP_ALLOW_URL_INCLUDE* -Values : yes | no -Default value : no +`PHP_ALLOW_URL_INCLUDE` +Values : *yes* | *no* +Default value : *no* If set to yes, allows using url in include() calls (i.e. : ftp://, http://, ...). -*PHP_FILE_UPLOADS* -Values : yes | no -Default value : yes +`PHP_FILE_UPLOADS` +Values : *yes* | *no* +Default value : *yes* If set to yes, allows clients to upload files. -*PHP_UPLOAD_MAX_FILESIZE* -Values : | XM -Default value : 10M +`PHP_UPLOAD_MAX_FILESIZE` +Values : ** | *XM* +Default value : *10M* Sets the maximum file size allowed when uploading files. -*PHP_DISABLE_FUNCTIONS* -Values : , ... -Default value : system, exec, shell_exec, passthru, phpinfo, show_source, highlight_file, popen, proc_open, fopen_with_path, dbmopen, dbase_open, putenv, chdir, mkdir, rmdir, chmod, rename, filepro, filepro_rowcount, filepro_retrieve, posix_mkfifo -List of PHP functions blacklisted. They can't be used anywhere in PHP code. +`PHP_DISABLE_FUNCTIONS` +Values : *, ...* +Default value : *system, exec, shell_exec, passthru, phpinfo, show_source, highlight_file, popen, proc_open, fopen_with_path, dbmopen, dbase_open, putenv, filepro, filepro_rowcount, filepro_retrieve, posix_mkfifo* +List of PHP functions blacklisted separated with commas. They can't be used anywhere in PHP code. + +### Fail2ban +`USE_FAIL2BAN` +Values : *yes* | *no* +Default value : *yes* +If set to yes, fail2ban will be used to block users getting too much "strange" HTTP codes in a period of time. +Instead of using iptables which is not possible inside a container, fail2ban will dynamically update nginx to ban/unban IP addresses. +If a number (`FAIL2BAN_MAXRETRY`) of "strange" HTTP codes (`FAIL2BAN_STATUS_CODES`) is found between a time interval (`FAIL2BAN_FINDTIME`) then the originating IP address will be ban for a specific period of time (`FAIL2BAN_BANTIME`). + +`FAIL2BAN_STATUS_CODES` +Values : +Default value : *400|401|403|404|405|444* +List of "strange" error codes that fail2ban will search for. + +`FAIL2BAN_BANTIME` +Values : ** +Default value : *3600* +The duration time, in seconds, of a ban. + +`FAIL2BAN_FINDTIME` +Values : ** +Default : value : *60* +The time interval, in seconds, to search for "strange" HTTP status codes. + +`FAIL2BAN_MAXRETRY` +Values : ** +Default : value : *10* +The number of "strange" HTTP status codes to find between the time interval. + +### ClamAV +`USE_CLAMAV_UPLOAD` +Values : *yes* | *no* +Default value : *yes* +If set to yes, ClamAV will scan every file uploads and block the upload if the file is detected. + +`USE_CLAMAV_SCAN` +Values : *yes* | *no* +Default value : *yes* +If set to yes, ClamAV will scan all the files inside the container every day. + +`CLAMAV_SCAN_REMOVE` +Values : *yes* | *no* +Default value : *yes* +If set to yes, ClamAV will automatically remove the detected files. ## TODO +- demo website, securityheaders results, ssl results - Default CSP -- Test with default wordpress install +- Custom Dockerfile based on bunkerized-nginx - Test with custom confs reverse proxy - Documentation - Custom TLS certificates -- HSTS preload +- HSTS preload, HPKP - Web UI