Bash Docker container innerhalb eines docker containers starten - geht das?

Bagbag schrieb:
Und warum willst du unter Docker dann traefik davor schalten?
Aus zwei Gründen: Ich kann das Forum dann jederzeit starten oder stoppen, oder auf eine andere Maschine umziehen. Alle benötigten Dateien liegen in einem lokalen Verzeichnis, der Rest bleibt unberührt.

Bagbag schrieb:
Einfach Port-Bind und fertig.
Ich verstehe nicht, wie du das meinst. Der traefik braucht Port 443 für https und 80 u. a. für die Certs. Traefik kann nicht zu Ports weiterleiten von Anwendungen, die direkt auf dem Host laufen.
 
Habs hinbekommen. Gab einen Trick ...

Folgendes

Code:
    extra_hosts:
      - "host.docker.internal:host-gateway"

Code:
    volumes:
      - "./proxy-conf/:/proxy-conf/"

Code:
    command:
      - "--providers.file.directory=/proxy-conf"

hinzufügen.

Dann die Datei proxy-conf/dynamic_conf.yml erstellen:

Code:
http:
  routers:
    to-forum:
      rule: Host(`f.irgendetwas.com`)
      entrypoints: websecure
      tls:
        certresolver: myresolver
      service: forum
  services:
    forum:
      loadbalancer:
        servers:
          - url: http://host.docker.internal:portHier/

Wieso denn jetzt eine zusätzliche "dynamic_conf.yml" anstatt "labels:"?

Ganz einfach, weil es für das "servers"-Array keine Label-Definition gibt, und es muss ein Array sein ... Hab extra in der Referenz nachgeschaut.

Läuft einwandfrei. Discourse noch einmal in einem Docker-Container kapseln zu wollen, war keine gute Idee ...

Weiteres siehe auch hier: https://stackoverflow.com/a/43541732

Noch mal Thx.
 
Püschel.

Habe ein neues Problem. Vorher hatte ich einen Cloud-Server mit vorgeschalteter Firewall. Nun habe ich einen Dedicated-Server ohne vorgeschaltete Firewall, aber mit ufw.

Discourse läuft auf Port 30899 und Docker übernimmt das https und leitet an diesen Port weiter.

Das Problem ist, dass ufw das interne Routing verbietet.

Wenn ich sudo ufw allow in 30899 hinzufüge, dann funktioniert es. Die Schattenseite ist aber, dass dann auch http://ip:30899 direkt aufgerufen werden kann, also Docker sozusagen umgangen werden kann.

Hat jemand eine Lösung dafür? Also, dass Docker bei der Kommunikation mit einem Host-Service nicht blockiert wird?

Auf SO habe ich gelesen, Docker verwende auch noch mal iptables, und das würde sich mit ufw beißen.
 
ufw allow from 172.1.1.1.1/24 to any port 30899

Nur halt mit dem subnet, das du in docker hast oder simpel mit 172.0.0.0/8.
 
  • Gefällt mir
Reaktionen: CyborgBeta
docker inspect bridge

Code:
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },

Bagbag schrieb:
oder simpel mit 172.0.0.0/8.

Sorry für die Frage, aber wofür steht /8? Ich probiere das mal gerade.
 
Das /8 ist die Subnetz-Maske. Das sagt, dass die ersten 8 Bits fest sind. Also die 172 und alles danach ist beliebig.

172.17.0.0/16 wäre entsprechend passend bei dir von 172.17.0.0 bis 172.17.255.255.
 
  • Gefällt mir
Reaktionen: CyborgBeta
Ich danke Dir sehr!

Code:
sudo ufw status verbose

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
...
30899                      ALLOW IN    172.0.0.0/8
...

sudo ufw allow from 172.0.0.0/8 to any port 30899 funktioniert einwandfrei.
 
  • Gefällt mir
Reaktionen: Bagbag
Hmmm, gut, dass ich noch einmal geschaut hatte. Es waren noch zwei sensible Ports von Docker-Services öffentlich zugänglich (es fand in der kurzen Zeit aber vermutlich kein Angriff statt :D ). Der Grund ist, dass Docker nicht zusammen mit ufw/iptables funktioniert: https://stackoverflow.com/questions/30383845/what-is-the-best-practice-of-docker-ufw-under-ubuntu , weil Docker iptables umgeht.

Eine Lösung kann sein, sensible Ports, die nur auf localhost erreichbar sein sollen, mit 127.0.0.1:port1:port2 zu exposen.

Dadurch ist port1 nur auf 127.0.0.1 erreichbar - und nicht auf 0.0.0.0.

Die zweite Lösung wäre, "iptables": false in die docker daemon config einzutragen, aber dann kann kein einziger Container mehr mit der Außenwelt kommunizieren. Ist also nicht praktikabel.



Gibt es zu ufw und iptables eigentlich eine Alternative für Debian 12?
 
Gibt mehrere. ebtables, Shorewall, firewalld.

Aber je nachdem wie das Hosting bei dir aussieht, würde ich einen OpenWrt lxc Container aufsetzen und alles darüber routen.
 
  • Gefällt mir
Reaktionen: CyborgBeta
Ich müsste das mal auf einem Nicht-Produktiv-System ausprobieren ... so besteht ja immer die Gefahr, mich selber auszusperren (wenn der SSH-Port aus Versehen geblockt wird) ... aber das ist inzwischen wohl ein neues Thema und hat jetzt wohl nicht mehr viel mit der ursprünglichen Frage zu tun.

Wäre OpenWrt lxc dann ein Ersatz für Traefik? Von Traefik möchte ich mich eigentlich nicht trennen.^^
 
Nein, OpenWrt ist ein Router OS und hat entsprechend Firewall, kannst einfach VPNs einrichten, so Zeug eben.

Sagen wir mal, es ist ein anderes, aber naheliegendes Thema 😄

SSH Port würde ich dann auch gar nicht mehr freigeben, sondern nur per VPN drauf. Wenn du das alles auf einem vServer hast, kannste ja immer über die KVM Konsole drauf.

Nein, OpenWrt ist primär kein Reverse-Proxy (kann es aber auch). Weißt du denn, was ein LXC Container ist? Technisch zwar sehr nah an Docker, hat aber einen anderen Einsatzzweck, quasi ein eigenes OS isoliert, ähnlich wie eine VM.
 
Bagbag schrieb:
Wenn du das alles auf einem vServer hast, kannste ja immer über die KVM Konsole drauf.
Aber nicht bei einem Dedicated + "Software"firewall. ;) Falls ich mich selber aussperre, bestünde nur noch die Möglichkeit, das Ding neu zu starten und alles neu zu installieren. ;)
 
Es gibt auch Hardware KVMs. Bei z.B. Hetzner kannst du dir sowas kostenfrei anschließen lassen und für 2-3h nutzen.

Davon ab kannst du dich auch mit deiner Firewall auf Debian aussperren, da sehe ich keinen Unterschied.
 
  • Gefällt mir
Reaktionen: CyborgBeta
Ach Fck!

