По принцип предпочитам за WEB сървър да ползвам Apache, но на няколко пъти ми се случи да боравя с Nginx. На пръв поглед ми се видя лек и удобен затова ще покажа как се инсталира върху Debian и как се настройва. За целта ни трябва: - инсталирана ОС, в случая Debian, - инсталирана и конфигурирана защитна стена (ufw), при условие, че нямате друга такава, - пренасочени портове TCP 80 и 443 Започваме с инсталацията.
apt update apt install nginx -y
Ако ползвате защитна стена на самия Debian то трябва и тя да се инсталира.
apt install ufw -y
Ако не ползвате то тази стъпка и няколко надолу отнасящи се за стената можете да ги пропуснете. Активираме стената.
ufw enable ufw status Firewall is active and enabled on system startup Status: active
Трябва да отговори че е активна. Между другото добра практика е винаги да има защитна стена, независимо, че имате рутер с такава. Това ще помогне за защита в локалната мрежа. Сега да позволим няколко порта, за да управляваме през тях машината.
ufw allow 22 ufw allow 80 ufw allow 443
Разрешихме портове, 22 за SSH, 80 за HTTP и 443 за HTTPS. Ако за тези услуги ползвате други портове то трябва да укажете които ползвате. Между другото, можете да боравите с защитната стена и чрез приложения. Нека да видим кои са позволени.
ufw app list ... ... Bind9 ... ... DNS SSH WWW ... и т.н.
Не показвам целия списък защото е дълъг. Нарочно по-горе не позволих порт 53 UDP за DNS-a. ще го позволим чрез ufw app. Има и още една разлика, специално в този случай. SSH-a ми работи на порт 6705, а тук сме позволили порт 22. Да проверим кои правила са активни.
ufw status Status: active To Action From -- ------ ---- 22 ALLOW Anywhere 80 ALLOW Anywhere 443 ALLOW Anywhere 22 (v6) ALLOW Anywhere (v6) 80 (v6) ALLOW Anywhere (v6) 443 (v6) ALLOW Anywhere (v6)
Разрешени портове 22, 80 и 443. Да позволим нашия SSH.
ufw allow 6705
Забележете, не използвах ufw allow SSH, защото щеше отново да освободи порт 22, а дефинирах точно порт 6705. Да разрешим и DNS-a
ufw allow dns Rule added Rule added (v6) ufw status Status: active To Action From -- ------ ---- 22 ALLOW Anywhere 80 ALLOW Anywhere 443 ALLOW Anywhere 6705 ALLOW Anywhere DNS ALLOW Anywhere 22 (v6) ALLOW Anywhere (v6) 80 (v6) ALLOW Anywhere (v6) 443 (v6) ALLOW Anywhere (v6) 6705 (v6) ALLOW Anywhere (v6) DNS (v6) ALLOW Anywhere (v6)
За сега това ни стига.
Да се върнем на Nginx.
systemctl status nginx
Активиран и работи без грешки. Самите конфигурационни файлове се намират в /etc/nginx. От там за сега ни вълнуват файла nginx.conf и папката sites-available. Първият е за общите настройки на Nginx, а папката е за създаване на виртуални сайтове.
nano /etc/nginx/nginx.conf user www-data; worker_processes 1; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/conf-enabled/*.conf; include /etc/nginx/sites-enabled/*.conf; }
Сега да видим какви виртуални сайтове имаме създадени по подразбиране.
ls -l /etc/nginx/sites-available total 4 -rw-r--r-- 1 root root 2412 Mar 14 2023 default
Наличен един виртуален сайт default. Това е глобален файл за всички виртуални сайтове. Има се на предвид следното. Примерно имаме два домейна (tlan.net и tachko.com). При използване на този глобален файл както и да напишем (http://tachko.com, http://tlan.net, https://tlan.net, https://tachko.com) винаги ще се отваря една и съща страница. Затова не трябва да е активен. Активирането на даден виртуален сайт става с линк на дадения файл, отговарящ за даден сайт към папка /etc/nginx/sites-enabled. Да проверим:
ls -l /etc/nginx/sites-enabled/ total 0 lrwxrwxrwx 1 root root 34 Apr 20 17:00 default -> /etc/nginx/sites-available/default
Точно така, в /etc/nginx/sites-enabled имаме линк default сочещ към файла /etc/nginx/sites-available/default Деактивирането на виртуалния сайт става, чрез триене на линка сочещ към дадения виртуален сайт. Задачата ни е да изтрием виртуалния сайт default и да създадем нов, примерно my.tlan.net.conf. За ръководство ще ползваме файла default.
cp /etc/nginx/sites-available/default /etc/nginx/sites-available/my.tlan.net.conf nano /etc/nginx/sites-available/my.tlan.net.conf server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; location / { try_files $uri $uri/ =404; } } ### Трябва да изглежда: server { listen 80; listen [::]:80; root /var/www/my.tlan.net/; index index.html index.htm index.nginx-debian.html; server_name my.tlan.net mail.my.tlan.net ns1.my.tlan.net www.my.tlan.net; location / { try_files $uri $uri/ =404; } }
Няколко неща се набиват на око. Първо пътя за разполагане на файловете за сайта е /var/www/my.tlan.net/. Второ името на сайта е: my.tlan.net и www.my.tlan.net Да се заемем с оправяне на пътя.
mkdir -p /var/www/my.tlan.net/ chown -R www-data:www-data /var/www/my.tlan.net/
Създадохме папка в указания път, и казахме кой да е собственик на папката. Да създадем тестов файл в тази папка. Все едно е нашия сайт.
nano /var/www/my.tlan.net/index.html <html> <head> <title>Welcome to My.Tlan.NET</title> </head> <body> <h1>The NGINX server block is working!</h1> </body> </html>
Да активираме виртуалния сайт.
ln -s /etc/nginx/sites-available/my.tlan.net.conf /etc/nginx/sites-enabled/
Не забравяме са спрем глобалния сайт default.
rm /etc/nginx/sites-enabled/default ls -l /etc/nginx/sites-enabled/ total 0 lrwxrwxrwx 1 root root 43 Apr 20 22:12 my.tlan.net.conf -> /etc/nginx/sites-available/my.tlan.net.conf
До тук добре. Да проверим правилността на конфигурационните файлове за Nginx.
nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
И тук всичко е наред. Да презаредим Nginx за да влязат промените в сила.
nginx -s reload 2024/04/20 22:19:06 [notice] 2988#2988: signal process started ### Също може и чрез: service nginx restart service nginx status ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled) Active: active (running) since Sat 2024-04-20 17:00:47 EEST; 5h 19min ago Docs: man:nginx(8) Main PID: 1424 (nginx) Tasks: 5 (limit: 4644) Memory: 3.8M CPU: 44ms CGroup: /system.slice/nginx.service ├─1424 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;" ├─2989 "nginx: worker process" ├─2990 "nginx: worker process" ├─2991 "nginx: worker process" └─2992 "nginx: worker process" Apr 20 17:00:47 my systemd[1]: Starting nginx.service - A high performance web server and a reverse proxy server... Apr 20 17:00:47 my systemd[1]: Started nginx.service - A high performance web server and a reverse proxy server.
Да тестваме: http://my.tlan.net
Остана да се справим и с HTTPS или сертификатите. Както винаги ще ползваме безплатните SSL сертификати на Let’s Encrypt. За целта ще инсталираме certbot.
apt install certbot python3-certbot-nginx -y
Да тестваме дали може да създадем сертификати.
certbot certonly --webroot --dry-run -w /var/www/my.tlan.net -d my.tlan.net -d mail.my.tlan.net -d ns1.my.tlan.net -d www.my.tlan.net
Теста мина успешно. Да генерираме сертификатите.
certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email tachko@my.tlan.net -d my.tlan.net -d mail.my.tlan.net -d ns1.my.tlan.net -d www.my.tlan.net
Инсталацията премина успешно. Да видим какво се получи:
nano /etc/nginx/sites-available/my.tlan.net.conf server { root /var/www/my.tlan.net/; index index.html index.htm index.nginx-debian.html; server_name my.tlan.net mail.my.tlan.net ns1.my.tlan.net www.my.tlan.net; location / { try_files $uri $uri/ =404; } listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/my.tlan.net/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/my.tlan.net/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot add_header Strict-Transport-Security "max-age=31536000" always; # managed by Certbot ssl_trusted_certificate /etc/letsencrypt/live/my.tlan.net/chain.pem; # managed by Certbot ssl_stapling on; # managed by Certbot ssl_stapling_verify on; # managed by Certbot } server { if ($host = www.my.tlan.net) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = ns1.my.tlan.net) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = mail.my.tlan.net) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = my.tlan.net) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; root /var/www/my.tlan.net/; index index.html index.htm index.nginx-debian.html; server_name my.tlan.net mail.my.tlan.net ns1.my.tlan.net www.my.tlan.net; location / { try_files $uri $uri/ =404; }
Прекрасно, до тук всичко е наред. Остана проблема с обновяването на сертификатите, защото валидността им е 90 дена. Пакетът certboot автоматично добавя времева задача която се изпълнява два пъти в деня на произволни часове. За да се подовява автоматино сертификата можем да ползвахме Cron или Systemd таймер. По-добрия вариант е втория. Таймера се определя във файла: /lib/systemd/system/certbot.timer За да разберем дали услугата е стартирана и кога ще е следващото събитеие изпълняваме:
systemctl status certbot.timer ● certbot.timer - Run certbot twice daily Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; preset: enabled) Active: active (waiting) since Sat 2024-04-20 22:40:45 EEST; 39min ago Trigger: Sun 2024-04-21 02:29:47 EEST; 3h 9min left Triggers: ● certbot.service Apr 20 22:40:45 my systemd[1]: Started certbot.timer - Run certbot twice daily.
Независимо от всичко това има и Cron файл в: /etc/cron.d/certbot. Не се бъркайте, тази задача няма да направи нищо поради “-d /run/systemd/system”, което проверява дали systemd е инсталиран. А както знаем Debian използва systemd. До тук всичко е прекрасно, но автоматично ще се подновяват само файловете на сертификата. Проблем е, че компоненти като Nginx, Apahche, PostFix и Dovecot няма да забележат промяната. За целта добавяме така наречения post-hook към certboot. Това ще рестартира всички гореспоменати процеси. За целата:
nano /etc/letsencrypt/cli.ini # Най-отдолу добавяме: post-hook = systemctl restart nginx postfix dovecot
Така вече всичко е наред. Сертификата автоматично ще се подновява на всеки 90 дена и след обновяването ще рестартира Nginx, PostFix и Dovecot. Последните две ги нямаме но не е проблем. Необходими са за в бъдеще когато ще ползваме пощенски сървър.
Малко претупано стана всичко по-горе. Инсталирахме сертификати, автоматично се оправи файла за виртуалния ни сайт да работи на порт 443 и т.н. Тук ще се пробвам да покажа как ще постигнем всичко това без certbot. Наново да проверим конфигурационния файл за виртуалния ни сайт преди ползването на certbot.
nano /etc/nginx/sites-available/my.tlan.net.conf server { listen 80; listen [::]:80; root /var/www/my.tlan.net/; index index.html index.htm index.nginx-debian.html; server_name my.tlan.net mail.my.tlan.net ns1.my.tlan.net www.my.tlan.net; location / { try_files $uri $uri/ =404; } }
Сега ще ползваме сертификатите генерирани по време на инсталацията на Debian. Те не са публично удостоверени но независимо от това ще ги използваме.
nano /etc/nginx/sites-available/my.tlan.net.conf server { listen 443 ssl; listen [::]:443 ssl; server_name my.tlan.net mail.my.tlan.net ns1.my.tlan.net www.my.tlan.net; root /var/www/my.tlan.net/; index index.html index.htm index.nginx-debian.html; ssl_certificate "/etc/letsencrypt/live/www.srv.world/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/www.srv.world/privkey.pem"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; location / { try_files $uri $uri/ =404; } } server { listen 80; listen [::]:80; return 301 https://$host$request_uri; root /var/www/my.tlan.net/; index index.html index.htm index.nginx-debian.html; server_name my.tlan.net mail.my.tlan.net ns1.my.tlan.net www.my.tlan.net; location / { try_files $uri $uri/ =404; } }
Горната секция server { отговаря за HTTPS на порт 443. Ползваме SSL сертификатите fullchain.pem и privkey.pem които имаме когато инсталирахме Debian. В долната секция server { чрез return 301 https://$host$request_uri; пренасочихме заявките от HTTP към HTTPS. Това е опростен вариант за ползване на HTTPS. За да влязат в сила промените отново трябва да се презареди Nginx.
service nginx reload
С това приключваме темата.