OpenBSD 5.3 - pf: Probleme bei Port Redirection/Port Forwarding

Morfio

Well-Known Member
Hallo zusammen,

ich möchte testweise SSH von über unsere Firewall von außen zu einem internen Server weiterleiten und stehe ein wenig auf dem Schlauch: Es funktioniert nicht. Hier die pf.conf:

Code:
# Variables
int_if   = "em1"
ext_if   = "em2"
localnet = $int_if:network

# Skip interfaces
set skip on lo

# NAT
pass out quick on $int_if
pass out on $ext_if from $localnet to any nat-to ($ext_if)

# Main rules
block in on $ext_if
block return in on $int_if

# SSH
pass inet proto tcp from 192.168.0.200 to $int_if port ssh

# Test
pass in quick log inet proto tcp from any to any port 2222 rdr-to 192.168.0.17 port 22

tcpdump sagt folgendes:

Code:
May 07 11:45:17.672725 xxx.xxx.xxx.xxx.22906 > 192.168.0.17.22: S 477158121:477158121(0) win 65535 <mss 1460,nop,wscale 6,sackOK,timestamp 2714574778 0> (DF)

Hat vielleicht jemand eine Idee? Ich ackere zwar gerade "The Book of PF" und "OpenBSD" vom C&L-Verlag durch sowie das Internet, aber irgendwie komme ich nicht auf die Lösung.

Viele Grüße

Morfio
 
Welche OpenBSD Version nutzt Du denn?

Fuer NAT solltest Du folgende Regel nutzen:

Code:
match out on $ext_if from $localnet nat-to ($ext_if:0)
 
hi

du musst rdr-to nutzen.

z.b.

match in wan_if inet proto tcp from any to (wan_if) port 22 rdr-to 192.168.0.200 port 22


holger
 
Welche OpenBSD Version nutzt Du denn?

Fuer NAT solltest Du folgende Regel nutzen:

Code:
match out on $ext_if from $localnet nat-to ($ext_if:0)

Benutze ich das, funktioniert NAT überhaupt nicht bei mir. Steht zwar auch in allen Beispielen so, bei mir passiert da aber nichts.

@mark05

Ich nutze doch rdr-to (letzte Zeile). Ich habe es jetzt mit deinem String versucht (wan_if durch $ext_if ersetzt und hinter match in noch ein on gemacht), funktioniert aber ebenfalls nicht.
 
Da ist irgendwie alles durcheinander, quick und non-quick rules, rules mit und ohne interface.

Ich empfehle, dich auf einen Stil festzulegen. Bei mir ist das 1) "quick" bei jeder rule 2) jede rule bezeichnet ein interface und state-policy steht auf if-bound.

Desweiteren: mache eine default block rule mit logging und lass überall sonst das logging weg. Bis auf einige Spezialsachen interessiert nämlich immer, was hängenbleibt, nicht was durchkommt.

Edit: geht das?

Code:
# Variables
int_if   = "em1"
ext_if   = "em2"

# Skip interfaces
set block-policy drop
set loginterface $ext_if
set skip on lo
set state-policy if-bound

# $ext_if
pass out quick on $ext_if nat-to ($ext_if) tagged NAT
pass  in quick on $ext_if inet proto tcp to ($ext_if) port 2222 rdr-to 192.168.0.17 port 22 tag RDR

# $int_if
pass out quick on $int_if tagged RDR
pass out quick on $int_if                from ($int_if)
pass  in quick on $int_if inet proto tcp from 192.168.0.200 to ($int_if) port 22
pass  in quick on $int_if inet           from ($int_if:network) tag NAT

# fallback
block return log quick

Ich nutze gern und häufig tags im Zusammenhang mit state-policy if-bound, weil man damit bei mehreren interfaces immer noch einen doppelten Check hat, dass das, was man reinlässt, auch tatsächlich auf dem interface rausdarf, wo es durch die Route rauswill. Vorteil: du siehst in der config direkt und ohne Seiteneffekte, was auf dem Interface abgehen darf. Was da nicht steht, findet auf dem Interface nicht statt, ganz einfach. Nachteil: doppelte states.

So, genug editiert.
 
