Netzwerkkonfiguration für Jail

Sickboy

Müßiggänger
Hallo,

ich habe das Problem, dass ich netzwerktechnisch nicht wirklich aus meiner Jail herauskomme. Irgendwie stehe ich da gerade auf dem Schlauch.

ifconfig:
Code:
bce0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=c01bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,VLAN_HWTSO,LINKSTATE>
        ether 00:1e:0b:c7:3e:40
        inet 192.168.3.33 netmask 0xffffff00 broadcast 192.168.3.255 
        inet 10.1.1.1 netmask 0xffffffff broadcast 10.1.1.1 
        inet 10.1.1.2 netmask 0xffffffff broadcast 10.1.1.2 
        inet 10.1.1.3 netmask 0xffffffff broadcast 10.1.1.3 
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active

/etc/jail.conf:
Code:
exec.start="/bin/sh /etc/rc";
exec.stop="/bin/sh /etc/rc.shutdown";
exec.clean;
mount.devfs;
interface="bce0";

path = "/usr/storage/jails/$name";

www {
    host.hostname = "www.example.com";
    ip4.addr = "10.1.1.1";
    allow.raw_sockets = 1;
}

ifconfig der Jail:
Code:
bce0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=c01bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,VLAN_HWTSO,LINKSTATE>
        ether 00:1e:0b:c7:3e:40
        inet 10.1.1.1 netmask 0xffffffff broadcast 10.1.1.1 
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active

Innerhalb der Jail kann ich auf die Host-IP (192.168.3.33 und alle Aliase) pingen, ins WAN reingepingt kommt nichts zurück. Auf dem Host geht das problemlos. Die /etc/resolv.conf der Jail ist identisch mit der des Hosts.

Ich frage mich jetzt, ob das ein Konfigurationsfehler meinerseits ist oder ob das an der Einstellung der HW-Firewall liegt, an dem der Host hängt (DMZ).
 
Der Denkfehler liegt darin, dass nur dein Host weiß, wer die 10.1.1.1 besitzt. Alle anderen Maschinen im Netzwerk wissen es nicht, können also keine Pakete senden und damit deine Pings nicht beantworten. In Richtung WAN ist es die selbe Situation. Der Router weiß nicht, wer Pakete für 10.1.1.1 empfangen soll. Es gibt zwei Auswege:
  • Du setzt Routen
  • Du setzt vor die Jails ein NAT
Das NAT ist meist einfacher. Aber nicht zwingen das, was du möchtest.
 
Wenn du vllt. noch beschreibst, was du erreichen willst (außer nur rumpingen), kann ich dir ggf. auch weiterhelfen. ;)

Ich persönlich habe auch jeden Dienst auf meinen Server(n) in separaten Jails mit 10.0.0.x IPs und leite mittels der Firewall pf von FreeBSD alle Pakete an ihre korrekte Adresse. Mehrere Webserver die auf Port 80/443 lauschen, gehen dabei über einen Reverseproxy der ebenfalls in einer Jail läuft.

Also wenn du Fragen zu so einem Setup hast, nur zu.
 
Die Netzwerkmasken sehen schonmal komisch aus. Du solltest eine der 10er Adressen mit einer größeren Mask als /32 konfigurieren oder die Aliase aus dem 192.168er Netz nehmen.
 
Hallo Nuke,

dein Setup klingt interessant, in einer Jail den ReverseProxy in den anderen jeweils Webserver für verschiedene Domain. Kannst du darüber was sagen?

Gruß ré
 
Ich bin zwar nicht Nuke, aber ich fahre ein ähnliches Konstrukt.

Ich habe nginx als Reverse-Proxy in einem Jail und leite per pf alle HTTP/HTTPS-Anfragen nur an dieses Jail weiter.
Per "servername" wird dann auf die übrigen Jails verteilt.

Gruß
Markus
 
dein Setup klingt interessant, in einer Jail den ReverseProxy in den anderen jeweils Webserver für verschiedene Domain. Kannst du darüber was sagen?

Also in der rc.conf die lokalen IPs anlegen:
Code:
# some local addresses for our jails
cloned_interfaces="lo1"
ifconfig_lo1_name="jail0"
ipv4_addrs_jail0="10.0.0.1/24 10.0.0.1-20/32"

In der Jail.conf die Jails an die entsprechenden IPs binden
Code:
exec.start  = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
exec.clean;
mount.devfs;

path = "/prison/${host.hostname}";
mount.fstab = "/etc/fstab.${host.hostname}";

reverseproxy {
  host.hostname = "reverseproxy.local";
  ip4.addr = 10.0.0.1;
}

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

In der pf NAT und Redirects einrichten:
Code:
# Variables                                                                                         
ALLIF = "{ jail0, re0 }"
PUBIF="re0"
JAILIF="jail0"
PUBIP="xxx.xxx.xxx.xxx"
JAILNET="10.0.0.0/24"

REVERSEJAIL="10.0.0.1"
#clean up
scrub in all

#ignore lo0
set skip on lo0

# Rules
nat pass on $PUBIF from $JAILNET to any -> $PUBIP
# redirect all traffic on the http/https ports to our reverseproxy jail
rdr pass on $PUBIF proto tcp from any to $PUBIP port {http, https} -> $REVERSEJAIL

# keep state on all communication (i think so)
pass out on $ALLIF all keep state
pass in on $ALLIF all keep state

Jetzt nginx als Reverseproxy konfigurieren (ich hatte vorher pound, aber das versagte bei mehreren SSL-Zertifikaten und wird auch nicht mehr großartig weiterentwickelt):
(Auszug)
Code:
[...]
http {
  upstream phpweb {
    server 10.0.0.2;
  }

  upstream cloud {
    server 10.0.0.3;
  }

[...]

  server {
    listen 443 ssl;
    server_name  ~.*my.domain.com.*;

    client_max_body_size 1024M;
    proxy_read_timeout 300;
    ssl on;
    ssl_certificate      /etc/ssl/certs/domain.com.crt;
    ssl_certificate_key  /etc/ssl/certs/domain.com.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "EECDH+AESGCM EDH+AESGCM EECDH -RC4 EDH -CAMELLIA -SEED !aNULL !eNULL !LOW !3DES !MD5 !   EXP !PSK !SRP !DSS !RC4";

    location / {
      proxy_pass http://cloud;
      proxy_redirect off;
      proxy_buffering off;
      proxy_set_header        Host            $host;
      proxy_set_header        X-Real-IP       $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;
      add_header              Front-End-Https   on;
    }

    location ~^/(myapp1|myapp2) {
      proxy_pass http://phpweb;
      proxy_redirect off;
      proxy_buffering off;
      proxy_set_header        Host            $host;
      proxy_set_header        X-Real-IP       $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;
      add_header              Front-End-Https   on;
    }
  }

Von den "server" Auszügen kann es auch mehrere geben. Ich hab jetzt pro Domain(gruppe) ein so ein Eintrag.

In den Webserver-Jails jetzt einfach an die lokale IP Port 80 binden. Ab und zu (z.B. bei owncloud) ist es auch nötig die Domain in die hosts der Jail einzutragen mit der IP des Reverseproxy, weil er sonst bei irgendwelchen Checks einen Roundtrip über die pf macht und dort hängen bleibt.

/prison/cloud.local/etc/hosts
Code:
10.0.0.1 my.domain.com

Ich bin mit dem Setup sehr zufrieden. Man muss nur aufpassen, dass wenn man so pro Domain ein SSL-Zertifikat verteilen will, muss der Browser SNI unterstützen. Das tun die meisten heutzutage, aber es gibt ja durchaus noch Firmen die mit Uralt-IE Versionen arbeiten.
Aber dadurch dass SSL am Reverseproxy konfiguriert ist, muss ich das nur da machen und nicht noch mal in all den Webservern dahinter.
 
Ich habe hier auf BSDForen.de Browser ohne SNI ausgesperrt, als wir auf Xenforo migriert haben. Bisher hat sich niemand beschwert. Allerdings haben wir auch ein Publikum, was im Großen und Ganzen auf moderne Browser setzt. Den größten Anteil alter Browser hat die Opera 12 Fraktion.
 
So, ich habe heute endlich Zeit gefunden, mich mit dem Problem zu beschäftigen. Mit nginx habe ich einen Reverse Proxy aufgesetzt und die Pakete dann mit PF weitergeleitet. Klappte sofort ohne Probleme. Besten Dank für die Hinweise.

Eine Frage hätte ich aber noch:
Die Netzwerkmasken sehen schonmal komisch aus. Du solltest eine der 10er Adressen mit einer größeren Mask als /32 konfigurieren oder die Aliase aus dem 192.168er Netz nehmen.
Kann das mal jemand kurz ausführen? Was muss man bei den Netzmasken für die Jails beachten und warum?
 
Du musst es aus der Sicht der Routingtabelle des Kernels sehen. Jede Adresse mit Maske erstellt einen Eintrag in der Routingtabelle.

Wenn du z.B. 192.168.0.0/24 auf einem Interface liegen hast, dann weiß der Kernel, dass das komplette /24 über das Interface erreichbar ist. Weitere Aliase aus diesem Netz sollten dann aber mit /32 konfiguriert werden, damit in der Routingtabelle nicht mehrere Routen für das gleiche Ziel (192.168.0.0/24) existieren.

Wenn du jetzt aber Aliases aus z.B. 10.1.1.0/24 konfigurierst, sollte einer davon auch tatsächlich mit /24 konfiguriert werden, damit der Kernel weiß, wie er 10.1.1.0/24 erreicht. Wichtig ist das aber nur, wenn du mit den Jails auch nach draußen willst - was du ja willst - weil du dann nämlich einen Router in 10.1.1.0/24 brauchst. Und der Kernel muss ja wissen, wie er den erreichen soll. (Oder du machst halt NAT).
 
Zurück
Oben