Этот вопрос, кажется, часто задают, но я не нашел хорошего решения проблемы, с которой я столкнулся.
У меня есть приложение для колб, которое находится за nginx.Приложение и nginx общаются через сокет uwsgi unix.Приложение имеет общедоступную конечную точку, которая открывается через Route53.Он также предоставляется через AWS API Gateway.Причиной такого двойного воздействия является то, что приложение заменяет существующее решение Lambda.Благодаря API-шлюзу я могу поддерживать устаревшие запросы до тех пор, пока они не перейдут к новой общедоступной конечной точке.Еще один факт, касающийся моего приложения: оно работает в модуле Kubernetes, за балансировщиком нагрузки.
Мне нужно получить доступ к IP-адресу клиента, который сделал запрос, чтобы я мог использовать поиск geoIP и исключать сбор данных для пользователей за пределами США (GDPR) среди прочего.Имея два пути к приложению, у меня есть два разных способа добраться до IP-адреса.
Удар по конечной точке из шлюза API
Когда я захожу через устаревшую версиюпуть, я получаю X-Forwarded-For, но я вижу только IP-адреса, которые зарегистрированы в Amazon.Я использовал первый в списке, но я вижу только один или два разных IP-адреса.Это тестовая среда, и это может быть правильным, но я так не думаю, потому что, когда я нажимаю на нее из локального браузера, я не нахожу свой IP.
Непосредственное попадание в конечную точку:
В этом случае в списке X-Forwarded-For нет данных, и единственный ip-адрес, который я могу найти, - request.remote_addr.Это, к сожалению, имеет только IP-адрес модуля или, возможно, балансировщика нагрузки.Я не уверен, что, как это в том же классе, но не соответствует ни одному.В любом случае, это определенно не IP-адрес клиента.Я нашел документацию в nginx, которая описывает доступные переменные, включая $ realip_remote_addr.Однако, когда я зарегистрировал это значение, оно было таким же, как remote_addr.
Ниже приведен код, который я использую для получения remote_addr:
def remote_addr(self, request):
x_forwarded_for = request.headers.get("X-Forwarded-For")
if x_forwarded_for:
ip_list = x_forwarded_for.split(",")
return ip_list[0]
else:
return request.remote_addr
Если это полезно, этомоя конфигурация сервера nginx:
server {
listen 8443 ssl;
ssl_certificate /etc/certs/cert;
ssl_certificate_key /etc/certs/key;
ssl_dhparam /etc/certs/dhparam.pem;
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA HIGH !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
server_tokens off;
location = /log {
limit_except POST {
deny all;
}
include uwsgi_params;
uwsgi_pass unix:///tmp/uwsgi.sock;
}
location = /ping {
limit_except GET {
deny all;
}
include uwsgi_params;
uwsgi_pass unix:///tmp/uwsgi.sock;
}
location = /health-check {
return 200 '{"response": "Healthy"}';
}
location /nginx_status {
stub_status;
}
}
Я потратил целый день, пытаясь разобраться в этом.Я уверен, что решение тривиально и, вероятно, вызвано отсутствием знаний / опыта использования nginx.