MPD5 + IPFW + NAT = Verzweiflung...

Rosendoktor

Well-Known Member
Hallo zusammen,

ich hab einen kleinen Server im lokalen Netz den ich gelegentlich für Experimente oder Spielereien nutze die ich nicht auf dem eigentlichen Router/Server machen will oder kann.

Der hängt erstmal einfach nur im LAN, die Netzwerkkonfiguration ist recht einfach:
rc.conf
Code:
ifconfig_re0="inet 192.168.0.242 netmask 255.255.255.0"
defaultrouter="192.168.0.251"
ifconfig_re0_ipv6="inet6 fd10:2842:f0d1:101:222:4dff:fed8:b463/64"
ipv6_defaultrouter="fd10:2842:f0d1:101::2"
ifconfig:
Code:
root@polaris:~# ifconfig
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
    ether 00:22:4d:d8:b4:63
    inet6 fe80::222:4dff:fed8:b463%re0 prefixlen 64 scopeid 0x1
    inet6 fd10:2842:f0d1:101:222:4dff:fed8:b463 prefixlen 64
    inet 192.168.0.242 netmask 0xffffff00 broadcast 192.168.0.255
    media: Ethernet autoselect (10baseT/UTP <full-duplex>)
    status: active
    nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
    options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
    inet6 ::1 prefixlen 128
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
    inet 127.0.0.1 netmask 0xff000000
    groups: lo
    nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
netstat:
Code:
root@polaris:~# netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags     Netif Expire
default            192.168.0.251      UGS         re0
127.0.0.1          link#2             UH          lo0
192.168.0.0/24     link#1             U           re0
192.168.0.242      link#1             UHS         lo0

Internet6:
Destination                       Gateway                       Flags     Netif Expire
::/96                             ::1                           UGRS        lo0
default                           fd10:2842:f0d1:101::2         UGS         re0
::1                               link#2                        UH          lo0
::ffff:0.0.0.0/96                 ::1                           UGRS        lo0
fd10:2842:f0d1:101::/64           link#1                        U           re0
fd10:2842:f0d1:101:222:4dff:fed8:b463 link#1                    UHS         lo0
fe80::/10                         ::1                           UGRS        lo0
fe80::%re0/64                     link#1                        U           re0
fe80::222:4dff:fed8:b463%re0      link#1                        UHS         lo0
fe80::%lo0/64                     link#2                        U           lo0
fe80::1%lo0                       link#2                        UHS         lo0
ff02::/16                         ::1                           UGRS        lo0

Nun stellt der kleine Server eine Tunnelverbindung her, über die er eine eigene öffentliche ipv4/ipv6 Adresse bekommt. Dabei wird ein Interface ng0 angelegt:
Code:
root@polaris:~# ifconfig ng0
ng0: flags=88d1<UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST> metric 0 mtu 1460
    inet6 fe80::222:4dff:fed8:b463%ng0 prefixlen 64 scopeid 0x3
    inet6 2a02:a00:e000:60::2 prefixlen 64
    inet6 2a02:a00:e000:60::53 prefixlen 64
    inet 188.246.4.189 --> 188.246.4.1 netmask 0xffffffff
    nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
Das Routing ist etwas komplizierter:
Code:
root@polaris:~# netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags     Netif Expire
0.0.0.0/1          ng0                US          ng0
default            192.168.0.251      UGS         re0
127.0.0.1          link#2             UH          lo0
128.0.0.0/1        ng0                US          ng0
188.246.0.50       192.168.0.251      UGHS        re0
188.246.4.1        link#3             UH          ng0
188.246.4.189      link#3             UHS         lo0
192.168.0.0/24     link#1             U           re0
192.168.0.0/16     192.168.0.251      UGS         re0
192.168.0.242      link#1             UHS         lo0

Internet6:
Destination                       Gateway                       Flags     Netif Expire
::/96                             ::1                           UGRS        lo0
default                           fd10:2842:f0d1:101::2         UGS         re0
::1                               link#2                        UH          lo0
::ffff:0.0.0.0/96                 ::1                           UGRS        lo0
2000::/3                          ng0                           US          ng0
2a02:a00:e000:60::/64             link#3                        U           ng0
2a02:a00:e000:60::2               link#3                        UHS         lo0
2a02:a00:e000:60::53              link#3                        UHS         lo0
fd10:2842:f0d1:101::/64           link#1                        U           re0
fd10:2842:f0d1:101:222:4dff:fed8:b463 link#1                    UHS         lo0
fe80::/10                         ::1                           UGRS        lo0
fe80::%re0/64                     link#1                        U           re0
fe80::222:4dff:fed8:b463%re0      link#1                        UHS         lo0
fe80::%lo0/64                     link#2                        U           lo0
fe80::1%lo0                       link#2                        UHS         lo0
fe80::%ng0/64                     link#3                        U           ng0
fe80::222:4dff:fed8:b463%ng0      link#3                        UHS         lo0
ff02::/16                         ::1                           UGRS        lo0
Im Wesentlichen hab' ich die Defaultroutes umgelegt auf das ng0 Interface (als "Pseudo" Defaultroutes, 0.0.0.0/1 und 128.0.0.0/1 bzw 2000::/3, da FreeBSD keine Route Metrik kennt) und ein paar statische Routen dazu damit der Tunnel nicht durch sich selbst läuft und die internen Netze erreichbar bleiben.

