Port Forwarding will nicht

bitmuncher

Senior-Nerd
Ausgangssituation

- 1x Gateway-Server (eth0:externe IP, eth1 und eth2: 192.168.0.2 und 192.168.0.4)
- mehrfach Irgendein-Server mit SSH (eth0 mit 192.168.0.X-Adresse, Bsp: Server1 mit eth0 192.168.0.11)
- 1x Loadbalancer, an dem alle Rechner hängen, der aber intern nur als Switch fungiert

Ziel:
Die Ports 60XX des Gateway-Servers sollen ein Port-Forwarding zu den Irgendein-Servern machen. So soll z.B. Port 6001 auf dem Gateway-Server zum SSH von 192.168.0.11 führen, Port 6002 auf 192.168.0.12 usw..

Leider geht's mit dieser Regel nicht:

Code:
iptables -A INPUT -p tcp --dport 6001 -j ACCEPT
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 6001 -j DNAT --to 192.168.0.11:22

Obwohl es nach sämtlichen Anleitungen und der Manpage nach funktionieren müsste. Der Loadbalancer mischt sich offenbar nicht ein, wie man einem Traceroute auf dem Gateway entnehmen kann:

Code:
# traceroute 192.168.0.11
traceroute to 192.168.0.11 (192.168.0.11), 30 hops max, 40 byte packets
 1  192.168.0.11 (192.168.0.11)  0.107 ms  0.100 ms  0.094 ms

Die Prerouting-Regel wird offenbar auch korrekt erstellt:

Code:
# iptables --list PREROUTING -t nat -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:6001 to:192.168.0.11:22

Und der Rest der Firewall-Regeln weisst eigentlich auch nichts auf, was das Durchleiten des Ports verhindern könnte.

Code:
# iptables -L -n
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           icmp type 8 
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22 flags:0x3F/0x02 
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:6001 

