Skip to main content
  1. Posts/
  2. blog.dsinf.net/

Serwer nginx – minimalizowanie zbieranych danych w logach dostępu

·289 words·2 mins
blog.dsinf.net logi loki nginx privacy promtail
Daniel Skowroński
Author
Daniel Skowroński

Kończąc opisane dwa miesiące temu zmiany w polityce prywatności, skończyłem projekt usuwania zbędnych danych z logów dostępu nginxa. Opiszę pokrótce gotowy fragment pliku konfiguracyjnego serwera i pokażę, jak skonfigurować Promtaila, żeby przetwarzał logi w nowym formacie.

W nginxie dyrektywa access_log (i często towarzysząca log_format) mogą być zdefiniowane na poziomie bloku http lub server. W moim wypadku są to globalne ustawienia dla wszystkich wirtualnych hostów i wygląda następująco:

map $remote_addr $remote_addr_anon {
  ~(?P<ip>\d+\.\d+\.\d+)\.    $ip.0;
  ~(?P<ip>[^:]+:[^:]+):       $ip::;
  127.0.0.1                   $remote_addr;
  ::1                         $remote_addr;
  default                     0.0.0.0;
}

map $http_x_forwarded_for $http_x_forwarded_for_anon {
  ~(?P<ip>\d+\.\d+\.\d+)\.    $ip.0;
  ~(?P<ip>[^:]+:[^:]+):       $ip::;
  127.0.0.1                   $http_x_forwarded_for;
  ::1                         $http_x_forwarded_for;
  default                     0.0.0.0;
}

log_format main 
  '[$time_local] $http_host '
  '$remote_addr_anon $http_x_forwarded_for_anon'
  '"$request" $status $body_bytes_sent';

access_log /var/log/nginx/access.log  main;

Format main zawiera absolutne minimum informacji przydatnych dla utrzymania serwera. Są to kolejno:

  • Czas requestu
  • Nagłówek Host z żądania, co przydatne jest, jeśli mamy kilka wirtualnych hostów w jednym logu
  • Adresy IP zdalnego hosta i z nagłówkaX-Forwarded-For, z których usunięto ostatni oktet
  • Metodę HTTP (np. GET, POST), ścieżkę URL żądania oraz wersję protokołu (np. HTTP/1.1)
  • Kod odpowiedzi
  • Ilość przesłanych bajtów odpowiedzi

Usunięcie ostatniego oktetu realizowane jest przez dyrektywy map. Gotowiec za: https://chriswiegman.com/2019/09/anonymizing-nginx-logs/

Warto zwrócić uwagę, że względem standardowego formatu logów nginxa nie kolekcjonujemy zbędnych:

  • Pełnych adresów IP
  • Nagłówka Referrer, co uniemożliwia śledzenie skąd użytkownik do nas trafił
  • Nagłówka User-Agent co anonimizuje używaną przeglądarkę

Jeśli używamy Promtaila do przekazywania logów do centralnego serwera przyda nam się zaktualizowany plik konfiguracyjny do parsowania linii logów:

scrape_configs:
- job_name: nginx_access
  static_configs:
  - targets:
      - localhost
    labels:
      hostname: "webserver.tld"
      job: nginx_access
      __path__: /var/log/nginx/access.log

  pipeline_stages:
  - match:
      selector: '{job="nginx_access"}'
      stages:
      - regex:
          expression: '^\[(?P<time_local>.*)\] (?P<http_host>[^ ]*) (?P<remote_addr_anon>[^ ]*) (?P<http_x_forwarded_for_anon>[^ ]*) "(?P<method>[^ ]*) (?P<request>[^ ]*) (?P<proto>[^ ]*)" (?P<status>[\d]+) (?P<body_bytes_sent>[\d]+)'
      - labels:
          http_host: 
          method:
          status:

Efektem zbierania logów przez Promtaila są takie oto dane widoczne w Loki: