Jails mit einer öffentlichen IP + NAT

gadean

Depp vom Dienst!
Guten Morgen,
ich bräuchte mal wieder etwas Hilfe, heute geht es ums NAT (pf) und jails.
Ich möchte in naher Zukunft bei Hetzner einen Server mieten, Erfahrungen mit BSD sind in so weit vorhanden das ich bei mir Daheim seit mehreren Jahren ein Server betreibe und mit dem m.M.n. ganz gut umgehen kann. Jedoch unterscheidet sich das hosten eines Servers im RZ von dem Daheim, ich sitz nicht hinter einer ded. Firewall und habe nicht die Möglichkeit frei IPs zu nutzen, also habe ich mir erst mal ein Plan aufgestellt was ich will und wie ich es konfigurieren. Dazu hab ich mir eine VM erstellt um alles zu testen.
Was nun neu für mich ist, ist PF (fürs NAT) und das binden der Jails auf ein geklontes Interface ( cloned_interfaces="lo1" ).

Ziel ist das die Jails über jail0 untereinander kommunizieren können und über eth0 nach draußen ge-nat-et werden bzw. eingehende Anfragen auf die entsprechende Jail. Dazu hab ich folgende configs.

/etc/rc.conf
Code:
#...
## Network
gateway_enable="YES"
gateway_if="eth0"
gateway_ip="192.168.178.1"
ifconfig_em0_name="eth0"
ifconfig_eth0="inet 192.168.178.140 netmask 255.255.255.0"
static_routes="gateway default"
route_gateway="-host $gateway_ip -interface $gateway_if"
route_default="default $gateway_ip"
# Jail-Network
cloned_interfaces="lo1"
ifconfig_lo1_name="jail0"
ifconfig_jail0="inet 10.0.0.1 netmask 255.255.255.0"
ifconfig_jail0_aliases="inet 10.0.0.2 netmask 255.255.255.0"

#...

/etc/jail.conf
Code:
# Startscript (sleep 1 second to prevent races)
exec.start="sleep 1";
exec.start+="/bin/sh /etc/rc";
# Shutdownscript
exec.stop = "/bin/sh /etc/rc.shutdown";
# Execute in a clean environment
exec.clean;
# Devfs
mount.devfs;
# Jail ruleset by default
devfs_ruleset=4;
path = "/tank/jails/$name";

# test1
test1 {
  host.hostname = "test1.local";
  ip4.addr = "10.0.0.2";
}

/etc/pf.conf
Code:
if_ext = "{ eth0 }"
if_int = "{ jail0 }"

table <rfc1918> persist { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/5 }

icmp_types = "echoreq"
open_tcp = "{ 2142, 2143 }"
open_udp = "{ ntp }"
jails = "{ 10.0.0.1, 10.0.0.2 }"
ip = 192.168.178.140
www = 10.0.0.2

set block-policy drop
set skip on lo0
set loginterface eth0
set optimization normal
set require-order yes
set fingerprints "/etc/pf.os"
set ruleset-optimization basic

scrub in all fragment reassemble random-id

rdr on $if_ext proto tcp from any to $if_int port { 2143 } -> $www # wird im Text unten erwähnt

nat on $if_ext proto {tcp udp icmp} from $jails to any -> $ip

block log all
block return
block in quick on $if_ext inet from <rfc1918> to any
antispoof quick for $if_ext

pass in on $if_ext proto tcp from any to any port $open_tcp keep state
pass in on $if_ext proto udp from any to any port $open_udp keep state
pass out quick all keep state
pass in on $if_ext inet proto icmp all icmp-type $icmp_types keep state
pass in on $if_ext inet proto udp from any to any port 33433 >< 33626 keep state
Die Regeln funktionieren so nicht richtig, ich komm zwar von der Jail ins Netz, jedoch nicht auf die Jail per ssh (egal von wo - Port: 2143), ändere ich in der markierten Zeile "$if_int" zu "$if_ext" komm ich von außen (andere PCs - nicht vom Host) in die Jail (was ich nicht nachvollziehen kann, die Jails laufen doch übers if "jail0"). Was jedoch gar nicht funktioniert ist die interne Kommunikation (vom Host (10.0.0.1) zur Jail (10.0.0.2:2143) wird geblockt).

Und in der Jail sieht die Ausgabe von "ifconfig" m.M.n. merkwürdig aus:
Code:
eth0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
        ether 00:50:56:29:84:95
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
jail0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
        inet 10.0.0.2 netmask 0xffffff00

Könntet Ihr mich evtl. erleuchten? Ist das vorgehen so überhaupt üblich oder würdet ihr das anders lösen? Und wie müssten die Regeln ausschauen damit folgendes funktioniert:
Code:
host = 192.168.178.140 / 10.0.0.1
jail1 = 10.0.0.2
jail2 = 10.0.0.3

# "host der die verbindung aufbaut" -> "ziel host":"ziel port"
externe Anfrage -> host:2142
externe Anfrage -> jail1:2143
externe Anfrage -> jail2:2144
host -> jail1:2143 (nur übers interne if)
jail1 -> jail2:2144 (nur übers interne if)
# usw.

Liebe Grüße
 
Hm kann meinen Beitrag nicht mehr editieren :-/
Nunja, bin etwas weiter, zu der "merkwürdigen" Ausgabe von "ifconfig" in der Jail habe ich ein Post von Yamagi gefunden (jail.conf Aequivalent (multiple Interfaces)) der das erklärt.
Zur Kommunikation der Jails untereinander: es lies sich mit einen "set skip on jail0" lösen, jedoch ist mir die Reichweite davon noch nicht ganz bewusst, öffne ich mir damit ungewollt die FW oder beschränkt sich das nur auf die interne Kommunikation?

Zur Konfiguration der Jail:
in der jail.conf habe ich ein "interface="jail0";" vergessen.
 
Hallo,

Das Setup ist meiner Meinung nach vollkommen ok. Ich verwende fast die gleiche Konfig.
ich komm zwar von der Jail ins Netz, jedoch nicht auf die Jail per ssh (egal von wo - Port: 2143),
Hier mal ein Auszug meiner PF Konfiguration:
Code:
wan = "re0"
jail = "lo1"

jail_base = "10.0.0.1"
$jail_db = "10.0.0.3"

jail_base_rdr_ssh = "11022"
jail_db_rdr_ssh = "13022"

# NAT/RDR JAIL
nat on $wan proto {tcp icmp} from $jail_base to any -> $wan
rdr on $wan proto tcp from any to $wan port $jail_base_rdr_ssh -> $jail_base port 22

# WAN TO JAIL
pass in log quick on $wan proto tcp from <T_SSH_ALLOWED> to $jail_base port 22

# JAIL TO JAIL
pass in quick on $jail proto tcp from $jail_base to $jail_db port 3306

Gruss
 
So ich glaub nu hab ich es etwas mehr verstanden, die im #1 Post erwähnte Zeile habe ich einfach falsch verstanden :D

Das hier wäre meine überarbeitete pf.conf
Code:
wan = "eth0"
jail = "jail0"

table <rfc1918> persist { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/5 }

icmp_types = "echoreq"
jails = "{ 10.0.0.1, 10.0.0.2 }"
ext_ip = "192.168.178.140"
host = "10.0.0.1"
test1 = "10.0.0.2"

set block-policy drop
set skip on lo0
set loginterface $wan
set optimization normal
set require-order yes
set fingerprints "/etc/pf.os"
set ruleset-optimization basic

scrub in all fragment reassemble random-id

# NAT/RDR
nat on $wan proto {tcp udp icmp} from $jails to any -> $ext_ip
rdr on $wan proto tcp from any to $wan port { 2142 } -> $host
rdr on $wan proto tcp from any to $wan port { 2143 } -> $test1

block log all
block return
block in quick on $wan inet from <rfc1918> to any
antispoof quick for $wan

# JAIL
pass in quick on $jail proto tcp from $jails to $host port 2142
pass in quick on $jail proto tcp from $jails to $test1 port 2143

# WAN
pass in on $wan proto tcp from any to $host port 2142 keep state
pass in on $wan proto tcp from any to $test1 port 2143 keep state
pass in on $wan inet proto icmp all icmp-type $icmp_types keep state
block out on $wan proto { icmp } from $jails to any
pass out quick all keep state

Kann man die so lassen? Besonders in hinblick auf folgenden Thread: Jails bei Hetzner
Dafür hab ich die vorletzte Zeile eingefügt die alle ausgehenden icmp Pakete aus dem Jailnetz deren Adresse nicht umgeschrieben wurde zu blockieren.
 