So funktioniert das größtenteils, die auf dem Server laufenden Dienste die auf den öffentlichen Adresse lauschen funktionieren und beantworten Anfragen von aussen auch brav durch den Tunnel.

Lediglich eines geht nicht: Interne Verbindungsversuche ins ipv4 Internet funktionieren nicht, ins ipv6 Internet aber schon. Sieht so aus:

Code:
root@polaris:~# ping www.heise.de
PING www.heise.de (193.99.144.85): 56 data bytes
^C
--- www.heise.de ping statistics ---
5 packets transmitted, 0 packets received, 100.0% packet loss
root@polaris:~#
root@polaris:~# ping6 www.heise.de
PING6(56=40+8+8 bytes) 2a02:a00:e000:60::2 --> 2a02:2e0:3fe:1001:7777:772e:2:85
16 bytes from 2a02:2e0:3fe:1001:7777:772e:2:85, icmp_seq=0 hlim=54 time=22.406 ms
16 bytes from 2a02:2e0:3fe:1001:7777:772e:2:85, icmp_seq=1 hlim=54 time=25.872 ms
^C
--- www.heise.de ping6 statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
^Xround-trip min/avg/max/std-dev = 22.406/24.139/25.872/1.733 ms
root@polaris:~#
root@polaris:~# ping -S 188.246.4.189 www.heise.de
PING www.heise.de (193.99.144.85) from 188.246.4.189: 56 data bytes
64 bytes from 193.99.144.85: icmp_seq=0 ttl=243 time=25.370 ms
64 bytes from 193.99.144.85: icmp_seq=1 ttl=243 time=24.130 ms
^C
--- www.heise.de ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 24.130/24.750/25.370/0.620 ms
root@polaris:~#
root@polaris:~# wget -4 www.heise.de
URL transformed to HTTPS due to an HSTS policy
--2020-07-06 01:52:58--  https://www.heise.de/
Auflösen des Hostnamens www.heise.de (www.heise.de)… 193.99.144.85
Verbindungsaufbau zu www.heise.de (www.heise.de)|193.99.144.85|:443 … fehlgeschlagen: Operation timed out.
Erneuter Versuch.

--2020-07-06 01:54:14--  (Versuch: 2)  https://www.heise.de/
Verbindungsaufbau zu www.heise.de (www.heise.de)|193.99.144.85|:443 … ^C
root@polaris:~#
root@polaris:~# wget -6 www.heise.de
URL transformed to HTTPS due to an HSTS policy
--2020-07-06 01:55:02--  https://www.heise.de/
Auflösen des Hostnamens www.heise.de (www.heise.de)… 2a02:2e0:3fe:1001:7777:772e:2:85
Verbindungsaufbau zu www.heise.de (www.heise.de)|2a02:2e0:3fe:1001:7777:772e:2:85|:443 … verbunden.
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 200 OK
Länge: 545005 (532K) [text/html]
Wird in »index.html.10« gespeichert.

index.html.10                                    100%[=======================================================================================================>] 532,23K  1,05MB/s    in 0,5s

2020-07-06 01:55:03 (1,05 MB/s) - »index.html.10« gespeichert [545005/545005]
Also, ipv6 funktioniert, ipv4 funktioniert nur, wenn explizit die öffentliche ip4 als Source angegeben wird. Das Gleiche gilt auch für andere interne Dienste wie einen Squid Proxy, dem muss ich explizit per "tcp_outgoing_address=188.246.4.189" Direktive sagen welche Adresse er ausgehend verwenden soll, dann geht es.

Für mich sieht das danach aus als müsste für ipv4 noch NAT aktiviert werden. Daran beisse ich mir aber die Zähne aus und bekomme es ums verrecken nicht zum funktionieren.

Da ich eh noch eine Firewall einrichten wollte hab ich folgende IPFW Regeln (im Wesentlichen von https://www.freebsd.org/doc/de_DE.ISO8859-1/books/handbook/firewalls-ipfw.html) übernommen:
Code:
root@polaris:~# ipfw list
00005 allow ip from any to any via re0
00010 allow ip from any to any via lo0
00012 allow icmp from any to any in via ng0
00012 allow ipv6-icmp from any to any in via ng0
00099 reass ip from any to any in
00100 nat 1 ip4 from any to any in via ng0
00101 check-state :default
00125 skipto 1000 tcp from any to any out via ng0 setup keep-state :default
00125 skipto 1000 udp from any to any out via ng0 keep-state :default
00130 skipto 1000 icmp from any to any out via ng0 keep-state :default
00130 skipto 1000 ipv6-icmp from any to any out via ng0 keep-state :default
00408 allow udp from any to 188.246.4.189 53 in via ng0
00408 allow tcp from any to 188.246.4.189 53 in via ng0
00408 allow udp from any to 2a02:a00:e000:60::53 53 in via ng0
00408 allow tcp from any to 2a02:a00:e000:60::53 53 in via ng0
00410 allow tcp from any to 188.246.4.189 22 in via ng0 setup limit src-addr 2 :default
00410 allow tcp from any to 2a02:a00:e000:60::2 22 in via ng0 setup limit src-addr 2 :default
00499 deny ip from any to any in via ng0
00999 deny ip from any to any
01000 nat 1 log logamount 5 ip4 from any to any out via ng0
01000 nat 1 log logamount 5 icmp from any to any out via ng0
01001 allow log logamount 5 ip from any to any
01001 allow log logamount 5 icmp from any to any
01001 allow log logamount 5 ipv6-icmp from any to any
01999 deny log logamount 5 ip from any to any
65535 allow ip from any to any
Im Log sehe ich bei einem "ping www.heise.de" dieses:
Code:
Jul  6 02:10:14 polaris kernel: ipfw: 1000 Nat ICMP:8.0 0.0.0.0 193.99.144.85 out via ng0
Jul  6 02:10:14 polaris syslogd: last message repeated 1 times
Jul  6 02:10:14 polaris kernel: ipfw: 1001 Accept ICMP:8.0 0.0.0.0 193.99.144.85 out via ng0
Jul  6 02:10:15 polaris kernel: ipfw: 1000 Nat ICMP:8.0 0.0.0.0 193.99.144.85 out via ng0
Jul  6 02:10:15 polaris syslogd: last message repeated 1 times
Jul  6 02:10:15 polaris kernel: ipfw: 1001 Accept ICMP:8.0 0.0.0.0 193.99.144.85 out via ng0
Jul  6 02:10:16 polaris kernel: ipfw: 1000 Nat ICMP:8.0 0.0.0.0 193.99.144.85 out via ng0
Jul  6 02:10:16 polaris syslogd: last message repeated 1 times
Jul  6 02:10:16 polaris kernel: ipfw: 1001 Accept ICMP:8.0 0.0.0.0 193.99.144.85 out via ng0
Jul  6 02:10:17 polaris kernel: ipfw: 1000 Nat ICMP:8.0 0.0.0.0 193.99.144.85 out via ng0
Jul  6 02:10:17 polaris syslogd: last message repeated 1 times
Jul  6 02:10:17 polaris kernel: ipfw: 1001 Accept ICMP:8.0 0.0.0.0 193.99.144.85 out via ng0
Jul  6 02:10:18 polaris kernel: ipfw: 1000 Nat ICMP:8.0 0.0.0.0 193.99.144.85 out via ng0
Jul  6 02:10:18 polaris kernel: ipfw: limit 5 reached on entry 1000
Jul  6 02:10:18 polaris kernel: ipfw: 1000 Nat ICMP:8.0 0.0.0.0 193.99.144.85 out via ng0
Jul  6 02:10:18 polaris kernel: ipfw: limit 5 reached on entry 1000
Jul  6 02:10:18 polaris kernel: ipfw: 1001 Accept ICMP:8.0 0.0.0.0 193.99.144.85 out via ng0
Jul  6 02:10:18 polaris kernel: ipfw: limit 5 reached on entry 1001
Also, die NAT Regel 1000 scheint zu greifen, die Regel 1001 lässt das Paket durch, aber der ping (oder wget oder was auch immer) funktioniert nicht. Stutzig macht mich die 0.0.0.0 Adresse im Log, nach meinem Verständnis sollte dort die öffentliche IP stehen?

Bin jetzt am Ende meiner Weisheit. Warum kann der Server selbst nicht ins ipv4 Internet? Liegt es wirklich am NAT, oder an was anderem?

Was ich schon probiert habe: Forwarding aktiviert, statt dem Interface die öffentliche ipv4 in den ipfw NAT Regeln verwendet, nix gebracht... Auch ein Test mit den vordefinierten Regelsätzen von IPFW (glaube es waren "Simple" und "Client") hat nicht funktioniert.

Wäre dankbar für Hilfe, auch wenn's etwas speziell ist und viel Code...

Grüße,

Robert
 
Zuletzt bearbeitet:

Rosendoktor

Well-Known Member
Hat sich erledigt...

Hab kurz nach dem Erstellen des Postings herausgefunden, dass der mpd5 selbst NAT für sein Interface machen kann, man muss es nur in der Konfiguraton einschalten. Wenn ich das mache und den ganzen NAT Krempel aus dem IPFW Skript entferne funtioniert auf den ersten Blick alles wie es soll. :rolleyes:

Hoffe es hat sich noch keiner durch den ganzen Code gewühlt... ;)
 

mr44er

moderater Moderator
Teammitglied
Ich hab zwar nach ng0 an mpd5 gedacht, aber nichts davon gelesen und daher hab ich das mal mit in den Threadtitel rein. ;)
 
Oben