В современных инфраструктурах информационной безопасности одной из ключевых задач является ограничение доступа к системным метрикам. По умолчанию Prometheus Node Exporter предоставляет метрики в открытом доступе, что может привести к утечке информации о состоянии системы или атаке на сервис мониторинга.
Для повышения безопасности необходимо реализовать возможность ограничения доступа к метрикам только для определённых IP-адресов, что позволит контролировать, какие клиенты могут запрашивать метрики.
В данной статье рассмотрим, как внести соответствующие изменения в код Node Exporter, а также процесс сборки обновленного пакета.
Изменение кода
Добавление нового флага командной строки
Для управления доступом по IP-адресам добавим новый аргумент —web.client-ip-only, который будет содержать список разрешённых IP-адресов, разделённых запятыми. Если параметр не указан, метрики будут доступны для всех.
В файле main.go регистрируем новый флаг:
clientIPOnly = kingpin.Flag( "web.client-ip-only", "Comma-separated list of allowed client IPs (e.g., '192.168.1.1,10.0.0.2'). Leave empty to allow all.", ).Default("").String()
Реализация фильтрации IP
Добавим middleware для обработки входящих HTTP-запросов и проверки IP-адреса клиента:
func ipFilterMiddleware(next http.Handler, allowedIPs map[string]struct{}, logger *slog.Logger) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { clientIP, _, err := net.SplitHostPort(r.RemoteAddr) if err != nil { logger.Warn("Failed to parse client IP", "error", err) http.Error(w, "Forbidden", http.StatusForbidden) return } if len(allowedIPs) > 0 { if _, allowed := allowedIPs[clientIP]; !allowed { logger.Warn("Access denied", "client_ip", clientIP) http.Error(w, "Forbidden", http.StatusForbidden) return } } next.ServeHTTP(w, r) }) }
Добавление middleware в обработчик метрик
В main.go изменим обработчик HTTP-запросов:
allowedIPs := make(map[string]struct{}) if *clientIPOnly != "" { for _, ip := range strings.Split(*clientIPOnly, ",") { allowedIPs[strings.TrimSpace(ip)] = struct{}{} } } http.Handle(*metricsPath, ipFilterMiddleware(newHandler(!*disableExporterMetrics, *maxRequests, logger), allowedIPs, logger))
Обновление главной страницы
Добавим отображение разрешённых IP-адресов на веб-странице:
clientIPDisplay := "*" if *clientIPOnly != "" { clientIPDisplay = *clientIPOnly } landingConfig := web.LandingConfig{ Name: "Node Exporter", Description: "Prometheus Node Exporter", Version: version.Info(), Links: []web.LandingLinks{ { Address: *metricsPath, Text: "Metrics", }, { Address: "#", Text: "Allowed IPs: " + clientIPDisplay, }, }, }
Сборка пакета для распространения
После внесения изменений необходимо пересобрать Node Exporter. Для этого выполните следующие шаги:
-
Установите Go и зависимости:
sudo apt update && sudo apt install -y golang -
Склонируйте исходный код Node Exporter:
git clone https://github.com/prometheus/node_exporter.git cd node_exporter -
Скомпилируйте бинарный файл:
make build -
Проверяем версию и новые параметры:
./node_exporter --version -
Запускаем с ограничением по IP:
./node_exporter --web.client-ip-only="192.168.1.1,10.0.0.2"
Добавление параметра —web.client-ip-only позволяет ограничить доступ к метрикам только для указанных IP-адресов. Это значительно повышает уровень безопасности и снижает риск несанкционированного доступа к системной информации.
Теперь, благодаря middleware-фильтрации, Node Exporter будет обслуживать только доверенные IP-адреса, а пользователи смогут легко настраивать этот параметр через командную строку.
Кому лень всем этим заниматься, можете воспользоваться готовым из моего репозитория:
https://github.com/MaxSimba/node-exporter
З.Ы. Просьба не пинать сильно, я не волшебник только учусь! Но за конструктивные предложения, плюс в карму! За сим откланиваюсь! По просьбам могу собрать пакет для deb или RPM репозитория.
ссылка на оригинал статьи https://habr.com/ru/articles/884786/
Добавить комментарий