Entschuldigt das ich das Thema schon wieder nach oben hole (evtl. könnte man die Zeitspanne fürs editieren anpassen?).
Ich hab mir noch etwas das Manual zu PF durchgelesen, bei den letzten 4 Regeln fehlt m.M.n. das "quick", da soweit ich das verstanden habe immer die letzte zutreffende Regel gewinnt?
Code:
# WAN
pass in quick on $wan proto tcp from any to $host port 2142 keep state
pass in quick on $wan proto tcp from any to $test1 port 2143 keep state
pass in quick on $wan inet proto icmp all icmp-type $icmp_types keep state
block return out quick on $wan proto { icmp } from $jails to any
pass out quick all keep state
Das "keep state" könnte ich eigentlich streichen, da es lt. Manual default ist?
Bei der vorletzten Regel wäre es noch geschickt "tcp" & "upd" hinzuzufügen, um alle ausgehende Pakete mit IPs aus $jails zu blockieren? Oder wäre die bessere Methode folgende Regel
Code:
block return out quick on $wan proto { tcp udp icmp } from ! $ext_ip to any

Um zb. den Zugriff auf einen Service der auf Port 8080 lauscht nur von der IP "192.168.178.10" zu erlauben wäre die folgende Regel
Code:
block return in quick on $wan proto tcp from ! 192.168.178.10 to $wan port 8080

Das "return" bei "block" sorgt dafür das die geblockten Verbindungen richtig geschlossen werden (wird mit TCP-RST quittiert).
---
Habe ich das alles soweit jetzt richtig verstanden oder liege ich mit den Aussagen falsch?

Liebe Grüße
 
Ich mache es immer so:
Code:
<INTERFACES definieren>

<IP ADRESSEN definieren>

<PORTS definieren>

<TABELLEN definieren>

set skip on lo0
scrub in on ...

<NAT definieren>
<RDR definieren>

block in
pass out

<PASS Regeln definieren>

Das "quick" bedeutet, dass der Durchlauf bei er ersten passenden Regel beendet wird und er nicht noch weiter durch den Regelsatz läuft.
 
Hi,
schon wieder ich der das Thema nach oben holt :/ hab noch ein klein wenig an den Regeln gearbeitet und stehe nun vor dem nächsten Problem. Ziel ist vom Host/von einer Jail/einem VPN Client übers externe Interface auf ein andere Jail zuzugreifen (DNS zeigt auf die externe IP). Unter dem Begriff "pf nat loopback" hab ich u.a. diese Seite gefunden, jedoch konnte ich die Regel nicht übertragen, auch habe ich folgenden Post gefunden, jedoch funktionierte auch diese Regel nicht. Nach einigen Dutzend Versuchen/Fehlschlägen bin ich nun wieder hier und hoffe ihr könnt mir helfen.
"Split-Horizon DNS" ist mir mit zu viel Aufwand verbunden (ein weiterer Service der gepflegt werden möchte etc.). Hier noch eine aktuelle pf.conf
Code:
ext_if = "eth0"
int_if = "jail0"

table <rfc1918> persist { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/5 }

icmp_types = "echoreq"
jails = "{ 10.0.0.1, 10.0.0.2, 10.0.0.3, 10.0.0.4, 10.0.0.5, 10.0.0.6, 10.0.0.7 }"
ext_ip = "192.168.178.140"
host = "10.0.0.1"
ts3 = "10.0.0.2"
httpd = "10.0.0.3"
svn = "10.0.0.4"
samba = "10.0.0.5"
converter = "10.0.0.6"
playground = "10.0.0.7"

set block-policy drop
set skip on lo0
set loginterface $ext_if
set optimization normal
set require-order yes
set fingerprints "/etc/pf.os"
set ruleset-optimization basic

scrub in all fragment reassemble random-id

# NAT/RDR
nat on $ext_if proto {tcp udp icmp} from $jails to any -> $ext_ip
rdr on $ext_if proto tcp from any to $ext_if port { 2142 } -> $host
rdr on $ext_if proto tcp from any to $ext_if port { 80 443 2143 } -> $httpd

block log all
block return
block in quick on $ext_if inet from <rfc1918> to any
block return out quick on $ext_if proto { tcp udp icmp } from ! $ext_ip to any
antispoof quick for $ext_if

# nat loopback?
#pass in quick on $int_if route-to ($ext_if $ext_ip) from any to $ext_ip keep state

# JAIL 2 JAIL
pass in quick on $int_if proto tcp from $jails to $host port { 2142 }
pass in quick on $int_if proto tcp from $jails to $httpd port { 80 443 2142 }

# WAN 2 JAIL
pass in quick on $ext_if proto tcp from any to $host port { 2142 } keep state
pass in quick on $ext_if proto tcp from any to $httpd port { 80 443 2143 } keep state
pass in quick on $ext_if inet proto icmp all icmp-type $icmp_types keep state
pass out quick all keep state
 
Zurück
Oben