bunkerized-nginx/README.md

256 lines
10 KiB
Markdown
Raw Normal View History

2019-08-20 23:20:48 +02:00
# bunkerized-nginx
nginx based Docker image secure by default.
2019-08-20 23:50:42 +02:00
## Main features
- HTTPS support with transparent Let's Encrypt automation
2020-04-13 22:17:17 +02:00
- State-of-the-art web security : HTTP security headers, php.ini hardening, prevent leaks, ...
2019-08-20 23:50:42 +02:00
- Integrated ModSecurity WAF with the OWASP Core Rule Set
2020-04-13 22:17:17 +02:00
- Automatic ban of bad behaviors with fail2ban
- Block TOR users, bad user-agents, countries, ...
- Detect bad files with ClamAV
- Based on alpine and compiled from source
2019-08-20 23:50:42 +02:00
- Easy to configure with environment variables
2019-11-22 14:21:06 +01:00
## Quickstart guide
### Run HTTP server with default settings
```shell
docker run -p 80:80 -v /path/to/web/files:/www bunkerity/bunkerized-nginx
```
2020-04-13 22:17:17 +02:00
Web files are stored in the /www directory, the container will serve files from there.
2019-11-22 14:21:06 +01:00
### Run HTTPS server with automated Let's Encrypt
```shell
2020-04-13 22:17:17 +02:00
docker run -p 80:80 -p 443:443 -v /path/to/web/files:/www -v /where/to/save/certificates:/etc/letsencrypt -e SERVER_NAME=www.yourdomain.com -e AUTO_LETS_ENCRYPT=yes -e REDIRECT_HTTP_TO_HTTPS=yes bunkerity/bunkerized-nginx
2019-11-22 14:21:06 +01:00
```
2020-04-13 22:17:17 +02:00
Certificates are stored in the /etc/letsencrypt directory, you should save it on your local drive.
If you don't want your webserver to listen on HTTP add the environment variable LISTEN_HTTP with a "no" value. But Let's Encrypt needs the port 80 to be opened so redirecting the port is mandatory.
Here you have three environment variables :
- SERVER_NAME : define the FQDN of your webserver, this is mandatory for Let's Encrypt (www.yourdomain.com should point to your IP address)
- AUTO_LETS_ENCRYPT : enable automatic Let's Encrypt creation and renewal of certificates
- REDIRECT_HTTP_TO_HTTPS : enable HTTP to HTTPS redirection
### Reverse proxy
You can setup a reverse proxy by adding your own custom configurations at http level.
For example, this is a dummy reverse proxy configuration :
```shell
if ($host = www.website1.com) {
proxy_pass http://192.168.42.10
}
if ($host = www.website2.com) {
proxy_pass http://192.168.42.11
}
```
All files in /http-confs inside the container will be included at http level. You can simply mount a volume where your config files are located :
```shell
docker run -p 80:80 -e SERVER_NAME="www.website1.com www.website2.com" -e SERVE_FILES=no -e DISABLE_DEFAULT_SERVER=yes -v /path/to/http/conf:/http-confs bunkerity/bunkerized-nginx
```
Here you have three environment variables :
- SERVER_NAME : list of valid Host headers sent by clients
- 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
2019-11-22 14:21:06 +01:00
2020-01-02 17:31:13 +01:00
## List of environment variables
2019-11-22 14:21:06 +01:00
2020-01-03 15:31:58 +01:00
### nginx
2020-01-02 17:13:44 +01:00
*SERVER_TOKENS*
Values : on | off
Default value : off
2019-11-22 14:21:06 +01:00
If set to on, nginx will display server version in Server header and default error pages.
2020-01-02 17:31:13 +01:00
*HEADER_SERVER*
Values : yes | no
Default value : no
2019-11-22 14:21:06 +01:00
If set to no, nginx will remove the Server header in HTTP responses.
2020-01-02 17:31:13 +01:00
*ALLOWED_METHODS*
Values : allowed HTTP methods separated with | char
Default value : GET|POST|HEAD
2019-11-22 14:21:06 +01:00
Only the HTTP methods listed here will be accepted by nginx. If not listed, nginx will close the connection.
2020-01-02 17:31:13 +01:00
*DISABLE_DEFAULT_SERVER*
Values : yes | no
Default value : no
2020-04-13 22:17:17 +02:00
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.
2019-11-22 14:21:06 +01:00
2020-01-03 15:31:58 +01:00
*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
Sets the maximum body size before nginx returns a 413 error code.
Setting to 0 means "infinite" body size.
*SERVER_NAME*
2020-01-03 16:53:26 +01:00
Values : <first name> <second name> ...
Default value : www.bunkerity.com
2020-04-13 22:17:17 +02:00
Sets the host names of the webserver separated with spaces. This must match the Host header sent by clients.
2020-01-03 16:53:26 +01:00
Useful when used with AUTO_LETSENCRYPT=yes and/or DISABLE_DEFAULT_SERVER=yes.
2020-01-03 15:31:58 +01:00
2020-04-13 22:17:17 +02:00
*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.
2020-01-03 15:31:58 +01:00
### HTTPS
*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.
2020-04-13 22:17:17 +02:00
*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
If set to yes, nginx will redirect all HTTP requests to HTTPS.
2020-01-03 15:31:58 +01:00
*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.
2019-11-22 14:21:06 +01:00
### Security headers
2020-01-02 17:31:13 +01:00
*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.
2019-11-22 14:21:06 +01:00
More info [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options).
2020-01-02 17:31:13 +01:00
*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).
2019-11-22 14:21:06 +01:00
2020-01-02 17:31:13 +01:00
*X_CONTENT_TYPE_OPTIONS*
Values : nosniff
Default value : nosniff
Tells the browser to be strict about MIME type.
2019-11-22 14:21:06 +01:00
More info [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options).
2020-01-02 17:31:13 +01:00
*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 : <directive> <allow list>
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
Adds some security to the cookies set by the server.
Accepted value can be found [here](https://github.com/AirisX/nginx_cookie_flag_module).
2019-11-22 14:21:06 +01:00
2020-01-03 15:31:58 +01:00
*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 : <directive 1>; <directive 2>; ...
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).
2020-01-03 16:55:58 +01:00
### Blocking
2020-01-03 15:31:58 +01:00
*BLOCK_COUNTRY*
Values : <country code 1> <country code 2> ...
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
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
Is set to yes, will block TOR clients.
### PHP
*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
If set to yes, PHP errors will be shown to clients.
*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 : <directory>
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
If set to yes, allows using url in fopen() calls (i.e. : ftp://, http://, ...).
*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
If set to yes, allows clients to upload files.
*PHP_UPLOAD_MAX_FILESIZE*
Values : <size in bytes> | XM
Default value : 10M
Sets the maximum file size allowed when uploading files.
*PHP_DISABLE_FUNCTIONS*
Values : <function 1>, <function 2> ...
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.
2019-08-20 23:50:42 +02:00
## TODO
2020-04-13 22:17:17 +02:00
- Default CSP
2020-03-29 23:10:21 +02:00
- Test with default wordpress install
- Test with custom confs reverse proxy
2019-08-20 23:50:42 +02:00
- Documentation
2020-03-31 09:46:23 +02:00
- Custom TLS certificates
2020-03-29 23:10:21 +02:00
- HSTS preload
2020-03-31 09:46:23 +02:00
- Web UI