Как сделать так, чтобы веб-сервер, находящийся за реверсным прокси, видел ip-адреса посетителей, а не этого реверсного прокси? А вот так.
Предположим, что сайт www.example.com живет на внутреннем сервере с адресом 10.0.0.123. Предположим, что реверсные прокси (а их может быть несколько) имеют внутренние адреса 10.0.0.99 и 10.0.10.99.
Настройки реверсного прокси на базе nginx
Создать в nginx виртуалхост такого вида:
server {
listen *:80;
server_name example.com www.example.com;
include letsencrypt.inc;
location / {
proxy_pass http://10.0.0.123;
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_buffers 8 16k;
proxy_buffer_size 32k;
}
large_client_header_buffers 4 81920;
access_log /var/log/nginx/example.com-access.log;
error_log /var/log/nginx/example.com-error.log;
}
server {
listen 443;
server_name example.com www.example.com;
include ssl.inc;
location / {
proxy_pass http://10.0.0.123;
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_buffers 8 16k;
proxy_buffer_size 32k;
}
large_client_header_buffers 4 81920;
access_log /var/log/nginx/example.com-access.log;
error_log /var/log/nginx/example.com-error.log;
}
Спецефичные для letsencrypt настройки:
Содержимое /etc/nginx/ssl.inc:
ssl on;
ssl_certificate /etc/dehydrated/certs/domains/fullchain.pem;
ssl_certificate_key /etc/dehydrated/certs/domains/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
Содержимое /etc/nginx/letsencrypt.inc:
location /.well-known/acme-challenge {
alias /var/www/dehydrated;
}
Разумеется, для работы с Let's encrypt надо корректно установить и настроить упоминаемый в данном конфиге dehydrated. В репах дебиана он есть.
Внутренний веб-сервер на базе nginx
Заменить в /etc/nginx/nginx.conf:
log_format combined1 '$http_x_real_ip - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'; access_log /var/log/nginx/access.log combined1; error_log /var/log/nginx/error.log;
Добавить в конфиг виртуалхоста:
set_real_ip_from 10.0.0.99; set_real_ip_from 10.0.10.99; real_ip_header X-Forwarded-For; real_ip_recursive on;
Добавить в «location ~ \.php$»:
fastcgi_param REMOTE_ADDR $http_x_real_ip;
Перезапустить nginx:
# systemctl reload nginx
Внутренний веб-сервер на базе apache
В файл /etc/apache2/conf-available/remoteip.conf написать:
RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 10.0.0.99 10.0.10.99
RemoteIPInternalProxy 10.0.0.99 10.0.10.99
LogFormat "%v:%p %a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%a %l %u %t \"%r\" %>s %O" common
Включить модуль remoteip, перезапустить апача:
# a2enmod remoteip # a2enconf remoteip # systemctl reload apache2