Установка Nginx на Debian/Ubuntu Linux
Что такое Nginx
Для работы web-сайтов используются различные серверы, обслуживающие HTTP запросы, их называют Web-серверами. Они могут передавать статические страницы и выполнять некоторые скрипты, подключая различные модули, например для работы с PHP, Perl, Asp и другие.
Самые популярные web-серверы в сети интернет - Apache2 и Nginx. Nginx может использоваться в качестве web-сервера или обратного прокси.
Предварительные требования
В руководстве полагаем, что Linux сервер на базе Debian 9+ или Ubuntu 18+ уже установлен и обновлен.
apt update apt upgrade
Установка Nginx
Установка из стандартного репозитория
apt update apt install -y nginx
Установка из репозитория Nginx
mainline- содержит самые новые функции, но не исключает ошибкиstable- включает только критические правки ошибок
Добавить подпись для репозитория nginx
wget -qO - https://nginx.org/keys/nginx_signing.key | apt-key add -
Добавить в apt репозиторий, указав дистрибутив и релиз:
DISTRIB=`cat /etc/os-release | grep "^ID=" | awk -F'=' '{print $2}'`
RELEASE=`cat /etc/os-release | grep "^VERSION_CODENAME=" | awk -F'=' '{print $2}'`
cat <<EOF >>/etc/apt/sources.list.d/nginx.list
deb https://nginx.org/packages/$DISTRIB/ $RELEASE nginx
deb-src https://nginx.org/packages/$DISTRIB/ $RELEASE nginx
EOFdeb https://nginx.org/packages/mainline/$DISTRIB/ $RELEASE nginx deb-src https://nginx.org/packages/mainline/$DISTRIB/ $RELEASE nginx
Обновить списки пакетов и установить nginx
apt update apt install -y nginx
Проверка работоспособности Nginx
nginx -v # nginx version: nginx/1.21.2
Проверить прослушивание порта 80
curl -v 127.0.0.1 # HTTP/1.1 200 OK # Server: nginx/1.21.2
Управление Nginx
Nginx может управляться через systemctl
systemctl start nginx systemctl enable nginx systemctl reload nginx systemctl status nginx systemctl stop nginx systemctl disable nginx
Во время работы перед применением новой конфигурации nginx нужно выполнить проверку этой конфигурации
nginx -t
При успешном выполнении выполнить применение конфигурации
nginx -s reload
Настройка виртуальных хостов Nginx
Конфигурация nginx расположена по умолчанию в /etc/nginx/
Расположение файлов web-сервера по умолчанию /var/www/
Разместим обычную веб-страницу в /var/www/antroot.ru/index.html
<html>
  <head>
    <title>Welcome to antroot.ru</title>
  </head>
  <body>
    <h1>antroot.ru welcome page!</h1>
    <p>It works!</p>
  </body>
</html>добавим блок конфигурации для неё /etc/nginx/sites-available/antroot.ru.conf
server {
    server_name antroot.ru www.antroot.ru;
    listen 80;
    if ($host = www.antroot.ru) {
        return 301 http://antroot.ru$request_uri;
    }
    root /var/www/antroot.ru/;
    index index.html index.htm index.php;
    location / {
            try_files $uri $uri/ =404;
    }
}остается "включить" сайт, для чего поместим ссылку в "разрешенных сайтах" на конфигурационный файл, размещенный в "доступных сайтах":
ln -s /etc/nginx/sites-available/antroot.ru.conf /etc/nginx/sites-enabled/
Выполнить проверку конфигурации nginx -t и загрузить конфиг nginx -s reload.
Далее, убедившись, что в DNS есть A-запись, указывающая на ваш сервер, переходим в браузере по этому адресу.
Подключение PHP
Для подключения выполнения сценариев PHP можно воспользоваться php-fpm:
apt install -y php php-fpm
и добавить в блок сайта server в конфигурационном файле /etc/nginx/sites-available/antroot.ru.conf обработку файлов с расширением php
location ~ \.php$ {
    try_files $uri = 404;
    include fastcgi_params;
    fastcgi_pass  unix:/var/run/php7.3-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
}Настройка Reverse Proxy на Nginx
Очень часто встречается конфигурация сети, когда серверы расположены в так называемой "демилитаризованной зоне" (DMZ), специальном сегменте сети предприятия, доступ в который строго регламентирован из соображений безопасности.
Предположим, что мы разместили в этой зоне несколько серверов, выдали им серые IP-адреса и предоставили доменное имя локальной сети в домене antroot.lan. Для более изящного решения технического задания укажем имена хостов серверов такими, какими они должны быть во внешнем мире в домене antroot.ru (локальное имя - IP-адрес - внешнее доменное имя):
- www.antroot.lan - 10.0.3.50 - www.antroot.ru
 - mail.antroot.lan - 10.0.3.51 - mail.antroot.ru
 - wiki.antroot.lan - 10.0.3.52 - wiki.antroot.ru
Для доступа к ним из внешнего мира настроим reverse proxy на nginx в конфигурации/etc/nginx/sites-available/export-dmz.conf: 
server {
  server_name ~^(?<subdomain>.*)\.antroot\.ru$;
  listen 80;
  resolver 10.0.2.2;
  location / {
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Connection "";
      if ( -f /var/www/dmz/$subdomain) {
          proxy_pass http://$subdomain.antroot.lan:$server_port$request_uri;
      }
  }
}- В строке 2 из доменного имени извлекается первая часть 
subdomain, если окончаниеantroot.ru - В строке 10 проверяется файл в директории 
/var/www/dmz/с именем поддомена - сервера, который необходимо вынести в сеть Интернет (это для безопасности, чтобы можно было включать/отключать серверы) - В строке 11, при наличии файла поддомена из предыдущего пункта, выполняется прокси-запрос на сервер в DMZ
 - Чтобы выполнилось разрешение имени сервера в локальном сети, указывается 
resolverв качестве локального сервера DNS. 
Далее, необходимо выполнить следующее, чтобы добавить сервер, например wiki:
- установить сервер в DMZ, задать ему 
hostname, совпадающий с поддоменом, выставляемым в интернет, напримерwikiс полным именемwiki.antroot.lan - добавить во "внешний" DNS A-запись с поддоменом сервера, указывающую на обратный прокси, например 
wiki.antroot.ru - создать файл в 
/var/www/dmz/с именем поддоменаwiki, можно пустой, или вписать информацию о дате добавления, назначении сервиса и т.п. 
ln -s /etc/nginx/sites-available/export-dmz.conf /etc/nginx/sites-enabled/ nginx -t nginx -s reload
Защита сервера с помощью TLS
После всех необходимых настроек виртуальных хостов и обратных прокси довольно важно защитить подключение к серверам от злоумышленников, для чего можно воспользоваться сервисом Let's Encrypt, получить сертификат SSL и установить на web-сервер.
В качестве инструмента для работы с Let's Encrypt используется certbot, входящий в состав стандартного репозитория Debian/Ubuntu Linux
apt install -y certbot python3-certbot-nginx
После установки запустить certbot, ввести адрес для уведомлений, выбрать из найденых в конфигурационных файлах nginx доменов и получить сертификат. После успешного получения, certbot запишет сертификат в ssl_certificate блока в конфигурации nginx, и предложит сделать редирект с небезопасного на защищенный адрес.
А также установит в crontab задание на обновление всех сертификатов на этом сервере.
Подключение кластера K8s через upstream
Конфигурация nginx.conf по умолчанию выглядит так:
user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}Подключим upstream в kube_apiserver в nginx.conf:
stream {
    upstream kube_apiserver {
        least_conn;
        # адреса узлов кластера
        server 10.0.2.2:6443;
        server 10.0.2.3:6443;
    }
    server {
        listen        1.2.3.4:6443; # внешний IP-адрес
        proxy_pass    kube_apiserver;
        proxy_timeout 10m;
        proxy_connect_timeout 1s;
    }
}и слегка подкрутим параметры подключений. 
Полный конфигурационный файл nginx.conf будет выглядеть так:
error_log  stderr notice;
pid        /var/run/nginx.pid;
user  nginx;
#worker_processes  auto;
worker_processes 2;
worker_rlimit_nofile 130048;
worker_shutdown_timeout 10s;
events {
    multi_accept on;
    use epoll;
    worker_connections 16384;
}
stream {
    upstream kube_apiserver {
        least_conn;
        server 10.0.2.2:6443;
        server 10.0.2.3:6443;
    }
    server {
        listen        1.2.3.4:16443; # внешний IP-адрес и порт
        proxy_pass    kube_apiserver;
        proxy_timeout 10m;
        proxy_connect_timeout 1s;
    }
}
http {
    aio threads;
    aio_write on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 5m;
    keepalive_requests 100;
    reset_timedout_connection on;
    server_tokens off;
    autoindex off;
    server {
        listen 8081;
        location /healthz {
            access_log off;
            return 200;
        }
        location /stub_status {
            stub_status on;
            access_log off;
        }
    }
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  65;
    #gzip  on;
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}При этом не теряется возможность подключать сайты из sites_enabled.
Подключение доменных имен поддомена в Ingress K8s
Для подключения доменных имен субдомена *.k8s.antroot.ru потребуется сделать несколько вещей в дополнение к приведенному выше конфигурационному файлу:
- Настроить 
upstreamдля перенаправление запросов в Ingress K8s по доменному имени *.k8s.antroot.ru - Подключить перенаправление запросов с 443 порта внешнего интерфейса сервера в 
upstreamIngress K8s - Настроить 
upstreamпо умолчанию для передачи трафика на 443 порт локального интерфейса - Настроить всем виртуальным хостам подключение на 443 порт локального интерфейса 127.0.0.1
 
...
stream {
    resolver 10.0.2.2;
    upstream k8s_srv_https {
        least_conn;
        server k8s1.antroot.lan:443;
        server k8s2.antroot.lan:443;
    }
    upstream default_https {
        server 127.0.0.1:443;
    }
    map $ssl_preread_server_name $upstream {
        ~^(.*)k8s\.antroot\.ru  k8s_srv_https;
        default         default_https;
    }
    server {
        listen 10.0.2.2:443;
        proxy_pass $upstream;
        ssl_preread on;
        tcp_nodelay on;
        proxy_timeout 10m;
        proxy_connect_timeout 2s;
    }
    log_format basic '$remote_addr [$time_local] '
            '$protocol $status $bytes_sent $bytes_received '
            '$session_time "$upstream_addr" '
            '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
    access_log /var/log/nginx/upstream_access.log basic;
    error_log  /var/log/nginx/upstream_error.log;
}
...и во всех конфигурационных файлах виртуальных сайтов привязать прослушивание к localhost:
server {
    server_name antroot.ru www.antroot.ru;
    listen 127.0.0.1:443;
...Теперь все приходящие запросы на внешний интерфейс прокси-сервера (в нашем случае 10.0.2.2) на порт 443 будут обслуживаться stream веб-сервера nginx, и в случае совпадения с маской субдомена *.k8s.antroot.ru прозрачно перенаправится в Ingress кластера K8s, в противном случае направится на локальный интерфейс 127.0.0.1:443 и дальше обработается правилами virtual hosts.