✨ Обновлена обработка IP-адресов и настройки доверенных прокси
- Упрощена настройка trust proxy для работы с nginx proxy manager. - Оптимизирована функция получения IP-адреса клиента с учетом локальных адресов и заголовков прокси. - Удалено избыточное логирование и улучшена обработка IPv6 адресов.
This commit is contained in:
parent
df2c94dc0e
commit
6c4753e9ad
57
server.js
57
server.js
@ -15,14 +15,8 @@ const app = express();
|
|||||||
const PORT = process.env.PORT || 3000;
|
const PORT = process.env.PORT || 3000;
|
||||||
|
|
||||||
// Настройка trust proxy для правильного получения IP адресов через прокси
|
// Настройка trust proxy для правильного получения IP адресов через прокси
|
||||||
// Доверяем localhost и стандартной Docker bridge сети
|
// Доверяем nginx proxy manager (обычно работает на localhost)
|
||||||
app.set("trust proxy", [
|
app.set("trust proxy", ["127.0.0.1", "::1", "::ffff:127.0.0.1"]);
|
||||||
"127.0.0.1",
|
|
||||||
"::1",
|
|
||||||
"172.17.0.0/16",
|
|
||||||
"10.0.0.0/8",
|
|
||||||
"192.168.0.0/16",
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Создаем директорию для аватарок, если её нет
|
// Создаем директорию для аватарок, если её нет
|
||||||
const uploadsDir = path.join(__dirname, "public", "uploads");
|
const uploadsDir = path.join(__dirname, "public", "uploads");
|
||||||
@ -302,37 +296,17 @@ function logAction(userId, actionType, details, ipAddress) {
|
|||||||
|
|
||||||
// Функция для получения IP-адреса клиента
|
// Функция для получения IP-адреса клиента
|
||||||
function getClientIP(req) {
|
function getClientIP(req) {
|
||||||
// Для отладки логируем все релевантные заголовки и IP адреса
|
|
||||||
const debugInfo = {
|
|
||||||
"req.ip": req.ip,
|
|
||||||
"req.connection.remoteAddress": req.connection?.remoteAddress,
|
|
||||||
"x-forwarded-for": req.headers["x-forwarded-for"],
|
|
||||||
"x-real-ip": req.headers["x-real-ip"],
|
|
||||||
"x-client-ip": req.headers["x-client-ip"],
|
|
||||||
"cf-connecting-ip": req.headers["cf-connecting-ip"],
|
|
||||||
};
|
|
||||||
console.log("IP Debug info:", JSON.stringify(debugInfo, null, 2));
|
|
||||||
|
|
||||||
// Используем встроенный в Express метод req.ip, который учитывает trust proxy
|
// Используем встроенный в Express метод req.ip, который учитывает trust proxy
|
||||||
let ip = req.ip;
|
let ip = req.ip;
|
||||||
|
|
||||||
// Если req.ip вернул undefined или является локальным/Docker адресом, пробуем другие варианты
|
// Если req.ip является локальным адресом, пробуем получить из заголовков
|
||||||
if (
|
if (!ip || ip === "127.0.0.1" || ip === "::1" || ip === "::ffff:127.0.0.1") {
|
||||||
!ip ||
|
|
||||||
ip === "127.0.0.1" ||
|
|
||||||
ip === "::1" ||
|
|
||||||
ip === "172.17.0.1" ||
|
|
||||||
ip.startsWith("172.17.") ||
|
|
||||||
ip.startsWith("10.") ||
|
|
||||||
ip.startsWith("192.168.")
|
|
||||||
) {
|
|
||||||
// Проверяем заголовки прокси по приоритету
|
// Проверяем заголовки прокси по приоритету
|
||||||
ip =
|
ip =
|
||||||
req.headers["x-forwarded-for"]?.split(",")[0].trim() ||
|
req.headers["x-forwarded-for"]?.split(",")[0].trim() ||
|
||||||
req.headers["x-real-ip"] ||
|
req.headers["x-real-ip"] ||
|
||||||
req.headers["x-client-ip"] ||
|
req.headers["x-client-ip"] ||
|
||||||
req.headers["cf-connecting-ip"] || // Для Cloudflare
|
req.headers["cf-connecting-ip"] || // Для Cloudflare
|
||||||
req.headers["x-cluster-client-ip"] || // Для кластеров
|
|
||||||
req.connection?.remoteAddress ||
|
req.connection?.remoteAddress ||
|
||||||
req.socket?.remoteAddress ||
|
req.socket?.remoteAddress ||
|
||||||
req.connection?.socket?.remoteAddress ||
|
req.connection?.socket?.remoteAddress ||
|
||||||
@ -344,38 +318,27 @@ function getClientIP(req) {
|
|||||||
// Убираем скобки IPv6
|
// Убираем скобки IPv6
|
||||||
ip = ip.replace(/[[\]]/g, "");
|
ip = ip.replace(/[[\]]/g, "");
|
||||||
|
|
||||||
// Проверяем, является ли это IPv6 адресом
|
// Обрабатываем IPv6 адреса
|
||||||
if (ip.includes("::")) {
|
if (ip.includes("::")) {
|
||||||
// Это IPv6 адрес (содержит "::" или несколько ":")
|
|
||||||
// IPv6 адреса могут быть в формате [::1]:port или ::1
|
|
||||||
const ipv6Match = ip.match(/^(\[)?([^\]]+)(\])?(:(\d+))?$/);
|
const ipv6Match = ip.match(/^(\[)?([^\]]+)(\])?(:(\d+))?$/);
|
||||||
if (ipv6Match) {
|
if (ipv6Match) {
|
||||||
ip = ipv6Match[2]; // Берем IPv6 адрес без скобок и порта
|
ip = ipv6Match[2];
|
||||||
}
|
}
|
||||||
} else if (ip.includes(":") && !ip.includes(".")) {
|
|
||||||
// IPv6 адрес без "::" но с несколькими ":"
|
|
||||||
// Например, 2001:db8::1
|
|
||||||
// Оставляем как есть
|
|
||||||
} else if (ip.includes(":")) {
|
} else if (ip.includes(":")) {
|
||||||
// IPv4 с портом (например, 192.168.1.1:3000)
|
// IPv4 с портом
|
||||||
const parts = ip.split(":");
|
const parts = ip.split(":");
|
||||||
if (parts.length === 2 && /^\d+$/.test(parts[1])) {
|
if (parts.length === 2 && /^\d+$/.test(parts[1])) {
|
||||||
ip = parts[0];
|
ip = parts[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// IPv4 без порта оставляем как есть
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Конвертируем IPv6 localhost в IPv4 для лучшей читаемости
|
// Конвертируем IPv6 localhost в IPv4
|
||||||
if (ip === "::1") {
|
if (ip === "::1" || ip === "::ffff:127.0.0.1") {
|
||||||
ip = "127.0.0.1";
|
ip = "127.0.0.1";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Финальный IP для логов
|
return ip || "unknown";
|
||||||
const finalIP = ip || "unknown";
|
|
||||||
console.log(`Final IP for logging: ${finalIP}`);
|
|
||||||
|
|
||||||
return finalIP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Миграции базы данных
|
// Миграции базы данных
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user