Chain FORWARD (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Was hab ich übersehen? Jemand eine Idee an welcher Stelle es hängen könnte?
 
Was sagt den der Routingtable des Gatewayservers?
Wo bleiben den die Datenpakete welche von ausserhalb durch das Gateway geschickt werden?
 
Zuletzt bearbeitet:
Der Gateway-Server ist vom Internet aus erreichbar und die anderen Rechner sind vom Gateway-Server aus erreichbar. Mehr sollte für ein Port-Forwarding ja eigentlich nicht notwendig sein. Ich will ja nicht alles routen, sondern nur einen spezifischen Port weiterleiten.

Wo die Pakete abbleiben würde ich auch gern wissen. Scheinbar werden sie vom Gateway geschluckt.
 
Genau das meine ich ja. Wenn die Packete in den Gatewayserver kommen, dann werden sie durch das Prerouting verändert. Der Kernel sieht also andere Packete und er weiss das diese nicht für ihn gedacht sind, aber weiss er auch an wen die gehen sollen? Deswegen frag ich ja auch nach den Routingtabellen und dem verbleib der Packete von wegen Wireshark und so. Ich habe das nämlich so gelöst das ich einmal einträge für die Iptables hatte und dazu noch änderungen im Routingtable. Allerdings war mein vorhaben nicht annähernd so komplex wie deins. mfg sw33t
 
Zuletzt bearbeitet:
Hab auf den Maschinen tcpdump laufen lassen. Die Pakete, die der Gateway weiterleitet, kommen beim Server nicht an. Ein direkter Zugriff vom Gateway auf den Server funktioniert aber problemlos. Die Routing-Tabelle:

Code:
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
X.X.X.96     *               255.255.255.240 U     0      0        0 eth0
192.168.0.0     *               255.255.255.0   U     0      0        0 eth1
default         X.X.X.97     0.0.0.0         UG    0      0        0 eth0

Die X.X.X-Adressen sind Netz-Adresse und Router im Rechenzentrum.
 
Ok so wie ich das sehe werden alle Packete wieder nach eth0 rausgeschickt. Korrigier mich bitte wenn ich falsch liege:

1.Eintrag, wenn du Router oder Netzadresse erreichen willst nimm die
Defaultroute
3.Eintrag nimm Netzadresse oder Router
2.Eintrag wenn du 192.168.0.0/24 erreichen willst,
dann nimm die Defaultroute.
welche 192.168.0.0/24 adressen aber gar nicht kennen sollte.

mfg

sw33t
 
Zuletzt bearbeitet:
Route 2 besagt, dass kein direkter Gateway für dieses Interface festgelegt ist, sofern die Adresse also nicht direkt erreichbar ist, wird's über den Default-Gateway versucht. Soweit ich das verstehe heisst das, dass Pakete zu 192.168.0.0 sowieso über dieses Device geleitet werden. Sonst kämen ja auch die Verbindungen zum Server nicht zustande, wenn ich mich vom Gateway aus via SSH einlogge. Aber selbst wenn ich die Route 2 so abändere:

Code:
192.168.0.0     192.168.0.100   255.255.255.0   UG    0      0        0 eth1

Wenn Anfragen für 192.168.0.0 also immer über eth1 (192.168.0.100) geschickt werden, greift das Port-Forwarding trotzdem nicht.
 
Tja dann bin ich auch am ende mit meinem latein

Ich hab meine Datei von damals mal aufgemacht.

Füge in deine Iptables mal ein:
iptables -t nat -A POSTROUTING -d X.X.X.X/Y -j MASQUERADE -o <device>
iptables -A FORWARD -s X.X.X.X/Y -j ACCEPT
iptables -A FORWARD -d X.X.X.X/Y -j ACCEPT

X.X.X.X/Y ist die Ipadresse samt netzwerkmaske des servers auf welchen geforwarded wird.
 
Zuletzt bearbeitet:
Ich hatte auch bereits zum Testen mal ein komplettes Routing eingefügt, aber auch damit ging nichts:

Code:
        echo 1 > /proc/sys/net/ipv4/ip_forward
        $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
        $IPTABLES -t nat -A POSTROUTING -o eth0 -j MASQUERADE
 
Hallo bitmuncher,

ich habe Dir mal etwas zusammengesucht. Kann es jetzt allerdings nicht selbst testen, dies sollten nach meinem Verständnis nach die Komponenten sein, die reichen müssen.

Code:
EXTERN="eth1"
INTERN="eth0"
DNAT_IP=192.168.0.11      # IP Adresse des CLIENT
TCP_DNAT="6001"           # TCP PORTS


# dicht machen
    iptables -P INPUT  DROP
    iptables -P OUTPUT DROP
    iptables -P FORWARD DROP

# Kommunikation Auf Loopback
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT

# Kommunikation interner Netzwerkkarte
    iptables -A INPUT -i $INTERN -j ACCEPT
    iptables -A OUTPUT -o $INTERN -j ACCEPT

# pakete reinlassen
iptables -A INPUT  -i $EXTERN -p tcp --dport 6001 -j ACCEPT
iptables -A OUTPUT -o $EXTERN -p tcp --sport 6001 -m state --state ESTABLISHED -j ACCEPT

# nat ein
iptables -t nat -A POSTROUTING -o $EXTERN -j MASQUERADE


# dnat auf server
iptables -t nat -A PREROUTING -i $EXTERN -p TCP --dport 6001   -j 
iptables -A FORWARD -i $EXTERN -d $DNAT_IP -p TCP --dport 6001 -j  
iptables -A FORWARD -i $INTERN -s $DNAT_IP -p TCP --sport 6001 -j
 
Macht nichts anderes als die Regeln, die ich eh verwende. Mittlerweile hab ich den SSH von 192.168.0.11 aber wieder auf 22 gelegt. Ändert aber nichts.

Code:
#!/bin/bash

IPTABLES=/sbin/iptables

case "$1" in 
start)
        echo "Setting Firewall..."

        echo "Resetting Rules..."
        $IPTABLES -F
        $IPTABLES -X
        $IPTABLES -t nat -F

        echo "Setting procfs values..."
        # no answer for broadcast pings
        echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
        # keep silent for strange ICMP messages
        echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
        # kick the ip spoofing shit (source validation)
        echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
        # set default ttl to another value than default 64
        echo 61 > /proc/sys/net/ipv4/ip_default_ttl
        # send RST packets if buffer is full
        echo 1 > /proc/sys/net/ipv4/tcp_abort_on_overflow
        # wait max 30s for FIN/ACK
        echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
        # max 3 SYN packets while connection handshake
        echo 3 > /proc/sys/net/ipv4/tcp_syn_retries
        # cancel connection handshake after 3 SYN/ACK packets
        echo 3 > /proc/sys/net/ipv4/tcp_synack_retries

        echo "Setting default rules..."
        $IPTABLES -P INPUT DROP
        $IPTABLES -P FORWARD ACCEPT
        $IPTABLES -P OUTPUT ACCEPT

        $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
        $IPTABLES -A INPUT -i lo -j ACCEPT
        $IPTABLES -A INPUT -i eth1 -j ACCEPT
        $IPTABLES -A INPUT -i eth2 -j ACCEPT

        echo "Minimal routing..."
        echo 1 > /proc/sys/net/ipv4/ip_forward
        $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
        $IPTABLES -t nat -A POSTROUTING -o eth0 -j MASQUERADE

        echo "Accepting pings..."
        $IPTABLES -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

        echo "SSH on Port 22..."
        $IPTABLES -A INPUT -p tcp --dport 22 --tcp-flags ALL SYN -j ACCEPT

        echo "Forwarding for 192.168.0.11..."
        $IPTABLES -A INPUT -p tcp --dport 6001 -j ACCEPT
        $IPTABLES -t nat -A PREROUTING -i eth0 -p tcp --dport 6001 -j DNAT --to 192.168.0.11:22

        ;;
*)
        echo "Usage: `basename $0` {start}" >&2
        exit 64
        ;;
esac

exit 0
 
Ich hab die Forwardings jetzt erstmal auf dem Loadbalancer gemacht. Ist zwar nicht die optimale Lösung, aber vielleicht hat ja irgendwann hier nochmal jemand eine Idee. Sonst versuche ich es zu lösen, wenn ich mal etwas mehr Zeit dafür habe. Danke aber bis hierher für die Vorschläge. Ich denke mittlerweile, dass das Problem darin besteht, dass die Route über den Loadbalancer läuft. Bei Gelegenheit werde ich mal im Switch ein passendes VLAN einstellen und schauen, ob es damit besser geht.
 
Zurück
Oben