secure_link + realip + if
Pavel
pavel2000 на ngs.ru
Пн Авг 20 18:25:36 UTC 2018
Здравствуйте.
Спасибо за Nginx!
В процессе использования появился вопрос по совместному
использованию
модулей ngx_http_secure_link_module и
ngx_http_realip_module, с использованием
проверки доступа через if (Да, "if is evil", но есть ли
другой способ?).
Ранее модуль ngx_http_secure_link_module использовался для
проверки
доступа в самостоятельной конфигурации, без realip_module.
Теперь сервис переезжает за дополнительный прокси в целях
защиты от DDOS,
и для получения реального айпи браузера добавился
ngx_http_realip_module.
Проблема в следущем: если в одном локейшне используются
два вышеуказанных
модуля + директива if, то переопределение remote_addr не
происходит.
Если if не использовать - переопределение работает.
Тестовая конфигурация:
user www-data;
worker_processes 1;
error_log /var/log/nginx/tst.error.log notice;
pid /var/run/nginx.tst.pid;
events {
worker_connections 1024;
# multi_accept on;
}
http {
include /etc/nginx/mime.types;
access_log /var/log/nginx/tst.access.log;
server {
listen 127.0.0.1:80;
server_name vhost;
root /tmp;
location / {
set_real_ip_from 127.0.0.1/32;
real_ip_header X-Forwarded-For;
secure_link $arg_st;
secure_link_md5 "${remote_addr}_$uri";
if ($secure_link = "") {
return 403;
}
add_header X-App-Secure-Uri $uri always;
add_header X-App-Secure-St $arg_st always;
add_header X-App-Secure-Addr $remote_addr always;
add_header X-App-Secure-RealIP
$realip_remote_addr always;
add_header X-Forwarded-For $http_x_forwarded_for
always;
}
}
}
nginx -c /tmp/nginx.tst.cfg
kill `cat /var/run/nginx.tst.pid`
Тестовый файл:
echo "tst.txt" > /tmp/tst.txt
При закомментированном if имеем ожидаемый ответ с
переопределением remote_addr, что видно по заголовку
X-App-Secure-Addr в ответе:
# curl -v -H "Host: vhost" -H "X-Forwarded-For: 8.8.8.8"
http://127.0.0.1/tst.txt
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET /tst.txt HTTP/1.1
> Host: vhost
> User-Agent: curl/7.57.0
> Accept: */*
> X-Forwarded-For: 8.8.8.8
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.3
< Date: Mon, 20 Aug 2018 17:51:31 GMT
< Content-Type: text/plain
< Content-Length: 8
< Last-Modified: Mon, 20 Aug 2018 17:47:59 GMT
< Connection: keep-alive
< ETag: "5b7afecf-8"
< X-App-Secure-Uri: /tst.txt
< X-App-Secure-Addr: 8.8.8.8
< X-App-Secure-RealIP: 127.0.0.1
< X-Forwarded-For: 8.8.8.8
< Accept-Ranges: bytes
<
tst.txt
* Connection #0 to host 127.0.0.1 left intact
Если разкомментировать if, то что-то ломается.
Судя по заголовкам ответа, переопределение значения
remote_addr не происходит,
и в модуле secure_link также используется IP подключения,
а не из заголовка X-Forwarded-For.
Модуль secure_link разрешает доступ, если подпись
сформирована для 127.0.0.1
# echo -n "127.0.0.1_/tst.txt" | openssl md5 -binary |
openssl base64 | tr +/ -_ | tr -d =
AEfp-bT-tHrEfZN8lwDJGQ
# curl -v -H "Host: vhost" -H "X-Forwarded-For: 8.8.8.8"
http://127.0.0.1/tst.txt?st=AEfp-bT-tHrEfZN8lwDJGQ
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET /tst.txt?st=AEfp-bT-tHrEfZN8lwDJGQ HTTP/1.1
> Host: vhost
> User-Agent: curl/7.57.0
> Accept: */*
> X-Forwarded-For: 8.8.8.8
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.3
< Date: Mon, 20 Aug 2018 18:05:09 GMT
< Content-Type: text/plain
< Content-Length: 8
< Last-Modified: Mon, 20 Aug 2018 17:47:59 GMT
< Connection: keep-alive
< ETag: "5b7afecf-8"
< X-App-Secure-Uri: /tst.txt
< X-App-Secure-St: AEfp-bT-tHrEfZN8lwDJGQ
< X-App-Secure-Addr: 127.0.0.1
< X-App-Secure-RealIP: 127.0.0.1
< X-Forwarded-For: 8.8.8.8
< Accept-Ranges: bytes
<
tst.txt
* Connection #0 to host 127.0.0.1 left intact
Ожидалось, что доступ будет разрешаться для IP 8.8.8.8,
значение которого
передается через X-Forwarded-For. Этого не происходит:
# echo -n "8.8.8.8_/tst.txt" | openssl md5 -binary |
openssl base64 | tr +/ -_ | tr -d =
WEpfZcYFo9shAa3_pwtACw
# curl -v -H "Host: vhost" -H "X-Forwarded-For: 8.8.8.8"
http://127.0.0.1/tst.txt?st=WEpfZcYFo9shAa3_pwtACw
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET /tst.txt?st=WEpfZcYFo9shAa3_pwtACw HTTP/1.1
> Host: vhost
> User-Agent: curl/7.57.0
> Accept: */*
> X-Forwarded-For: 8.8.8.8
>
< HTTP/1.1 403 Forbidden
< Server: nginx/1.10.3
< Date: Mon, 20 Aug 2018 18:07:14 GMT
< Content-Type: text/html
< Content-Length: 169
< Connection: keep-alive
< X-App-Secure-Uri: /tst.txt
< X-App-Secure-St: WEpfZcYFo9shAa3_pwtACw
< X-App-Secure-Addr: 127.0.0.1
< X-App-Secure-RealIP: 127.0.0.1
< X-Forwarded-For: 8.8.8.8
<
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.10.3</center>
</body>
</html>
* Connection #0 to host 127.0.0.1 left intact
Какие будут рекомендации?
Спасибо.
Подробная информация о списке рассылки nginx-ru