How to Make Your Website More Secure? How to Restrict Services Started via Docker Containers with UFW? UFW One-Click Script
Contents
This article explains how to configure the UFW firewall using a one-click script to restrict network access for Docker container services, enhancing website security.
One-Click Script
curl https://raw.githubusercontent.com/Yoosu-L/Scripts/refs/heads/main/setup_ufw.sh -sSf | sh
Script Content
#!/bin/bash
# Exit on any error
set -e
echo "Starting UFW setup script..."
# Install required packages
echo "Installing required packages..."
apt-get update -y && apt-get install ufw
# Configure UFW
echo "Configuring UFW ports..."
ufw allow 22/tcp comment 'ssh'
ufw allow 80/tcp comment 'http'
ufw allow 443/tcp comment 'https'
# Get SSH port from sshd_config
SSH_PORT=$(grep -E "^Port\s+[0-9]+" /etc/ssh/sshd_config | awk '{print $2}')
# If no Port is specified in sshd_config, use default port 22
if [ -z "$SSH_PORT" ]; then
echo "No SSH port specified in sshd_config, using default port 22"
SSH_PORT=22
fi
echo "Allowing SSH port: $SSH_PORT"
ufw allow ${SSH_PORT}/tcp comment 'ssh'
# Add Docker rules to after.rules
echo "Adding Docker rules to UFW configuration..."
cat << 'EOF' >> /etc/ufw/after.rules
# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:ufw-docker-logging-deny - [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -j ufw-user-forward
-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16
-A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 172.16.0.0/12
-A DOCKER-USER -j RETURN
-A ufw-docker-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW DOCKER BLOCK] "
-A ufw-docker-logging-deny -j DROP
COMMIT
# END UFW AND DOCKER
EOF
# Check if nginx container exists
echo "Checking nginx container..."
if ! docker ps | grep -q nginx; then
echo "Error: nginx container not found!"
exit 1
fi
# Get nginx container IP and configure UFW rules
echo "Configuring UFW rules for nginx container..."
NGINX_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx)
if [ -z "$NGINX_IP" ]; then
echo "Error: Could not get nginx container IP!"
exit 1
fi
echo "Nginx container IP: $NGINX_IP"
# Configure UFW rules for nginx
ufw route allow proto tcp from any to $NGINX_IP port 80 comment 'docker nginx bridge'
ufw route allow proto tcp from any to $NGINX_IP port 443 comment 'docker nginx bridge'
ufw allow from $NGINX_IP to any comment 'allow docker nginx ip'
# Enable UFW
echo "Enabling UFW..."
echo "y" | ufw enable
echo "UFW setup completed successfully!"
How to Use
- Save this script as
setup_ufw.sh
- Add execute permission to the script:
chmod +x setup_ufw.sh
- Run the script with root privileges:
sudo ./setup_ufw.sh
This script:
- Uses error checking mechanisms (
set -e
) - Adds progress indicators
- Gets the SSH port from
sshd_config
- Checks if the nginx container exists
- Verifies whether the nginx container IP was successfully obtained
- Uses heredoc (
cat << 'EOF'
) to add UFW rules - Automatically confirms UFW enablement (
echo "y" | ufw enable
)
Please note:
- Ensure Docker is installed and the nginx container is running before executing this script
- The script requires root privileges
Detailed Step Analysis
Install ufw
apt-get update -y && apt-get install ufw
Open ports 22, 80, 443
ufw allow 22/tcp comment 'ssh'
ufw allow 80/tcp comment 'http'
ufw allow 443/tcp comment 'https'
Find the non-standard SSH port through the file /etc/ssh/sshd_config
to prevent disconnection after enabling ufw
# Get SSH port from sshd_config
SSH_PORT=$(grep -E "^Port\s+[0-9]+" /etc/ssh/sshd_config | awk '{print $2}')
# If no Port is specified in sshd_config, use default port 22
if [ -z "$SSH_PORT" ]; then
echo "No SSH port specified in sshd_config, using default port 22"
SSH_PORT=22
fi
echo "Allowing SSH port: $SSH_PORT"
ufw allow ${SSH_PORT}/tcp comment 'ssh'
Modify the configuration file /etc/ufw/after.rules
and add the following rules at the end (to block external network access to Docker exposed ports)
# Add Docker rules to after.rules
cat << 'EOF' >> /etc/ufw/after.rules
# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:ufw-docker-logging-deny - [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -j ufw-user-forward
-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16
-A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 172.16.0.0/12
-A DOCKER-USER -j RETURN
-A ufw-docker-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW DOCKER BLOCK] "
-A ufw-docker-logging-deny -j DROP
COMMIT
# END UFW AND DOCKER
EOF
Open docker nginx ports 80 and 443
ufw route allow proto tcp from any to $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx) port 80 comment 'docker nginx bridge'
ufw route allow proto tcp from any to $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx) port 443 comment 'docker nginx bridge'
Allow the docker nginx private address to access all ports on the machine
ufw allow from $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx) to any comment 'allow docker nginx ip'
Enable ufw
ufw enable