🐹 Nginx: Проксирование запросов с помощью proxy_pass.

Содержание:

1. Введение.
2. Настройка proxy_pass в nginx.
3. Передача реального IP-адреса (Real IP) клиента в nginx при proxy_pass.
4. Передача https через nginx с помощью proxy pass.
5. Проксирование определенной директории или файлов.
6. Руководство пользователя.
7. Оригиналы источников информации.


На чем было опробовано:

  1. CentOS 7 Linux x86_64 release 7.8.2003.
  2. Nginx 1.19.4.

1. Введение.

В nginx имеется одна интересная директива proxy_pass. Она позволяет проксировать запросы на удалённый сервер.

2. Настройка proxy_pass в nginx.

Проксирование ресурса с IP-адреса за NAT в интернет, мы передаем реальный IP-адрес клиента с помощью директивы proxy_set_header, которая добавляет в заголовок X-Real-IP настоящий IP-адрес клиента.

Будем проксировать файл myip.php с содержимым. 

<?php
echo $_SERVER['REMOTE_ADDR']
?>

Текст файла конфигурации примет вид:

server {
    listen 80;
    server_name test.site.ru;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/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://test.site.ru. У вас должно открыться содержимое, аналогичное тому, что вы увидите, набрав http://192.168.13.31 в локальной сети.

3. Передача реального IP-адреса (Real IP) клиента в nginx при proxy_pass.

В этом примере нужно на принимающей стороне, то есть test_srv сделать обратную замену — заменить информацию об адресе отправителя на ту, что указана в заголовке X-Real-IP.

Добавляем в секцию server следующие параметры:

set_real_ip_from 94.142.141.246;
real_ip_header X-Real-IP;

Полностью секция server на test_srv в самом простом варианте получается следующей:

server {
	listen       80 default_server;
	server_name  test.site.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://test.site.ru/myip.php. Вы должны увидеть свой реальный IP-адрес.

4. Передача https через nginx с помощью proxy pass.

Если у вас сайт работает по https, то достаточно настроить ssl только на nginx_srv, если вы не беспокоитесь за передачу информации от nginx_srv к test_srv. Она может осуществляться по незащищенному протоколу.

Рассмотрим пример с бесплатным сертификатом Let’s Encrypt.

Ссылка: «CentOS 7: Настройка бесплатного ssl-сертификата Let’s Encrypt».

Очень удобно настроить на одном сервере автоматическое получение всех необходимых сертификатов. 

Для этого нам надо на nginx_srv добавить еще один location - /.well-known/acme-challenge/.

Полная секция server нашего тестового сайта на момент получения сертификата будет выглядеть вот так:

server {
    listen 80;
    server_name test.site.ru;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location /.well-known/acme-challenge/ {
	root /web/sites/test.site.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 test.site.ru;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    return 301 https://$server_name$request_uri;
    }

server {
    listen 443 ssl http2;
    server_name test.site.ru;
    access_log /var/log/nginx/ssl-access.log;
    error_log /var/log/nginx/ssl-error.log;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/test.site.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/test.site.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/test.site.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;
    }
}

Происходит проксирование с другого IP-адреса и шифрование по https.

5. Проксирование определенной директории или файлов.

Допустим, у вас форум живет в директории http://test.site.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/test.site.ru/www/images;
	}

6. Руководство пользователя.

Подробнее о модуле ngx_http_proxy_module можно узнать из официальной документации по nginx.

Ссылка: http://nginx.org/ru/.

7. Оригиналы источников информации.

  1. serveradmin.ru «Проксирование запросов в nginx с помощью proxy_pass».

Читайте также: