[fli4l] statisches Forward vs. dynamischer NAT-Eintrag
Christoph Schulz
fli4l at kristov.de
Do Aug 18 07:15:07 CEST 2016
Hallo!
Am Thu, 18 Aug 2016 01:32:58 +0200 schrieb Erwin Lottermann:
> So weit ich das beobachten konnte, verwendet ein Client bei SIP
> normalerweise keinen zufälligen Quellport sondern ebenfalls 5060.
OK, das wusste ich nicht.
> Bei SIP ist es keine ganz untypische Situation, dass die NAT-Einträge
> wegen UDP-Timeout gelöscht werden, weil lange (z.B. 1 Stunde) keine
> Daten über die Verbindung gehen. Um trotzdem erreichbar zu sein, wird
> vielfach empfohlen, ein statisches Forwarding für den externen Port 5060
> udp für die fritzbox im LAN einzurichten.
>
> Jetzt startet jemand einen zweiten SIP-Client A' im LAN und es gibt
> gerade keinen NAT-Eintrag für die SIP-Verbindung der Fritzbox A, weil
> das Timeout abgelaufen ist. Oder die Fritzbox ist gar nicht
> eingeschaltet. Oder der zweite SIP-Client verbindet sich gar nicht zu
> B:5060 wie die Fritzbox, sondern zu C:5060.
>
> Wir haben dann im Router ein statisch eingerichtetes Forwarding für den
> externen Port 5060 Richtung Fritzbox:5060 und wir haben einen dynamisch
> entstandenen NAT-Eintrag C:5060->A':5060
>
> Jetzt sendet C:5060 an F:5060 Daten
>
> Welche Regel greift jetzt zuerst?
Die conntrack-Regel. Siehe die Priorisierung im Linux-Kernel:
kristov at peacock /usr/src/linux $ grep NF_IP_PRI_ include/uapi/linux/
netfilter_ipv4.h
NF_IP_PRI_FIRST = INT_MIN,
NF_IP_PRI_CONNTRACK_DEFRAG = -400,
NF_IP_PRI_RAW = -300,
NF_IP_PRI_SELINUX_FIRST = -225,
NF_IP_PRI_CONNTRACK = -200,
NF_IP_PRI_MANGLE = -150,
NF_IP_PRI_NAT_DST = -100,
NF_IP_PRI_FILTER = 0,
NF_IP_PRI_SECURITY = 50,
NF_IP_PRI_NAT_SRC = 100,
NF_IP_PRI_SELINUX_LAST = 225,
NF_IP_PRI_CONNTRACK_HELPER = 300,
NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
NF_IP_PRI_LAST = INT_MAX,
NF_IP_PRI_CONNTRACK = -200 < -100 = NF_IP_PRI_NAT_DST, also erst
CONNTRACK, dann Destination NAT.
Außerdem wird die nat-Tabelle nur für *neue* Verbindungen (genauer: Flows)
zu Rate gezogen, d.h. der Conntrack-Status muss "NEW" sein. Das ist in
der Funktion nf_nat_ipv4_fn() in net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
implementiert:
switch (ctinfo) {
[...]
case IP_CT_NEW:
if (!nf_nat_initialized(ct, maniptype)) {
unsigned int ret;
ret = do_chain(priv, skb, state, ct);
^^^^^^^^
(hier wird die NAT-Tabelle abgearbeitet)
[...]
default:
/* ESTABLISHED */
NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
ctinfo == IP_CT_ESTABLISHED_REPLY);
if (nf_nat_oif_changed(state->hook, ctinfo, nat, state-
>out))
goto oif_changed;
}
Ein Bild sagt häufig mehr als tausend Worte. Eines der typischen
Diagramme zum Linux-Paketfilter kann man z.B. unter https://
upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg
finden. Hier sieht man gut, dass die conntrack-Behandlung in der
PREROUTING-Ketter zwar nach der raw-, aber noch vor der mangle- oder nat-
Tabelle passiert. In der oben verlinkten Grafik steht sogar explizit drin:
"nat" table only consulted for "NEW" connections
Viele Grüße,
--
Christoph Schulz
[fli4l-Team]
Mehr Informationen über die Mailingliste Fli4L