Zuletzt bearbeitet:
Ich habe es mal überarbeitet. Die SSH-Regel benötige ich nur, damit ich auf der Kiste momentan herumbasteln kann.

NAT funktioniert so aber nicht und das Portforwarding auch nicht:

Code:
int_if   = "em1"
ext_if   = "em2"
localnet = $int_if:network

# Skip interfaces
set skip on lo

# NAT
match out log on $ext_if from $localnet nat-to ($ext_if:0)

# Main rules
block all 

# SSH
pass inet proto tcp from 192.168.0.200 to $int_if port ssh 

# Redirecting
match in quick on $ext_if inet proto tcp from any to ($ext_if) port 22 rdr-to 192.168.0.200 port 22
 
match ist kein pass. Im Moment erlaubst du _nur_ ssh von .200.

Edit: Wie geht denn NAT? Das wird doch nirgends erlaubt? Vielleicht noch rumlungernde states? Mach mal pfctl -F states und fang somit from scratch an.
 
Wie sieht der state aus, wenn du es versuchst? Ich kann mich in state-policy floating nur schwer reindenken.

"from any" kannst du weglassen.
 
Auf .200 ist auch ein sshd erreichbar? Ich wüsste nicht mal, ob der state mit dem rdr überhaupt auf int_if gilt. :)
 
Ja, allerdings nicht von der Firewall aus:

root@hellboy:/root: ssh 192.168.0.17
ssh: connect to host 192.168.0.17 port 22: No route to host
 
Dann geht auch ssh von aussen auf die Firewall.

Wie gesagt, mach das log an die block rule und schau, was hängenbleibt, wenn etwas nicht geht. Davon kann man nämlich meist besser die nächsten Überlegungen ableiten.
 
Ist halt die Frage, ob das gewollt ist. Als Kontrollfreak in Sachen pf würde ich mir keine Sachen aufreißen wollen, die ich nicht beabsichtigt hab. Heißt: default block und jede pass rule so spezifisch wie möglich.
 
Nein, auf der Firewall sollte man nicht landen. Ich arbeite testweise am Forwarding, damit im Falle eines Falles mein Kollege mich mal freischalten kann, so dass ich von außen kurz ins Netz komme.
 
Nein, auf der Firewall sollte man nicht landen. Ich arbeite testweise am Forwarding, damit im Falle eines Falles mein Kollege mich mal freischalten kann, so dass ich von außen kurz ins Netz komme.

anchors

Code:
# Variables
int_if   = "em1"
ext_if   = "em2"

# Skip interfaces
set block-policy drop
set loginterface $ext_if
set skip on lo
set state-policy if-bound

# $ext_if
pass out quick on $ext_if nat-to ($ext_if) tagged NAT
pass  in quick on $ext_if inet proto tcp to ($ext_if) port 2222 rdr-to 192.168.0.17 port 22 tag RDR
anchor "ssh_in" in quick on $ext_if inet proto tcp to ($ext_if) port 22

# $int_if
pass out quick on $int_if tagged RDR
pass out quick on $int_if                from ($int_if)
pass  in quick on $int_if inet proto tcp from 192.168.0.200 to ($int_if) port 22
pass  in quick on $int_if inet           from ($int_if:network) tag NAT

# fallback
block return log quick

Freischalten mit
Code:
echo "pass" | pfctl -a ssh_in -f -
blocken mit
Code:
pfctl -a ssh_in -F rules

Edit: Achso, "ins Netz". Das Beispiel oben war jetzt für Zugriff von außen auf die Firewall. rdr-to "sollte" aber auch bei nem anchor gehen, hab ich noch nicht probiert.
 
Zuletzt bearbeitet:
Danke, genau so brauchte ich das (von der Funktion). Jetzt muss ich es noch auseinandernehmen und nachlesen.
 
hi

gemaess deiner letzen regeln die du gepostet hast machst du ein block all auf allen
interfaces


damit must du natuerlich auch ein internen traffic "ver"regeln.

alternativ wuerde ich erstmal nur das ext_if ein block machen incl log

also

block log on $ext_if


damit kannst du mit
tcpdump -e -vvv -n -i pflog0 sehen was wo gelblockt wird.

interner traffic ist dann nicht betroffen

holger
 
Zurück
Oben