D8.5 Network Security 🌐

Isolation με internal networks

tasks:

  # ── Backend: no internet ──────────────────
  - name: Backend network (isolated)
    community.docker.docker_network:
      name:     production_backend
      state:    present
      internal: true       # ← ΔΕΝ έχει internet access!

  # ── Frontend: internet access ─────────────
  - name: Frontend network
    community.docker.docker_network:
      name:  production_frontend
      state: present

  # ── Database: backend only ────────────────
  - name: PostgreSQL (backend only)
    community.docker.docker_container:
      name:    postgres_db
      image:   postgres:15-alpine
      state:   started
      networks:
        - name: production_backend    # ← ΜΟΝΟone network!
      # Δεν έχει internet, δεν εκτίθεται εκτός

  # ── App: gateway (frontend + backend) ─────
  - name: App container
    community.docker.docker_container:
      name:    myapp
      image:   myapp:latest
      state:   started
      networks:
        - name: production_frontend   # ← βλέπει nginx
        - name: production_backend    # ← βλέπει db

  # ── Nginx: frontend only + ports ──────────
  - name: Nginx (public)
    community.docker.docker_container:
      name:  nginx_proxy
      image: nginx:1.25-alpine
      state: started
      ports:
        - "80:80"
        - "443:443"
      networks:
        - name: production_frontend   # ← βλέπει μόνο app

Port exposure — Minimal

tasks:

  # ── ❌ Expose σε όλες τις interfaces ─────
  - community.docker.docker_container:
      ports:
        - "8080:8080"      # ← 0.0.0.0:8080 → εκτεθειμένο παντού!

  # ── ✅ Expose μόνο σε localhost ───────────
  - community.docker.docker_container:
      ports:
        - "127.0.0.1:8080:8080"    # ← μόνο localhost
        # Ο nginx (reverse proxy) αναλαμβάνει το public

  # ── ✅ Expose μόνο σε internal network ────
  - community.docker.docker_container:
      ports: []    # ← ΚΑΝΕΝΑ published port!
      networks:
        - name: internal_net    # ← μόνο μέσω Docker network

UFW + Docker integration

Το Docker from default παρακάμπτει το UFW! Χρειάζεται ειδική ρύθμιση:

tasks:

  # ── Ρύθμιση Docker για σεβασμό UFW ────────
  - name: Docker daemon config για UFW
    ansible.builtin.copy:
      dest:    /etc/docker/daemon.json
      content: |
        {
          "iptables": true,
          "ip-forward": true
        }
      mode: '0644'
    notify: Restart Docker

  # ── UFW rules ─────────────────────────────
  - name: UFW default deny
    community.general.ufw:
      state:  enabled
      policy: deny
    when: ansible_facts['os_family'] == "Debian"

  - name: Allow SSH
    community.general.ufw:
      rule:  allow
      port:  "{{ ansible_port | default(22) }}"
      proto: tcp
    when: ansible_facts['os_family'] == "Debian"

  - name: Allow HTTP/HTTPS (nginx)
    community.general.ufw:
      rule:  allow
      port:  "{{ item }}"
      proto: tcp
    loop: ["80", "443"]
    when: ansible_facts['os_family'] == "Debian"

    # Docker containers που χρησιμοποιούν
    # 127.0.0.1:port binding ΔΕΝ χρειάζονται UFW rules
    # γιατί δεν εκτίθενται εκτός του host!

handlers:
  - name: Restart Docker
    ansible.builtin.service:
      name:  docker
      state: restarted

Σύνοψη D8.5

Network Security
│
├── internal: true → no internet για backends
│
├── Port binding:
│   ├── "127.0.0.1:port:port" → localhost only ✅
│   └── "port:port"           → 0.0.0.0 (expose) ❌
│
├── Minimal exposure:
│   └── Μόνο nginx εκτίθεται (80/443)
│       Όλα τα άλλα: internal networks
│
└── UFW + Docker:
    ├── Docker παρακάμπτει UFW by default
    └── Λύση: 127.0.0.1 binding + UFW rules