Skip to content

Instantly share code, notes, and snippets.

@deploy595
Created July 25, 2024 14:04
Show Gist options
  • Save deploy595/205ea7985fbf41fe66ab9a082021ed6a to your computer and use it in GitHub Desktop.
Save deploy595/205ea7985fbf41fe66ab9a082021ed6a to your computer and use it in GitHub Desktop.
Block all outgoing connections from inside a docker container except https using firewalld.

Install, start and enable:

  apt install firewalld
  systemctl start firewalld 
  systemctl enable firewalld

Add rules for host:

  firewall-cmd --permanent --zone=public --add-port=22/tcp
  firewall-cmd --permanent --zone=public --add-port=80/tcp
  firewall-cmd --permanent --zone=public --add-port=8080/tcp
  firewall-cmd --permanent --zone=public --add-port=8083/tcp
  firewall-cmd --permanent --zone=public --add-port=443/tcp
  firewall-cmd --permanent --zone=public --add-port=8443/tcp
  firewall-cmd --permanent --zone=public --add-port=22/tcp

Add chain for docker:

  firewall-cmd --permanent --direct --remove-rules ipv4 filter DOCKER-USER
  firewall-cmd --permanent --direct --add-chain ipv4 filter DOCKER-USER

Allow internal docker communication (Run docker network inspect <your_network> to obtain network submask):

  firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -j RETURN -s 172.18.0.0/16 -m comment --comment "allow internal docker communication"

Accept dns requests:

    firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN -m comment --comment "accept dns requests"
    firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -p udp -m udp --dport 53 --sport 1024:65535 -j RETURN -m comment --comment "accept dns requests"
    firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -p tcp -m tcp --dport 53 -j ACCEPT -m comment --comment "accept dns requests"

Accept http(s) traffic:

    firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -p tcp -m multiport --dports 80,443,8080,8083,8443 -s 0.0.0.0/0 -j ACCEPT -m comment --comment "accept http(s) traffic"
    firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -p tcp -m multiport --sports 80,443,8080,8083,8443 -s 0.0.0.0/0 -j ACCEPT -m comment --comment "accept https(s) traffic"

Accept our remote postgres:

    firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -p tcp -s 5.XXX.XXX.149 --sport 5432 -j ACCEPT -m comment --comment "our remote postgres"
    firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -p tcp -d 5.XXX.XXX.149 --dport 5432 -j ACCEPT -m comment --comment "our remote postgres"

Enable logging (access via dmesg command or check /var/log/syslog):

  firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

Reject all other out traffic:

firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -j REJECT -m comment --comment "reject all other out traffic"

Restart:

  firewall-cmd --reload
  systemctl stop docker && systemctl stop firewalld
  systemctl start firewalld && systemctl start docker

Save this file as check_connection.py:

# coding=utf-8
import socket

def _connect(target, port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket.setdefaulttimeout(1)

    result = s.connect_ex((target, port))
    if result == 0:
        print("Port {} is open".format(port))
    else:
        print("Port {} is closed".format(port))
    s.close()

ip = '82.196.4.187'
_connect(ip, 80)
_connect(ip, 443)
_connect(ip, 22)

Execute this file inside docker container:

python check_connection.py

Expected results:

Port 80 is open
Port 443 is open
Port 22 is closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment