Home » Linux » CentOS » Проксирование запросов в nginx с помощью proxy_pass

Проксирование запросов в nginx с помощью proxy_pass

Хочу рассказать об одной полезной возможности nginx, которую регулярно использую в своих делах. Речь пойдет о настройке проксирования запросов на удаленный сервер с помощью nginx и директивы proxy_pass. Я приведу примеры различных настроек и расскажу, где сам использую данный модуль популярного веб сервера.

Теоретический курс по основам сетевых технологий. Позволит системным администраторам упорядочить и восполнить пробелы в знаниях. Цена очень доступная, есть бесплатный доступ. Все подробности по . Можно пройти тест на знание сетей, бесплатно и без регистрации.

Введение

Немного расскажу своими словами о том, как работает модуль ngx_http_proxy_module. Именно он реализует весь функционал, о котором пойдет речь. Допустим, у вас в локальной или виртуальной сети есть какие-то сервисы, не имеющие прямого доступа из интернета. А вы хотите таковой иметь. Можно пробрасывать нужные порты на шлюзе, можно что-то еще придумывать. А можно сделать проще всего — настроить единую точку входа на все свои сервисы в виде nginx сервера и с него проксировать различные запросы к нужным серверам.

Расскажу на конкретных примерах, где я это использую. Для наглядности и простоты буду прям по порядку перечислять эти варианты:

  1. Ранее я рассказывал о настройке чат серверов — matrix и mattermost. В этих статьях я как раз рассказывал о том, как проксировать запросы в чат с помощью nginx. Прошелся по теме вскользь, не останавливаясь подробно. Суть в том, что вы настраиваете на любом виртуальном сервере эти чаты, помещаете их в закрытые периметры сети без лишних доступов и просто проксируете запросы на эти сервера. Они идут через nginx, который у вас смотрит во внешний интернет и принимает все входящие соединения.
  2. Допустим, у вас есть большой сервер с множеством контейнеров, например докера. На нем работает множество различных сервисов. Вы устанавливаете еще один контейнер с чистым nginx, на нем настраиваете проксирование запросов на эти контейнеры. Сами контейнеры мапите только к локальному интерфейсу сервера. Таким образом, они будут полностью закрыты извне, и при этом вы можете гибко управлять доступом.
  3. Еще один популярный пример. Допустим, у вас есть сервер с гипервизором proxmox или любым другим. Вы настраиваете на одной из виртуальных машин шлюз, создаете локальную сеть только из виртуальных машин без доступа в нее извне. Делаете в этой локальной сети для всех виртуальных машин шлюз по-умолчанию в виде вашей виртуальной машины со шлюзом. На виртуальных серверах в локальной сети размещаете различные сервисы и не заморачиваетесь с настройками фаервола на них. Вся их сеть все равно не доступна из интернета. А доступ к сервисам проксируете с помощью nginx, установленным на шлюз или на отдельной виртуальной машине с проброшенными на нее портами.
  4. Мой личный пример. У меня дома есть сервер synology. Я хочу организовать к нему простой доступ по https из браузера по доменному имени. Нет ничего проще. Настраиваю на сервере nginx получение бесплатного сертификата Let’s encrypt, настраиваю проксирование запросов на мой домашний ip, там на шлюзе делаю проброс внутрь локалки на synology сервер. При этом я могу фаерволом ограничить доступ к серверу только одним ip, на котором работает nginx. В итоге на самом synology вообще ничего не надо делать. Он и знать не знает, что к нему заходят по https, по стандартному порту 443.
  5. Допустим, у вас большой проект, разбитый на составные части, которые живут на разных серверах. К примеру, на отдельном сервере живет форум, по пути /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.31ip адрес blog_srv
77.37.224.139ip адрес клиента, с которого я буду заходить на сайт

Настройка 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.

Передача реального ip в nginx proxy_pass

Дальше рассмотрим более сложные конфигурации.

Передача 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 с помощью proxy pass в nginx

Наш сайт работает по 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 читайте в отдельной большой статье с моими личными примерами.

Заключение

Не понравилась статья и хочешь научить меня администрировать? Пожалуйста, я люблю учиться. Комментарии в твоем распоряжении. Расскажи, как сделать правильно!

На этом у меня все. Не рассмотрел еще один возможный вариант, когда вы проксируете https сайт и передаете инфу на бэкенд тоже по https. Нет под рукой готового примера, чтобы проверить, а заочно не стал рисовать конфиг. По идее, ничего сложного в этом нет, настраиваете nginx на обоих серверах с одним и тем же сертификатом. Но наверняка не скажу, что все заработает при этом. Возможно, есть какие-то нюансы с таким проксированием. Мне обычно не приходится так делать.

Как я уже писал в начале, в основном проксирую запросы с одного внешнего веб сервера на закрытый периметр сети, куда нет никому доступа. В этом случае у меня нет необходимости использовать https при передаче запросов на бэкенд. В качестве бэкенда не обязательно будет отдельный сервер. Это запросто может быть контейнер на этом же сервере.

Онлайн курсы по Mikrotik

Если у вас есть желание научиться работать с роутерами микротик и стать специалистом в этой области, рекомендую пройти курсы по программе, основанной на информации из официального курса MikroTik Certified Network Associate. Помимо официальной программы, в курсах будут лабораторные работы, в которых вы на практике сможете проверить и закрепить полученные знания. Все подробности на сайте . Стоимость обучения весьма демократична, хорошая возможность получить новые знания в актуальной на сегодняшний день предметной области. Особенности курсов:
  • Знания, ориентированные на практику;
  • Реальные ситуации и задачи;
  • Лучшее из международных программ.

Помогла статья? Есть возможность отблагодарить автора

Автор Zerox

Zerox
Владимир, системный администратор, автор сайта. Люблю настраивать сервера, изучать что-то новое, делиться знаниями, писать интересные и полезные статьи. Открыт к диалогу и сотрудничеству.

42 комментария

  1. Аватар
    Виталий

    Наблюдаю странное поведение системы. Есть 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 ошибку.
    Что я делаю не так?

  2. Аватар
    Дмитрий

    Добрый день, пытаюсь разобраться с reverse proxy на nginx. Если с 80 портом понятно более менее.
    Не понятен момент если внутри локальной сети есть сайт с https уже и сертификатом, как проксировать его?
    Еще один заводить?

    Не понятно из мануала для чего нужен.

    location /.well-known/acme-challenge/ {
    root /web/sites/blog.zeroxzed.ru/www/;
    }

    Тем более тут путь к каталогу с сайтом указан, но у меня на сервере с proxy nginx нету же каталога? Или его в любом случае нужно создавать?

    • Zerox

      Если у вас в локальной сети уже настроен https сайт, то проксируйте его точно так же, как и обычный. Копируйте на сервер с nginx сертификат и настраивайте хост на работу с сертификатом, а дальше проксируйте так же, как и по 80-му порту, только на 443.

      location /.well-known/acme-challenge/ {
      root /web/sites/blog.zeroxzed.ru/www/;
      }

      Эта конструкция нужна для того, чтобы автоматически обновлять сертификаты для сайтов с помощью let’s encrypt.

      • Аватар
        Дмитрий

        То есть для обновления сертификата в будущем, можно создать эти деректории с пустыми каталогоми www для каждого домена, на сервере с proxy nginx ? Для того чтобы обновить сертификат в последствии?

        • Zerox

          Да. Только не забудьте учесть то, что сертификат нужно будет как-то передавать на сам исходный сайт, если он тоже по https работает.

          • Аватар
            Дмитрий

            Да уже задумался потому как сегодня сделал сертифакат https для домена на сервере с proxy nginx, но тут обратная сторона, теперь если смотреть из мира то сайт с https, а внутри локальной сети нет.
            А как лучше сделать чтобы там и там было одинаково, и при этом обновлять удобно?

            • Zerox

              Все зависит от инфраструктуры. Можно всех пользователей направлять на nginx proxy по https. В общем случае, я сайты оставляю на http, а на proxy настраивают https. Все запросы к сайту только через proxy, напрямую закрыты. Так проще всего управлять сертификатами. Они все в одном месте.

              Если так не получается, то обновляю сертификаты на proxy и скриптами передаю на сам сайт и там перезапускаю веб сервер после обновления сертификата.

              • Аватар
                Дмитрий

                А не могли бы поделиться примером скрипта, я так понимаю сертификаты передаются с одного сервера на другой?

                • Zerox

                  Это не имеет смысла, так как сильно зависит от того, как все устроено. Где-то я монтирую по nfs директорию с сертификатами с nginx сервера на сам сайт. А где-то через rsync передаю по расписанию новые файлы сертификатов. По месту нужно решение делать. Самое простое — копирование через rsync, это одна команда. И вторая команда, перезапуск web сервера на сайте, после замены сертификатов.

  3. Аватар
    Владимир

    Добрый день!
    Я абсолютный новичок в администрировании Линукс, и начал ее изучение, так как хочу иметь свой nextcloud торентокачалками и медиасервером.
    Соответственно у меня вопрос, могу ли я имея зарегистрированное доменное имя и арендованный VPS осуществлять доступ к облаку(на домашнем сервере) через реверс прокси (да много кейсов было описано вначале, и частично один из некоторых подходит) хотелось бы более детальный ответ как это дело настроить, ну или чтобы ткнули лицом в мануал.
    Заранее спасибо

    • Zerox

      Да, можно. Как настроить, вам по шагам никто не расскажет, так как это не тривиальная задача. Настраивайте 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;

        • Zerox

          Так вы проверьте, если работает как надо, значит все правильно :) Если у вас уже настроен ddns, то зачем вам отдельное доменное имя и vps? Заходите сразу через ddns.

          • Аватар
            Владимир

            Не могу настроить letsencrypt для ddns, а на самоподписные сертификаты ругаются браузеры. Вот мне подсказали реализацию через домен с vps и реверс-прокси

  4. Аватар

    здравствуйте, надеюсь вы всё ещё живы и ответ будет быстрым,

    ситуация которая произошла у меня достаточно лёгкая, но я уже целый день угробил на поиск решения проблемы,

    есть сервер example.com
    в нём есть директория, пустая пусть названа serveradmin
    нужно сделать так чтоб после запроса example.com/serveradmin открывался (в пример) ваш сайт, но в адресной строке остаётся example.com/serveradmin

    • Zerox

      Абстрактный пример с сайтом в таком виде, как вы описали, работать не будет. Напишите полную задачу, что вы хотите сделать.

      • Аватар

        проксировать например контент вашего сайта на своём, но урл в адресной строке не изменять
        у меня получилось достичь результата благодаря php, но это не устроило меня, хотелось бы как-то через конфиг nginx’а

        • Zerox

          Так не получится. Как минимум, у wordpress стоит редирект на имя основного домена. Он будет всегда заменять адрес на оригинальный, который указан в настройках wordpress. Редирект будет выполняться на уровне php. Я не знаю, возможно ли в принципе силами nginx это исправить. Мне кажется, что нет.

      • Аватар

        этот пхп код

      • Аватар

        ?php
        echo file_get_contents(‘http://serveradmin.ru’);
        ?

  5. Аватар

    Доброго времени.
    На сервере 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 на все это хозяйство.)

    • Zerox

      А в чем проблема передать сертификаты на nginx? Без них никак не обойтись. Браузеры обращаются в первую очередь к nginx и проверяют сертификат у него. Лично я обычно все сертификаты настраиваю на frontend, а c backend идет работа по http, если он в закрытой сети. Это решает вопрос с автопродлением и передачей сертификатов.

  6. Аватар

    При настройке проксирования с 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.»

  7. Аватар

    А у меня такой вопрос:
    Как обернуть проксируемый запрос к 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

  8. Аватар

    Здравствуйте! Не совсем понял зачем нужна эта часть
    location /.well-known/acme-challenge/ {
    root /web/sites/blog.zeroxzed.ru/www/;
    }
    при передаче https

  9. Аватар

    Keepalived?

  10. Аватар

    2) apache
    3 ) apache

    Дальше настроил балансировку — у меня всё получилось

    Теперь поступила такая задачка — настроить так, чтобы они (2 и 3) backend — ы работали как master и slave. Чтобы одни и те же данные были на обоих backend — серверах. В случае падание одного из них второй работал.??

  11. Аватар

    привет всем! профессионалы пожалуйста дайте совет!!! Как решить такую задачку.??

    Я на vmware поднимал 3 сервера:
    1) nginx

  12. Аватар

    Решил проблему.

    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;

  13. Аватар

    Здравствуйте.
    Хорошая статья, спасибо.
    Но у меня возникла вот какая проблема…
    Установлен Редмайн, где запросы с 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;
    }
    }

    Вот этот вариант конфига зацикливает запросы. Как можно этого избежать? Что посоветуете?

    • Zerox

      Так сходу трудно что-то посоветовать. Такую схему я сам использую. Редирект с http на https, а потом на бэкенд. Единственное, я не на сокеты редирекчю, а по tcp порту. Не знаю, имеет ли это в данном случае значение. Схема такая рабочая. Возможно здесь проблема именно в первых редиректах с http на https и с www. Попробуйте сначала без них. Если будет работать, то нужно уже отдельно с редиректами разбираться.

  14. Аватар

    Можно ли проксировать запросы на разные порты на один внутренний ip (типа что-то 443 и 10050)? как это будет выглядеть в конфигурации?

  15. Аватар

    Я правильно понимаю, что нужен отдельный аппаратный прокси, который будет заниматься исключительно проксированием или можно обойтись Докер-контейнером с ngnix на одном из серверов?

    • Zerox

      Да чем угодно можно обойтись. Это же работает на уровне софта — nginx. Он на железе, в виртуалке или контейнере может работать. Все зависит от потребностей.

  16. Аватар
    Николай

    Для некоторых приложений нужно еще указывать с какого протокола пришел запрос (http или httpS)
    Актуально для бекенда, который геренит полные а не относительные ссылки. Например, для ruby

    proxy_set_header X-Forwarded-Proto $scheme;

    • Zerox

      Да, все верно. Вообще, есть много полезных параметров, которые я в том числе использую. Например, таймаут ожидания ответа бэкенда. Актуально, когда их несколько и работает балансировка. Думаю, на эту тему отдельную статью сделать.

Добавить комментарий

Ваш e-mail не будет опубликован.

Нажимая кнопку "Отправить комментарий" Я даю согласие на обработку персональных данных.