Ghost in my Router (pf-Probleme für Paranoide)

Josen

UNIX-Enthusiast
Hallo BSDForen-Leser,
seit einigen Tagen plage ich mich nun bereits mit dem "sexiest Packetfilter alive" (pf) herrum.

Einfach und genial die Möglichkeiten, die er mir bietet, angefangen bei synproxy bis steateful filtering von UDP.



Mein Netzwerk ist so aufgebaut:

Internet #1 (tun0): --> Internet
Internet #2 (noch nicht da): --> Internet
Server-Netzwerk (fxp0): --> Server Netzwerk
User-Netzwerk (fxp1): --> User-Netzwerk

Mein Ruleset soll den Zugang der User/Server und der Benutzer aus dem Internet regeln.

Leider funktioniert mein Router nicht so, wie er eigentlich sollte. Hier eine aktuelle Routing-Table:

<--SNIP-->
Routing tables

Internet:
Destination Gateway Flags
default dsl-gate.kamp.net UG
127.0.0.0 localhost UG
localhost localhost UH
172.16.0.0 link#3 U
172.16.1.0 link#4 U
172.16.1.20 0:d:61:58:6e:ab UH
172.16.1.200 0:a:95:f2:d3:49 UH
172.16.1.254 0:e:c:50:bf:4c UH
dsl-gate.kamp.ne reverse-213-146-11 UH
BASE-ADDRESS.MCA localhost U
<--SNAP-->

Vom Router aus scheint die Routing-Table zu funktionieren. Ich konnte alle getesteten Hosts außerhalb meines Provider-Netzes erreichen (web.de, sex.de, bsdforen.de, spamhaus.org).

Ebeneso ist IP-Forwarding ("net.inet.ip.forwarding=1") aktiviert, daran sollte es also nicht liegen.


Hier nun mein erster (komplexerer) Versuch für ein pf-Ruleset:
(Bei Bedarf kann ich auch noch die ca. 4 noch längeren Versuche der letzten Tage posten)


Code:
server_if="fxp0"
server_ip="172.16.0.254"
server_subnet="172.16.0.0/24"

user_if="fxp1"
user_ip="172.16.1.254"
user_subnet="172.16.1.0/24"

inet1_if="tun0"
inet1_ip="213.146.116.123"


www_ports = "{www, https}"
proxy_ports = "{3128, 8080}"
server_ports = "{www, https, 3128, 8080, ssh, ftp, smtp, pop3, imap, domain}"






# Block Policy Regeln
set block-policy return

# Das Interface zum loggen bestimmter Pakete
set loginterface pflog0

# Optimierung: Inaktive Verbindungen bleiben
set optimization conservative

# Traffic wird immer Normalisiert
scrub all no-df random-id fragment reassemble



#------------------------------------------------------------------------------#
# Regeln fuer NAT (Network Address Translation) auf inet1

# Nat fuer alle User/Server
nat on $inet1_if from {$server_subnet, $user_subnet} to any -> ($inet1_if)


#------------------------------------------------------------------------------#
# Port-Redirection Regeln

# Transparenter FTP-,WWW-,HTTPS-Proxy fuer Server-Subnetz
rdr on $server_if proto tcp from $server_subnet to any port {ftp,www,https} -> server_ip port 8080
rdr on $user_if proto tcp from $user_subnet to any port {ftp,www,https} -> user_ip port 8080 

#------------------------------------------------------------------------------#
# Regeln fuer Packetfiltering allgemein

# Default Deny Policy
block all


#------------------------------------------------------------------------------#
## Regeln fuer das Internet #1 (via tun0)

# --> Dienste des Routers die genutzt werden duerfen
# Nameserver (djbdns) - TCP/UDP
pass in quick on $inet1_if proto {tcp,udp} from any to any port domain keep state

# Webserver via HTTP/HTTPS (apache) - TCP
pass in quick on $inet1_if proto tcp from any to any port $www_ports keep state

# Mailserver via SMTP (qmail) - TCP
pass in quick on $inet1_if proto tcp from any to any port smtp keep state

# --> Dienste des Internets die genutzt werden duerfen durch User (fxp1)
# Webserver sind erlaubt
# SSH ist erlaubt
# FTP ist erlaubt
# SMTP ist erlaubt
pass out quick on $inet1_if proto tcp from $user_if port $server_ports keep state
pass out quick on $inet1_if proto {tcp, udp} from $user_if port domain keep state


# --> Dienste des Internets die genutzt werden duerfen durch Server (fxp0)
# Alles ist erlaubt
pass out quick on $inet1_if from $server_subnet keep state

pass out on $inet1_if proto tcp all modulate state flags S/SA
pass out on $inet1_if proto {udp, icmp} all keep state



#------------------------------------------------------------------------------#
# Regeln fuer das Loopback-Device (via lo0)
# Loopback ist immer erlaubt
pass quick on lo0 all



#------------------------------------------------------------------------------#
# Regeln fuer das Server-Netzwerk (via fxp0)

# IP-Spoofing verhindern
antispoof log for $server_if

# --> Dienste der Server die genutzt werden duerfen
# Webserver sind erlaubt
# SSH ist erlaubt
# FTP ist erlaubt
# SMTP ist erlaubt
# Proxy ist erlaubt
pass out on $server_if proto tcp from any to any port $server_ports synproxy state


# --> Dienste des Routers die genutzt werden duerfen
# Webserver ist erlaubt
# SSH ist erlaubt
# FTP ist erlaubt
# SMTP ist erlaubt
pass in on $server_if proto tcp from $server_subnet to $server_ip port $server_ports





#------------------------------------------------------------------------------#
# Regeln fuer das User-Netzwerk (via fxp1)

# Debugging: Alles durchlassenpass quick on $user_if all
#pass quick on $user_if from any to any

# --> Dienste des uebrigen Netzes die genutzt werden duerfen
# Webserver sind erlaubt
# SSH ist erlaubt
# FTP ist erlaubt
# SMTP ist erlaubt
pass out on $user_if proto tcp from $user_subnet modulate state flags S/SA
pass out on $user_if proto {icmp,udp} from $user_subnet keep state

# --> Dienste des Routers die genutzt werden duerfen
# SSH ist erlaubt
# Webserver ist erlaubt
pass in quick log on $user_if proto tcp from $user_subnet to $user_subnet port ssh keep state
pass in quick on $user_if proto tcp from $user_subnet to $user_subnet port $server_ports keep state
pass in quick on $user_if proto {tcp, udp} from $user_subnet to $user_subnet port domain keep state


Ich denke, dass ich einen ganz grundsätzlichen Denkfehler gemacht habe, komme jedoch nicht darauf, welchen.

Aus Sicht der Netzwerkkarten ist einkommender Traffic der, der vom Netzwerk in den Router kommt und ausgehender der, der vom Router nach draußen ins Netzwerk gesendet wird.

Aber was ist, wenn Traffic auf einem Interface hineinkommt, aber auf einem anderen (Internet) wieder herrauskommt? Wird er dann über das erste Interface (out) zum zweiten (in) gesendet oder kommt er nur auf dem einen an, wird verarbeitet (ohne in/out) und passiert auf dem zweiten hinaus?


Danke im Vorraus für eure Hinweise,
Falk
 
Hi,

also was das In / Out auf zwei verschiedenen Interfaces angeht kann man sich das recht einfach vorstellen: Es geht quasi immer um den Absender und an wen das Paket geht. Wenn du also eine Out Regel auf einem Interface machst, dann ist deine Sicht schon richtig. Nur Pakete die der Rechner darüber rausschickt passen zu der Regel, genau wie eine In Regel nur auf Pakete zutrifft, die zu dem Rechner geschickt werden.

Also nachdem das Paket über das erste Interface reingekommen ist, verlässt es das zweite nach draussen. Beim ersten Interface handelt es sich also um "In", bei dem zweiten über "out".

Gruß, I.MC
 
Zuletzt bearbeitet:
INTERNET (in) ---> COMPUTER ---> SERVER-NETZ (out)


und nicht


INTERNET (in) ---> SERVER-NETZ (in) Computer SERVER-NETZ (out)


Gut, dann mach ich mich mal an die 5. Version der Rules. Wenigstens wird pf-Rulesets schreiben nicht langweilig.


Brauch noch jemand ein Ruleset? Stehe zur Verfügung!



-Falk
 
Was mir gerade aufgefallen ist:

Warum kann ich kein Makro zusammen mit einer Port-Angabe in eine Rule einbauen?
Durch die Expansion des Makros entsteht doch eine vollkommen legitime Regel für pf. Ich dachte an sowas:


Code:
pass in on $user_if proto tcp from $user_subnet to $user_ip port {$server_ports, pptp} keep state


Sehr lustig. Wenn ich den Port aber mit in das Makro aufnehme, dann wird die Regel richtig expandiert. Komisch, sehr komisch.


-Falk
 
Herrlich herrlich herrlich. Ich kanns ja doch nicht lassen. Hier also mein funktionierendes Ruleset:

Code:
#### S E R V E R ####
server_if="fxp0"
server_ip="172.16.0.254"
server_subnet="172.16.0.0/24"
#### U S E R ####
user_if="fxp1"
user_ip="172.16.1.254"
user_subnet="172.16.1.0/24"
#### I N T E R N E T #1 ####
inet1_if="tun0"
inet1_ip="213.146.116.123"
#### N E T Z W E R K ####
www_ports = "{www, https}"
proxy_ports = "{8080}"
server_ports = "{www, https, 3128, 8080, ssh, ftp, smtp, pop3, imap, pptp}"
rfc1918 = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"



#### PF - O P T I O N S ####
# Block Policy Regeln
set block-policy return
# Das Interface zum loggen bestimmter Pakete
set loginterface pflog0
# Optimierung: Inaktive Verbindungen bleiben
set optimization conservative
# Traffic wird immer Normalisiert
scrub all no-df random-id fragment reassemble



#### N A T ####
# Nat fuer alle User/Server
nat on $inet1_if from {$user_subnet, $server_subnet} to any -> ($inet1_if)

#### R E D I R E C T I O N ####
# Transparenter FTP-,WWW-,HTTPS-Proxy fuer Server-Subnetz
rdr on $server_if proto tcp from $server_subnet to any port {ftp,www,https} -> $server_ip port 8080
rdr on $user_if proto tcp from $user_subnet to any port {ftp,www,https} -> $user_ip port 8080


#### P A C K E T F I L T E R I N G ####
# Default Deny Policy
block all


## A N T I RFC1918 R U L E S ##
block drop in quick on $inet1_if from $rfc1918 to any
block drop out quick on $inet1_if from any to $rfc1918
















## Internet
# --> Dienste des Routers die genutzt werden duerfen
# Nameserver (djbdns) - TCP/UDP
pass in quick on $inet1_if proto {tcp,udp} from any to any port domain keep state

# Webserver via HTTP/HTTPS (apache) - TCP
pass in on $inet1_if proto tcp from any to any port $www_ports keep state

# Mailserver via SMTP (qmail) - TCP
pass in quick on $inet1_if proto tcp from any to any port smtp keep state

# Alles darf raus, nachdem es mit NAT bearbeitet wurde
pass out on $inet1_if from $inet1_ip keep state


# ICMPv6 beantworten wegen IPv6-Tunnel!
pass in quick proto icmp6 from any keep state



## User
# Traffic der User darf alles, nur nicht auf dem Router
pass in quick on $user_if from $user_subnet to !$user_ip keep state
pass out quick on $user_if from $user_subnet keep state

# Der Router aus Sicht der User
pass in on $user_if proto tcp from $user_subnet to $user_ip port $server_ports keep state
pass in on $user_if proto {tcp, udp} from $user_subnet to $user_ip port domain keep state
pass in on $user_if proto icmp from $user_subnet to $user_ip keep state



## Server
# Traffic der Server darf alles, nur nicht auf dem Router
pass in on $server_if from $server_subnet to !$user_ip keep state
pass out on $server_if proto {tcp,udp} from any to $server_subnet port $server_ports synproxy state
pass out on $server_if proto icmp from {$user_subnet, $server_ip} to $server_subnet keep state

# Der Router aus Sicht der Server
pass in on $server_if proto tcp from $server_subnet to $server_ip port $server_ports keep state
pass in on $server_if proto {tcp, udp} from $server_subnet to $server_ip port domain keep state
pass in on $server_if proto icmp from $server_subnet to $server_ip keep state


-Falk
 
Zurück
Oben