Das, was ich möchte, ist schlicht nicht möglich oder nur mit einem für mich nicht praktikablen Aufwand erreichbar - mit Debian und einer Firewall auf derselben Maschine. :(

Ich möchte ja, dass der Discourse-Port nur für das Docker-Bridge-Netzwerk (bzw. das proxy_default-Netzwerk, das Bridge als Treiber hat) erreichbar ist, und nicht öffentlich.

Das geht aber nicht ohne Weiteres, weil Docker gerne die Zuständigkeit der iptables-Konfiguration selber übernehmen möchte und sich da auch nicht beeinflussen lässt.

Ich hab es mit nftables und mit Shorewall probiert. Docker unterstützt nftables nicht, und die Shorewall-Konfiguration mit mehreren Interfaces bzw. Subnets bzw. Firewalls ist viel zu kompliziert.

tl;dr: Ich kann damit leben, wie es zurzeit ist, und muss halt nur aufpassen, keine Ports auf 0.0.0.0 zu öffnen, die nicht öffentlich zugänglich sein sollen.

Danke erst mal für Deine Hilfe ... aber das Ding ist jetzt erst mal abgehakt.
 
Ich habe mal was ausprobiert.

Das ist meine /etc/nftables.conf:

JSON:
flush ruleset

table inet firewall {

    chain inbound_ipv4 {
        # accepting ping (icmp-echo-request) for diagnostic purposes.
        # However, it also lets probes discover this host is alive.
        # This sample accepts them within a certain rate limit:
        #
        icmp type echo-request limit rate 5/second accept
    }

    chain inbound_ipv6 {
        # accept neighbour discovery otherwise connectivity breaks
        #
        icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept

        # accepting ping (icmpv6-echo-request) for diagnostic purposes.
        # However, it also lets probes discover this host is alive.
        # This sample accepts them within a certain rate limit:
        #
        # icmpv6 type echo-request limit rate 5/second accept
    }

    chain inbound {

        # By default, drop all traffic unless it meets a filter
        # criteria specified by the rules that follow below.
        type filter hook input priority 0; policy drop;

        # Allow traffic from established and related packets, drop invalid
        ct state vmap { established : accept, related : accept, invalid : drop }

        # Allow loopback traffic.
        iifname lo accept

        # Allow on ports ... for IPv4 and IPv6.
        tcp dport { 123, 234, usw. } accept

        ip saddr 172.17.0.0/16 accept
        ip saddr 172.18.0.0/16 accept

        # Uncomment to enable logging of denied inbound traffic
        log prefix "[nftables] Inbound Denied: " counter drop
    }

    chain forward {
        # Drop everything (assumes this device is not a router)
        type filter hook forward priority 0; policy drop;
    }

    # no need to define output chain, default policy is accept if undefined.
}

Angelehnt an: https://wiki.nftables.org/wiki-nftables/index.php/Simple_ruleset_for_a_server

Das Seltsame ist, dass es funktioniert, wenn ich nft -f /etc/nftables.conf aufrufe, NACHDEM Docker gestartet wurde.

Rufe ich es davor auf (oder nach einem Neustart), funktioniert es nicht mehr, weil die Websites usw. auf 443 nicht mehr erreichbar sind.

Ich vermute (oder weiß), dass docker compose nach dem build des Netzwerks noch weitere Regeln hinzufügt. Diese kann ich durch nft list ruleset sehen:

Code:
# hier das, was oben steht...

# Warning: table ip nat is managed by iptables-nft, do not touch!
table ip nat {
        chain DOCKER {
                ## gekürzt
        }

        chain POSTROUTING {
                ## gekürzt
        }

        chain PREROUTING {
                ## gekürzt
        }

        chain OUTPUT {
                ## gekürzt
        }
}
# Warning: table ip filter is managed by iptables-nft, do not touch!
table ip filter {
        chain DOCKER {
                ## gekürzt
        }

        chain DOCKER-ISOLATION-STAGE-1 {
                ## gekürzt
        }

        chain DOCKER-ISOLATION-STAGE-2 {
                ## gekürzt
        }

        chain FORWARD {
                ## gekürzt
        }

        chain DOCKER-USER {
                ## gekürzt
        }
}
table ip6 nat {
        chain DOCKER {
        }
}
table ip6 filter {
        chain DOCKER {
        }

        chain DOCKER-ISOLATION-STAGE-1 {
                ## gekürzt
        }

        chain DOCKER-ISOLATION-STAGE-2 {
                ## gekürzt
        }

        chain FORWARD {
                ## gekürzt
        }

        chain DOCKER-USER {
                ## gekürzt
        }
}

Ich wollte ja eigentlich nur erreichen, dass ein bestimmter Port nur "intern", vom Subnet 172.18.0.0/16 aus, erreichbar ist, und nicht auch vom www. Aber anscheinend funktioniert das nicht.

Zu guter Letzt hatte ich noch eine kleine Funktion geschrieben, die aber auch nicht funktioniert:

Bash:
block_port_for_www() {
  if [[ $# -ne 1 ]]; then
    echo "Illegal number of parameters" >&2
    exit 2
  fi
  APP_PORT=$1
  iptables -A INPUT -i lo -p tcp --dport "$APP_PORT" -j ACCEPT
  iptables -A INPUT -p tcp --dport "$APP_PORT" -j DROP
}

Das Interface "lo" ist Docker offenbar nicht.
 
Ta!

Es hat geklappt:

Code:
flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy accept;

        # Allow incoming ping
        # but still honor limit and drop the excess
        # It could have been rewritten using anonymous chains
        # but I kept it simple.
        # It has to be done as an exception to the stateful rule
        # so before it.

        icmp type echo-request limit rate 15/second accept
        icmp type echo-request drop
        icmpv6 type echo-request limit rate 15/second accept
        icmpv6 type echo-request drop

        # firewall becomes stateful from here:
        # bulk of the traffic will be handled by this single rule
        ct state established,related accept

        # Allow connections from localhost
        iif "lo" accept

        # Allow connections on port 30899 (Discourse) from localhost
        # tcp dport 30899 iif "lo" accept # already allowed by rule above

        # Allow connections from Docker containers
        ip saddr 172.18.0.0/16 accept

        # Allow specific ports from remote hosts via TCP
        tcp dport { ...ssh usw... } accept

        # Allow specific ports from remote hosts via UDP
        # udp dport { ... } accept

        # minimal ICMPv6 support for an end-node system
        # non-LAN ICMPv6 (as well as IPv4 ICMP) packets used to report
        # errors are handled by the generic stateful rule.
        icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept

        # Drop all other incoming traffic
        drop
    }
}

Wer das übernehmen möchte, sollte unbedingt vorher tcp dport { ...ssh usw... } accept anpassen. :)

Edit: Geht leider doch nicht.
 
Zuletzt bearbeitet:
Zurück
Oben