Вопрос или проблема
У меня есть работающий веб-сайт (на PHP), который обслуживается напрямую через nginx, а не через обратный прокси. Основная конфигурация nginx ниже:
server {
listen 80;
server_name my.server.com;
index index.php;
root /var/www/myserver/public;
location /client {
root /var/www/myserver;
autoindex off;
location ~* ^.+.(js|css|png|jpg|svg|svgz|jpeg|gif|ico|tpl)$ {
access_log off;
expires max;
}
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
location /api/v1/ {
if (!-e $request_filename){
rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
}
}
}
Когда пользователь переходит на сайт для входа, перед тем как ему будет представлен index.php, позволяющий войти, я хотел бы проверить его IP-адрес перед тем, как обслуживать index.php; отказав в доступе, если он неподходящий, или продолжить обычную обработку, если он подходящий. Черный и белый списки не подойдут, так как у всех будет хотя бы одна попытка попытаться получить доступ.
Мне хотелось бы, чтобы что-то вроде следующего выполнялось на главной странице в начале сессии:
location = / {
proxy_pass http://localhost:9017; # служба проверки ip
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Каков подходящий способ сделать это?
Ответ или решение
Чтобы вставить проверку IP-адреса перед тем, как клиент будет перенаправлен на приложение PHP, можно использовать Nginx для реализации простой механики контроля доступа на основе IP-адресов. Ниже представлено подробное руководство по этому процессу.
Шаг 1. Настройка Nginx для проверки IP-адреса
Хотя вы упомянули, что не работаете через обратный прокси, вам все равно нужно правильно настроить конфигурацию вашего Nginx для добавления логики проверки IP-адреса. Ваша конфигурация может выглядеть следующим образом:
server {
listen 80;
server_name my.server.com;
index index.php;
root /var/www/myserver/public;
# Блок проверки IP-адреса
location = / {
# Проверка IP-адреса
set $allowed_ip 0;
# Здесь вы можете перечислить разрешенные IP-адреса
# Замените "192.168.1.1" на ваш разрешенный IP
if ($remote_addr = "192.168.1.1") {
set $allowed_ip 1;
}
# Проверка, разрешен ли IP-адрес
if ($allowed_ip = 0) {
return 403; # Запретить доступ
}
# Если IP-адрес разрешен, продолжать нормальную обработку
try_files $uri $uri/ /index.php?$query_string;
}
location /client {
root /var/www/myserver;
autoindex off;
location ~* ^.+.(js|css|png|jpg|svg|svgz|jpeg|gif|ico|tpl)$ {
access_log off;
expires max;
}
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
location /api/v1/ {
if (!-e $request_filename){
rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
}
}
}
Шаг 2. Объяснение конфигурации
-
Проверка IP-адреса: В блоке
location = /
используется переменная$allowed_ip
для проверки, разрешен ли IP-адрес. Вif
условии вы можете указать разрешённые IP-адреса. Если IP соответствует, переменная устанавливается в 1, в противном случае — 0. -
Возврат 403: Если переменная
$allowed_ip
остается равной 0 (IP-адрес не разрешен), сервер возвращает статус 403 (доступ запрещен). -
Обработка запросов: Если IP-адрес разрешен, Nginx продолжает нормальную обработку запросов, используя конструкцию
try_files
, что позволяет искать запрашиваемый файл или передавать запрос вindex.php
.
Шаг 3. Дополнительные настройки
Вы можете добавить больше правил для проверки IP-адресов, например, используя директиву geo
для более гибкой настройки:
geo $allowed_ip {
default 0;
# Укажите разрешенные IP-адреса
192.168.1.1 1;
10.0.0.2 1;
}
Затем используйте $allowed_ip
в вашем блоке location
так же, как в предыдущем примере.
Заключение
Теперь у вас есть функционирующая система проверки IP-адреса перед тем, как пользователи получают доступ к вашему приложению. Это решение обеспечивает дополнительный уровень безопасности, позволяя вам контролировать, кто может получить доступ к вашему приложению PHP, прежде чем они увидят страницу для входа.