From 8fc3182cb9a70bc06b9d5d4a7dcdcd9059eb0cbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=27rysiek=27=20Wo=C5=BAniak?= Date: Tue, 14 Jul 2020 14:37:04 +0000 Subject: [PATCH] initial jab at fpm config --- services/etc/nginx/sites/example.com_fpm.conf | 219 ++++++++++++++++++ .../etc/nginx/snippets/common-blocks.conf | 41 ++++ services/etc/nginx/snippets/fastcgi.conf | 34 +++ 3 files changed, 294 insertions(+) create mode 100644 services/etc/nginx/sites/example.com_fpm.conf create mode 100644 services/etc/nginx/snippets/common-blocks.conf create mode 100644 services/etc/nginx/snippets/fastcgi.conf diff --git a/services/etc/nginx/sites/example.com_fpm.conf b/services/etc/nginx/sites/example.com_fpm.conf new file mode 100644 index 0000000..d8970be --- /dev/null +++ b/services/etc/nginx/sites/example.com_fpm.conf @@ -0,0 +1,219 @@ +### THIS IS INCOMPLETE/WORK IN PROGRESS + +# www.example.com website +server { + listen 80; + listen 443 ssl; + server_name www.example.com example.com; + + # general vhost settings + access_log /srv/logs/nginx/example.com.access.log combined; + error_log /srv/logs/nginx/example.com.error.log error; + + # ssl keycert + ssl_certificate /srv/data/secrets/letsencrypt/live/example.com/fullchain.pem; + ssl_certificate_key /srv/data/secrets/letsencrypt/live/example.com/privkey.pem; + + # TLS settings + # can't set headers in an if that is *not* in a location, + # so we need to work around this + add_header Strict-Transport-Security "max-age=31536000"; + + # general vhost settings + root /srv/www/; + + # fastcgi defaults + include snippets/fastcgi.conf; + index index.html index.htm index.php; + + # no php is touched for static content. + # include the "?$args" part so non-default permalinks don't break + # when using query string + try_files $uri $uri/ /index.php?$args; + + # common blocks + include snippets/common-blocks.conf; + + # XML-RPC blocked + # https://www.hostinger.com/tutorials/xmlrpc-wordpress + location = /xmlrpc.php { + return 404; + } + + # TLS letsencrypt stateless acme config + # no need for webroot and stuff + # + # this is described for acme.sh, + # but should work with any LE client + # https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode + location ~ "^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)$" { + default_type text/plain; + return 200 "$1."; + } + + # we simply might not have a favicon, robots.txt, et al -- if we do, serve these, if not, 204 NO CONTENT + # and ignore logging either way + location ~* .*/(robots\.txt|favicon\.ico|apple-touch-icon\.png|apple-touch-icon-precomposed\.png)$ { + try_files $uri =204; + log_not_found off; + access_log off; + } + + # retina bullshit + location ~* ^(.*)@[0-9]x\.(js|css|png|jpg|jpeg|gif|ico|svg|pdf|json|woff|ttf|otf|flv|swf|avi|webm|webp)$ { + try_files $uri $1.$2 =404; + expires max; + log_not_found off; + add_header X-Cache-Config "STATIC RETINA" always; + } + + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|pdf|json|woff|ttf|otf|flv|swf|avi|webm|webp)$ { + try_files $uri =404; + expires max; + #log_not_found off; # we need this on for the time being + add_header X-Cache-Config "STATIC" always; + } + + # basic proxy params + import snippets/proxy_headers_general.conf; + + # proxy zone + proxy_cache fasada; + # use stale cached resources in case upstream is not available for some reason + proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; + proxy_cache_background_update on; + proxy_cache_revalidate on; + proxy_cache_lock on; + + # reasonable default + proxy_cache_valid 200 10s; + + + # admin area *has to* be uncached; blocking here, + # should be made available on admin.domain.tld + location ~* ^/(wp-admin|admin|login|wp-login|signin).* { + add_header X-Proxy-Cache $upstream_cache_status; + proxy_cache off; + proxy_pass http://127.0.0.1:10080; + } + + # WordPress themes + location ~* ^/wp-content/themes/.* { + + # forced cache + include snippets/proxy_headers_caching.conf; + # generic settings we need to re-include due to the above using `proxy_set_header` + # and thus invalidating the parent block-level use of it + include snippets/proxy_headers_general.conf; + + # settings for this location block + add_header Cache-Control "public"; + proxy_cache_valid 200 301 302 303 307 308 30m; + proxy_cache_valid 404 30s; + expires 30m; + + # no need for access log for these + access_log off; + proxy_pass http://127.0.0.1:10080; + + } + + # robots.txt, favicons, apple icons, etc + location ~* .*/(robots\.txt|favicon\.ico|apple-touch-icon\.png|apple-touch-icon-precomposed\.png)$ { + + # forced cache + include snippets/proxy_headers_caching.conf; + # generic settings we need to re-include due to the above using `proxy_set_header` + # and thus invalidating the parent block-level use of it + include snippets/proxy_headers_general.conf; + + # settings for this location block + add_header Cache-Control "public"; + proxy_cache_valid 200 301 302 303 307 308 5h; + proxy_cache_valid 404 30s; + expires 5h; + + # no need for access log for these + access_log off; + proxy_pass http://127.0.0.1:10080; + } + + # images and other static resources + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|json|woff|woff2|ttf|otf|bmp|cur|gz|svgz|mp4|ogg|ogv|webm|htc|mp4|mpeg|mp3|txt|pdf)$ { + + # forced cache + include snippets/proxy_headers_caching.conf; + # generic settings we need to re-include due to the above using `proxy_set_header` + # and thus invalidating the parent block-level use of it + include snippets/proxy_headers_general.conf; + + # settings for this location block + add_header Cache-Control "public"; + proxy_cache_valid 200 301 302 303 307 308 15m; + proxy_cache_valid 404 30s; + expires 15m; + + proxy_pass http://127.0.0.1:10080; + } + + # reverse proxy to upstream, for *everything else* + # caching for 1 minute + location / { + + # if redirect_fbclid map is active, do 301 to the new url + if ( $redirect_fbclid ) { + return 301 $redirect_fbclid; + } + + # if we have the wordpress admin cookie set, no caching please + # + # this makes previews work and fixes the admin interface + # (by allowing /wp-json/ requests to be uncached and have cookies on them) + # + # using an error page hack because nginx config is lacking in this area + # ref: + # - https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/ + # - https://serverfault.com/a/811981 + # - https://wordpress.stackexchange.com/questions/218588/post-preview-mechanism-architecture + error_page 418 = @uncached; + if ( $http_cookie ~* ".*wordpress_logged_in_.+" ) { + return 418; + } + + # forced cache + include snippets/proxy_headers_caching.conf; + # generic settings we need to re-include due to the above using `proxy_set_header` + # and thus invalidating the parent block-level use of it + include snippets/proxy_headers_general.conf; + + # settings for this location block + add_header Cache-Control "no-store"; + proxy_cache_valid 200 301 302 303 307 308 20s; + proxy_cache_valid 404 20s; + + # some basic security headers + add_header Content-Security-Policy "frame-ancestors 'self'"; + add_header X-Frame-Options SAMEORIGIN; + + proxy_pass http://127.0.0.1:10080; + } + + # the php fpm proxy + location ~ \.php$ { + # this controls the read-only mode (basically, limits HTTP methods to GET only) + include snippets/read-only-mode.conf; + #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini + fastcgi_next_upstream error timeout invalid_header http_500; + fastcgi_connect_timeout 2; + + fastcgi_pass phpfpm; + } + +} + +# explicitly uncached +location @uncached { + add_header X-Proxy-Cache-Status $upstream_cache_status; + proxy_cache off; + proxy_pass http://127.0.0.1:10080; +} diff --git a/services/etc/nginx/snippets/common-blocks.conf b/services/etc/nginx/snippets/common-blocks.conf new file mode 100644 index 0000000..e34d31b --- /dev/null +++ b/services/etc/nginx/snippets/common-blocks.conf @@ -0,0 +1,41 @@ +# common locations that are blocked +# to be included in all sites +# +# these have to be defined as regex locations +# (~ or ~*) + +# seriously, no flash please +location ~* .*\.swf(\?.*)?$ { + return 410; +} + +# .htaccess should always be blocked +location ~* .*/\.ht { + return 410; +} + +# git-related stuff +location ~* .*/\.(git|svn).* { + return 410; +} + +# README.md +location ~* .*/README(\..+)?$ { + return 410; +} + +# we just don't host these +location ~* .*/.*\.(jsp|asp|sh|cgi)$ { + return 410; +} + +# dotfiles -- nope, unless we're talking about .well-known +location ~* .*/\.(?!well-known)[a-zA-Z0-9]+ { + return 410; +} + +# script files should never be served +# especially from images/cache/media/log/temp/upload directories +location ~* /(images?|cache|media|logs?|te?mp|uploads?)/.*\.(php|pl|py|jsp|asp|sh|cgi)$ { + return 410; +} diff --git a/services/etc/nginx/snippets/fastcgi.conf b/services/etc/nginx/snippets/fastcgi.conf new file mode 100644 index 0000000..da68a7c --- /dev/null +++ b/services/etc/nginx/snippets/fastcgi.conf @@ -0,0 +1,34 @@ + +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 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; + +# for codeigniter +fastcgi_buffer_size 128k; +fastcgi_buffers 4 256k; +fastcgi_busy_buffers_size 256k; + +# yeah, we want php-fpm errors in nginx errorlogs +fastcgi_intercept_errors on; +fastcgi_index index.php;