From d1ab7d369c155d8b6dfa293b0239309e55db608c Mon Sep 17 00:00:00 2001 From: "corrado.mulas" Date: Tue, 19 May 2026 00:00:03 +0200 Subject: [PATCH] 1st commit - refined 2019 cfg + AI made README (I despise writing docs so it was either letting AI write README or having none, sorry) --- README.md | 111 ++++++++++ docker/.env.example | 15 ++ docker/docker-compose.yml | 107 ++++++++++ nginx/conf.d/header.conf | 18 ++ nginx/conf.d/ssl.conf | 20 ++ nginx/custom.d/cors | 49 +++++ nginx/custom.d/errorpage | 57 ++++++ nginx/custom.d/jsonerrorpage | 190 ++++++++++++++++++ nginx/custom.d/koi-utf | 115 +++++++++++ nginx/custom.d/koi-win | 109 ++++++++++ nginx/custom.d/mime.types | 97 +++++++++ nginx/custom.d/proxy_params | 11 + nginx/custom.d/win-utf | 132 ++++++++++++ nginx/fcgi.d/fastcgi-php.conf | 20 ++ nginx/fcgi.d/fastcgi.conf | 32 +++ nginx/fcgi.d/fastcgi_params | 31 +++ nginx/fcgi.d/scgi_params | 23 +++ nginx/fcgi.d/uwsgi_params | 23 +++ nginx/nginx.conf | 73 +++++++ nginx/sites-available/drive.mulas.me | 146 ++++++++++++++ .../snippets/letsencrypt-acme-challenge.conf | 51 +++++ nginx/snippets/snakeoil.conf | 9 + 22 files changed, 1439 insertions(+) create mode 100644 docker/.env.example create mode 100644 docker/docker-compose.yml create mode 100644 nginx/conf.d/header.conf create mode 100644 nginx/conf.d/ssl.conf create mode 100644 nginx/custom.d/cors create mode 100644 nginx/custom.d/errorpage create mode 100644 nginx/custom.d/jsonerrorpage create mode 100644 nginx/custom.d/koi-utf create mode 100644 nginx/custom.d/koi-win create mode 100644 nginx/custom.d/mime.types create mode 100644 nginx/custom.d/proxy_params create mode 100644 nginx/custom.d/win-utf create mode 100644 nginx/fcgi.d/fastcgi-php.conf create mode 100644 nginx/fcgi.d/fastcgi.conf create mode 100644 nginx/fcgi.d/fastcgi_params create mode 100644 nginx/fcgi.d/scgi_params create mode 100644 nginx/fcgi.d/uwsgi_params create mode 100644 nginx/nginx.conf create mode 100644 nginx/sites-available/drive.mulas.me create mode 100644 nginx/snippets/letsencrypt-acme-challenge.conf create mode 100644 nginx/snippets/snakeoil.conf diff --git a/README.md b/README.md index e1fb7d8..6c9f54e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,113 @@ # nextcloud +Config and compose files for my self-hosted Nextcloud at `drive.net.mulas.me`. + +Two pieces: + +- `nginx/` — the vhost, TLS profile, and header set I wrote and hardened for Nextcloud back in **2019** and have been using in production since then. I revised it in 2026 to match new Nextcloud docs directives. +- `docker/` — a small Compose stack with MariaDB, Redis, and Memcached. Nextcloud itself runs on the host, served by NGINX and PHP-FPM, because I had an abysmal experience with Nextcloud's containerised setup, in particular on updating and adding modules. The containers only provide the backing services. + +## Layout + +`docker/docker-compose.yml` — the MariaDB + Redis + Memcached stack. + +Everything under `nginx/` mirrors `/etc/nginx/` on the server: + +- `nginx.conf` — main `http{}` block: tuning, real-ip, gzip, headers-more +- `conf.d/header.conf` — HSTS and the Nextcloud-recommended hardening headers +- `conf.d/ssl.conf` — TLS 1.2, AEAD ciphers, OCSP stapling +- `sites-available/drive.mulas.me` — the vhost +- `custom.d/` — mime types, cors, error pages, charset maps +- `fcgi.d/` — fastcgi / scgi / uwsgi params +- `snippets/` — letsencrypt ACME challenge, snakeoil + +## Docker stack + +Images are pinned, all overridable via env: + +| Service | Default tag | Env override | +|-------------|--------------------|---------------------------| +| `db` | `mariadb:11.8-ubi9`| `ENV_MARIADB_VERSION` | +| `redis` | `redis:7.4.9-alpine`| `ENV_REDIS_VERSION` | +| `memcached` | `memcached:alpine3.23`| `ENV_MEMCACHED_VERSION` | + +State, configs, and sockets land under `${ENV_BASE_DIR}//{data,config,socket}`. In production `ENV_BASE_DIR=/opt/nextcloud`. + +MariaDB credentials are mounted as Docker secrets — files on the host, never in the repo: + +``` +/opt/nextcloud/secrets/mariadb_root_password.txt +/opt/nextcloud/secrets/mariadb_app_password.txt +``` + +`MYSQL_USER` and `MYSQL_DATABASE` are intentionally blank in the compose file; fill them in (or move them to an `.env`) before bringing the stack up. + +## Bringing it up + +```bash +# host paths +sudo mkdir -p /opt/nextcloud/{mariadb,redis,memcached}/{data,config,socket} +sudo mkdir -p /opt/nextcloud/secrets && sudo chmod 700 /opt/nextcloud/secrets + +# secrets +openssl rand -base64 48 | sudo tee /opt/nextcloud/secrets/mariadb_root_password.txt +openssl rand -base64 48 | sudo tee /opt/nextcloud/secrets/mariadb_app_password.txt +sudo chmod 600 /opt/nextcloud/secrets/*.txt + +# env +echo 'ENV_BASE_DIR=/opt/nextcloud' > docker/.env + +# go +( cd docker && docker compose up -d ) +``` + +Wait for the `db` healthcheck (it pings `mysqladmin`) to come up green before pointing Nextcloud at it. + +## Nginx install + +```bash +sudo cp nginx/nginx.conf /etc/nginx/nginx.conf +sudo cp -r nginx/conf.d/* /etc/nginx/conf.d/ +sudo cp -r nginx/custom.d nginx/fcgi.d /etc/nginx/ +sudo cp -r nginx/snippets/* /etc/nginx/snippets/ +sudo cp nginx/sites-available/drive.mulas.me /etc/nginx/sites-available/ +sudo ln -sf /etc/nginx/sites-available/drive.mulas.me /etc/nginx/sites-enabled/drive.mulas.me + +sudo nginx -t && sudo systemctl reload nginx +``` + +What you need on the host for this to work: + +- Nginx built with `headers-more` (the config uses `more_set_headers`) +- PHP-FPM 8.5 with a socket at `/var/run/php/php8.5-fpm.sock` +- A Let's Encrypt cert for `drive.net.mulas.me` and a `dhparams.pem` at `/etc/ssl/private/dhparams.pem` +- Nextcloud unpacked at `/ssda1/www/drive.net.mulas.me/` + +## Wiring Nextcloud to the stack + +In `config/config.php` (not in this repo): + +```php +'dbtype' => 'mysql', +'dbhost' => '127.0.0.1:3306', +'dbname' => '', +'dbuser' => '', +'dbpassword' => trim(file_get_contents('/opt/nextcloud/secrets/mariadb_app_password.txt')), + +'memcache.local' => '\OC\Memcache\APCu', +'memcache.distributed' => '\OC\Memcache\Memcached', +'memcache.locking' => '\OC\Memcache\Redis', +'redis' => ['host' => '127.0.0.1', 'port' => 6379], +'memcached_servers' => [['127.0.0.1', 11211]], +``` + +## Things worth knowing before reusing this elsewhere + +- The compose file publishes 3306/6379/11211 on all interfaces — fine when Nextcloud runs on the same host and the box has a firewall, but bind them to `127.0.0.1` if you're not in that situation. +- `set_real_ip_from` in `nginx.conf` trusts `127.0.0.1` and `192.168.1.0/24`. Change it for your network. +- `ssl.conf` is TLS 1.2 only. There's a commented-out line to flip on TLS 1.3 when you're ready. +- `client_max_body_size` is 50 GB and the proxy/fastcgi timeouts are essentially infinite — that's deliberate for large WebDAV uploads and long sync sessions, not an oversight. + +## License + +BSD 3-clause — see [LICENSE](LICENSE). diff --git a/docker/.env.example b/docker/.env.example new file mode 100644 index 0000000..e579a64 --- /dev/null +++ b/docker/.env.example @@ -0,0 +1,15 @@ +ENV_BASE_DIR=/opt/nextcloud +ENV_MARIADB_VERSION=11.8-ubi9 +ENV_REDIS_VERSION=7.4.9-alpine +ENV_MEMCACHED_VERSION=alpine3.23 + +ENV_MYSQL_USER=nextcloud +ENV_MYSQL_DATABASE=nextcloud + +ENV_BACKUP_VERSION=1.2.0 +ENV_BACKUP_S3_BUCKET= +ENV_BACKUP_S3_PREFIX=nextcloud-db +ENV_BACKUP_S3_REGION=us-east-1 +ENV_BACKUP_S3_ACCESS_KEY= +ENV_BACKUP_S3_SECRET_KEY= +ENV_BACKUP_S3_ENDPOINT= diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..d96f95f --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,107 @@ +############################################################ +# # +# ________ ___ # +# / ____/ |/ / /\_/\ * # +# / / / /|_/ / ( o.o ) # +# / /___/ / / / > ^ < # +# \____/_/ /_/ _| |_ # +# # +# Maria DB server + backup container for Nextcloud # +# Author: Corrado Mulas # +# # +# No rights reserved 2026 # +# * lil' bastard fiber eater # +############################################################ + +services: + + db: + container_name: nextcloud-db + image: mariadb:${ENV_MARIADB_VERSION:-11.8-ubi9} + volumes: + - ${ENV_BASE_DIR}/mariadb/data:/var/lib/mysql + - ${ENV_BASE_DIR}/mariadb/config:/etc/mysql/conf.d + - ${ENV_BASE_DIR}/mariadb/socket:/var/run/mysqld + networks: + - nextcloud_cts + ports: + - "3306:3306" + + restart: always + secrets: + - mysql_root_password + - mysql_app_password + + + environment: + - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql_root_password + - MYSQL_PASSWORD_FILE=/run/secrets/mysql_app_password + - MYSQL_USER=${ENV_MYSQL_USER} + - MYSQL_DATABASE=${ENV_MYSQL_DATABASE} + - MYSQL_ALLOW_EMPTY_PASSWORD=no + + healthcheck: + test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD + + redis: + container_name: nextcloud-redis + image: redis:${ENV_REDIS_VERSION:-7.4.9-alpine} + volumes: + - ${ENV_BASE_DIR}/redis/data:/data + - ${ENV_BASE_DIR}/redis/config:/usr/local/etc/redis + - ${ENV_BASE_DIR}/redis/socket:/var/run/redis + networks: + - nextcloud_cts + ports: + - "6379:6379" + + restart: always + + memcached: + container_name: nextcloud-memcached + image: memcached:${ENV_MEMCACHED_VERSION:-alpine3.23} + volumes: + - ${ENV_BASE_DIR}/memcached/data:/data + - ${ENV_BASE_DIR}/memcached/config:/etc/memcached.conf + - ${ENV_BASE_DIR}/memcached/socket:/var/run/memcached + networks: + - nextcloud_cts + ports: + - "11211:11211" + + restart: always + + backup: + container_name: nextcloud-backup + image: databack/mysql-backup:${ENV_BACKUP_VERSION:-1.2.0} + networks: + - nextcloud_cts + + restart: always + secrets: + - mysql_root_password + + environment: + - DB_SERVER=db + - DB_PORT=3306 + - DB_USER=root + - DB_PASS_FILE=/run/secrets/mysql_root_password + - DB_DUMP_CRON=0 */6 * * * + - DB_DUMP_RETENTION=28 + - DB_DUMP_TARGET=s3://${ENV_BACKUP_S3_BUCKET}/${ENV_BACKUP_S3_PREFIX} + - AWS_ACCESS_KEY_ID=${ENV_BACKUP_S3_ACCESS_KEY} + - AWS_SECRET_ACCESS_KEY=${ENV_BACKUP_S3_SECRET_KEY} + - AWS_DEFAULT_REGION=${ENV_BACKUP_S3_REGION} + - AWS_ENDPOINT_URL=${ENV_BACKUP_S3_ENDPOINT} + +# secret files on server +secrets: + mysql_root_password: + file: /opt/nextcloud/secrets/mariadb_root_password.txt + mysql_app_password: + file: /opt/nextcloud/secrets/mariadb_app_password.txt + +# default network for this docker stack +networks: + nextcloud_cts: + driver: bridge diff --git a/nginx/conf.d/header.conf b/nginx/conf.d/header.conf new file mode 100644 index 0000000..e2a693d --- /dev/null +++ b/nginx/conf.d/header.conf @@ -0,0 +1,18 @@ + # This is an NGINX configuration file written and used by me in order to set security response headers. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + +add_header Referrer-Policy "no-referrer" always; +add_header X-Content-Type-Options "nosniff" always; +add_header X-Frame-Options "SAMEORIGIN" always; +add_header X-Permitted-Cross-Domain-Policies "none" always; +add_header X-Robots-Tag "noindex, nofollow" always; + +add_header Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), interest-cohort=(), magnetometer=(), microphone=(), payment=(), usb=()" always; + +add_header Cross-Origin-Opener-Policy "same-origin" always; diff --git a/nginx/conf.d/ssl.conf b/nginx/conf.d/ssl.conf new file mode 100644 index 0000000..c00d008 --- /dev/null +++ b/nginx/conf.d/ssl.conf @@ -0,0 +1,20 @@ + # This is an NGINX configuration file written and used by me in order to set a hardened TLS profile. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +ssl_dhparam /etc/ssl/private/dhparams.pem; + +ssl_protocols TLSv1.2 TLSv1.3; +ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; +ssl_prefer_server_ciphers off; + +ssl_session_timeout 1d; +ssl_session_cache shared:SSL:50m; +ssl_session_tickets off; + +ssl_stapling on; +ssl_stapling_verify on; +ssl_buffer_size 4k; \ No newline at end of file diff --git a/nginx/custom.d/cors b/nginx/custom.d/cors new file mode 100644 index 0000000..8be21e9 --- /dev/null +++ b/nginx/custom.d/cors @@ -0,0 +1,49 @@ + # This is an NGINX configuration file written and used by me in order to enable CORS support. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +# +# CORS header support +# +# One way to use this is by placing it into a file called "cors_support" +# under your Nginx configuration directory and placing the following +# statement inside your **location** block(s): +# +# include cors_support; +# +# As of Nginx 1.7.5, add_header supports an "always" parameter which +# allows CORS to work if the backend returns 4xx or 5xx status code. +# +# For more information on CORS, please see: http://enable-cors.org/ +# Forked from this Gist: https://gist.github.com/michiel/1064640 +# + +set $cors ''; +set $http_origin '*'; + set $cors 'true'; + + + access_log off; + add_header Pragma public; +expires 365d; + add_header Cache-Control "public, no-transform"; + +if ($cors = 'true') { + add_header 'Access-Control-Allow-Origin' "$http_origin" always; + add_header 'Access-Control-Allow-Credentials' 'true' always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always; + # required to be able to read Authorization header in frontend + #add_header 'Access-Control-Expose-Headers' 'Authorization' always; +} + +if ($request_method = 'OPTIONS') { + # Tell client that this pre-flight info is valid for 20 days + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; +} \ No newline at end of file diff --git a/nginx/custom.d/errorpage b/nginx/custom.d/errorpage new file mode 100644 index 0000000..d649d68 --- /dev/null +++ b/nginx/custom.d/errorpage @@ -0,0 +1,57 @@ + # This is an NGINX configuration file written and used by me in order to map HTTP errors to static HTML pages. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + + # error_page 503 /main.html; + # location = /maint.html { + # root /var/www/; + # } + +########### 4xx ########################## + + error_page 401 @error41; + location @error41 { + root /var/www/errors; + rewrite ^(.*)$ /401.html break; + } + + error_page 403 @error43; + location @error43 { + root /var/www/errors; + rewrite ^(.*)$ /403.html break; + } + + error_page 404 @error44; + location @error44 { + root /var/www/errors; + rewrite ^(.*)$ /404.html break; + } + +########### 5xx ###########################à + + error_page 500 @error50; + location @error50 { + root /var/www/errors; + rewrite ^(.*)$ /500.html break; + } + + error_page 502 @error52; + location @error52 { + root /var/www/errors; + rewrite ^(.*)$ /502.html break; + } + + error_page 503 @error53; + location @error53 { + root /var/www/errors; + rewrite ^(.*)$ /503.html break; + } + + error_page 504 @error54; + location @error54 { + root /var/www/errors; + rewrite ^(.*)$ /504.html break; + } \ No newline at end of file diff --git a/nginx/custom.d/jsonerrorpage b/nginx/custom.d/jsonerrorpage new file mode 100644 index 0000000..9400b30 --- /dev/null +++ b/nginx/custom.d/jsonerrorpage @@ -0,0 +1,190 @@ + # This is an NGINX configuration file written and used by me in order to return error pages in JSON format, in API contexts. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +error_page 400 /400.json; +location /400.json{ + return 400 '{"error": {"status_code": 400,"status": "Bad Request"}}'; +} + +error_page 401 /401.json; +location /401.json{ + return 401 '{"error": {"status_code": 401,"status": "Unauthorized"}}'; +} + +error_page 402 /402.json; +location /402.json{ + return 402 '{"error": {"status_code": 402,"status": "Payment Required"}}'; +} + +error_page 403 /403.json; +location /403.json{ + return 403 '{"error": {"status_code": 403,"status": "Forbidden"}}'; +} + +error_page 404 /404.json; +location /404.json{ + return 404 '{"error": {"status_code": 404,"status": "Not Found"}}'; +} + +error_page 405 /405.json; +location /405.json{ + return 405 '{"error": {"status_code": 405,"status": "Method Not Allowed"}}'; +} + +error_page 406 /406.json; +location /406.json{ + return 406 '{"error": {"status_code": 406,"status": "Not Acceptable"}}'; +} + +error_page 407 /407.json; +location /407.json{ + return 407 '{"error": {"status_code": 407,"status": "Proxy Authentication Required"}}'; +} + +error_page 408 /408.json; +location /408.json{ + return 408 '{"error": {"status_code": 408,"status": "Request Timeout}}'; +} + +error_page 409 /409.json; +location /409.json{ + return 409 '{"error": {"status_code": 409,"status": "Conflict"}}'; +} + +error_page 410 /410.json; +location /410.json{ + return 410 '{"error": {"status_code": 410,"status": "Gone"}}'; +} + +error_page 411 /411.json; +location /411.json{ + return 411 '{"error": {"status_code": 411,"status": "Length Required"}}'; +} + +error_page 412 /412.json; +location /412.json{ + return 412 '{"error": {"status_code": 412,"status": "Precondition Failed"}}'; +} + +error_page 413 /413.json; +location /413.json{ + return 413 '{"error": {"status_code": 413,"status": "Payload Too Large"}}'; +} + +error_page 414 /414.json; +location /414.json{ + return 414 '{"error": {"status_code": 414,"status": "URI Too Long"}}'; +} + +error_page 415 /415.json; +location /415.json{ + return 415 '{"error": {"status_code": 415,"status": "Unsupported Media Type"}}'; +} + +error_page 416 /416.json; +location /416.json{ + return 416 '{"error": {"status_code": 416,"status": "Range Not Satisfiable"}}'; +} + +error_page 417 /417.json; +location /417.json{ + return 417 '{"error": {"status_code": 417,"status": "Expectation Failed"}}'; +} + +error_page 418 /418.json; +location /418.json{ + return 418 '{"error": {"status_code": 418,"status": "I\'m a teapot"}}'; +} + +error_page 420 /420.json; +location /420.json{ + return 420 '{"error": {"status_code": 420,"status": "Enhance your calm"}}'; +} + +error_page 422 /422.json; +location /422.json{ + return 422 '{"error": {"status_code": 422,"status": "Unprocessable Entity"}}'; +} + +error_page 423 /423.json; +location /423.json{ + return 423 '{"error": {"status_code": 423,"status": "Locked"}}'; +} + +error_page 424 /424.json; +location /424.json{ + return 424 '{"error": {"status_code": 424,"status": "Failed Dependency"}}'; +} + +error_page 426 /426.json; +location /426.json{ + return 426 '{"error": {"status_code": 426,"status": "Upgrade Required"}}'; +} + +error_page 428 /428.json; +location /428.json{ + return 428 '{"error": {"status_code": 428,"status": "Precondition Required"}}'; +} + +error_page 429 /429.json; +location /429.json{ + return 429 '{"error": {"status_code": 429,"status": "Too Many Requests"}}'; +} + +error_page 431 /431.json; +location /431.json{ + return 431 '{"error": {"status_code": 431,"status": "Request Header Fields Too Large"}}'; +} + +error_page 451 /451.json; +location /451.json{ + return 451 '{"error": {"status_code": 451,"status": "Unavailable For Legal Reasons"}}'; +} + +error_page 500 /500.json; +location /500.json{ + return 500 '{"error": {"status_code": 500,"status": "Internal Server Error"}}'; +} + +error_page 501 /501.json; +location /501.json{ + return 501 '{"error": {"status_code": 501,"status": "Not Implemented"}}'; +} +error_page 502 /502.json; +location /502.json{ + return 502 '{"error": {"status_code": 502,"status": "Bad Gateway"}}'; +} + +error_page 503 /503.json; +location /503.json{ + return 503 '{"error": {"status_code": 503,"status": "Service Temporarily Unavailable"}}'; +} + +error_page 504 /504.json; +location /504.json{ + return 504 '{"error": {"status_code": 504,"status": "Gateway Timeout"}}'; +} + +error_page 505 /505.json; +location /505.json{ + return 505 '{"error": {"status_code": 505,"status": "HTTP Version Not Supported"}}'; +} + +error_page 506 /506.json; +location /506.json{ + return 506 '{"error": {"status_code": 506,"status": "Variant Also Negotiates"}}'; +} + +error_page 507 /507.json; +location /507.json{ + return 507 '{"error": {"status_code": 507,"status": "Insufficient Storage"}}'; +} + +error_page 511 /511.json; +location /511.json{ + return 511 '{"error": {"status_code": 511,"status": "Network Authentication Required"}}'; +} \ No newline at end of file diff --git a/nginx/custom.d/koi-utf b/nginx/custom.d/koi-utf new file mode 100644 index 0000000..fefee29 --- /dev/null +++ b/nginx/custom.d/koi-utf @@ -0,0 +1,115 @@ + # This is an NGINX configuration file written and used by me in order to define a KOI8-R to UTF-8 charset map. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +# This map is not a full koi8-r <> utf8 map: it does not contain +# box-drawing and some other characters. Besides this map contains +# several koi8-u and Byelorussian letters which are not in koi8-r. +# If you need a full and standard map, use contrib/unicode2nginx/koi-utf +# map instead. + +charset_map koi8-r utf-8 { + + 80 E282AC ; # euro + + 95 E280A2 ; # bullet + + 9A C2A0 ; #   + + 9E C2B7 ; # · + + A3 D191 ; # small yo + A4 D194 ; # small Ukrainian ye + + A6 D196 ; # small Ukrainian i + A7 D197 ; # small Ukrainian yi + + AD D291 ; # small Ukrainian soft g + AE D19E ; # small Byelorussian short u + + B0 C2B0 ; # ° + + B3 D081 ; # capital YO + B4 D084 ; # capital Ukrainian YE + + B6 D086 ; # capital Ukrainian I + B7 D087 ; # capital Ukrainian YI + + B9 E28496 ; # numero sign + + BD D290 ; # capital Ukrainian soft G + BE D18E ; # capital Byelorussian short U + + BF C2A9 ; # (C) + + C0 D18E ; # small yu + C1 D0B0 ; # small a + C2 D0B1 ; # small b + C3 D186 ; # small ts + C4 D0B4 ; # small d + C5 D0B5 ; # small ye + C6 D184 ; # small f + C7 D0B3 ; # small g + C8 D185 ; # small kh + C9 D0B8 ; # small i + CA D0B9 ; # small j + CB D0BA ; # small k + CC D0BB ; # small l + CD D0BC ; # small m + CE D0BD ; # small n + CF D0BE ; # small o + + D0 D0BF ; # small p + D1 D18F ; # small ya + D2 D180 ; # small r + D3 D181 ; # small s + D4 D182 ; # small t + D5 D183 ; # small u + D6 D0B6 ; # small zh + D7 D0B2 ; # small v + D8 D18C ; # small soft sign + D9 D18B ; # small y + DA D0B7 ; # small z + DB D188 ; # small sh + DC D18D ; # small e + DD D189 ; # small shch + DE D187 ; # small ch + DF D18A ; # small hard sign + + E0 D0AE ; # capital YU + E1 D090 ; # capital A + E2 D091 ; # capital B + E3 D0A6 ; # capital TS + E4 D094 ; # capital D + E5 D095 ; # capital YE + E6 D0A4 ; # capital F + E7 D093 ; # capital G + E8 D0A5 ; # capital KH + E9 D098 ; # capital I + EA D099 ; # capital J + EB D09A ; # capital K + EC D09B ; # capital L + ED D09C ; # capital M + EE D09D ; # capital N + EF D09E ; # capital O + + F0 D09F ; # capital P + F1 D0AF ; # capital YA + F2 D0A0 ; # capital R + F3 D0A1 ; # capital S + F4 D0A2 ; # capital T + F5 D0A3 ; # capital U + F6 D096 ; # capital ZH + F7 D092 ; # capital V + F8 D0AC ; # capital soft sign + F9 D0AB ; # capital Y + FA D097 ; # capital Z + FB D0A8 ; # capital SH + FC D0AD ; # capital E + FD D0A9 ; # capital SHCH + FE D0A7 ; # capital CH + FF D0AA ; # capital hard sign +} \ No newline at end of file diff --git a/nginx/custom.d/koi-win b/nginx/custom.d/koi-win new file mode 100644 index 0000000..416dcee --- /dev/null +++ b/nginx/custom.d/koi-win @@ -0,0 +1,109 @@ + # This is an NGINX configuration file written and used by me in order to define a KOI8-R to Windows-1251 charset map. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +charset_map koi8-r windows-1251 { + + 80 88 ; # euro + + 95 95 ; # bullet + + 9A A0 ; #   + + 9E B7 ; # · + + A3 B8 ; # small yo + A4 BA ; # small Ukrainian ye + + A6 B3 ; # small Ukrainian i + A7 BF ; # small Ukrainian yi + + AD B4 ; # small Ukrainian soft g + AE A2 ; # small Byelorussian short u + + B0 B0 ; # ° + + B3 A8 ; # capital YO + B4 AA ; # capital Ukrainian YE + + B6 B2 ; # capital Ukrainian I + B7 AF ; # capital Ukrainian YI + + B9 B9 ; # numero sign + + BD A5 ; # capital Ukrainian soft G + BE A1 ; # capital Byelorussian short U + + BF A9 ; # (C) + + C0 FE ; # small yu + C1 E0 ; # small a + C2 E1 ; # small b + C3 F6 ; # small ts + C4 E4 ; # small d + C5 E5 ; # small ye + C6 F4 ; # small f + C7 E3 ; # small g + C8 F5 ; # small kh + C9 E8 ; # small i + CA E9 ; # small j + CB EA ; # small k + CC EB ; # small l + CD EC ; # small m + CE ED ; # small n + CF EE ; # small o + + D0 EF ; # small p + D1 FF ; # small ya + D2 F0 ; # small r + D3 F1 ; # small s + D4 F2 ; # small t + D5 F3 ; # small u + D6 E6 ; # small zh + D7 E2 ; # small v + D8 FC ; # small soft sign + D9 FB ; # small y + DA E7 ; # small z + DB F8 ; # small sh + DC FD ; # small e + DD F9 ; # small shch + DE F7 ; # small ch + DF FA ; # small hard sign + + E0 DE ; # capital YU + E1 C0 ; # capital A + E2 C1 ; # capital B + E3 D6 ; # capital TS + E4 C4 ; # capital D + E5 C5 ; # capital YE + E6 D4 ; # capital F + E7 C3 ; # capital G + E8 D5 ; # capital KH + E9 C8 ; # capital I + EA C9 ; # capital J + EB CA ; # capital K + EC CB ; # capital L + ED CC ; # capital M + EE CD ; # capital N + EF CE ; # capital O + + F0 CF ; # capital P + F1 DF ; # capital YA + F2 D0 ; # capital R + F3 D1 ; # capital S + F4 D2 ; # capital T + F5 D3 ; # capital U + F6 C6 ; # capital ZH + F7 C2 ; # capital V + F8 DC ; # capital soft sign + F9 DB ; # capital Y + FA C7 ; # capital Z + FB D8 ; # capital SH + FC DD ; # capital E + FD D9 ; # capital SHCH + FE D7 ; # capital CH + FF DA ; # capital hard sign +} \ No newline at end of file diff --git a/nginx/custom.d/mime.types b/nginx/custom.d/mime.types new file mode 100644 index 0000000..f26fa71 --- /dev/null +++ b/nginx/custom.d/mime.types @@ -0,0 +1,97 @@ + # This is an NGINX configuration file written and used by me in order to define MIME types for served files. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +types { + text/html html htm shtml; + text/css css; + text/xml xml; + image/gif gif; + image/jpeg jpeg jpg; + application/javascript js; + text/javascript mjs; + application/wasm wasm; + 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/tiff tif tiff; + image/vnd.wap.wbmp wbmp; + image/x-icon ico; + image/x-jng jng; + image/x-ms-bmp bmp; + image/svg+xml svg svgz; + image/webp webp; + + application/font-woff woff; + 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.ms-excel xls; + application/vnd.ms-fontobject eot; + application/vnd.ms-powerpoint ppt; + application/vnd.wap.wmlc wmlc; + application/vnd.google-earth.kml+xml kml; + application/vnd.google-earth.kmz kmz; + 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; + + application/vnd.openxmlformats-officedocument.wordprocessingml.document docx; + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx; + application/vnd.openxmlformats-officedocument.presentationml.presentation pptx; + + 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; +} \ No newline at end of file diff --git a/nginx/custom.d/proxy_params b/nginx/custom.d/proxy_params new file mode 100644 index 0000000..71082e1 --- /dev/null +++ b/nginx/custom.d/proxy_params @@ -0,0 +1,11 @@ + # This is an NGINX configuration file written and used by me in order to set proxy request headers. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +proxy_set_header Host $http_host; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header X-Forwarded-Proto $scheme; \ No newline at end of file diff --git a/nginx/custom.d/win-utf b/nginx/custom.d/win-utf new file mode 100644 index 0000000..a4a1d1f --- /dev/null +++ b/nginx/custom.d/win-utf @@ -0,0 +1,132 @@ + # This is an NGINX configuration file written and used by me in order to define a Windows-1251 to UTF-8 charset map. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +# This map is not a full windows-1251 <> utf8 map: it does not +# contain Serbian and Macedonian letters. If you need a full map, +# use contrib/unicode2nginx/win-utf map instead. + +charset_map windows-1251 utf-8 { + + 82 E2809A; # single low-9 quotation mark + + 84 E2809E; # double low-9 quotation mark + 85 E280A6; # ellipsis + 86 E280A0; # dagger + 87 E280A1; # double dagger + 88 E282AC; # euro + 89 E280B0; # per mille + + 91 E28098; # left single quotation mark + 92 E28099; # right single quotation mark + 93 E2809C; # left double quotation mark + 94 E2809D; # right double quotation mark + 95 E280A2; # bullet + 96 E28093; # en dash + 97 E28094; # em dash + + 99 E284A2; # trade mark sign + + A0 C2A0; #   + A1 D18E; # capital Byelorussian short U + A2 D19E; # small Byelorussian short u + + A4 C2A4; # currency sign + A5 D290; # capital Ukrainian soft G + A6 C2A6; # borken bar + A7 C2A7; # section sign + A8 D081; # capital YO + A9 C2A9; # (C) + AA D084; # capital Ukrainian YE + AB C2AB; # left-pointing double angle quotation mark + AC C2AC; # not sign + AD C2AD; # soft hypen + AE C2AE; # (R) + AF D087; # capital Ukrainian YI + + B0 C2B0; # ° + B1 C2B1; # plus-minus sign + B2 D086; # capital Ukrainian I + B3 D196; # small Ukrainian i + B4 D291; # small Ukrainian soft g + B5 C2B5; # micro sign + B6 C2B6; # pilcrow sign + B7 C2B7; # · + B8 D191; # small yo + B9 E28496; # numero sign + BA D194; # small Ukrainian ye + BB C2BB; # right-pointing double angle quotation mark + + BF D197; # small Ukrainian yi + + C0 D090; # capital A + C1 D091; # capital B + C2 D092; # capital V + C3 D093; # capital G + C4 D094; # capital D + C5 D095; # capital YE + C6 D096; # capital ZH + C7 D097; # capital Z + C8 D098; # capital I + C9 D099; # capital J + CA D09A; # capital K + CB D09B; # capital L + CC D09C; # capital M + CD D09D; # capital N + CE D09E; # capital O + CF D09F; # capital P + + D0 D0A0; # capital R + D1 D0A1; # capital S + D2 D0A2; # capital T + D3 D0A3; # capital U + D4 D0A4; # capital F + D5 D0A5; # capital KH + D6 D0A6; # capital TS + D7 D0A7; # capital CH + D8 D0A8; # capital SH + D9 D0A9; # capital SHCH + DA D0AA; # capital hard sign + DB D0AB; # capital Y + DC D0AC; # capital soft sign + DD D0AD; # capital E + DE D0AE; # capital YU + DF D0AF; # capital YA + + E0 D0B0; # small a + E1 D0B1; # small b + E2 D0B2; # small v + E3 D0B3; # small g + E4 D0B4; # small d + E5 D0B5; # small ye + E6 D0B6; # small zh + E7 D0B7; # small z + E8 D0B8; # small i + E9 D0B9; # small j + EA D0BA; # small k + EB D0BB; # small l + EC D0BC; # small m + ED D0BD; # small n + EE D0BE; # small o + EF D0BF; # small p + + F0 D180; # small r + F1 D181; # small s + F2 D182; # small t + F3 D183; # small u + F4 D184; # small f + F5 D185; # small kh + F6 D186; # small ts + F7 D187; # small ch + F8 D188; # small sh + F9 D189; # small shch + FA D18A; # small hard sign + FB D18B; # small y + FC D18C; # small soft sign + FD D18D; # small e + FE D18E; # small yu + FF D18F; # small ya +} \ No newline at end of file diff --git a/nginx/fcgi.d/fastcgi-php.conf b/nginx/fcgi.d/fastcgi-php.conf new file mode 100644 index 0000000..72519b2 --- /dev/null +++ b/nginx/fcgi.d/fastcgi-php.conf @@ -0,0 +1,20 @@ + # This is an NGINX configuration file written and used by me in order to set FastCGI parameters for PHP. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +# regex to split $uri to $fastcgi_script_name and $fastcgi_path +fastcgi_split_path_info ^(.+\.php)(/.+)$; + +# Check that the PHP script exists before passing it +try_files $fastcgi_script_name =404; + +# Bypass the fact that try_files resets $fastcgi_path_info +# see: http://trac.nginx.org/nginx/ticket/321 +set $path_info $fastcgi_path_info; +fastcgi_param PATH_INFO $path_info; + +fastcgi_index index.php; +include /etc/nginx/fcgi.d/fastcgi.conf; \ No newline at end of file diff --git a/nginx/fcgi.d/fastcgi.conf b/nginx/fcgi.d/fastcgi.conf new file mode 100644 index 0000000..689e38d --- /dev/null +++ b/nginx/fcgi.d/fastcgi.conf @@ -0,0 +1,32 @@ + # This is an NGINX configuration file written and used by me in order to set the full FastCGI parameter set. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; +fastcgi_param QUERY_STRING $query_string; +fastcgi_param REQUEST_METHOD $request_method; +fastcgi_param CONTENT_TYPE $content_type; +fastcgi_param CONTENT_LENGTH $content_length; + +fastcgi_param SCRIPT_NAME $fastcgi_script_name; +fastcgi_param REQUEST_URI $request_uri; +fastcgi_param DOCUMENT_URI $document_uri; +fastcgi_param DOCUMENT_ROOT $document_root; +fastcgi_param SERVER_PROTOCOL $server_protocol; +fastcgi_param REQUEST_SCHEME $scheme; +fastcgi_param HTTPS $https if_not_empty; + +fastcgi_param GATEWAY_INTERFACE CGI/1.1; +fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; + +fastcgi_param REMOTE_ADDR $remote_addr; +fastcgi_param REMOTE_PORT $remote_port; +fastcgi_param SERVER_ADDR $server_addr; +fastcgi_param SERVER_PORT $server_port; +fastcgi_param SERVER_NAME $server_name; + +# PHP only, required if PHP was built with --enable-force-cgi-redirect +fastcgi_param REDIRECT_STATUS 200; \ No newline at end of file diff --git a/nginx/fcgi.d/fastcgi_params b/nginx/fcgi.d/fastcgi_params new file mode 100644 index 0000000..bed71e4 --- /dev/null +++ b/nginx/fcgi.d/fastcgi_params @@ -0,0 +1,31 @@ + # This is an NGINX configuration file written and used by me in order to set FastCGI request parameters. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +fastcgi_param QUERY_STRING $query_string; +fastcgi_param REQUEST_METHOD $request_method; +fastcgi_param CONTENT_TYPE $content_type; +fastcgi_param CONTENT_LENGTH $content_length; + +fastcgi_param SCRIPT_NAME $fastcgi_script_name; +fastcgi_param REQUEST_URI $request_uri; +fastcgi_param DOCUMENT_URI $document_uri; +fastcgi_param DOCUMENT_ROOT $document_root; +fastcgi_param SERVER_PROTOCOL $server_protocol; +fastcgi_param REQUEST_SCHEME $scheme; +fastcgi_param HTTPS $https if_not_empty; + +fastcgi_param GATEWAY_INTERFACE CGI/1.1; +fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; + +fastcgi_param REMOTE_ADDR $remote_addr; +fastcgi_param REMOTE_PORT $remote_port; +fastcgi_param SERVER_ADDR $server_addr; +fastcgi_param SERVER_PORT $server_port; +fastcgi_param SERVER_NAME $server_name; + +# PHP only, required if PHP was built with --enable-force-cgi-redirect +fastcgi_param REDIRECT_STATUS 200; \ No newline at end of file diff --git a/nginx/fcgi.d/scgi_params b/nginx/fcgi.d/scgi_params new file mode 100644 index 0000000..5c02cba --- /dev/null +++ b/nginx/fcgi.d/scgi_params @@ -0,0 +1,23 @@ + # This is an NGINX configuration file written and used by me in order to set SCGI request parameters. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +iscgi_param REQUEST_METHOD $request_method; +scgi_param REQUEST_URI $request_uri; +scgi_param QUERY_STRING $query_string; +scgi_param CONTENT_TYPE $content_type; + +scgi_param DOCUMENT_URI $document_uri; +scgi_param DOCUMENT_ROOT $document_root; +scgi_param SCGI 1; +scgi_param SERVER_PROTOCOL $server_protocol; +scgi_param REQUEST_SCHEME $scheme; +scgi_param HTTPS $https if_not_empty; + +scgi_param REMOTE_ADDR $remote_addr; +scgi_param REMOTE_PORT $remote_port; +scgi_param SERVER_PORT $server_port; +scgi_param SERVER_NAME $server_name; \ No newline at end of file diff --git a/nginx/fcgi.d/uwsgi_params b/nginx/fcgi.d/uwsgi_params new file mode 100644 index 0000000..719cc93 --- /dev/null +++ b/nginx/fcgi.d/uwsgi_params @@ -0,0 +1,23 @@ + # This is an NGINX configuration file written and used by me in order to set uWSGI request parameters. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +uwsgi_param QUERY_STRING $query_string; +uwsgi_param REQUEST_METHOD $request_method; +uwsgi_param CONTENT_TYPE $content_type; +uwsgi_param CONTENT_LENGTH $content_length; + +uwsgi_param REQUEST_URI $request_uri; +uwsgi_param PATH_INFO $document_uri; +uwsgi_param DOCUMENT_ROOT $document_root; +uwsgi_param SERVER_PROTOCOL $server_protocol; +uwsgi_param REQUEST_SCHEME $scheme; +uwsgi_param HTTPS $https if_not_empty; + +uwsgi_param REMOTE_ADDR $remote_addr; +uwsgi_param REMOTE_PORT $remote_port; +uwsgi_param SERVER_PORT $server_port; +uwsgi_param SERVER_NAME $server_name; \ No newline at end of file diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..c35f16d --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,73 @@ + # This is an NGINX configuration file written and used by me in order to configure NGINX globally. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +user www-data; +worker_processes auto; +pid /run/nginx.pid; +include /etc/nginx/modules-enabled/*.conf; + +events { + worker_connections 1024; + multi_accept on; + use epoll; +} + +http { + + client_max_body_size 50G; + disable_symlinks off; + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + proxy_connect_timeout 99999s; + proxy_send_timeout 99999s; + proxy_read_timeout 99999s; + fastcgi_send_timeout 99999s; + fastcgi_read_timeout 99999s; + + server_names_hash_bucket_size 64; + + set_real_ip_from 127.0.0.1; + set_real_ip_from 192.168.1.0/24; + real_ip_header X-Forwarded-For; + real_ip_recursive on; + + include /etc/nginx/custom.d/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings — protocols and ciphers live in conf.d/ssl.conf + ## + + ## + # Logging Settings + ## + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + ## + # Gzip Settings + ## + + gzip on; + gzip_disable "msie6"; + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; + + server_tokens off; # removed pound sign + more_set_headers 'Server: D-I/O-CANet WS'; + more_set_headers 'X-Powered-By: Mago Otelma'; +} \ No newline at end of file diff --git a/nginx/sites-available/drive.mulas.me b/nginx/sites-available/drive.mulas.me new file mode 100644 index 0000000..1237fd1 --- /dev/null +++ b/nginx/sites-available/drive.mulas.me @@ -0,0 +1,146 @@ + # This is an NGINX configuration file written and used by me in order to serve my Nextcloud instance at drive.net.mulas.me. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +upstream php-handler { + server unix:/var/run/php/php8.5-fpm.sock; +} + +server { + listen 80; + + server_name drive.net.mulas.me; + include /etc/nginx/snippets/letsencrypt-acme-challenge.conf; + + rewrite ^ https://drive.net.mulas.me$request_uri? permanent; +} + +server { + server_name drive.net.mulas.me; + listen 443 ssl http2; + + include /etc/nginx/snippets/letsencrypt-acme-challenge.conf; + + ssl_certificate /etc/letsencrypt/live/drive.net.mulas.me/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/drive.net.mulas.me/privkey.pem; + ssl_stapling on; + + root /ssda1/www/drive.net.mulas.me/; + + location = / { + if ($http_user_agent ~ ^DavClnt) { + return 302 /remote.php/webdav/$is_args$args; + } + } + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + location = /.well-known/carddav { + return 301 $scheme://$host/remote.php/dav; + } + + + location = /.well-known/caldav { + return 301 $scheme://$host/remote.php/dav; + } + + #SOCIAL app enabled? Please uncomment the following row + rewrite ^/.well-known/webfinger /public.php?service=webfinger last; + + #WEBFINGER app enabled? Please uncomment the following two rows. + rewrite ^/.well-known/host-meta /public.php?service=host-meta last; + rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; + client_max_body_size 50G; + + location / { + rewrite ^ /index.php; + } + + location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { + return 404; + } + + location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { + return 404; + } + + location ^~ /apps/rainloop/app/data { + deny all; + } + + # location ~ \.(?:flv|mp4|mov|m4a)$ { + # mp4; + # mp4_buffer_size 100M; + # mp4_max_buffer_size 10240M; + # fastcgi_split_path_info ^(.+?.php)(\/.*|)$; + # set $path_info $fastcgi_path_info; + # try_files $fastcgi_script_name =404; + # include /etc/nginx/fcgi.d/fastcgi_params; + # # include php_optimization.conf; + # } + + + location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy)\.php(?:$|\/) { + fastcgi_split_path_info ^(.+?\.php)(\/.*|)$; + set $path_info $fastcgi_path_info; + try_files $fastcgi_script_name =404; + include /etc/nginx/fcgi.d/fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $path_info; + fastcgi_param HTTPS on; + # Avoid sending the security headers twice + fastcgi_param modHeadersAvailable true; + # Enable pretty urls + fastcgi_param front_controller_active true; + fastcgi_pass php-handler; + fastcgi_intercept_errors on; + fastcgi_request_buffering off; + fastcgi_max_temp_file_size 0; + fastcgi_hide_header X-Powered-By; + } + + + # location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) { + # fastcgi_split_path_info ^(.+?\.php)(\/.*|)$; + # set $path_info $fastcgi_path_info; + # try_files $fastcgi_script_name =404; + # include /etc/nginx/fcgi.d/fastcgi_params; + # include php_optimization.conf; + # + # } + + location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) { + try_files $uri/ =404; + index index.php; + } + + location ~ \.(?:css|js|svg|gif|map|png|html|ico|jpg|jpeg)$ { + try_files $uri /index.php$request_uri; + access_log off; + expires 360d; + } + + location ~ \.(?:mjs|webp|wasm|tflite|ogg|flac|mp4|webm)$ { + try_files $uri /index.php$request_uri; + access_log off; + expires 360d; + } + + location ~ \.(?:otf|ttf|woff2?)$ { + try_files $uri /index.php$request_uri; + access_log off; + expires 7d; + } + + location /remote { + return 301 /remote.php$request_uri; + } + +} \ No newline at end of file diff --git a/nginx/snippets/letsencrypt-acme-challenge.conf b/nginx/snippets/letsencrypt-acme-challenge.conf new file mode 100644 index 0000000..c205ef5 --- /dev/null +++ b/nginx/snippets/letsencrypt-acme-challenge.conf @@ -0,0 +1,51 @@ + # This is an NGINX configuration file written and used by me in order to serve Let's Encrypt ACME challenges. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +############################################################################# +# Configuration file for Let's Encrypt ACME Challenge location +# This file is already included in listen_xxx.conf files. +# Do NOT include it separately! +############################################################################# +# +# This config enables to access /.well-known/acme-challenge/xxxxxxxxxxx +# on all our sites (HTTP), including all subdomains. +# This is required by ACME Challenge (webroot authentication). +# You can check that this location is working by placing ping.txt here: +# /var/www/letsencrypt/.well-known/acme-challenge/ping.txt +# And pointing your browser to: +# http://xxx.domain.tld/.well-known/acme-challenge/ping.txt +# +# Sources: +# https://community.letsencrypt.org/t/howto-easy-cert-generation-and-renewal-with-nginx/3491 +# +############################################################################# + +# Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx) +# We use ^~ here, so that we don't check other regexes (for speed-up). We actually MUST cancel +# other regex checks, because in our other config files have regex rule that denies access to files with dotted names. +location ^~ /.well-known/acme-challenge/ { + + # Set correct content type. According to this: + # https://community.letsencrypt.org/t/using-the-webroot-domain-verification-method/1445/29 + # Current specification requires "text/plain" or no content header at all. + # It seems that "text/plain" is a safe option. + default_type "text/plain"; + + # This directory must be the same as in /etc/letsencrypt/cli.ini + # as "webroot-path" parameter. Also don't forget to set "authenticator" parameter + # there to "webroot". + # Do NOT use alias, use root! Target directory is located here: + # /var/www/common/letsencrypt/.well-known/acme-challenge/ + root /var/www/letsencrypt; +} + +# Hide /acme-challenge subdirectory and return 404 on all requests. +# It is somewhat more secure than letting Nginx return 403. +# Ending slash is important! +location = /.well-known/acme-challenge/ { + return 404; +} diff --git a/nginx/snippets/snakeoil.conf b/nginx/snippets/snakeoil.conf new file mode 100644 index 0000000..449ccd0 --- /dev/null +++ b/nginx/snippets/snakeoil.conf @@ -0,0 +1,9 @@ + # This is an NGINX configuration file written and used by me in order to load the self-signed snakeoil certificate. + # + # (c) Corrado Mulas + # + # For the full copyright and license information, please view the LICENSE + # file that was distributed with this source code. + +ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; +ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; \ No newline at end of file