Вернулся к переносу заметок со старого блога и раскопал несколько интересных заметок по Nginx. Возможно кому-нибудь пригодятся.
Конфигурация с несколькими Upstream-серверами
Такая конфигурация у меня используется для проксирования трафика к Ingress кубера. Три ноды, вайлдкард сертификат Let’s encrypt и как мне кажется прекрасное решение получилось для стэйдж-кластера.
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream upstreamk8s {
server 10.54.110.50:80;
server 10.54.110.55:80;
server 10.54.110.57:80;
}
server {
listen 80;
server_name *.pp.smsfinanceit.ru;
# Enforce HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name *.pp.smsfinanceit.ru;
access_log /var/log/nginx/pp.smsfinanceit.ru-access.log;
error_log /var/log/nginx/pp.smsfinanceit.ru-error.log warn;
ssl_certificate /etc/letsencrypt/live/pp.smsfinanceit.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/pp.smsfinanceit.ru/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
client_max_body_size 64M;
fastcgi_buffers 64 4K;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
fastcgi_hide_header X-Powered-By;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://upstreamk8s;
}
}
Ошибка 504 Gateway timeout
Увеличиваем время ожидания Backend-а
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
Типовая конфигурация Reverse-Proxy
Конфигурация Reverse-Proxy для прокидывания на Backend с оборачиванием в HTTPS и именно эта конфигурация использовалась для работы Xwiki.
Из плюшек:
- Проставляем необходимые флаги
- Заворачиваем в HTTPS при помощи Let’s encript
- Протокол http2
- Сжатие данных
- Перенаправление с http на https
- Перенаправление с www
- и т.п.
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name www.anton-c.ru anton-c.ru;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name www.anton-c.ru anton-c.ru;
access_log /var/log/nginx/anton-c.ru-access.log;
error_log /var/log/nginx/anton-c.ru-error.log warn;
ssl_certificate /etc/letsencrypt/live/anton-c.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/anton-c.ru/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
client_max_body_size 64M;
fastcgi_buffers 64 4K;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
if ($host ~ ^www\.(?<domain>.+)$) {
return 301 $scheme://$domain$request_uri;
}
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_pass http://127.0.0.1:8080;
}
}
Хитрая конфигурация для NextCloud за Reverse-proxy Nginx
Пока было немного времени на праздниках я сделал хитрую связку с Next Cloud работающим на PHP-FPM (штатно там Apache) за реверс-прокси с тем же Nginx. Решение не идеальное, но рабочее.
<?php
$CONFIG = array (
'instanceid' => 'XXXSECRETXXX',
'passwordsalt' => 'XXXSECRETXXX',
'secret' => 'XXXSECRETXXX',
'trusted_domains' =>
array (
0 => 'cloud-test.aagt.ru',
1 => 'cloud.aagt.ru',
2 => '10.240.250.10',
),
'datadirectory' => '/mnt/gluster-storage/nextcloud-data/',
'dbtype' => 'pgsql',
'version' => '28.0.1.1',
'overwrite.cli.url' => 'https://cloud.aagt.ru',
'dbname' => 'nextcloud_db',
'dbhost' => 'localhost',
'dbport' => '',
'dbtableprefix' => 'oc_',
'dbuser' => 'nextcloud_user',
'dbpassword' => 'XXXSECRETXXX',
'installed' => true,
'theme' => '',
'loglevel' => 2,
'maintenance' => false,
'mail_smtpmode' => 'smtp',
'mail_sendmailmode' => 'smtp',
'mail_from_address' => 'cloud',
'mail_domain' => 'aagt.ru',
'mail_smtpauthtype' => 'PLAIN',
'mail_smtpauth' => 1,
'mail_smtphost' => 'mail.bds.su',
'mail_smtpport' => '25',
'mail_smtpname' => 'cloud@aagt.ru',
'mail_smtppassword' => 'XXXSECRETXXX',
'default_phone_region' => 'RU',
'memcache.local' => '\\OC\\Memcache\\APCu',
'filelocking.enabled' => true,
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' =>
array (
'host' => '127.0.0.1',
'port' => 6379,
),
'memcache.distributed' => '\\OC\\Memcache\\Redis',
'trusted_proxies' =>
array (
0 => '10.240.250.3',
),
'overwriteprotocol' => 'https',
'overwritecondaddr' => '^10\\.240\\.250\\.3$',
);
Конфигурация Nginx для PHP-приложения (надо потом это в кубик утащить):
server {
listen 81;
server_name cloud.aagt.ru;
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 X-XSS-Protection "1; mode=block" always;
# Path to the root of your installation
root /var/www/vhosts/cloud.aagt.ru/;
access_log /var/log/nginx/cloud.aagt.ru-access.log;
error_log /var/log/nginx/cloud.aagt.ru-error.log warn;
client_max_body_size 2048M;
fastcgi_buffers 64 4K;
proxy_connect_timeout 120;
proxy_send_timeout 120;
proxy_read_timeout 120;
send_timeout 120;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
if ($host ~ ^www\.(?<domain>.+)$) {
return 301 $scheme://$domain$request_uri;
}
location = /robots.txt {
allow all;
}
error_page 403 /core/templates/403.php;
error_page 404 /core/templates/404.php;
location / {
rewrite ^ /index.php$uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^/(?:updater|ocs-provider)(?:$|/) {
try_files $uri/ =404;
index index.php;
}
location ~* \.(?:svg|gif|png|html|ttf|woff|woff2|ico|jpg|jpeg|js|css)$ {
try_files $uri /index.php$uri$is_args$args;
}
}
Конфигурация для Reverse-proxy (там тоже свои тараканы живут):
server {
listen 80;
server_name www.cloud.aagt.ru cloud.aagt.ru;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name www.cloud.aagt.ru cloud.aagt.ru;
access_log /var/log/nginx/cloud.aagt.ru-access.log;
error_log /var/log/nginx/cloud.aagt.ru-error.log warn;
ssl_certificate /etc/letsencrypt/live/cloud.aagt.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.aagt.ru/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
client_max_body_size 2048M;
fastcgi_buffers 64 4K;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
location = /.well-known/carddav {
return 301 $scheme://$host:$server_port/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host:$server_port/remote.php/dav;
}
if ($host ~ ^www\.(?<domain>.+)$) {
return 301 $scheme://$domain$request_uri;
}
location / {
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_pass http://10.240.250.10:81;
}
}