From b77b7a74532500b447fd38c48cd97d28d0021921 Mon Sep 17 00:00:00 2001 From: Greg Sarjeant <1686767+gsarjeant@users.noreply.github.com> Date: Sun, 15 Jun 2025 20:03:13 -0400 Subject: [PATCH] Add comments to all example web server configs. --- examples/apache/shared-hosting/.htaccess | 11 +- .../apache/vps/root/tkr.my-domain.com.conf | 32 ++---- .../vps/root/tkr.my-domain.com.ssl.conf | 96 ++++++++++++++++ .../apache/vps/subfolder/my-domain.com.conf | 32 ++---- .../vps/subfolder/my-domain.com.ssl.conf | 89 +++++++++++++++ examples/nginx/root/nginx.conf | 15 +++ examples/nginx/root/nginx.ssl.conf | 107 ++++++++++++++++++ examples/nginx/subfolder/nginx.conf | 13 ++- examples/nginx/subfolder/nginx.ssl.conf | 99 ++++++++++++++++ 9 files changed, 446 insertions(+), 48 deletions(-) create mode 100644 examples/apache/vps/root/tkr.my-domain.com.ssl.conf create mode 100644 examples/apache/vps/subfolder/my-domain.com.ssl.conf create mode 100644 examples/nginx/root/nginx.ssl.conf create mode 100644 examples/nginx/subfolder/nginx.ssl.conf diff --git a/examples/apache/shared-hosting/.htaccess b/examples/apache/shared-hosting/.htaccess index 49e4823..c57d4fa 100644 --- a/examples/apache/shared-hosting/.htaccess +++ b/examples/apache/shared-hosting/.htaccess @@ -1,3 +1,12 @@ +# Example Apache VirtualHost +# for serving tkr as a subdirectory path +# on shared hosting via .htaccess +# +# e.g. http://www.my-domain.com/tkr +# +# This should work without modification if you extract the app +# to /tkr from your web document root + # Enable mod_rewrite RewriteEngine On @@ -14,7 +23,7 @@ RewriteCond %{THE_REQUEST} \s/[^?\s]*\.php[\s?] [NC] RewriteRule ^.*$ - [R=404,L] # Security: Block access to sensitive directories -RewriteRule ^(storage|src|templates|uploads|config)(/.*)?$ - [F,L] +RewriteRule ^(storage|src|templates|examples|config)(/.*)?$ - [F,L] # Security: Block access to hidden files RewriteRule ^\..*$ - [F,L] diff --git a/examples/apache/vps/root/tkr.my-domain.com.conf b/examples/apache/vps/root/tkr.my-domain.com.conf index 4969843..334225e 100644 --- a/examples/apache/vps/root/tkr.my-domain.com.conf +++ b/examples/apache/vps/root/tkr.my-domain.com.conf @@ -1,29 +1,15 @@ -# Apahe VirtualHost example -# for serving tkr as a subdomain root -# e.g. https://tkr.my-domain.com/ +# Example Apache VirtualHost +# for serving tkr as a subdomain root without SSL +# e.g. http://tkr.my-domain.com/ +# +# NOTE: Do not use in production. +# This is provided for docker compose +# (The included docker-compose file will mount it in the container image) - ServerName tkr.my-domain.com + # Replace localhost with your subdomain, e.g. tkr.my-domain.com + ServerName localhost DocumentRoot /var/www/tkr/public -##################################################################### -# Start commenting here to use with docker-compose -##################################################################### - # Redirect HTTP to HTTPS - Redirect permanent / https://tkr.my-domain.com/ - - - - ServerName tkr.my-domain.com - DocumentRoot /var/www/tkr/public - - # SSL Configuration - SSLEngine on - SSLCertificateFile /etc/letsencrypt/live/tkr.my-domain.com/fullchain.pem - SSLCertificateKeyFile /etc/letsencrypt/live/tkr.my-domain.com/privkey.pem -##################################################################### -# Start commenting here to use with docker-compose -##################################################################### - # Security headers Header always set X-Frame-Options "SAMEORIGIN" Header always set X-XSS-Protection "1; mode=block" diff --git a/examples/apache/vps/root/tkr.my-domain.com.ssl.conf b/examples/apache/vps/root/tkr.my-domain.com.ssl.conf new file mode 100644 index 0000000..d1d967f --- /dev/null +++ b/examples/apache/vps/root/tkr.my-domain.com.ssl.conf @@ -0,0 +1,96 @@ +# Example Apache VirtualHost +# for serving tkr as a subdomain root with SSL +# e.g. https://tkr.my-domain.com/ +# +# Use SSL in production. +# This is a minimal SSL confiuration +# For more robust SSL configuration, refer to https://ssl-config.mozilla.org/ + + # Replace localhost with your subdomain, e.g. tkr.my-domain.com + ServerName localhost + DocumentRoot /var/www/tkr/public + # Redirect HTTP to HTTPS + Redirect permanent / https://tkr.my-domain.com/ + + + + ServerName localhost + DocumentRoot /var/www/tkr/public + + # SSL Configuration + SSLEngine on + + # Assumes you're using letsencrypt for cert generation + # Replace with the actual paths to your cert and key + SSLCertificateFile /etc/letsencrypt/live/tkr.my-domain.com/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/tkr.my-domain.com/privkey.pem + + # Security headers + Header always set X-Frame-Options "SAMEORIGIN" + Header always set X-XSS-Protection "1; mode=block" + Header always set X-Content-Type-Options "nosniff" + Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" + + # Block access to sensitive directories + + Require all denied + + + Require all denied + + + Require all denied + + + Require all denied + + + # Block access to hidden files + + Require all denied + + + # Cache CSS files + + Header set Cache-Control "public, max-age=3600" + + + # Serve static CSS file + Alias /css/tkr.css /var/www/tkr/public/css/tkr.css + + # 404 all non-css static files (images, js, fonts, etc.) + # so those requests don't hit the PHP app + # (this is to reduce load on the PHP app from bots and scanners) + + + Require all denied + + + + # Enable rewrite engine + + Options -Indexes + AllowOverride None + Require all granted + + RewriteEngine On + + # Block direct PHP access + RewriteCond %{THE_REQUEST} \s/[^?\s]*\.php[\s?] [NC] + RewriteRule ^.*$ - [R=404,L] + + # Serve the one static file that exists: css/tkr.css + # (Pass requests to css/custom/ through to the PHP app) + RewriteCond %{REQUEST_URI} !^/css/custom/ + RewriteRule ^css/tkr\.css$ css/tkr.css [L] + + # Everything else to front controller + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^(.*)$ index.php [L] + + + # Error and access logs + ErrorLog ${APACHE_LOG_DIR}/tkr_error.log + CustomLog ${APACHE_LOG_DIR}/tkr_access.log combined + diff --git a/examples/apache/vps/subfolder/my-domain.com.conf b/examples/apache/vps/subfolder/my-domain.com.conf index ff449ae..5c6989b 100644 --- a/examples/apache/vps/subfolder/my-domain.com.conf +++ b/examples/apache/vps/subfolder/my-domain.com.conf @@ -1,28 +1,14 @@ -# Apahe VirtualHost example -# for serving tkr as a subdirectory path -# e.g. https://www.my-domain.com/tkr +# Example Apache VirtualHost +# for serving tkr as a subdirectory path without SSL +# e.g. http://www.my-domain.com/tkr +# +# NOTE: Do not use in production. +# This is provided for docker compose +# (The included docker-compose file will mount it in the container image) - ServerName my-domain.com + # Replace localhost with your subdomain, e.g. tkr.my-domain.com + ServerName localhost DocumentRoot /var/www/html - -##################################################################### -# Start commenting here to use with docker-compose -##################################################################### - # Redirect HTTP to HTTPS - Redirect permanent / https://my-domain.com/ - - - - ServerName my-domain.com - DocumentRoot /var/www/html - - # SSL Configuration - SSLEngine on - SSLCertificateFile /etc/letsencrypt/live/my-domain.com/fullchain.pem - SSLCertificateKeyFile /etc/letsencrypt/live/my-domain.com/privkey.pem -##################################################################### -# Stop commenting here to use with docker-compose -##################################################################### # Security headers Header always set X-Frame-Options "SAMEORIGIN" diff --git a/examples/apache/vps/subfolder/my-domain.com.ssl.conf b/examples/apache/vps/subfolder/my-domain.com.ssl.conf new file mode 100644 index 0000000..22b8ffa --- /dev/null +++ b/examples/apache/vps/subfolder/my-domain.com.ssl.conf @@ -0,0 +1,89 @@ +# Example Apache VirtualHost +# for serving tkr as a subdirectory path with SSL +# e.g. https://www.my-domain.com/tkr +# +# Use SSL in production. +# This is a minimal SSL confiuration +# For more robust SSL configuration, refer to https://ssl-config.mozilla.org/ + + # Replace localhost with your subdomain, e.g. tkr.my-domain.com + ServerName localhost + DocumentRoot /var/www/html + # Redirect HTTP to HTTPS + Redirect permanent / https://my-domain.com/ + + + + # Replace localhost with your subdomain, e.g. tkr.my-domain.com + ServerName localhost + DocumentRoot /var/www/html + + # SSL Configuration + SSLEngine on + + # Assumes you're using letsencrypt for cert generation + # Replace with the actual paths to your cert and key + SSLCertificateFile /etc/letsencrypt/live/my-domain.com/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/my-domain.com/privkey.pem + + # Security headers + Header always set X-Frame-Options "SAMEORIGIN" + Header always set X-XSS-Protection "1; mode=block" + Header always set X-Content-Type-Options "nosniff" + Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" + + # tkr Application at /tkr + # NOTE: If you change the directory name, + # remember to update all instances of /var/www/tkr in this file to match + Alias /tkr /var/www/tkr/public + + # Block access to sensitive TKR directories + + Require all denied + + + Require all denied + + + Require all denied + + + Require all denied + + + # 404 all non-css static files in /tkr (images, js, fonts, etc.) + # so those requests don't hit the PHP app + # (this is to reduce load on the PHP app from bots and scanners) + + + Require all denied + + + + # tkr application directory + + Options -Indexes + AllowOverride None + Require all granted + + RewriteEngine On + + # Block direct PHP access + RewriteCond %{THE_REQUEST} \s/[^?\s]*\.php[\s?] [NC] + RewriteRule ^.*$ - [R=404,L] + + # Serve the one static file that exists: css/tkr.css + # (Pass requests to css/custom/ through to the PHP app) + RewriteCond %{REQUEST_URI} !^/tkr/css/custom/ + RewriteRule ^css/tkr\.css$ css/tkr.css [L] + + # Send everything else to the front controller + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^(.*)$ index.php [L] + + + # Error and access logs + ErrorLog ${APACHE_LOG_DIR}/my-domain_error.log + CustomLog ${APACHE_LOG_DIR}/my-domain_access.log combined + diff --git a/examples/nginx/root/nginx.conf b/examples/nginx/root/nginx.conf index daa695e..c134f66 100644 --- a/examples/nginx/root/nginx.conf +++ b/examples/nginx/root/nginx.conf @@ -1,5 +1,14 @@ +# Example nginx config +# for serving tkr as a subdomain without SSL +# e.g. http://tkr.my-domain.com/ +# +# NOTE: Do not use in production. +# This is provided for docker compose +# (The included docker-compose file will mount it in the container image) server { listen 80; + # replace localhost with your subdomain + # e.g. tkr.my-domain.com server_name localhost; root /var/www/tkr/public; @@ -39,6 +48,9 @@ server { # But if someone tries to directly access index.php, that file will throw a 404 # so bots and scanners can't tell this is a php app location = /index.php { + # If you're running php-fpm on the same server as nginx, + # then change this to the local php-fpm socket + # e.g. fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_pass php:9000; fastcgi_param SCRIPT_FILENAME /var/www/tkr/public/index.php; include fastcgi_params; @@ -61,6 +73,9 @@ server { # Fallback for /tkr routing - all non-file requests (e.g. /login) go to index.php location @tkr_fallback { + # If you're running php-fpm on the same server as nginx, + # then change this to the local php-fpm socket + # e.g. fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_pass php:9000; fastcgi_param SCRIPT_FILENAME /var/www/tkr/public/index.php; include fastcgi_params; diff --git a/examples/nginx/root/nginx.ssl.conf b/examples/nginx/root/nginx.ssl.conf new file mode 100644 index 0000000..3208bcb --- /dev/null +++ b/examples/nginx/root/nginx.ssl.conf @@ -0,0 +1,107 @@ +# Example nginx config +# for serving tkr as a subdomain with SSL +# e.g. https://tkr.my-domain.com/ +# +# Use SSL in production. +# This is a minimal SSL confiuration +# For more robust SSL configuration, refer to https://ssl-config.mozilla.org/ +server { + listen 443 ssl; + listen [::]:443 ssl; + + # replace localhost with your subdomain + # e.g. tkr.my-domain.com + server_name localhost; + + # Assumes you're using letsencrypt for cert generation + # Replace with the actual paths to your cert and key + ssl_certificate /etc/letsencrypt/live/tkr.my-domain.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/tkr.my-domain.com/privkey.pem; + + root /var/www/tkr/public; + index index.php; + + # Security headers + # The first rule is to prevent including in a frame on a different domain. + # Remove it if you want to do that. + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + + # Deny access to hidden files + location ~ /\. { + deny all; + access_log off; + log_not_found off; + } + + # PHP routing - everything goes through index.php + location / { + # Cache static files + # Note that I don't actually serve most of this (just css) + # but this prevents requests for static content from getting to the PHP handler. + # + # I've excluded /css/custom so that requests for uploaded css can be handled by the PHP app. + # That lets me store uploaded content outside of the document root, + # so it isn't served directly. + location ~* ^/(?!css/custom/).+\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + try_files $uri =404; + } + + # index.php is the entry point + # It needs to be sent to php-fpm + # But if someone tries to directly access index.php, that file will throw a 404 + # so bots and scanners can't tell this is a php app + location = /index.php { + # If you're running php-fpm on the same server as nginx, + # then change this to the local php-fpm socket + # e.g. fastcgi_pass unix:/run/php/php8.2-fpm.sock; + fastcgi_pass php:9000; + fastcgi_param SCRIPT_FILENAME /var/www/tkr/public/index.php; + include fastcgi_params; + + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param QUERY_STRING $query_string; + } + + # Block attempts to access all other .php files directly + # (these are bots and scanners) + location ~ ^/.+\.php$ { + return 404; + } + + # forward other requests to the fallback block, + # which sends them to php-fpm for handling + try_files $uri $uri/ @tkr_fallback; + } + + # Fallback for /tkr routing - all non-file requests (e.g. /login) go to index.php + location @tkr_fallback { + # If you're running php-fpm on the same server as nginx, + # then change this to the local php-fpm socket + # e.g. fastcgi_pass unix:/run/php/php8.2-fpm.sock; + fastcgi_pass php:9000; + fastcgi_param SCRIPT_FILENAME /var/www/tkr/public/index.php; + include fastcgi_params; + + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param QUERY_STRING $query_string; + } + + # Deny access to sensitive directories + location ~ ^/(storage|src|templates|uploads|config) { + deny all; + return 404; + } +} + +server { + listen 80 default_server; + listen [::]:80 default_server; + + return 301 https://$host$request_uri; +} diff --git a/examples/nginx/subfolder/nginx.conf b/examples/nginx/subfolder/nginx.conf index eb5dacf..249eb4b 100644 --- a/examples/nginx/subfolder/nginx.conf +++ b/examples/nginx/subfolder/nginx.conf @@ -1,5 +1,16 @@ +# Example nginx config +# for serving tkr as a subdfolder without SSL +# e.g. http://my-domain.com/tkr +# +# NOTE: Do not use in production. +# This is provided for docker compose +# (The included docker-compose file will mount it in the container image) server { - listen 80; + listen 80 default_server; + listen [::]:80 default_server; + + # replace localhost with your subdomain + # e.g. tkr.my-domain.com server_name localhost; root /var/www/html; diff --git a/examples/nginx/subfolder/nginx.ssl.conf b/examples/nginx/subfolder/nginx.ssl.conf new file mode 100644 index 0000000..a5b5076 --- /dev/null +++ b/examples/nginx/subfolder/nginx.ssl.conf @@ -0,0 +1,99 @@ +# Example nginx config +# for serving tkr as a subdfolder with SSL +# e.g. https://my-domain.com/tkr +# +# Use SSL in production. +# This is a minimal SSL confiuration +# For more robust SSL configuration, refer to https://ssl-config.mozilla.org/ +server { + listen 443 ssl; + listen [::]:443 ssl; + + # Replace localhost with your domain + # e.g. my-domain.com + server_name localhost; + + root /var/www/html; + index index.html; + + # Security headers + # The first rule is to prevent including in a frame on a different domain. + # Remove it if you want to do that. + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + + # Deny access to hidden files + location ~ /\. { + deny all; + access_log off; + log_not_found off; + } + + # PHP routing - everything under /tkr goes through index.php + location /tkr { + alias /var/www/tkr/public; + index index.php; + + # Cache static files + # Note that I don't actually serve most of this (just css) + # but this prevents requests for static content from getting to the PHP handler. + # + # I've excluded /css/custom so that requests for uploaded css can be handled by the PHP app. + # That lets me store uploaded content outside of the document root, + # so it isn't served directly. + location ~* ^/tkr/(?!css/custom/).+\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + try_files $uri =404; + } + + # index.php is the entry point + # It needs to be sent to php-fpm + # But if someone tries to directly access index.php, that file will throw a 404 + # so bots and scanners can't tell this is a php app + location = /tkr/index.php { + fastcgi_pass php:9000; + fastcgi_param SCRIPT_FILENAME /var/www/tkr/public/index.php; + include fastcgi_params; + + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param QUERY_STRING $query_string; + } + + # Block attempts to access all other .php files directly + # (these are bots and scanners) + location ~ ^/tkr/.+\.php$ { + return 404; + } + + # forward other requests to the fallback block, + # which sends them to php-fpm for handling + try_files $uri $uri/ @tkr_fallback; + } + + # Fallback for /tkr routing - all non-file requests (e.g. /login) go to index.php + location @tkr_fallback { + fastcgi_pass php:9000; + fastcgi_param SCRIPT_FILENAME /var/www/tkr/public/index.php; + include fastcgi_params; + + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param QUERY_STRING $query_string; + } + + # Deny access to sensitive directories + location ~ ^/tkr/(storage|src|templates|uploads|config) { + deny all; + return 404; + } +} + +server { + listen 80 default_server; + listen [::]:80 default_server; + + return 301 https://$host$request_uri; +}