Späť na blog

Linux ARP Cache Zastarané Záznamy: Blackhole Traffic Po Failoveri

Failover prebehol cisto a potom traffic zmizol v stale ARP cache. “Load balancer failover dokončený ale traffic stále ide na mŕtvy node.” Príčina: klient servery majú cachované ARP záznamy mapujúce virtuálnu IP na MAC adresu starého nodu, ignorujúc failover.

Prostredie: Linux servery, VRRP/keepalived/floating IPs, databázové failovery, migrácie load balancerov

Problém

Traffic Blackhole Po Failoveri

Časová os databázového failoveru:

T+0:00   Primary (10.0.1.10, MAC aa:bb:cc:11:22:33) je zdravý
         App servery majú ARP: 10.0.1.10 → aa:bb:cc:11:22:33

T+0:30   Primary zlyháva, keepalived spustí failover
T+0:31   Secondary preberá VIP 10.0.1.10
         Secondary MAC: aa:bb:cc:44:55:66
         Secondary posiela gratuitous ARP

T+0:32   Niektoré app servery aktualizujú ARP cache ✓
T+0:33   Iné app servery stále majú starú cache:
         10.0.1.10 → aa:bb:cc:11:22:33 (mŕtvy MAC!)

T+0:35   Traffic zo serverov so starou cache → blackhole
         Pakety poslané na starý MAC, nikdy nedosiahnu nový primary
         Connection timeouty, aplikačné chyby

T+5:00   ARP cache expiruje, refreshne sa
         Konečne funguje správne

Prečo Gratuitous ARP Nie Vždy Funguje

Problémy propagácie gratuitous ARP:

┌─────────────────────────────────────────────────────────────┐
│ Secondary posiela: "10.0.1.10 je na aa:bb:cc:44:55:66"     │
│                                                             │
│ Toto je broadcast, ale...                                   │
│                                                             │
│ ✗ Switche nemusia floodovať na všetky porty                │
│ ✗ Niektoré hosty ignorujú nevyžiadané ARP aktualizácie     │
│ ✗ Linux gc_stale_time bráni okamžitej aktualizácii         │
│ ✗ Sieťové firewally môžu dropnúť ARP broadcasts            │
│ ✗ VLANy nemusia správne propagovať gratuitous ARP          │
└─────────────────────────────────────────────────────────────┘

Správanie Linux ARP cache:
- gc_stale_time: 60s default - nerefreshne pred týmto
- base_reachable_time: 30s - považuje záznam za platný
- Aj s gratuitous ARP, môže preferovať existujúci "potvrdený" záznam

Príčina

Stavy Linux ARP Cache

Životný cyklus ARP záznamu:

INCOMPLETE → REACHABLE → STALE → DELAY → PROBE → FAILED
    ↑                       │
    └───────────────────────┘ (alebo refresh)

Popis stavov:
- REACHABLE: Nedávno potvrdený, používa sa priamo
- STALE: Nepotvrdený nedávno, ale stále používaný (!)
- DELAY: Chystá sa probing pre potvrdenie
- PROBE: Aktívne prebieha probing (unicast ARP)
- FAILED: Nedosiahnuteľný

Problém: STALE záznamy sa POUŽÍVAJÚ, nerefreshujú sa okamžite!

Predvolené Timeouty

# Skontroluj parametre ARP cache
sysctl net.ipv4.neigh.default.gc_stale_time
# 60 sekúnd - ako dlho pred garbage collection STALE

sysctl net.ipv4.neigh.default.base_reachable_time_ms
# 30000 ms - ako dlho je záznam REACHABLE

sysctl net.ipv4.neigh.default.gc_thresh3
# 1024 - max záznamov pred agresívnym GC

# Celkový čas kedy môže byť záznam stale ale používaný: gc_stale_time + probing
# Môže byť 60-120 sekúnd traffic na zlú destináciu!

Diagnostika

Skontroluj Stav ARP Cache

# Zobraz ARP cache so stavom
ip neigh show

# Výstup:
# 10.0.1.10 dev eth0 lladdr aa:bb:cc:11:22:33 STALE
#                                              ^^^^^ Problém!

# Sleduj zmeny ARP cache
ip monitor neigh

# Skontroluj konkrétny záznam
ip neigh show 10.0.1.10

Over Cestu Traffic

# Skontroluj či pakety dosahujú správnu destináciu
tcpdump -i eth0 -n host 10.0.1.10

# Uvidíš traffic idúci na ZLÝ MAC:
# 12:00:01 IP app-server > 10.0.1.10: TCP...
# Frame dst: aa:bb:cc:11:22:33 (starý MAC, mŕtvy server!)

# Správne po refreshi:
# Frame dst: aa:bb:cc:44:55:66 (nový MAC, aktívny server)

Skontroluj Príjem Gratuitous ARP

# Na app serveri, sleduj gratuitous ARP
tcpdump -i eth0 -n arp

# Mal by si vidieť:
# 12:00:30 ARP, Reply 10.0.1.10 is-at aa:bb:cc:44:55:66

# Ale ak nevidíš, skontroluj:
# - Sieťovú cestu (VLANy, firewally)
# - Správanie floodinku switcha
# - Kernel ignorujúci nevyžiadané ARP

Riešenie

Možnosť 1: Zníž Timeouty ARP Cache

# Zníž čas kedy záznamy zostávajú STALE
sysctl -w net.ipv4.neigh.default.gc_stale_time=30
sysctl -w net.ipv4.neigh.eth0.gc_stale_time=30

# Zníž REACHABLE čas
sysctl -w net.ipv4.neigh.default.base_reachable_time_ms=15000

# Urob persistentné v /etc/sysctl.d/arp.conf:
net.ipv4.neigh.default.gc_stale_time = 30
net.ipv4.neigh.default.base_reachable_time_ms = 15000

Možnosť 2: Akceptuj Gratuitous ARP Aktualizácie

# Zapni prijímanie nevyžiadaných ARP aktualizácií
sysctl -w net.ipv4.conf.all.arp_accept=1
sysctl -w net.ipv4.conf.eth0.arp_accept=1

# Toto prinúti Linux aktualizovať cache na gratuitous ARP
# aj pre existujúce záznamy

# Persistentné:
net.ipv4.conf.all.arp_accept = 1

Možnosť 3: Flushni ARP Cache Pri Failoveri

#!/bin/bash
# failover_arp_flush.sh - Spusti na klient serveroch po failoveri

VIP="10.0.1.10"

# Zmaž konkrétny ARP záznam
ip neigh del $VIP dev eth0 2>/dev/null

# Alebo flushni a nechaj znova naučiť
ip neigh flush $VIP

# Over
ip neigh show $VIP
# Ansible playbook na flush ARP pri failoveri
---
- name: Flush stale ARP entries
  hosts: app_servers
  tasks:
    - name: Delete VIP ARP entry
      command: ip neigh del {{ vip }} dev eth0
      ignore_errors: yes

    - name: Force ARP refresh with ping
      command: ping -c 1 {{ vip }}
      ignore_errors: yes

Možnosť 4: Pošli Viac Gratuitous ARP

# V keepalived.conf - pošli viac gratuitous ARP
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100

    # Pošli gratuitous ARP viackrát
    garp_master_delay 1
    garp_master_repeat 5        # Pošli 5-krát
    garp_master_refresh 30      # Opakuj každých 30s
    garp_master_refresh_repeat 2

    virtual_ipaddress {
        10.0.1.10/24
    }
}

Možnosť 5: Použi arping Pre Aktívny Refresh

#!/bin/bash
# active_arp_announce.sh - Spusti na novom primary po failoveri

VIP="10.0.1.10"
INTERFACE="eth0"

# Pošli flood gratuitous ARP
for i in {1..10}; do
    arping -U -I $INTERFACE $VIP -c 1
    arping -A -I $INTERFACE $VIP -c 1
    sleep 0.1
done

# -U: Nevyžiadaná ARP reply (gratuitous)
# -A: Nevyžiadaný ARP request (niektoré systémy preferujú toto)

Monitoring

groups:
  - name: arp-cache
    rules:
      - alert: ARPCacheStaleVIP
        expr: |
          time() - arp_entry_last_confirmed_seconds{ip=~"10.0.1.*"} > 120
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Zastaraný ARP záznam pre VIP {{ $labels.ip }}"

      - alert: FailoverTrafficBlackhole
        expr: |
          rate(tcp_retransmits_total{dest=~"10.0.1.*"}[1m]) > 100
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Vysoké TCP retransmity na VIP - možný ARP problém"

Checklist

## Linux ARP Cache Failover

### Pred Failoverom
- [ ] Nakonfiguruj znížený gc_stale_time (30s namiesto 60s)
- [ ] Zapni arp_accept=1 na klient serveroch
- [ ] Nakonfiguruj keepalived pre viac gratuitous ARP
- [ ] Otestuj failover s tcpdump monitoringom

### Počas/Po Failoveri
- [ ] Over že gratuitous ARP bol poslaný z nového primary
- [ ] Skontroluj stav ARP cache na klient serveroch
- [ ] Flushni zastarané záznamy ak potrebné
- [ ] Monitoruj connection timeouty

### Ak Nastane Traffic Blackhole
- [ ] Identifikuj postihnuté servery: ip neigh show | grep STALE
- [ ] Flushni ARP cache: ip neigh flush <VIP>
- [ ] Pošli dodatočné gratuitous ARP z nového primary
- [ ] Skontroluj sieťovú cestu pre problémy propagácie ARP

Záver

Lekcia: Linux ARP cache je lepkavý - preferuje existujúce záznamy pred gratuitous ARP aktualizáciami. Nakonfiguruj agresívne cache timeouty a zapni arp_accept=1 pre rýchlejšiu reakciu na failover.

Kľúčové princípy:

  1. STALE záznamy sa stále používajú - traffic ide na starý MAC
  2. gc_stale_time=30 pre rýchlejšiu expiráciu cache
  3. arp_accept=1 pre prijímanie gratuitous ARP aktualizácií
  4. Pošli viac gratuitous ARP z nového primary

Súvisiace články

Súvisiace články

Citujte tento článok

Ak na článok odkazujete, pridajte pôvodnú URL a uveďte autora.

Michal Drozd. "Linux ARP Cache Zastarané Záznamy: Blackhole Traffic Po Failoveri". https://www.michal-drozd.com/sk/blog/linux-arp-cache-failover-stale/ (Publikované 14. februára 2025).