ОБРАТНЫЙ ПРОКСИ-СЕРВЕР NGINX

 homenetТопология домашней сети постепенно усложняется и, кажется, пора бы уже настроить обратный прокси-сервер. Суть его работы сводится к тому, чтобы перенаправлять запросы по разным серверам. Так, набрав в адресной строке браузера madmentat.ru, мы попадаем на Mad-PC3, а если mail.madmentat.ru, то на веб-морбу почтового сервера Mad-PC4. Ну, и таких поддоменов можно наделать чертову уйму, на все случаи жизни. К тому же, получается, все ssl сертификаты теперь хранятся в одном месте и больше не надо долго компостировать себе мозги, чтобы, например, включить https протокол на Микротике. Все делает уже знакомый нам и простой в использовании Cerbot.

Отмечу, что первоначальная настройка заняла у меня довольно много времени, мой nginx наотрез отказывался заводиться. Три дня искал причину, потом все-таки не выдержал и обратился за помощью к фрилансеру. Заплатил денег, но не так уж и много, за то уже вместе мы докапались до сути проблемы - оказалось все дело в том, что на том же компе (Mad-PC2) был установлен apache2, так что, если у вас по каким-то причинам не получается настроить обрытный прокси-сервер, необходимо убедиться, что больше никакие сервисы не перехватывают запросы, обращаемые через 80-й и 443-й порты. Для этого можно воспользоваться программой, вроде TCP Connector. Подключаемся на порт 80 и шлем запрос типа

<code>ProductOnly</code>
tcpConnector tcpConnector2

На самом деле, там пофигу чего писать - скорее всего, в ответ все равно вернется страничка в виде html кода, с сообщением об ошибке, и там будет видно что за сервак отработал по запросу. Если вы настраиваете nginx, то, соответственно, Апача там быть не должно, а если уж у вас по какой-то причине все-таки установлен Апач и вы не можете от него отказаться, тогда готовьтесь задрачиваться с настройкой портов, которые слушают ваши серваки, чтобы они друг другу не мешали.

В данном примере рассмотрим следующий кейс: наш виртуальный сервер Apache 2, расположенный, согласно схеме, на Mad-PC3 с контекстом test.madmentat.ru, слушает порт 8080. Итак, пожалуй, приступим.

Для начала установим сам nginx:

sudo apt install -y nginx

Далее создадим файл конфигурации.

sudo nano /etc/nginx/sites-available/test.conf

server {
    server_name test.madmentat.ru www.test.madmentat.ru;
    access_log /var/log/nginx/test.log;
    error_log /var/log/nginx/test-error.log;
    location / {
        proxy_pass http://192.168.88.238:8080;
        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 X-Forwarded-Proto $scheme;
    }   
}

sudo cp /etc/nginx/sites-available/test.conf /etc/nginx/sites-enabled/test.conf

Теперь установим cerbot и установим сам сертификат на сервер.

sudo apt install certbot python3-certbot-nginx

sudo certbot --nginx -d test.madmentat.ru -d www.test.madmentat.ru

К слову, cerbot любит поебывать мозги, если не может достучаться до проксируемого хоста. Лучше всего там подготовить голый виртуальный сервер с обычными портами и стандартным index.html, "Hello World!", и только потом запустить скрипт на нашем nginx. Сам скрипт будет задавать вопросы, надо отвечать исходя из контекста - там ничего сложного. Вот, собственно, и все. Пример тут.

 

ЧАСТЬ 2, СИЛЬНО ПОЗЖЕ

Работая, в компании АРД-Системы Северо-Запад, я столкнулся с локальным распиздяйством со стороны нашего провайдера Инфолан. А весь сыр-бор случился из-за камеры наблюдения, охватывающей наш парадный вход и ворота склада. Очень важный объект, требующий особого внимания. До того как я принял на себя роль местного сисадмина, тут приезжали их ребята и настроили эту камеру.... Таким образом, чтобы она оказалась не в общей сети, а в подсети, черз роутер. То есть, им пришлось пробросить порты через NAT основного шлюза на Кинетик, и через кинетик на саму камеру. В какой-то момент я, естественно, этот Кинетик нахуй выкинул в коробку с таким же барахлом, а камеру оставил в общей сети, и пароль на ней сбросил, так как надо было подключить ее к нашему видеорегистратору... Изучил внимательней настройки Микротика - а там порты были проброшены 80 и 8080 на тот Кинетик... Причем, как оказалось, 8080 вообще даже и не работал... То есть, они подключили камеру напрямую через порт 80! Вот прямо так, незатейливо! Но ведь при таком раскладе вырастает целая проблема... Представляете, какая имено? Вообще-то у меня тут веб-серверы работают и так далее... И я не знал, как ее решить, ну почему-то не приходило на ум, хотя к тому моменту у меня уже был настроен прокси-nginx для внутренних нужд и DNS сервер для AD. Проблема заключалась в том, что порт 80 в итоге слушал мой реверс- прокси-Nginx, а не камера, и, конечно, картинка не транслировалась в облако. Пробовал с ними общаться... Несколько раз звонил, писал всякие кляузы, чтобы они на своем облачном серваке настройку поменяли - хуй там плавал, ни в какую не хотят! Столько нервов на них потратил... Наконец-то меня осенило... Посмотрел в настройки Trassir-клиента, там был указан сервер trassir2.gorod.tv. Пробил его IP комндой dig., и настроил новый конфиг на Nginx-реверс-прокси:

sudo nano /etc/nginx/sites-enabled/trassir.conf

server {
    listen 80;

    # Проверяем, что запрос пришел из подсети 46.32.68.0/24 для камеры
    location / {
        set $is_trassir_subnet 0;
        if ($remote_addr ~ ^46\.32\.68\.) {
            set $is_trassir_subnet 1;
        }

        # Если это подсеть Trassir, проксируем на камеру
        if ($is_trassir_subnet) {
            proxy_pass http://192.168.88.37:80;  # IP вашей камеры
            break;
        }

        # Если запрос не из подсети Trassir, проксируем на основной сервис
        proxy_pass http://localhost;  # Замените на ваш основной сервис
    }

    # Директивы проксирования, которые должны быть глобально для всех 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;
}

sudo systemctl restart nginx

То есть, мы тут слушаем порт 80 и если запросы приходят из подсети 46.32.68.0/24, тогда перенапрвляем из на камеру, а если откуда-то еще, тогда проксируем на локальный хост! Вот и все решение, ребята! Целый месяц нервотрепки, а оказалось все так просто...

ПРИМЕРЫ РАБОЧИХ КОНФИГОВ

 Обычный сайт

server {
    listen 80;
    listen [::]:80;
    server_name ard-s.ru www.ard-s.ru;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name ard-s.ru www.ard-s.ru;

    # Размер тела запроса для загрузок
    client_max_body_size 1024m;

    # SSL
    ssl_certificate     /etc/letsencrypt/live/ard-s.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ard-s.ru/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass     http://192.168.88.17;
        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 X-Forwarded-Proto $scheme;
    }

}

Основной шлюз (Mikrotik GateWay):

server {
     server_name mikrotik.ard-s.ru www.mikrotik.ard-s.ru;
     location / {
         proxy_pass http://192.168.88.1:1982;  # ← убедись, что порт верный!
         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 X-Forwarded-Proto $scheme;
    }
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mikrotik.ard-s.ru/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mikrotik.ard-s.ru/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
}
server {
    if ($host = www.mikrotik.ard-s.ru) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    if ($host = mikrotik.ard-s.ru) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    server_name mikrotik.ard-s.ru www.mikrotik.ard-s.ru;
    listen 80;
    return 404; # managed by Certbot
}

Почтовый сервер iRedMail:

server {
    listen 80;
    server_name mail.ard-s.ru;

    # Перенаправление на HTTPS (опционально, но рекомендуется)
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name mail.ard-s.ru;

    # SSL-сертификаты (например, от Let's Encrypt)
    ssl_certificate /etc/letsencrypt/live/mail.ard-s.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mail.ard-s.ru/privkey.pem;

    # Безопасные настройки SSL (можно взять из Mozilla SSL Config Generator)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;

    location / {
        proxy_pass https://192.168.88.42;
        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 X-Forwarded-Proto $scheme;

        # Важно для корректной работы веб-интерфейсов
        proxy_ssl_verify off;  # только если на 242 используется самоподписанный сертификат
        proxy_redirect off;
    }

}

Видеорегистратор

server {
    server_name secure.ard-s.ru;

    listen 443 ssl;
    ssl_certificate     /etc/letsencrypt/live/secure.ard-s.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/secure.ard-s.ru/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam         /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://192.168.88.23;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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 X-Forwarded-Proto $scheme;
        proxy_read_timeout 86400;
        proxy_send_timeout 86400;
    }

}

server {
    listen 80;
    server_name secure.ard-s.ru;
    return 301 https://$host$request_uri;
}