Несколько заметок по Nginx

Вернулся к переносу заметок со старого блога и раскопал несколько интересных заметок по 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;
    }

}

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *