Files

50 lines
2.6 KiB
Bash

Z=$(state_get zone)
fw() { firewall-cmd --zone="$Z" "$@"; }
# Rich rules that accept SSH from a source address, now (or --permanent).
ssh_rules() { fw "$@" --list-rich-rules 2>/dev/null | grep -E 'source address="?[0-9.]+(/[0-9]+)?' | grep -E 'service name="?ssh"?|port port="?22"?' | grep -w accept; }
# Every established SSH client address falls in a rule's network.
clients_covered() {
local nets
nets=$(ssh_rules | sed -E 's/.*source address="?([0-9./]+)"?.*/\1/')
ss -Htn state established '( sport = :22 )' | awk '{print $4}' | sed -E 's/:[0-9]+$//; s/^\[?::ffff://; s/\]$//' |
python3 -c '
import ipaddress, sys
nets = [ipaddress.ip_network(n, strict=False) for n in sys.argv[1].split()]
for a in sys.stdin.read().split():
try:
ip = ipaddress.ip_address(a)
except ValueError:
continue
if ip.is_loopback or ip.version != 4:
continue
if not any(ip in n for n in nets):
sys.exit(1)' "$nets"
}
peer_ssh() { in_peer timeout 5 bash -c 'exec 3<>/dev/tcp/10.99.0.1/22; head -c 4 <&3' 2>/dev/null | grep -q SSH; }
peer_curl() {
local i
for i in 1 2 3 4 5; do
in_peer curl -s --max-time 3 http://10.99.0.1:8080/ | grep -q "Lab httpd" && return 0
sleep 2
done
return 1
}
task 1 "SSH allowed only from one network, with a rich rule"
need "firewalld is running" active firewalld
need "a rich rule accepts SSH from a network, now and permanently" '[ -n "$(ssh_rules)" ] && [ -n "$(ssh_rules --permanent)" ]'
need "the ssh service is out of the zone, now and permanently" '! fw --query-service=ssh && ! fw --permanent --query-service=ssh'
need "port 22 isn't open to everyone" '! fw --query-port=22/tcp'
need "your current SSH connections come from inside the rule's network" clients_covered
need "the peer (10.99.0.2) can't reach SSH" '! peer_ssh'
task 2 "TCP port 8080 forwarded to port 80"
need "httpd is running" active httpd
need "the zone forwards 8080/tcp to port 80, now and permanently" 'fw --list-forward-ports | grep -q "port=8080:proto=tcp:toport=80:" && fw --permanent --list-forward-ports | grep -q "port=8080:proto=tcp:toport=80:"'
need "curl http://10.99.0.1:8080/ from the peer reaches httpd" peer_curl
task 3 "Traffic from 192.168.50.0/24 goes to the internal zone"
need "the internal zone has source 192.168.50.0/24, now" 'firewall-cmd --zone=internal --list-sources | grep -qw "192\.168\.50\.0/24"'
need "and permanently" 'firewall-cmd --permanent --zone=internal --list-sources | grep -qw "192\.168\.50\.0/24"'
need "firewall-cmd --get-active-zones lists internal with it" 'firewall-cmd --get-active-zones | grep -A3 "^internal" | grep -q "192\.168\.50\.0/24"'