Skip to content

Commit

Permalink
Merge pull request #3 from mlollo/main
Browse files Browse the repository at this point in the history
Support ufw allow from IP using a UFW_FROM label
  • Loading branch information
shinebayar-g authored Dec 29, 2020
2 parents 7ddddf9 + fb02536 commit f480686
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 6 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,28 @@ To Action From
443/tcp ALLOW Anywhere
```

**Step 7**. Hardening firewall rules with UFW_FROM

You can choose to restrict incoming traffic from specific IPs or Subnets.
For example :

```
➜ docker run -d -p 8080:80 -l UFW_MANAGED=TRUE -l "UFW_FROM=192.168.0.2;192.168.1.0/24" nginx:alpine
13a6ef724d92f404f150f5796dabfd305f4e16a9de846a67e5e99ba53ed2e4e7
```

will add following entry to ufw list.

```
➜ sudo ufw status
Status: active
To Action From
-- ------ ----
22 ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
172.17.0.2 80/tcp ALLOW FWD 192.168.0.2 <= this baby added allowing only 192.168.0.2 to access nginx server
172.17.0.2 80/tcp ALLOW FWD 192.168.1.0/24 <= this baby added allowing only 192.168.1.0/24 to access nginx server
```
31 changes: 25 additions & 6 deletions src/ufw-docker-automated.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python
import subprocess
import docker
from ipaddress import ip_network

client = docker.from_env()

Expand All @@ -22,6 +23,7 @@ def manage_ufw():
container_port_num = None
container_port_protocol = None
ufw_managed = None
ufw_from = None

container_port_dict = container.attrs['NetworkSettings']['Ports'].items()

Expand All @@ -35,6 +37,14 @@ def manage_ufw():
if 'UFW_MANAGED' in container.labels:
ufw_managed = container.labels.get('UFW_MANAGED').capitalize()

if 'UFW_FROM' in container.labels:
try:
ufw_from = [ip_network(str(_sub)) for _sub in container.labels.get('UFW_FROM').split(';')]
except ValueError as e:
print(f"Invalid UFW label: UFW_FROM={container.labels.get('UFW_FROM')} exception={e}")
ufw_from = -1
pass

if ufw_managed == 'True':
for key, value in container_port_dict:
if value:
Expand All @@ -46,12 +56,21 @@ def manage_ufw():
if value:
container_port_num = list(key.split("/"))[0]
container_port_protocol = list(key.split("/"))[1]
print(f"Adding UFW rule: {container_port_num}/{container_port_protocol} of container {container.name}")
subprocess.run([f"sudo ufw route allow proto {container_port_protocol} \
from any to {container_ip} \
port {container_port_num}"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True,
shell=True)
if not ufw_from:
print(f"Adding UFW rule: {container_port_num}/{container_port_protocol} of container {container.name}")
subprocess.run([f"sudo ufw route allow proto {container_port_protocol} \
from any to {container_ip} \
port {container_port_num}"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True,
shell=True)
elif isinstance(ufw_from, list):
for subnet in ufw_from:
print(f"Adding UFW rule: {container_port_num}/{container_port_protocol} of container {container.name} from {subnet}")
subprocess.run([f"sudo ufw route allow proto {container_port_protocol} \
from {subnet} to {container_ip} \
port {container_port_num}"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True,
shell=True)

if event_type == 'kill' and ufw_managed == 'True':
ufw_length = subprocess.run(
Expand Down

0 comments on commit f480686

Please sign in to comment.