Хочу рассказать об одной полезной возможности nginx, которую регулярно использую в своих делах. Речь пойдет о настройке проксирования запросов на удаленный сервер с помощью nginx и директивы proxy_pass. Я приведу примеры различных настроек и расскажу, где сам использую данный модуль популярного веб сервера.
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
Введение
Немного расскажу своими словами о том, как работает модуль ngx_http_proxy_module. Именно он реализует весь функционал, о котором пойдет речь. Допустим, у вас в локальной или виртуальной сети есть какие-то сервисы, не имеющие прямого доступа из интернета. А вы хотите таковой иметь. Можно пробрасывать нужные порты на шлюзе, можно что-то еще придумывать. А можно сделать проще всего - настроить единую точку входа на все свои сервисы в виде nginx сервера и с него проксировать различные запросы к нужным серверам.
Расскажу на конкретных примерах, где я это использую. Для наглядности и простоты буду прям по порядку перечислять эти варианты:
- Ранее я рассказывал о настройке чат серверов - matrix и mattermost. В этих статьях я как раз рассказывал о том, как проксировать запросы в чат с помощью nginx. Прошелся по теме вскользь, не останавливаясь подробно. Суть в том, что вы настраиваете на любом виртуальном сервере эти чаты, помещаете их в закрытые периметры сети без лишних доступов и просто проксируете запросы на эти сервера. Они идут через nginx, который у вас смотрит во внешний интернет и принимает все входящие соединения.
- Допустим, у вас есть большой сервер с множеством контейнеров, например докера. На нем работает множество различных сервисов. Вы устанавливаете еще один контейнер с чистым nginx, на нем настраиваете проксирование запросов на эти контейнеры. Сами контейнеры мапите только к локальному интерфейсу сервера. Таким образом, они будут полностью закрыты извне, и при этом вы можете гибко управлять доступом.
- Еще один популярный пример. Допустим, у вас есть сервер с гипервизором proxmox или любым другим. Вы настраиваете на одной из виртуальных машин шлюз, создаете локальную сеть только из виртуальных машин без доступа в нее извне. Делаете в этой локальной сети для всех виртуальных машин шлюз по-умолчанию в виде вашей виртуальной машины со шлюзом. На виртуальных серверах в локальной сети размещаете различные сервисы и не заморачиваетесь с настройками фаервола на них. Вся их сеть все равно не доступна из интернета. А доступ к сервисам проксируете с помощью nginx, установленным на шлюз или на отдельной виртуальной машине с проброшенными на нее портами.
- Мой личный пример. У меня дома есть сервер synology. Я хочу организовать к нему простой доступ по https из браузера по доменному имени. Нет ничего проще. Настраиваю на сервере nginx получение бесплатного сертификата Let's encrypt, настраиваю проксирование запросов на мой домашний ip, там на шлюзе делаю проброс внутрь локалки на synology сервер. При этом я могу фаерволом ограничить доступ к серверу только одним ip, на котором работает nginx. В итоге на самом synology вообще ничего не надо делать. Он и знать не знает, что к нему заходят по https, по стандартному порту 443.
- Допустим, у вас большой проект, разбитый на составные части, которые живут на разных серверах. К примеру, на отдельном сервере живет форум, по пути /forum от основного домена. Вы просто берете и настраиваете проксирование всех запросов по адресу /forum на отдельный сервер. Точно так же можно без проблем все картинки перенести на другой сервер и проксировать к ним запросы. То есть вы можете создать любой location и переадресовывать запросы к нему на другие сервера.
Надеюсь в общем и целом понятно, о чем идет речь. Вариантов использования много. Я привел самые распространенные, которые пришли в голову и которые использую сам. Из плюсов, которые считаю наиболее полезными именно из своих кейсов, отмечу 2:
- Без проблем можете настроить https доступ к сервисам, при этом совершенно не трогая эти сервисы. Вы получаете и используете сертификаты на nginx сервере, используете https соединение с ним, а сам nginx уже передает информацию на сервера со службами, которые могут работать по обычному http и знать не знают о https.
- Вы очень легко можете менять адреса, куда проксируете запросы. Допустим у вас есть сайт, его запросы проксируются на отдельный сервер. Вы подготовили обновление или переезд сайта. Отладили все на новом сервере. Теперь вам достаточно на сервере nginx изменить адрес старого сервера на новый, куда будут перенаправляться запросы. И все. Если что-то пойдет не так, можете оперативно вернуть все обратно.
С теорией закончил. Перейдем теперь к примерам настройки. В своих примерах я буду использовать следующие обозначения:
blog.zeroxzed.ru | доменное имя тестового сайта |
nginx_srv | имя внешнего сервера с установленным nginx |
blog_srv | локальный сервер с сайтом, куда проксируем соединения |
94.142.141.246 | внешний ip nginx_srv |
192.168.13.31 | ip адрес blog_srv |
77.37.224.139 | ip адрес клиента, с которого я буду заходить на сайт |
Настройка proxy_pass в nginx
Рассмотрим самый простой пример. Буду использовать свой технический домен zeroxzed.ru в этом и последующих примерах. Допустим, у нас есть сайт blog.zeroxzed.ru. В DNS создана A запись, указывающая на ip адрес сервера, где установлен nginx - nginx_srv. Мы будем проксировать все запросы с этого сервера на другой сервер в локальной сети blog_srv, где реально размещается сайт. Рисуем конфиг для секции server.
server { listen 80; server_name blog.zeroxzed.ru; access_log /var/log/nginx/blog.zeroxzed.ru-access.log; error_log /var/log/nginx/blog.zeroxzed.ru-error.log; location / { proxy_pass http://192.168.13.31; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; } }
Заходим по адресу http://blog.zeroxzed.ru. Мы должны попасть на blog_srv, где тоже должен работать какой-то веб сервер. В моем случае это будет тоже nginx. У вас должно открыться содержимое, аналогичное тому, что вы увидите, набрав http://192.168.13.31 в локальной сети. Если что-то не работает, то проверьте сначала, что по адресу директивы proxy_pass у вас все корректно работает.
Посмотрим логи на обоих сервера. На nginx_srv вижу свой запрос:
77.37.224.139 - - [19/Jan/2018:15:15:40 +0300] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
Проверяем blog_srv:
94.142.141.246 - - [19/Jan/2018:15:15:40 +0300] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko" "77.37.224.139"
Как мы видим, запрос сначала пришел на nginx_srv, был переправлен на blog_srv, куда он пришел уже с адресом отправителя 94.142.141.246. Это адрес nginx_srv. Реальный же ip адрес клиента мы видим только в самом конце лога. Это неудобно, так как директива php REMOTE_ADDR не будет возвращать настоящий ip адрес клиента. А он очень часто бывает нужен. Мы это дальше исправим, а пока создадим в корне сайта на chat_srv тестовую страничку для проверки ip адреса клиента следующего содержания:
<?php echo $_SERVER['REMOTE_ADDR'] ?>
Назовем ее myip.php. Перейдем по адресу http://blog.zeroxzed.ru/myip.php и проверим, как сервер определит наш адрес. Никак не определит :) Он покажет адрес nginx_srv. Исправляем это и учим nginx передавать реальный ip адрес клиента на сервер.
Передача реального ip (real ip) адреса клиента в nginx при proxy_pass
В предыдущем примере мы на самом деле передаем реальный ip адрес клиента с помощью директивы proxy_set_header, которая добавляет в заголовок X-Real-IP настоящий ip адрес клиента. Теперь нам нужно на принимающей стороне, то есть blog_srv сделать обратную замену - заменить информацию об адресе отправителя на ту, что указана в заголовке X-Real-IP. Добавляем в секцию server следующие параметры:
set_real_ip_from 94.142.141.246; real_ip_header X-Real-IP;
Полностью секция server на blog_srv в самом простом варианте получается следующей:
server { listen 80 default_server; server_name blog.zeroxzed.ru; root /usr/share/nginx/html; set_real_ip_from 94.142.141.246; real_ip_header X-Real-IP; location / { index index.php index.html index.htm; try_files $uri $uri/ =404; } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_intercept_errors on; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_ignore_client_abort off; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
Сохраняем конфиг, перечитываем его и снова проверяем http://blog.zeroxzed.ru/myip.php. Вы должны увидеть свой реальный ip адрес. Его же вы увидите в логе web сервера на blog_srv.
Дальше рассмотрим более сложные конфигурации.
Передача https через nginx с помощью proxy pass
Если у вас сайт работает по https, то достаточно настроить ssl только на nginx_srv, если вы не беспокоитесь за передачу информации от nginx_srv к blog_srv. Она может осуществляться по незащищенному протоколу. Рассмотрю пример с бесплатным сертификатом let's encrypt. Это как раз один из кейсов, когда я использую proxy_pass. Очень удобно настроить на одном сервере автоматическое получение всех необходимых сертификатов. Подробно настройку let's encrypt я рассматривал отдельно. Сейчас будем считать, что у вас стоит certbot и все готово для нового сертификата, который потом будет автоматически обновляться.
Для этого нам надо на nginx_srv добавить еще один location - /.well-known/acme-challenge/. Полная секция server нашего тестового сайта на момент получения сертификата будет выглядеть вот так:
server { listen 80; server_name blog.zeroxzed.ru; access_log /var/log/nginx/blog.zeroxzed.ru-access.log; error_log /var/log/nginx/blog.zeroxzed.ru-error.log; location /.well-known/acme-challenge/ { root /web/sites/blog.zeroxzed.ru/www/; } location / { proxy_pass http://192.168.13.31; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; } }
Перечитывайте конфиг nginx и получайте сертификат. После этого конфиг меняется на следующий:
server { listen 80; server_name blog.zeroxzed.ru; access_log /var/log/nginx/blog.zeroxzed.ru-access.log; error_log /var/log/nginx/blog.zeroxzed.ru-error.log; return 301 https://$server_name$request_uri; # редирект обычных запросов на https } server { listen 443 ssl http2; server_name blog.zeroxzed.ru; access_log /var/log/nginx/blog.zeroxzed.ru-ssl-access.log; error_log /var/log/nginx/blog.zeroxzed.ru-ssl-error.log; ssl on; ssl_certificate /etc/letsencrypt/live/blog.zeroxzed.ru/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/blog.zeroxzed.ru/privkey.pem; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; location /.well-known/acme-challenge/ { root /web/sites/blog.zeroxzed.ru/www/; } location / { proxy_pass http://192.168.13.31; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; } }
Проверяем, что получилось.
Наш сайт работает по https, при том, что мы вообще не трогали сервер, где этот сайт располагается. Конкретно с web сайтом это может быть не так актуально, но если вы проксируете запросы не на обычный сайт, а на какой-то нестандартный сервис, который трудно перевести на https, это может быть хорошим решением.
Проксирование определенной директории или файлов
Рассмотрим еще один пример. Допустим, у вас форум живет в директории http://blog.zeroxzed.ru/forum/, вы хотите вынести форум на отдельный web сервер для увеличения быстродействия. Для этого к предыдущему конфигу добавьте еще один location.
location /forum/ { proxy_pass http://192.168.13.31; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_redirect default; }
Еще одно популярное решение. Вы можете отдавать картинки с одного сервера, а все остальное с другого. В моем примере, картинки будут жить на том же сервере, где nginx, а остальной сайт на другом сервере. Тогда у нас должна быть примерно такая конфигурация локаций.
location / { proxy_pass http://192.168.13.31; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; } location ~ \.(gif|jpg|png)$ { root /web/sites/blog.zeroxzed.ru/www/images; }
Чтобы все это работало корректно, необходимо, чтобы сам сайт умел правильно размещать свои изображения. Вариантов это организовать множество. Можно как на сервере монтировать сетевые паки различными способами, так и программистам изменять код для управления размещением изображений. В любом случае, это комплексный подход к работе с сайтом.
Существует очень много директив для управления прокси-соединениями. Все они описаны в соответствующей документации nginx. Я не большой специалист по настройке nginx. В основном использую свои готовые конфиги, зачастую даже не вникая в суть, если получается сразу решить задачу. Подсматриваю что-то у других, записываю к себе, стараюсь разобраться.
Особое внимание следует уделить директивам кэширования proxy_cache, если в этом есть потребность. Можно существенно увеличить отклик веб сайта, если подходящим образом настроить отдачу кэша. Но это тонкий момент и нужно настраивать в каждом конкретном случае отдельно. Готовых рецептов тут не бывает.
Более подробно о комплексной настройке nginx читайте в отдельной большой статье с моими личными примерами.
Часто задаваемые вопросы по теме статьи (FAQ)
В общем случае не обязательно. Но есть некоторый софт, который не может корректно работать в таком режиме. Он не понимает, как корректно обрабатывать такую ситуацию. Может создавать ссылки вида http://site.ru:443, которые будут являться ошибочными. В таком случае необходимо настроить обмен между nginx и бэк сервером тоже https соединение.
Я в таких случаях использую 2 способа, в зависимости от ситуации. Самый простой - на сервере с nginx настроить nfs сервер, а на бэкенде подмонтировать по nfs к себе директорию /etc/letsencrypt и спокойно использовать сертификаты, как-будто они лежат локально. Второй вариант - использовать простой bash скрипт для копирования сертификатов к себе на сервер по scp. В обоих случаях надо не забыть на бэкенде перезапускать службы, которые использую сертификат, после его обновления.
В такой ситуации может помочь правка файла /etc/hosts на самом бэкенде. Сделайте там статическую запись с именем сайта и локальным ip адресом. Тогда запросы с самого сервера будут приходить на него же локально, а не на nginx proxy.
Однозначного ответа на этот вопрос не может быть. В чем-то это схожий софт, но есть и существенные отличия. В общем случае, описанном в статье, принципиальной разницы нет. У haproxy в бесплатной версии есть функционал, который присутсвует только в nginx plus. Так что нужно смотреть по конкретным задачам и решать, какой продукт подойдет лучше.
Конечно да. Но на практике они очень малы, если nginx и целевой сервер находятся в общей локальной сети. С учетом задержек при передачи пакетов по сети интернет, этими локальными задержками можно пренебречь. Они будут ничтожно малы. Если же вы проксируете запросы через интернет, то нужно внимательно смотреть величину задержек между nginx и бэкендом. Желательно их делать минимальными, располагая сервера поближе друг к другу.
Заключение
На этом у меня все. Не рассмотрел еще один возможный вариант, когда вы проксируете https сайт и передаете инфу на бэкенд тоже по https. Нет под рукой готового примера, чтобы проверить, а заочно не стал рисовать конфиг. По идее, ничего сложного в этом нет, настраиваете nginx на обоих серверах с одним и тем же сертификатом. Но наверняка не скажу, что все заработает при этом. Возможно, есть какие-то нюансы с таким проксированием. Мне обычно не приходится так делать.
Как я уже писал в начале, в основном проксирую запросы с одного внешнего веб сервера на закрытый периметр сети, куда нет никому доступа. В этом случае у меня нет необходимости использовать https при передаче запросов на бэкенд. В качестве бэкенда не обязательно будет отдельный сервер. Это запросто может быть контейнер на этом же сервере.
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
Здравствуйте. Спасибо за статью. Есть действующий веб-сервер (сайт site5.ru) в локальной сети на котором дополнительно установлен и настроен nginx (backend далее) c действующим сертификатом для которого на роутере по портам 80/443 сделан проброс. Возникла необходимость разместить еще несколько серверов которые должны так же работать по ssl и планы в ближайшей перспективе избавиться от веб-сервера с backend. Создан новый прокси сервер nginx (Frontend). Необходимо сделать редирект/перенаправление с Frontend на backend. Для остальных серверов Frontend будет работать в штатном режиме (принимать, обрабатывать и отдавать клиентам запросы). Не могу составить конфиг, буду рад дельному совету. Заранее спасибо.
Всем добра. Подскажите пожалуйста, в чем может быть проблема. Есть два VDS и два сайта. Задача что бы на определенном разделе первого сайта открывался второй. В конфигурационном файле nginx первого сайта прописал следующее:
location ~ ^/history/(.*)$ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_pass http://ip_второго_сайта/$1$is_args$args;
}
В итоге всё работает, за исключением того, что с проксируемого сайта не доступны стили и картинки (получаем ломанную вёрстку без картинок), что еще нужно подкрутить?
Привет. Владимир, а вам приходилось решать задачу, когда ssl-сертификаты не на nginx, а на конечном сервере. Трафик должен проходить сквозь nginx, как тогда установить безопасное https соединение? Такое вообще возможно? Сертификаты перенести на сервер с nginx нельзя))) Скажем так, на той стороне свой CA-сервер и он хочет рулить всеми серфами.
Ни разу с такой задачей не сталкивался. Думаю, что без использования сертификата сервер с nginx-proxy работать не сможет. Я не понимаю, как это технически может быть выполнено. Тут либо оба по http работают, либо по https. Пропускать шифрованный трафик https по протоколу http не получится. Клиент и сервер должны общаться напрямую для обмена ключами, а тут посередине будет стоять nginx без шифрования. Надо делать простой проброс 443 порта с маршрутизатора на веб сервер напрямую, минуя nginx.
В интернете есть домен example.com по адресу https://test.example.com:7443 идет перенаправление в локальную сеть на адрес 192.168.0.36 далее там стоит traefik который пропускает через себя HTTPS-трафик и отдает уже трафик HTTP. за ним стоит NGINX который принимает только трафик HTTP. так как SSL сертификаты на нем не настроены. Теперь мне надо чтобы этот трафик ушел на адрес https://192.168.0.102 через самоподписанные сертификаты. Какие написать команды NGINX чтоб он смог перенаправить меня правильно если запросы на example.com будут идти из интернета.
Не подскажете куда копать:
У меня nginx (172.16.4.44) за микротиком (172.16.4.1) и в логах доступа только один адрес 172.16.4.1 и никакие советы не дают исправить этого поведения.
Вы как пробрасываете запросы от Mikrotik к Nginx? Покажите правило.
/ip firewall nat
add action=dst-nat chain=dstnat disabled=no dst-address= \
dst-port=80,443 in-interface-list=WAN log=no log-prefix="" protocol=tcp \
to-addresses=172.16.4.44
add action=netmap chain=dstnat disabled=no dst-address= \
dst-port=80,443 log=no log-prefix="" protocol=tcp src-address=10.10.0.0/16 \
to-addresses=172.16.4.44
add action=src-nat chain=srcnat disabled=no dst-address=172.16.4.44 \
dst-port=80,443 log=no log-prefix="" protocol=tcp src-address=10.10.0.0/16 \
to-addresses=172.16.4.1
Почему правил три? Достаточно одного, первого. Если не ошибаюсь, подмену адреса клиента на 172.16.4.1 делает правило с netmap. Его не надо использовать для проброса портов, хотя оно и может это делать.
Остальные 2 для доступа из локальной сети по внешнему адресу
У вас во время пробросов портов к веб серверу пакеты проходят по правилу с action=dst-nat или с action=netmap? Включите логирование правил и проверьте. То, что проходит по netmap должно быть с изменённым адресом отправителя на 172.16.4.1, а то, что через dst-nat должно содержать настоящий адрес отправителя. Я тут могу ошибаться, так как надо вспоминать и тестировать, но мне кажется, дело в этом. Припоминаю такую же проблему с netmap.
Огромное спасибо. Пошёл тестировать
Протестировал. Ничем не отличается. Каждый тест делаю из вне. Даже отключаю VPN.
Решил проверить с отключенными правилами харпиннат (теми двумя доступа из сети), не помогло.
Добрый день!
Был бы рад если подсказали по проблеме. На сайте https://site.ru имеется форма во фрейме с сайта https://sub.site.ru
Я пробую прописать в src формы например https://site.ru/proxy_form/form.php вместо https://sub.server.ru/first_form/form.php и проксировать в локейшене /form1/
location /proxy_form/ {
proxy_pass https://sub.server.ru/first_form/;
#proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 1800;
proxy_connect_timeout 1800;
}
Но Вместо формы 404 ошибку отдает.
Заранее большое спасибо за подсказку!)
Добрый день, спасибо за полезную статью.
У меня возник вопрос ...
Настроено прокси одного доменного имени и соответственно все хосты имеющие его приписку автоматически проксируются. Мне нужно добавить в исключение конкретный хост, чтобы он не смотрел в интернет. Можете посоветовать как это можно сделать и можно ли вообще ?
Ниже приложу текущий конфиг:
server {
# port 80
server_name ~^(?.+)\.mydome\.com$;
# server_name ~^(?.+)\.mydome\.ru$;
include include.d/https_redirect;
include include.d/extra;
include include.d/essentials;
}
server {
# port 443
listen 443 ssl http2;
server_name ~^(?.+)\.mydome\.com$;
# server_name ~^(?.+)\.mydome\.ru$;
# error_log /var/log/nginx/zz-err debug;
error_log /var/log/nginx/zz-test warn;
include include.d/ssl;
include include.d/extra;
include include.d/essentials;
location / {
proxy_pass https://$domain.mydome.com;
include include.d/proxy_params;
}
}
Не понял вопрос. Как связано то, что хост смотрит в интернет и проксирование?
Не правильно описал проблему. Настроено таким образом, что любой хост относящийся к определенному домену, проходящий через проксю, оказывается вывешен в интернет. Это сделано намерено. Мне нужно, чтобы 1 конкретный хост не заворачивался автоматически на проксю и тем самым не был доступен извне.
Самое простое - поставить настройки этого виртуального хоста с доменом выше другого правила. Запрос обработается той частью конфигурации, которая применится раньше.
Доброго времени суток. Уже несколько часов не могу сообразить, что делаю не так:
Необходимо в nginx реализовать простую переадресацию:
при переходе по ссылке на http://127.0.0.1/index.php/856880 должен идти редирект на http://127.0.0.1:8090/index.php/856888
на 127.0.0.1 стоит nginx
на 127.0.0.1:8090 стоит сервис
как это реализовать? Пробую через proxy_pass ошибка 502
А если сделать обычный редирект, а не проксирование? Типа такого:
location /index.php/856880 {
return 301 http://127.0.0.1:8090/index.php/856888;
}
Спасибо, помогли!
Привет!
Появилась ошибка при отправке почты со своего сайта (на фронтэнде nginx), iredmail в этой же сети на бэкэнде:
SMTP Error: Could not connect to SMTP host. Connection failed. stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed
Соединение фронт с бэком устанавливают, рукопожатие по ssh есть. Чую, что в настройках дело, но куда копать?
Не понимаю написанного. При чём тут почта, ssh, фронт, бэк и статья про проксирование в nginx? SMTP клиент отвечает, что не принимает сертификат от сервера, потому что не может проверить его подлинность: "certificate verify failed". К nginx это не имеет никакого отношения.
Владимир, Добрый день. Спасибо за статью.
Подскажите, пожалуйста, планируется ли статья по Envoy proxy?
По статистике якобы Nginx revers proxy используется в 95% случаев, а Envoy proxy всего в 5% случаев, но если я правильно понял потенциал у него больше чем у Nginx revers proxy.
https://www.wappalyzer.com/technologies/reverse-proxies/
С установкой Envoy proxy проблем нет. Почему-то правда нет unit для systemctl, но это мелочи.
А вот наглядных статей по настройке очень мало ... почему-то.
Не планирую. Не вижу большого смысла. Лично меня Nginx полностью устраивает. А тот, кто сознательно выбирает Envoy по какой-то причине, скорее всего уже умеет его настраивать.
Здравствуйте! Я начинающий разработчик, и был бы очень рад небольшому совету с вашей стороны) Есть web-сайт, работающий на VDS. Фронт отдается автоматически при переходе по адресу сайта, также на vds на 4200 порте запущен бек на nestJS. По http все работает отлично(когда с фронта запрос идет к моему домену и порту), при переводе на https решил сделать так - запустить бек локально и с помощью nginx на самом vds просто проксировать запросы с фронта(обычный react без фреймворка - spa приложение) по пути /api/myServerPath/ в локальную сеть к нужному порту. SSL сертификат поставить только на домен. Насколько это адекватное и приемлемое решение? Может лучше тогда и фронт разместить как то локально и к нему тоже проксировать, чтобы все по правилам решения таких задач было. Не смог почему то найти ответ в гугле. Заранее спасибо)
Или лучше такое делать с помощью docker например?
Это нормальное решение. На бэк не обязательно настраивать https, тем более когда они с фронтом на одной машине работают. Https важно там, где идёт общение с клиентом. Всё остальное зависит от требований безопасности. В общем случае можно по http гонять данные в закрытых периметрах. А общение по localhost на VDS это закрытый периметр.
Спасибо большое)
Добрый день!
Подскажите пожалуйста, я настроил почтовый сервер postfix/dovecot через реверсивный прокси, сертификаты генерятся на Nginx(Revers proxy), на почтовом серваке для работы с сертификатами подкинул nfs шару перезапустил службы все работает все хорошо, правильно ли я понимаю что по истечении трех месяцев когда nginx обновит сертификаты мне нужно как то в автоматическом режиме перезагрузить службы postfix и dovecot на почтовом сервере?
Да, всё верно. Postfix и Dovecot нужно будет обязательно перезапустить. Можно hook сделать на сервере с Nginx, который будет по ssh подключаться и перезапускать службы на почтовом сервере.
Сделал авторизацию по ssh ключам между серверами, но для рестарта служб нужны права sudo, и соответственно просит вводить пароль, как это можно обыграть без пароля, или я не в ту сторону копаю?
Вариантов решения задачи может быть много. Разрешите пользователю в sudoers выполнять команду на перезапуск без пароля.
Добрый день!
Можете пожалуйста помочь с таким вопросом:
proxy pass настроен на другой URL
location / {
return 301 https://test.work.kz$request_uri;
#proxy_pass https://worklayout-dev.adat.systems;
expires $expires;
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 1m;
proxy_connect_timeout 1m;
}
}
server {
root /var/www;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name test.work.kz;
ssl on;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate /etc/nginx/certs/work_2024.crt;
ssl_certificate_key /etc/nginx/certs/work_2024.key;
proxy_max_temp_file_size 0;
gzip on;
gzip_types text/plain application/xml text/css application/javascript;
gzip_min_length 1000;
location / {
proxy_pass https://worklayout-dev.adat.systems;
# proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 1800;
proxy_connect_timeout 1800;
}
И все работает прекрасно, то есть при переходе по ссылке https://test.work.kz автоматически проксируется на https://worklayout-dev.adat.systems при этом в адресной строке браузера отображается test.work.kz. Но есть одна проблема если в момент когда страница https://test.work.kz только открылась и сразу же нажать на какое-либо меню, то в адресной строке будет отображаться https://worklayout-dev.adat.systems. Если же после загрузки страницы https://test.work.kz 2-3 секунды подождать, то уже никаких подмен в адресной строке не будет. Как-то можно этого избежать?
Я не знаю, как всё это должно корректно работать. Никогда таких замен не делал.
Доброго дня.
Я что-то не понимаю что делает
location /.well-known/acme-challenge/ {
root /web/sites/blog.zeroxzed.ru/www/;
}
У меня поднимается защищенное соединение с одним только
location / {
proxy_pass http://192.168.0.3:80;
proxy_set_header X-Real-IP $remote_addr;
}
И ещё непонятно, есть А-запись zeroxzed.ru или blog.zeroxzed.ru?
Спасибо.
Догадался поискать по странице ))) С location /.well-known/acme-challenge понятно, остался открытым вопрос про А-запись.
Я так понимаю, если у меня есть доменное имя name.net, я не могу просто так присобачить к нему mysite.name.net, мне нужно использовать Wildcart, а на nginx настраивать server_name для обработки запросов к mysite.name.net?
Приветствую!
А есть опыт проксирования на Exchange server?
Если есть, то как реализовывалась схема с реальным IP?
Я не настраивал проксирование на Exchange. По моему опыту, проксирование можно настроить для любой веб службы. По крайней мере я не встречал ни одной, где бы это нельзя было реализовать.
Я настроил проксирование для OWA.
Проблема в том, что OWA считает, что запрос идет с обратного прокси, а для выявления нарушителей это неправильно
Nginx умеет передавать адрес реального IP в заголовке. Можно настроить корректное распознавание клиентов.
Вы про - proxy_set_header Host $host;
Если да, то не работает или Exchange это не воспринимает
Это тоже не катит:
set_real_ip_from 'IP-адрес reverse proxy';
real_ip_header X-Real-IP;
Кстати, у меня вопрос по точной и правильной настройке.
У меня реверс прокси отправляет запросы на 2 backend хоста, но...
Условно представим, что это:
mail.domain.ru
srv1.domain.ru
srv2.domain.ru
Если в запросе фигурирует имя другого хоста (DNS имя связано с внешним IP-адресом, но пока не опубликовано - mail.domain.ru), запросы идут на srv1.domain.ru.
Подскажите, пожалуйста, каким образом мне сделать, чтобы сервер отвечал что такого хоста нет?
Не очень понял задачу. Если запрос идёт на имя домена, которое не описано в конфигурации nginx, то открывается тот домен, который в конфигурации nginx стоит первый. Можно сделать любой виртуальный хост default_server и отвечать будет он. На этом хосте можно сразу возвращать 404. Тогда по IP и по несуществующим доменам всем будет возвращаться 404.
Понял. Спасибо!
Добрый день. вопрос есть веб сервер с серым айпи за натом провайдера есть vps с белым ip между ними поднят впн туннель. так вот вопрос не много офтоп как правильней и безопасней реализовать, поднять на vps nginx и настроить прокси пас или просто натировать порты веб в туннель и уже все делать на веб сервере.
Тут нельзя однозначно сказать, как лучше и безопаснее. Сделайте так, как вам удобнее управлять. Более корректно, мне кажется, на VPS поднять Nginx. Даже если отвалится связь по VPN, Nginx будет фиксировать все подключения и показывать пользователям ошибку 5ХХ. Можно даже текст какой-то подготовить. А если пробросить порты, то у пользователей будут подвисать подключения с неизвестной ошибкой в браузере, который просто по таймауту будет отключаться.
Привет. Хорошая статия. Я из Болгарии и возможно ошибок в тексте. Извините об етом. У меня такая проблема: хочу на одном сервере ставить почту(будет mail.sajt.bg) и prestashop. Ето будет возможно? МОжете мне помочь разобратся с етим ?
Да, это возможно. Чем вам помочь, я не знаю.
Добрый день. Настроил по данной статье, все работает, одна проблема задержка 6с на запрос.
Все сервера в одной подсети. Как поймать на каком этапе такая задержка? Спасибо.
Делал проброс с роутера напрямую на сервер задержка минимальна.
Когда делаю через reverse proxy добавляется 5-6с.
Вдруг у кого то есть варианты?
server {
if ($host = ****.***.ru) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name ****.***.ru;
access_log /var/log/****.***.ru-access.log;
error_log /var/log/****.***.ru-error.log;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name ****.***.ru.ru;
client_max_body_size 0;
access_log /var/log/****.***.ru.ru-ssl-access.log;
error_log /var/log/****.***.ru-ssl-access.log;
ssl_certificate /usr/local/etc/letsencrypt/live/****.***.ru-0003/fullchain.pem; # managed by Certbot
ssl_certificate_key /usr/local/etc/letsencrypt/live/****.***.ru-0003/privkey.pem; # managed by Certbot
ssl_session_timeout 5m;
ssl_protocols TLSv1.2;
#ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
location / {
proxy_pass http://**.**.**.**;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
client_max_body_size 0;
proxy_max_temp_file_size 0;
proxy_read_timeout 1200s;
proxy_buffering off;
}
}
Можно попробовать включить в стандартный лог информацию о времени ответа бэкенда. Это поможет понять, бэкенд отвечает медленно или задержка на самой проксе. Для этого в формат лога надо добавить переменную $upstream_response_time.
Здравствуйте. Я просто не выспался и нефига не понял или в статье действительно не указано где конкретно и как "рисовать" конфиг? На мой взгляд, отсутствие строчки типа "sudo nano /etc/nginx.conf" (или как там?!) непосредственно под строкой "Рисуем конфиг для секции server" анулирует всю пользу от статьи. Придется идти искать другую.
Добрый день.
Вопрос также по проксированию, а проблема такая: сервер + nginx, на том же сервере - докер контейнер canjan/janus-gateway ( сеть контейнера host, порты все доступны) доступ прописан в конфиге нжинкс так:
server {
listen 443 ssl;
server_name myserverjanus.name;
add_header Strict-Transport-Security "max-age=31536000";
ssl_certificate /etc/letsencrypt/live/myserverjanus.name/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myserverjanus.name/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
access_log /var/log/janus/nginx_access.log ;
error_log /var/log/janus/nginx_error.log debug;
location /janus {
proxy_pass http://localhost:8188; #8088 - http without ssl
proxy_read_timeout 300;
proxy_connect_timeout 60;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#Allow the use of websockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'Upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Запрос приходит, но в ответе: bad gateway 502 Информации по подключению к янусу за nginx очень мало - бьюсь уже несколько недель.
А если зайти на http://localhost:8188 или http://localhost:8188/janus, то какие ответы будут?
День добрый.
В свое время так и не дошла до вашего коммента. В общем, дело закончилось тем, что янус ( сидит в докере) слушает обращения к себе без nginx ( конфиг для него просто закомментирован). Перехват пакетом nginx с последующим проксированием в контейнер януса так и не заработал. При этом слушает он именно порт 8188 ( и слушает он HTTPS). НО, заработало все только тогда, когда собрался свой собственный контейнер ( с нужной версионной ветки)
Приветствую!
Подскажите, пожалуйста, возможно ли средствами nginx сделать такой фокус:
Есть некий сервис, который работает как REST API приложение.
Написанна вторая версия бэкенда, которая работает с теми же самими данными, что и первая, и хотелось бы ее протестировать
в боевых условиях с текущем фронтендом.
Возникла идея каким-то образом настроить параллельный прокси всех POST-запросов на боевой сервер с первой версией бека
на какой-нибудь тестовый со второй версией. Проще говоря сделать так, чтобы все POST-запросы улетали и на первый и на второй сервер,
но при этом ничего не меняя в коде фронтенда.
А куда будут улетать ответы от второй версии бэка? Скопировать запросы к первому бэку на второй не трудно. Это можно сделать либо с помощью модуля ngx_http_mirror_module, либо с помощью функции post_action. Дальше нужно поискать в сети подробности этих способов и попробовать реализовать.
Приветствуй. Ответы со второго сервака в пустоту должны улетать, ну или как-то их логировать буду))). Нам надо только протеститровать то как бек отрабатывает POST запросы.
Спасибо! Буду искать инфу по модули и про функцию post_action. Не знал о них.
Всё бы ничего и вполне понятно, только один вопрос остался) А в каком файле это всё прописывать?
В файле конфигурации виртуального хоста.
/etc/nginx/conf.d/example.com.conf как я пониаю? Просто прописал и мне выдаёт 404 ошибку(
Здравствуйте! подскажите пожалуйста как реализовать такую архитектуру: nginx смотрит наружу, еще 2 сервера работают в локальной сети 1-вый сервер через прокси работает по домену site.domain.com а 2-ой должен работать по URL site.domain.com/nextcloud. nginx проксирует но не может найти css, js, img
проксирую так:
location /qwe/ {
proxy_pass http://192.168.1.173/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_redirect default;
Я затрудняюсь сходу ответить, как тут правильно сделать. Я так делал, это решаемо, но надо немного продумать и правила сделать, проверить. Желательно на принимающем сервере подпапки /nextcloud тоже настроить работу по url с подпапкой /nextcloud: http://192.168.1.173/nextcloud, иначе придётся не только редирект делать, но и редактирование запросов. Я так думаю, что из-за этого не находит css, js, img. Приходит запрос на адрес site.domain.com/nextcloud, nginx его проксирует на http://192.168.1.173/nextcloud, а сервер 192.168.1.173 не имеет такого url. Он сразу по ip отвечает.
Тут надо логи обоих серверов смотреть, на какие урлы приходят запросы и какие отдают 404. На основе этого думать, как поменять конфигурацию, чтобы все работало правильно.
Привет, тебе удалось решить проблему?
А разве получится трансформировать хттпс-запросы к nginx в обычные хттп-запросы к конечному сервису?
Да, без проблем.
А как это в принципе работать будет, поясните хотя бы в двух словах, если не затруднит. Разные протоколы-то, всё же. По типу NAT будет реализовываться постоянная подмена заголовков?
Почему разные? Не вижу тут никаких противоречий. Шифрование происходит между браузером клиента и веб сервером nginx, куда приходит его запрос. Nginx расшифровывает данные и дальше их передаёт либо по http, либо по https, в зависимости от настроек проксирования.
Спасибо за статью, помогла. Но есть вопрос.
LE сертификат может обновлятся только на рабочем сервере.
Настроил проксирование по защищенному протоколу, выпущенный рабочий серт перенёс на фронтэнд, где он уже будет обновляться в дальнейшем.
Теперь, если не обновлять серт на бекэнде, то когда он просрочится, будет ли работать проксирование через nginx с ошибкой?
Например в curl есть опция не проверять валидность сертификата и игнорировать ошибку. В nginx это не нужно?
Думаю, что не будет работать, но я не проверял. Есть несколько способов передать на бэкенд свежий сертификат:
1. Монтировать по nfs или smb каталог /etc/letsencrypt с прокси на бэкенд.
2. Копировать свежие сертификаты на бэкенд.
В зависимости от конкретной ситуации, я использую либо первый, либо второй метод.
Добрый вечер.
Владимир подскажите как реализовать.
Хочу что бы каждый контейнер докера выходил в интернет через свой прокси (купленный прокси).
Если можно подробнее.
Возможно ли это через один nginx в контейнере?
Эта тема к nginx не имеет никакого отношения. Простого решения тут нет. Использование прокси это уровень приложения, а не контейнера. Соответственно, от приложений в контейнерах и нужно плясать.
Добрый день. Нужна консультация.
Развернут почтовый сервер. Доступ в локальной сети осуществляется по адресу mail.company.ru
Развернут прокси сервер для публикации во вне.
server {
listen 443;
server_name mail.company.ru;
access_log /var/log/nginx/mail.company.ru-access.log;
error_log /var/log/nginx/mail.company.ru-error.log;
location / {
proxy_pass http://mail.company.ru;
A запись добавлена на в DNS-зону.
Всё работает.
Сейчас возникла потребность сделать доступ с наружи к почтовому серверу по другому доменному имени, т.е внутри локалки всё так и оставить, а вот снаружи поменять.
Как я понимаю, нужно добавить новую А запись образно говоря message.
Затем на прокси сервере поменять конфиг.
server {
listen 443;
server_name message.company.ru;
access_log /var/log/nginx/mail.company.ru-access.log;
error_log /var/log/nginx/mail.company.ru-error.log;
location / {
proxy_pass http://mail.company.ru;
Перезапустить nginx и всё должно работать.
Поправьте если что то упускаю.
В теории, так должно получиться, но нужно обязательно при проксировании заменить заголовок с именем домена в запросах. Подробно писал об этом в отдельной заметке - https://t.me/srv_admin/1741
Либо есть проще вариант. Если веб сервер, где запущен веб интерфейс, при обращении по ip я открывает этот веб интерфейс, можно проксировать не по имени домена, а по ip:
proxy_pass 10.20.20.1:80;
Спасибо, попробую в ближайшее время и отпишусь о результатах, может кому будет полезно.
А можно сделать проксирование сразу пачки портов на внутренний айпи?
типа такого Listen 80-85 -> 1.2.3.4:80-85 ?
Это на уровне фаервола надо делать, а не приложения типа nginx.
Подскажите можно ли настроить проксирование imap. Есть почта для домена от Яндекса, есть терминальный сервер с интернетом только через прокси. На данный момент пользователи ходят на почту через web браузер. Цель - настроить внутри терминального сервера почтовый клиент mozilla thunderbird (у него есть настройки прокси, но они нужны для обновление самого клиента, работу с письмами не настроить)
Я подобное не настраивал никогда в таком виде, как вы хотите, так что не знаю, как это в реальности делается. Знаю только, что smtp и imap обычно проксируют через haproxy. По идее, вам нужен почтовый клиент, который умеет использовать прокси для проверки почты.
А почему просто не открыть imap порты на выход до серверов яндекса? Зачем заморочки с прокси? Если http прокси обычно используют для ограничения доступа и сбора статистики, то тут какая роль прокси сервера? Доступ ограничен не будет, так как почтовый сервер один и тот же, к которому обращаются клиенты.
Здравствуйте, Владимир,
Может сможете подсказать с решением:
Имеется два сервера в одной локальной сети:
172.16.1.10 (смотрит наружу, на нем крутятся сайты)
172.16.1.20 (не смотрит наружу, на нем хочу установить Zabbix)
Как можно наилучшим образом настроить внешний доступ к панели Zabbix?
Пытаюсь организовать доступ по ссылке site.ru/zabbixpanel путем проксирования через 172.16.1.10
Прописал на сервере 172.16.1.10 для виртуального хоста site.ru на Nginx такой location:
location /zabbixpanel {
proxy_pass http://172.16.1.20;
proxy_set_header Host $proxy_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
На сервере 172.16.1.20, где установил Zabbix конфигурация такая:
server {
listen 80;
server_name 172.16.1.20;
root /usr/share/zabbix;
Но в итоге получаю ошибку 404, в логах проксируемого сервера 172.16.1.20:
[26/Nov/2021:11:21:09 +0500] 172.16.1.20 "GET /zabbixpanel/ HTTP/1.0" 404
Ощущение, что в целом что-то неправильно делаю и можно как-то по-другому. Буду благодарен за помощь.
С доступом не должно быть никаких проблем, если использовать проксирование с первого сервера, который смотрит наружу. Просто повесьте zabbix на отдельный поддомен. Так будет удобнее и проще всего. С отдельным location вы что-то в настройках напутали, либо сам Zabbix не умеет такие подключения нормально отрабатывать. Я вижу, что на Zabbix у вас ошибка связанная с тем, что про location /zabbixpanel он вообще ничего не знает, а запросы с первого сервера приходят как есть с урлом в виде /zabbixpanel
Тут надо либо на поддомен перенести Zabbix, либо аккуратно с location разобраться и сделать их одинаковыми на первом и втором сервере.
Спасибо за ответ.
В итоге получилось сделать проксирование через location. Чтобы заработало таким образом, нужно было добавить слэш в конце директив location и proxy-pass, т.е. так:
location /zabbixpanel/ {
proxy_pass http://172.16.1.20/;
proxy_set_header Host $proxy_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
Почему так происходит, кому интересно, можно почитать здесь:
http://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_pass
http://nginx.org/ru/docs/http/ngx_http_core_module.html#location
Возможно через поддомен было бы удобнее, просто привычка делать через location.
Здравствуйте. У меня схожий случай. Прописала аналогично location и не забыв слэши. Но выходит ошибка 504. Что в моем случае может быть не так, что исправить? Буду благодарна за ответ
Здравствуйте Владимир.
По поводу примера №2 этой статьи, прочитал пояснение - засомневался.
"...Если у вас сайт работает по https, то достаточно настроить ssl только на nginx_srv, если вы не беспокоитесь за передачу информации от nginx_srv к blog_srv".
Интересует схема когда есть два nginx и на одном из них работает некий http-сервис, виртуальный сайт, работающий именно по http, и не умеющий https. А второй nginx - это proxy для первого, на нем сейчас вообще ничего кроме стартовой страницы nginx/centos нет, и к нему есть доступ из мира.
На proxy-сервер получаю сертификаты, и пользователи из мира работают с первым сервером, как-бы, по https.
Скажите, плз., Вы эту схему привели в пример?
Спасибо.
Да, все верно. Https настраивается на прокси сервере для работы с запросами пользователей. А сам прокси с другим сервером работает по http.
Спасибо.
Подскажите, а как сделать проксирование, если локальный сайт расположен по адресу http://192.168.0.10/mysite ?
Попробуйте прям вот на этот url и проксировать.
proxy_pass http://192.168.0.10/mysite;
Я не знаю, что получится. Такой экзотикой никогда не занимался. Лучше сразу все по-нормальному сделать без костылей.
Пробовал конечно же изначально прежде чем писать комментарий. Дело в том, что по другому нельзя. Хочу пробросить базы 1с, которые опубликованы на IIS сервере и они имеют доступ только в формате http://АдресСервера/НазваниеБазы1с. Внутри локальной сети всё нормально работает, но вот пробросить во внешнюю сеть не получается, тем более что база не одна, а их несколько
А с какого адреса проксируете? Кто принимает соединения? 1С я таким образом проксирую, с этим нет проблем. Берем домен site.ru Проксируем его на http://192.168.0.10 А чтобы попасть в конкретную базу, набираем http://site.ru/basa1 и всё работает.
Гениально)) Спасибо огромное. Я почему то не додумался подставлять названия баз к поддомену и думал на каждую базу свой поддомен сделать, а так выходит даже проще, один поддомен на все базы и только URI менять) Всё работает в таком виде!
Здравствуйте.
Вы очень доходчиво подаете материал.
Настолько, что достаточно копипастить не задумываясь? все примеры работают - 'то расслабляет, шаг в сторону, и начинаются трудности.
Завидую Вашей работоспособности.
Спасибо за труды.
Есть nginx внутри сети, на котором пара виртуальных хостов (http, настроено тоже по Вашей инструкции, в основном).
Появилась задача организовать защищенный доступ к одному виртуальному хосту из мира.
Поднял виртуалку со вторым nginx (proxy).
По первому, самому простому примеру из этой статьи сделал - все ок., работает, если обращаться к nginx-proxy по имени name.domain.local (такому же, как у виртуального хоста на nginx, работающем внутри сети).
Помогите, плз., нарисовать конфиг (если это возможно) для схемы, когда из мира приходят запросы к внешнему nginx (nginx-proxy) на доменное имя dom.domain.com, а он перенаправляет запросы на второй nginx, который в локалке, на виртуальный хост name.domain.local.
В итоге, пользователь должен работать из мира с локальным сервером, не подозревая об этом.
Спасибо.
Я не знаю, как это сделать. Надо тестировать, разбираться. Это не типовая задача. Тут надо как-то запросы менять на первом proxy, чтобы на второй они приходили уже с заголовками локального домена, чтобы локальный веб сервер их обрабатывал. И потом делать обратную замену. Все это слишком сложно. Я бы решал задачу каким-то другим способом.
Спасибо за ответ, Владимир. Удачи Вам
У меня проблема с wordpress, который крутится на апаче.
Перенаправил на nginx reverse proxy, но теперь съехали все стили - куда копать не пойму.
На самом wordpress надо что-то прописывать или нет?
Иногда да, иногда нет. Открывайте отладчик в браузере и смотрите, почему стили поехали. Возможно, какие-то урлы не загружаются. Вот тут одни из подобных проблем разбираю - https://serveradmin.ru/oshibka-wordpress-izvinite-vam-ne-razresheno-prosmatrivat-etu-straniczu/
Здравствуйте. подскажите пожалуйста, куда этот путь указывает, если сайт у нас лежит на другом сервере?
location /.well-known/acme-challenge/ {
root /web/sites/blog.zeroxzed.ru/www/;
разобрался, благодарю
Здравствуйте,
интересует такой вопрос, как сделать чтобы когда вводишь адрес https://website видеть контент с другого сайта https://website2 но при этом чтоб URL адрес оставался https://website.
Если использовать proxy_pass то происходит редирект обычный с заменой https://website на https://website2.
Я подозреваю, что с помощью nginx и proxy_pass это сделать невозможно. Я не понимаю, как подобное настроить.
Коллеги подскажите как настроить nginx на Windiws:
Есть внутренний ресурс к которому нужно предоставить доступ c наружи например 1с.portal.ru:7777/kab/doc/ - 10.10.15.5, для него в dmz поднят proxy на windows, установлен nginx, данному proxy серверу сопоставлен внешний ip и во внешнем dns сопоставлено имя 1с.portal.ru. Подскажите как сконфигурить конфиг чтобы при обращении к из вне по 1с.portal.ru попадать 1с.portal.ru:7777/kab/doc/. Спасибо.
Я моментами искал как же этот ngnx заставить работать по моему если вдруг кому пригодится
1 качаем утилиту hfs на ней можно открыть файловый сервер указать папку с файлами и все
2 это настройки для ngnx
events {
worker_connections 4096; ## Default: 1024
}
http {
server {
listen 80;
listen [::]:80;
server_name vashdomen.sytes.net;
.
location / {
proxy_pass http://192.168.1.111:8080/; утилита hfs запученна на винде под этим ip
proxy_set_header Host $host;
}
}
}
Я просто не знаю другого решения как можно ngnx или apache указать папку с файлами на windows причем мне просто не нужен сайт, а файлы )))))))))
Если есть знающие подскажите )))
А простого решения и нет в случае с windows. Запустить HFS как раз то, что и нужно было сделать в данном случае. Так что все правильно сделали.
Ели качать большой файл то соединение сброситься !!!
Прописал конфиг как показано в начале для nginx, прописал проксирования на локальную машину 192.168.0.106, получаю 502 Bad Gateway.
2021/03/29 12:30:33 [error] 22508#22508: *22 connect() failed (110: Connection timed out) while connecting to upstream, client: 72.251.226.6, server: dev.barbium.com, request: "GET /favicon.ico HTTP/1.1", upstream: "http://192.168.0.106:80/favicon.ico", host: "dev.example.com", referrer: "http://dev.example.com/"
Тут четко указано, что подключение к upstream отваливается по таймауту. Чисто сетевая ошибка. Разбирайтесь с ней.
Вопрос возник - а если на бекенде висят 10 сайтов - все 10 надо прописывать в конфиге ngix proxy?
Каждый в отдельную секцию или как?
У вас пример с одним сайтом - это понятно, а если их over 10 как быть?
Спасибо
Не задумывался об этом. Может быть можно указать в один вирутальный хост все домены и будет работать. Но я бы так не делал. Для каждого домена делал отдельный виртуальный хост и конфиг. Если их много, то создание автоматизировал бы с помощью bash или ansible. Сам я лично автоматизировал через ansible добавление сайтов на фронт и бэк со всеми необходимыми настройками.
Спасибо за статью. Она помогла мне решить ошибку циклической переадресации.
Nginx слушает 443 и перенаправляет на Apache, который слушает 8080 по протоколу https.
Ошибка возникала, потому что я просто указывал одну строку:
proxy_pass https://localhost:8080;
После добавления следующих строк (как в вашем примере), все заработало:
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
гш-з
Добрый день!
Подскажите пожалуйста данный способ подходит для проксирования web трафика?
Или можно как ни будь настроить для любого трафика?
К примеру в сети есть не только веб серверы.
Они используют не стандартные порты.
Пытался прописать по аналогии с web только изменив на нужный порт.
Но ни чего вышло.
Вот пример конфига
server {
listen 25595;
server_name wer.example.com;
access_log /var/log/nginx/cyprym.site-access.log;
error_log /var/log/nginx/cyprym.site-error.log;
....
location / {
proxy_pass http://192.168.15.101;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
Чую, что то-то упусткаю, но не понимаю что именно.
На маршрутизаторе соответствено открыты необходимые порты на прокси.
Буду признателен, если ткнете меня в нужную сторону.
Понял свой косяк, использовал proxy_pass а нужно было fastcgi_pass, теперь сижу его разбираю.
Этот способ именно для web трафика и подходит в первую очередь. Nginx может и другой трафик проксировать, но я не использовал его для этого. Точно знаю, что можно smtp коннекты проксировать через него.
Я понял свои ошибки, но пока не могу понять, почему не хочет отрабатывать stream.... в конфе nginx.conf прописал... но он не отрабатывает как надо, в логах вообще пустота....
Но все равно спасибо за ответ. Буду изучать это напрвление.
Вот пример для не http/https трафика - т.е. для транспортного уровня модели OSI.
Здесь у нас 2 сервера postgresql, между которыми мы будем кидать трафик. Можно изменить данную конфигурацию под себя (оставив один сервер)
stream { #Объявляем TCP/UDP обратный прокси
upstream stream_psql { #Объявляем балансировщик нагрузки (перечисляем серверы кластера баз данных)
least_conn;
server psql:5432; #Первый сервер с портом
server psql2:5432; #Второй сервер с портом
}
server { #Объявляем прокси для порта 5432 (стандартный postgresql порт)
listen 5432;
proxy_pass stream_psql; #Проксируем данные соединения на ранее объявленный балансировщик "stream_psql"
proxy_timeout 3s;
proxy_connect_timeout 1s;
}
}
Спасибо, интересно. А в чем тут может быть принципиальная разница с HAproxy? Я смотрю для баз и всего остального чаще именно ее используют. А для web чаще nginx. Не знаю, с чем это связано, не разбирался.
Честно говоря, не знаю, не пользовался HAproxy. Просто заинтересовала возможность использования nginx для создания отказоустойчивых сервисов.
> Открыт к диалогу и сотрудничеству.
Хм. Оказывается, совершенно не открыт.
Не увидел диалога и сотрудничества. Вижу только просьбу решить проблему. Никаких обязательств решать чужие проблемы, особенно в праздники, я не давал.
Ваша статья замечательная и доходчивая , но все равно у меня не выходит малахитовый цветок :(
Реверсного проксирования достиг нижеследующим фрагментом конфига, но чтобы сайт показывал реальный IP посетителя, не получается никак - он всегда показывает IP прокси.
Где же я ошибаюсь? :-o
#---------------------------------------------
server {
listen 185.33.33.33:80; # IP [и порт] реверсного прокси-сервера
location / {
proxy_pass http://94.22.22.22:2222; # URL [и порт] реального веб-сервера
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect default;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
set_real_ip_from 185.33.33.33;
real_ip_header X-Real-IP;
}
}
#---------------------------------------------
> set_real_ip_from 185.33.33.33;
> real_ip_header X-Real-IP;
Эти две дерективы нужно написать на бэкэнде.
set_real_ip_from 185.33.33.33; - Означает, что бэкэнд доверяет информации о заголовках пришедшей от данного ip адреса, т.е "нашего" фронтэнда.
real_ip_header X-Real-IP; - Означает, что бэкэнд будет использовать значение поля X-Real-IP, которое придет от фронтэнда, в качестве адреса клиента.
Настроил проксирование с получение сертифаката на прокси по Вашей статье, всё прекрасно работает. Проксирование идёт на сервер с сайтами на WordPress, которые работают на NGINX. Тем не менее, пришлось на сайте все ссылки и картинки исправить на https://, в опциях WP так же выставить https://
Случайно обнаружил в "состоянии здоровья сайта", что:
"Петлевой запрос к вашему сайту не удался. Возможности, зависящие от его работоспособности, не могут работать так, как должны.
Ошибка: cURL error 7: Failed connect to learn.site.ru:443; Connection refused (http_request_failed)"
Подскажите, с чем это может быть связано?
По поводу wordpress за прокси с nginx писал отдельно - https://serveradmin.ru/oshibka-wordpress-izvinite-vam-ne-razresheno-prosmatrivat-etu-straniczu/
У меня так и настроено как в статье про Wordpres с самого начала. Вопрос конкретно про ошибку cURL error 7: Failed connect to learn.site.ru:443; Connection refused (http_request_failed)
Выполняя через curl с самого сервера даже теоретически я получу ошибку. Ведь сервер слушает только 80 порт. Как это Вы обошли?
Не понял, а зачем делать curl запрос с самого сервера на 443 порт? Конечно, ответа нет, его же никто не слушает. Делайте либо на 80-й порт, либо на самом web сервере пропишите в hosts, чтобы по адресу сайта запрос шел не локально, а на прокси, где 443 порт корректно ответит.
Так этот запрос не я делаю, а движок WordPress. В админке - настройки - здоровье сайта у меня висят 2 предупреждения:
"Петлевой запрос к вашему сайту не удался. Возможности, зависящие от его работоспособности, не могут работать так, как должны.
Ошибка: cURL error 7: Failed connect to learn.trudmore.ru:443; Connection refused (http_request_failed)"
и
Запрос к REST API неудачен из-за ошибки.
Ошибка: cURL error 7: Failed connect to learn.trudmore.ru:443; Connection refused (http_request_failed)
Так то всё работает нормально, но ошибки раздражают. Кстати, один из сайтов на этом же сервере работает через Cloudfire и таких ошибок на нём нет.
Я говорю, попробуй добавить в hosts на веб сервере запись, что по имени домена надо обращаться на прокси сервер. И проверь пинг к адресу сайта через консоль. Пинг должен идти не на локалхост, а на nginx proxy. Сайт через cloudflare по этой причине и не дает ошибок. Там изменена dns запись, так что по адресу сайта запрос идет на внешний сервер cloudflareа оттуда обратно на сайт.
Огромное спасибо!!! Всё заработало. Я невнимательно прочитал предыдущий комментарий, прописывал в файле hosts не на прокси, а на локальный.
Чтобы не забыть, напишу тут
proxy_set_header Referer "https://google.com";
Установить реферер.
Делом в том, что у меня запросы на принимающий запросы сервер идут с пустым реферером :)
Конечно это установка принудительно фейкого реферера, может вы знаете как реальный реферер перенаправлять?
Например есть Домен nginx.org, на серваке у меня только этот домен, содержимое на другом, на вот, при обращении к сайту nginx.org как мне видеть реальный реферер на принимающем сервере?
А как сделать так, чтоб мой сайт нельзя было так с зеркалить?
Запретите доступ к сайту по ip того ресурса, который зеркалит.
А если это onion сайт в сети TOR
Блин, два дня бился с проблемой перенаправления реального ip, нашел данную статью, причем ведь в закладках была.
Все решил за пять минут
Огромное спасибо !!
Добрый день! Сделал все по Вашей инструкции
Но после замены в nginx.conf https://prnt.sc/qifwdk при проверке на ошибки выдает https://prnt.sc/qifws8
как закомментировать строчку ошибка пропадает но при переходе по доменноми имени выдает ошибку https://prnt.sc/qifzm9
Скажите, если я хочу задать не IP адрес в proxy_pass, а имя домена. Попробовал это сделать, но обращение идет к IP адресу домену, на этом у меня адресе несколько десятков доменов, мне нужно обратиться к конкретному домену, как это сделать?
location / {
proxy_pass http://192.168.13.31;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
Хороший вопрос. Я ни разу не пробовал так делать. Подумал бы, что будет обращение к домену, а nginx по факту резолвит домен в ip адрес и обращается по нему. Если найдете решение, прошу поделиться.
Мой конфиг на VPS 1, IP которого указан в качесте А записи для домена в днс менеджере. Достаточно ли на сервере иметь только конфиг для проксирования запросов на другой сервер?
У меня для домена получилось так: Задач при обращении к сайту test1.ru на Vps1 перенаправлять запрос на сайт test2 расположенным на vps2
server {
listen 80;
server_name test1.ru;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://test2.ru;
}
}
При обращении к домену который я проксирую на другой ип конфигом который я прикрепил выше, вот такой ответ получаю.
Please enable cookies.
Error 1001 Ray ID: 5328262b08a4d22c • 2019-11-08 14:13:42 UTC
DNS resolution error
What happened?
You've requested a page on a website (test.ru) that is on the Cloudflare network. Cloudflare is currently unable to resolve your requested domain (test.ru). There are two potential causes of this:
Most likely: if the owner just signed up for Cloudflare it can take a few minutes for the website's information to be distributed to our global network.
Less likely: something is wrong with this site's configuration. Usually this happens when accounts have been signed up with a partner organization (e.g., a hosting provider) and the provider's DNS fails.
Cloudflare Ray ID: 5328262b08a4d22c • Your IP: 192.123.227.152 • Performance & security by Cloudflare
Сайт через cloudflare работает. Он не пропускает такие проксированные запросы. Тут надо разбираться внимательно и думать, как лучше поступить. Подсказать нечего.
Parameter value can contain variables. In this case, if an address is specified as a domain name, the name is searched among the described server groups, and, if not found, is determined using a resolver.
For example:
server {
...
resolver 127.0.0.1;
set $backend "http://dynamic.example.com:80";
proxy_pass $backend;
...
}
Уважаемый Zerox,
могу ли я обратиться к вам по поводу настройки проксирования на живом проекте ?
Пишите на почту, обсудим. Адрес в разделе контакты.
Наблюдаю странное поведение системы. Есть site1.ru и site2.ru, есть роутер и NAS Synology за ним. На роутере NGINX.
Конфигурация:
server {
listen 80;
server_name site1.ru;
location / {
proxy_pass http://192.168.1.2:49001;
}
}
server {
listen 80;
server_name site2.ru;
location / {
proxy_pass http://192.168.1.2:80;
}
location /target/ {
# return 402;
proxy_pass http://192.168.1.2:49001;
}
}
На NAS настроен виртуальный хостинг на порт 49001.
Так вот site1.ru открывает страничку, а site2.ru/target присылает с NAS 404 ошибку.
Что я делаю не так?
А запрос site2.ru/target/ со слешом на конце, что показывает?
Так же 404
Тогда идите на целевой сайт и смотрите в логах, почему 404 ошибка идет. Нужно понять, по какому урлу приходит запрос.
Добрый день, пытаюсь разобраться с reverse proxy на nginx. Если с 80 портом понятно более менее.
Не понятен момент если внутри локальной сети есть сайт с https уже и сертификатом, как проксировать его?
Еще один заводить?
Не понятно из мануала для чего нужен.
location /.well-known/acme-challenge/ {
root /web/sites/blog.zeroxzed.ru/www/;
}
Тем более тут путь к каталогу с сайтом указан, но у меня на сервере с proxy nginx нету же каталога? Или его в любом случае нужно создавать?
Если у вас в локальной сети уже настроен https сайт, то проксируйте его точно так же, как и обычный. Копируйте на сервер с nginx сертификат и настраивайте хост на работу с сертификатом, а дальше проксируйте так же, как и по 80-му порту, только на 443.
location /.well-known/acme-challenge/ {
root /web/sites/blog.zeroxzed.ru/www/;
}
Эта конструкция нужна для того, чтобы автоматически обновлять сертификаты для сайтов с помощью let's encrypt.
То есть для обновления сертификата в будущем, можно создать эти деректории с пустыми каталогоми www для каждого домена, на сервере с proxy nginx ? Для того чтобы обновить сертификат в последствии?
Да. Только не забудьте учесть то, что сертификат нужно будет как-то передавать на сам исходный сайт, если он тоже по https работает.
Да уже задумался потому как сегодня сделал сертифакат https для домена на сервере с proxy nginx, но тут обратная сторона, теперь если смотреть из мира то сайт с https, а внутри локальной сети нет.
А как лучше сделать чтобы там и там было одинаково, и при этом обновлять удобно?
Все зависит от инфраструктуры. Можно всех пользователей направлять на nginx proxy по https. В общем случае, я сайты оставляю на http, а на proxy настраивают https. Все запросы к сайту только через proxy, напрямую закрыты. Так проще всего управлять сертификатами. Они все в одном месте.
Если так не получается, то обновляю сертификаты на proxy и скриптами передаю на сам сайт и там перезапускаю веб сервер после обновления сертификата.
А не могли бы поделиться примером скрипта, я так понимаю сертификаты передаются с одного сервера на другой?
Это не имеет смысла, так как сильно зависит от того, как все устроено. Где-то я монтирую по nfs директорию с сертификатами с nginx сервера на сам сайт. А где-то через rsync передаю по расписанию новые файлы сертификатов. По месту нужно решение делать. Самое простое - копирование через rsync, это одна команда. И вторая команда, перезапуск web сервера на сайте, после замены сертификатов.
Добрый день!
Я абсолютный новичок в администрировании Линукс, и начал ее изучение, так как хочу иметь свой nextcloud торентокачалками и медиасервером.
Соответственно у меня вопрос, могу ли я имея зарегистрированное доменное имя и арендованный VPS осуществлять доступ к облаку(на домашнем сервере) через реверс прокси (да много кейсов было описано вначале, и частично один из некоторых подходит) хотелось бы более детальный ответ как это дело настроить, ну или чтобы ткнули лицом в мануал.
Заранее спасибо
Да, можно. Как настроить, вам по шагам никто не расскажет, так как это не тривиальная задача. Настраивайте nexcloud и проксируйте запросы на него через nginx proxy_pass, установленный на vps. Как это сделать, рассказано выше в статье.
Посмотрите пожалуйста, правильно ли указаны конфиги
На ВПСке
server {
listen 80;
server_name cloud.my_domain.ru;
access_log /var/log/nginx/blog.zeroxzed.ru-access.log;
error_log /var/log/nginx/blog.zeroxzed.ru-error.log;
location / {
proxy_pass http://username.ddns.net/nextcloud; #Настроил ddns для локальной машины
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
На домашнем серваке на Apache
ProxyPreserveHost On
ProxyPass / http://IP_VPS:8080/ #(Адрес VPS)
ProxyPassReverse / http://IP_VPS:8080/
Забыл подправить
access_log /var/log/nginx/cloud.my_domain.ru-access.log;
error_log /var/log/nginx/cloud.my_domain.ru-error.log;
Так вы проверьте, если работает как надо, значит все правильно :) Если у вас уже настроен ddns, то зачем вам отдельное доменное имя и vps? Заходите сразу через ddns.
Не могу настроить letsencrypt для ddns, а на самоподписные сертификаты ругаются браузеры. Вот мне подсказали реализацию через домен с vps и реверс-прокси
здравствуйте, надеюсь вы всё ещё живы и ответ будет быстрым,
ситуация которая произошла у меня достаточно лёгкая, но я уже целый день угробил на поиск решения проблемы,
есть сервер example.com
в нём есть директория, пустая пусть названа serveradmin
нужно сделать так чтоб после запроса example.com/serveradmin открывался (в пример) ваш сайт, но в адресной строке остаётся example.com/serveradmin
Абстрактный пример с сайтом в таком виде, как вы описали, работать не будет. Напишите полную задачу, что вы хотите сделать.
проксировать например контент вашего сайта на своём, но урл в адресной строке не изменять
у меня получилось достичь результата благодаря php, но это не устроило меня, хотелось бы как-то через конфиг nginx'а
Так не получится. Как минимум, у wordpress стоит редирект на имя основного домена. Он будет всегда заменять адрес на оригинальный, который указан в настройках wordpress. Редирект будет выполняться на уровне php. Я не знаю, возможно ли в принципе силами nginx это исправить. Мне кажется, что нет.
этот пхп код
?php
echo file_get_contents('http://serveradmin.ru');
?
Доброго времени.
На сервере apache 10.0.0.3 настроил SSL все работает, по https заходит
Теперь задача поставить фронтенд nginx на сервере 10.0.0.1
Делаю
server{
listen 443;
...
...
...
location / {
proxy_pass https://10.0.0.3:443;
...
...
}
}
Пишет ERR_SSL_PROTOCOL_ERROR
Получается нет таких костылей в nginx чтобы НЕ указывать пути до ssl сертификатов, которые расположены на apache сервере?
(зачем понадобился nginx да еще на другом сервере? хотим в будущем балансировщик и nginx будет делать proxy_pass на node.js и другие сервисы. тоесть концепция такая что отдельный сервер со своими apache сайтами и сертификатами от них, отдельно node.js и отдельный балансировщик nginx на все это хозяйство.)
А в чем проблема передать сертификаты на nginx? Без них никак не обойтись. Браузеры обращаются в первую очередь к nginx и проверяют сертификат у него. Лично я обычно все сертификаты настраиваю на frontend, а c backend идет работа по http, если он в закрытой сети. Это решает вопрос с автопродлением и передачей сертификатов.
Илья имею подобную задачу вам удалось решить данный вопрос? Автоматически подтягивать на фронт или проксировать с бекенда?
Как я уже написал, не подтянув сертификаты на фронт эту проблему не решить. Фронт первый получает запрос на доменный url и он должен иметь валидный сертификат у себя.
При настройке проксирования с nginx на apache в директиве location / { } при передачи заголовка через proxy_set_header Host $host; Выходит ошибка "Bad Request Your browser sent a request that this server could not understand. Additionally, a 400 Bad Request error was encountered while trying to use an ErrorDocument to handle the request."
А у меня такой вопрос:
Как обернуть проксируемый запрос к api в auth_basiс (встроить логин и пароль b64)?
Nginx должен проксировать запрос с api. Но на api сервере авторизация логин пароль( auth_basic).
использую для ранней разработки - безопасность не важна
использовал такую настройку(не помагает - все равно спрашивает пароль):
upstream app_db2{
server 192.168.1.66:8890;
keepalive 16;
}
server {
# listen 80;
server_name db2-dev.com;
access_log /var/log/nginx/db2.log;
location /api {
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_pass https://dev1.com/api/v0.1;
proxy_set_header Authorization "Basic ***"; #*** -логин:пароль в base64
# default_type application/json;
# return 200 '{"code":"1", "message": "Unknown Error"}';
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://app_db2/;
proxy_redirect off;
}
Подскажите правильный config
Здравствуйте! Не совсем понял зачем нужна эта часть
location /.well-known/acme-challenge/ {
root /web/sites/blog.zeroxzed.ru/www/;
}
при передаче https
Keepalived?
2) apache
3 ) apache
Дальше настроил балансировку - у меня всё получилось
Теперь поступила такая задачка - настроить так, чтобы они (2 и 3) backend - ы работали как master и slave. Чтобы одни и те же данные были на обоих backend - серверах. В случае падание одного из них второй работал.??
привет всем! профессионалы пожалуйста дайте совет!!! Как решить такую задачку.??
Я на vmware поднимал 3 сервера:
1) nginx
Решил проблему.
1) вместо
return 301 https://site.ru$request_uri;
поставил
rewrite ^(.*)$ https://site.ru$request_uri permanent;
2) в location @thin
добавил ещё одну строку
proxy_set_header X-Forwarded-Proto $scheme;
Здравствуйте.
Хорошая статья, спасибо.
Но у меня возникла вот какая проблема...
Установлен Редмайн, где запросы с NGINX проксируются на сокет THIN. NGINX работает по HTTP на порту 80. Начинаю настраивать NGINX на работу через HTTPS... Делаю сначала переадресацию 301 с порта 80 на порт 443, а потом с 443 проксирую на сокет THIN, всё это в рамках одной машины. Но почему-то до сокета запросы не доходят, а снова попадают на порт 80, и получается петля — браузер пишет, что произошло слишком много переадресаций.
Вот конфиг NGINX рабочего варианта только по HTTP:
upstream pm {
server unix:/tmp/thin.0.sock;
}
server {
server_name site.ru;
listen *:80;
root /home/redmine/redmine/public;
location / {
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
try_files $uri/index.html $uri.html $uri @thin;
}
location @thin {
proxy_pass http://pm;
}
}
А вот конфиг НЕрабочего варианта с использованием HTTPS:
upstream pm {
server unix:/tmp/thin.0.sock;
}
# редирект с http на https и сразу без www
server {
server_name site.ru http://www.site.ru;
listen 80;
return 301 https://pm.fisoli.ru$request_uri;
}
# редирект по https с www на без www
server {
server_name http://www.site.ru;
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/site.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site.ru/privkey.pem;
return 301 https://site.ru$request_uri;
}
# основной раздел
server {
server_name site.ru;
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/site.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site.ru/privkey.pem;
root /home/redmine/redmine/public;
location / {
try_files $uri/index.html $uri.html $uri @thin;
}
location @thin {
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://pm;
}
}
Вот этот вариант конфига зацикливает запросы. Как можно этого избежать? Что посоветуете?
Так сходу трудно что-то посоветовать. Такую схему я сам использую. Редирект с http на https, а потом на бэкенд. Единственное, я не на сокеты редирекчю, а по tcp порту. Не знаю, имеет ли это в данном случае значение. Схема такая рабочая. Возможно здесь проблема именно в первых редиректах с http на https и с www. Попробуйте сначала без них. Если будет работать, то нужно уже отдельно с редиректами разбираться.
Можно ли проксировать запросы на разные порты на один внутренний ip (типа что-то 443 и 10050)? как это будет выглядеть в конфигурации?
Не очень понял вопрос.
По идее, должно быть так
server {
listen 443 ssl; # проксирование с https://site1.example.com на внутренний айпи:8081
server_name site1.example.com;
ssl on;
location / {
proxy_pass http://внутренний_айпи_1:8081/;
}
}
server {
listen 443 ssl; # проксирование с https://site2.example.com на внутренний айпи:8082
server_name site2.example.com;
ssl on;
location / {
proxy_pass http://внутренний_айпи_2:8082/;
}
}
Я правильно понимаю, что нужен отдельный аппаратный прокси, который будет заниматься исключительно проксированием или можно обойтись Докер-контейнером с ngnix на одном из серверов?
Да чем угодно можно обойтись. Это же работает на уровне софта - nginx. Он на железе, в виртуалке или контейнере может работать. Все зависит от потребностей.
Those who have aspirations have thousands of things, and those who have no ambitions only feel that it is difficult
Для некоторых приложений нужно еще указывать с какого протокола пришел запрос (http или httpS)
Актуально для бекенда, который геренит полные а не относительные ссылки. Например, для ruby
proxy_set_header X-Forwarded-Proto $scheme;
Да, все верно. Вообще, есть много полезных параметров, которые я в том числе использую. Например, таймаут ожидания ответа бэкенда. Актуально, когда их несколько и работает балансировка. Думаю, на эту тему отдельную статью сделать.