Установка 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 EOF
deb 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 порта внешнего интерфейса сервера в
upstream
Ingress 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
.