firewalls 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. example/EXAMPLE.md +55 -0
  2. example/etc/firewalld/firewalld.conf +33 -0
  3. example/etc/firewalld/helpers/.gitkeep +1 -0
  4. example/etc/firewalld/icmptypes/.gitkeep +1 -0
  5. example/etc/firewalld/ipsets/trusted-dns.xml +16 -0
  6. example/etc/firewalld/lockdown-whitelist.xml +8 -0
  7. example/etc/firewalld/policies/egress-policy.xml +44 -0
  8. example/etc/firewalld/services/.gitkeep +1 -0
  9. example/etc/firewalld/services/example-service.xml.example +7 -0
  10. example/etc/firewalld/zones/public.xml +9 -0
  11. example/etc/logrotate.d/firewalld +19 -0
  12. example/etc/sysctl.d/99-firewall-hardening.conf +26 -0
  13. example/etc/syslog-ng/conf.d/firewalld.conf +29 -0
  14. example/post_deploy.sh.example +19 -0
  15. firewalls/__init__.py +25 -0
  16. firewalls/cli.py +579 -0
  17. firewalls/locale/es/LC_MESSAGES/firewalls.mo +0 -0
  18. firewalls/locale/es.po +492 -0
  19. firewalls/locale/firewalls.pot +493 -0
  20. firewalls/locale/fr/LC_MESSAGES/firewalls.mo +0 -0
  21. firewalls/locale/fr.po +492 -0
  22. firewalls/locale/hi/LC_MESSAGES/firewalls.mo +0 -0
  23. firewalls/locale/hi.po +492 -0
  24. firewalls/locale/ro/LC_MESSAGES/firewalls.mo +0 -0
  25. firewalls/locale/ro.po +492 -0
  26. firewalls/locale/ru/LC_MESSAGES/firewalls.mo +0 -0
  27. firewalls/locale/ru.po +492 -0
  28. firewalls/locale/zh/LC_MESSAGES/firewalls.mo +0 -0
  29. firewalls/locale/zh.po +492 -0
  30. firewalls/log_control.py +105 -0
  31. firewalls/log_egress.py +243 -0
  32. firewalls/log_ingress.py +244 -0
  33. firewalls/monitor.py +382 -0
  34. firewalls/poethepoet.py +111 -0
  35. firewalls/probes.py +376 -0
  36. firewalls-0.1.0.dist-info/METADATA +252 -0
  37. firewalls-0.1.0.dist-info/RECORD +39 -0
  38. firewalls-0.1.0.dist-info/WHEEL +4 -0
  39. firewalls-0.1.0.dist-info/entry_points.txt +7 -0
example/EXAMPLE.md ADDED
@@ -0,0 +1,55 @@
1
+ # Firewall Configuration: [MACHINE_NAME]
2
+
3
+ ## 📋 Machine Overview
4
+ - **Hostname / Identifier**: `[MACHINE_NAME]` (e.g., `web-server`, `dev-laptop`)
5
+ - **Role**: [Workstation / Web Server / NAS / Local Router]
6
+ - **Network Interface**: `[INTERFACE]` (e.g., `eth0`, `eno1`, `wlan0`)
7
+ - **Operating System**: Gentoo Linux
8
+ - **Firewall Backend**: `nftables`
9
+ - **Default Zone**: `public` (bound to `[INTERFACE]`, target `DROP`)
10
+ - **Egress Policy**: `egress-policy` (target `DROP`, `HOST` -> `ANY`)
11
+ - **Security Model**: **Dual Default Deny (Bidirectional Zero Trust)**.
12
+ - **Ingress**: No open ports by default unless explicitly permitted. Unsolicited incoming packets are discarded (`DROP`).
13
+ - **Egress**: Only explicitly authorized outgoing connections are allowed (strict DNS, NTP, HTTP/HTTPS, etc.). Any other outbound traffic is blocked and dropped (`DROP`).
14
+
15
+ ---
16
+
17
+ ## 🛡️ Active Rules and Functional Behavior
18
+
19
+ ### 1. Outgoing Traffic (*Egress Filtering* - `policies/egress-policy.xml`)
20
+ - **Policy**: **DEFAULT DENY (Target `DROP`)**.
21
+ - **Logging**: Dropped connections logged to `/var/log/firewalld/denied.log`.
22
+
23
+ | Service / Port | Protocol | Status | Functional Justification |
24
+ | :--- | :--- | :--- | :--- |
25
+ | `http` | TCP (80) | **Allowed** | Standard web browsing and package repository downloads. |
26
+ | `https` | TCP (443) / UDP (443) | **Allowed** | Secure web browsing and HTTP/3 (QUIC). |
27
+ | `dns` (Restricted) | UDP / TCP (53) | **Allowed (IPSet)** | DNS queries restricted to the `trusted-dns` IPSet to prevent DNS tunneling and data exfiltration. |
28
+ | `ntp` | UDP (123) | **Allowed** | System time synchronization. |
29
+ | `dhcp` | UDP (67, 68) | **Allowed** | Local network IPv4 DHCP lease renewal (if applicable). |
30
+ | `rsync` | TCP (873) | **Optional** | Gentoo Portage tree synchronization (`emerge --sync`). |
31
+ | **Anti-Spoofing** | `127.0.0.0/8` outbound | **DENIED (DROP)** | Immediate drop for packets with spoofed loopback source addresses. |
32
+ | **Any other outbound** | All | **DENIED (DROP)** | Strict drop for uncatalogued outbound traffic. |
33
+
34
+ ### 2. Incoming Traffic (*Ingress Filtering* - `zones/public.xml`)
35
+ - **Zone**: `public` (Target: `DROP`, Interface: `[INTERFACE]`)
36
+ - **Policy**: **DEFAULT DENY (Target `DROP`)**.
37
+
38
+ | Service / Port | Protocol | Status | Functional Justification |
39
+ | :--- | :--- | :--- | :--- |
40
+ | `ssh` | TCP (22) | **Configurable** | Disabled by default on workstations; restrict to administration IPs on servers. |
41
+ | **Any other inbound** | All | **DENIED (DROP)** | Absolute drop of all unsolicited incoming traffic. |
42
+
43
+ ---
44
+
45
+ ## 🔒 Security Mechanisms and System Hardening
46
+
47
+ 1. **D-Bus Lockdown (`Lockdown=yes`)**: Protects `firewalld` so non-privileged processes cannot alter rules via D-Bus.
48
+ 2. **Strict DNS Filtering (`trusted-dns`)**: Prevents malware from querying arbitrary rogue DNS resolvers.
49
+ 3. **Kernel Hardening (`sysctl.d/99-firewall-hardening.conf`)**:
50
+ - `rp_filter = 1` (Strict IPv4 reverse path filtering / anti-spoofing).
51
+ - `accept_redirects = 0` (Prevention of ICMP redirect attacks).
52
+ - `log_martians = 1` (Kernel logging of martian / impossible source addresses).
53
+ 4. **Dedicated Logging (`syslog-ng` + `logrotate`)**:
54
+ - Denied events routed to `/var/log/firewalld/denied.log` with rate limiting (`throttle(30)`).
55
+ - Keeps `/var/log/messages` and `dmesg` clean and noise-free.
@@ -0,0 +1,33 @@
1
+ # Default configuration for firewalld on Gentoo Linux
2
+ # Documentation: man firewalld.conf
3
+
4
+ # Default zone
5
+ DefaultZone=public
6
+
7
+ # Clean up on exit or stop
8
+ CleanupOnExit=yes
9
+
10
+ # Lockdown (limits D-Bus interface changes to users/commands in lockdown-whitelist.xml)
11
+ Lockdown=yes
12
+
13
+ # Reverse Path Filter check on IPv6
14
+ IPv6_rpfilter=yes
15
+
16
+ # Rule individual calls or combined restore
17
+ IndividualCalls=no
18
+
19
+ # Log denied packets. Options: 'all', 'unicast', 'broadcast', 'multicast', 'off'.
20
+ # 'off' by default to keep dmesg clean; CLI monitors enable it on demand.
21
+ LogDenied=off
22
+
23
+ # Automatic helper assignment
24
+ AutomaticHelpers=system
25
+
26
+ # Firewall backend implementation (nftables recommended)
27
+ FirewallBackend=nftables
28
+
29
+ # Flush all runtime rules on reload
30
+ FlushAllOnReload=yes
31
+
32
+ # Filter IPv6-in-IPv4 packets as per RFC 3964
33
+ RFC3964_IPv4=yes
@@ -0,0 +1 @@
1
+ # Placeholder to maintain directory structure
@@ -0,0 +1 @@
1
+ # Placeholder to maintain directory structure
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <ipset type="hash:ip">
3
+ <short>trusted-dns</short>
4
+ <description>IPSet of trusted secure DNS resolvers (Cloudflare, Quad9, Google DNS, and local router)</description>
5
+ <!-- Example local gateway or DNS resolver -->
6
+ <entry>192.168.1.1</entry>
7
+ <!-- Cloudflare DNS -->
8
+ <entry>1.1.1.1</entry>
9
+ <entry>1.0.0.1</entry>
10
+ <!-- Quad9 DNS -->
11
+ <entry>9.9.9.9</entry>
12
+ <entry>149.112.112.112</entry>
13
+ <!-- Google DNS -->
14
+ <entry>8.8.8.8</entry>
15
+ <entry>8.8.4.4</entry>
16
+ </ipset>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <whitelist>
3
+ <short>Lockdown Whitelist Template</short>
4
+ <description>Restricts D-Bus firewall manipulation strictly to root (UID 0) and authorized commands.</description>
5
+ <user id="0"/>
6
+ <command name="/usr/bin/python*"/>
7
+ <command name="/usr/bin/firewall-cmd"/>
8
+ </whitelist>
@@ -0,0 +1,44 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <policy target="DROP">
3
+ <short>Egress-Policy-Template</short>
4
+ <description>Strict egress control: default drop (target DROP). Only explicitly authorized outgoing connections are permitted.</description>
5
+ <ingress-zone name="HOST"/>
6
+ <egress-zone name="ANY"/>
7
+
8
+ <!-- Anti-Spoofing: Immediate drop of outgoing packets with spoofed loopback addresses -->
9
+ <rule family="ipv4">
10
+ <source address="127.0.0.0/8"/>
11
+ <drop/>
12
+ </rule>
13
+
14
+ <!-- DNS restricted strictly to trusted resolvers (trusted-dns IPSet) -->
15
+ <rule family="ipv4">
16
+ <destination ipset="trusted-dns"/>
17
+ <service name="dns"/>
18
+ <accept/>
19
+ </rule>
20
+
21
+ <!-- Standard and secure web browsing -->
22
+ <service name="http"/>
23
+ <service name="https"/>
24
+ <!-- HTTP/3 / QUIC -->
25
+ <port port="443" protocol="udp"/>
26
+
27
+ <!-- Time synchronization -->
28
+ <service name="ntp"/>
29
+
30
+ <!-- DHCP client for local network IP renewal -->
31
+ <service name="dhcp"/>
32
+
33
+ <!-- Uncomment if machine synchronizes Gentoo Portage packages via rsync -->
34
+ <!-- <service name="rsync"/> -->
35
+
36
+ <!-- Example rich rule for a specific destination -->
37
+ <!--
38
+ <rule family="ipv4">
39
+ <destination address="192.168.1.50"/>
40
+ <service name="ssh"/>
41
+ <accept/>
42
+ </rule>
43
+ -->
44
+ </policy>
@@ -0,0 +1 @@
1
+ # Placeholder to maintain directory structure
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Example custom service definition -->
3
+ <service>
4
+ <short>custom-app</short>
5
+ <description>Example custom application service</description>
6
+ <port protocol="tcp" port="8080"/>
7
+ </service>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <zone target="DROP">
3
+ <short>Public</short>
4
+ <description>Public zone with strict default-drop policy (target DROP). Unsolicited incoming packets are dropped unless explicitly authorized.</description>
5
+ <!-- Replace 'eth0' with the machine's actual network interface (e.g., eno1, enp3s0, wlan0) -->
6
+ <interface name="eth0"/>
7
+ <!-- Example: Enable SSH only if necessary (or restrict with a rich rule by source IP) -->
8
+ <!-- <service name="ssh"/> -->
9
+ </zone>
@@ -0,0 +1,19 @@
1
+ /var/log/firewalld/*.log {
2
+ weekly
3
+ missingok
4
+ rotate 12
5
+ compress
6
+ delaycompress
7
+ notifempty
8
+ create 0640 root root
9
+ sharedscripts
10
+ postrotate
11
+ if [ -f /run/syslog-ng.pid ]; then
12
+ kill -HUP $(cat /run/syslog-ng.pid) 2>/dev/null || true
13
+ elif command -v rc-service >/dev/null 2>&1; then
14
+ rc-service syslog-ng reload 2>/dev/null || true
15
+ elif command -v systemctl >/dev/null 2>&1; then
16
+ systemctl reload syslog-ng 2>/dev/null || true
17
+ fi
18
+ endscript
19
+ }
@@ -0,0 +1,26 @@
1
+ # Network Hardening, Anti-Spoofing, and Kernel Protections for Gentoo Linux
2
+ # Location: /etc/sysctl.d/99-firewall-hardening.conf
3
+
4
+ # 1. Enable strict Reverse Path Filtering (IPv4 Anti-Spoofing)
5
+ net.ipv4.conf.all.rp_filter = 1
6
+ net.ipv4.conf.default.rp_filter = 1
7
+
8
+ # 2. Disable ICMP redirect acceptance and transmission (prevents MITM attacks)
9
+ net.ipv4.conf.all.accept_redirects = 0
10
+ net.ipv4.conf.default.accept_redirects = 0
11
+ net.ipv4.conf.all.secure_redirects = 0
12
+ net.ipv4.conf.default.secure_redirects = 0
13
+ net.ipv4.conf.all.send_redirects = 0
14
+ net.ipv4.conf.default.send_redirects = 0
15
+
16
+ # 3. Disable IP source routing acceptance (prevents malicious routing)
17
+ net.ipv4.conf.all.accept_source_route = 0
18
+ net.ipv4.conf.default.accept_source_route = 0
19
+
20
+ # 4. Log martian packets (impossible or unroutable source addresses)
21
+ net.ipv4.conf.all.log_martians = 1
22
+ net.ipv4.conf.default.log_martians = 1
23
+
24
+ # 5. Ignore ICMP echo broadcast and bogus error responses
25
+ net.ipv4.icmp_echo_ignore_broadcasts = 1
26
+ net.ipv4.icmp_ignore_bogus_error_responses = 1
@@ -0,0 +1,29 @@
1
+ # syslog-ng configuration for firewalld on Gentoo Linux
2
+ # /etc/syslog-ng/conf.d/firewalld.conf
3
+
4
+ # 1. Daemon service logs for firewalld
5
+ filter f_firewalld { program("firewalld"); };
6
+ destination d_firewalld { file("/var/log/firewalld/firewalld.log"); };
7
+ log { source(src); filter(f_firewalld); destination(d_firewalld); flags(final); };
8
+
9
+ # 2. Denied and dropped packet logs (LogDenied=all or unicast)
10
+ filter f_firewalld_all_denied {
11
+ match("_REJECT|_DROP|_DENIED|FINAL_REJECT|FINAL_DROP" value("MESSAGE") flags(ignore-case));
12
+ };
13
+
14
+ # Noise exclusions to prevent log flooding (adjust according to your network environment):
15
+ filter f_firewalld_denied {
16
+ filter(f_firewalld_all_denied)
17
+ # Example: discard local network mDNS noise (UDP port 5353)
18
+ and not match("DPT=5353" value("MESSAGE"))
19
+ # Example: discard ICMPv6 router advertisement noise
20
+ and not match("PROTO=ICMPv6" value("MESSAGE") flags(ignore-case));
21
+ };
22
+
23
+ # Rate-limiting with throttle(30) to prevent disk exhaustion from DoS or log flooding attacks
24
+ destination d_firewalld_denied { file("/var/log/firewalld/denied.log" throttle(30)); };
25
+ log { source(src); filter(f_firewalld_denied); destination(d_firewalld_denied); flags(final); };
26
+
27
+ # 3. Discard any remaining firewall drop logs (the excluded noise above)
28
+ # so they do not leak into /var/log/messages or subsequent catch-all destinations
29
+ log { source(src); filter(f_firewalld_all_denied); flags(final); };
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ # Example post-deployment script
3
+ # Automatically executed upon completion of 'poetry run firewalls_deploy <machine>'
4
+ # (Rename to post_deploy.sh to activate on the corresponding machine directory)
5
+
6
+ set -euo pipefail
7
+
8
+ # Example: Dynamically resolve a domain and add its IP to a firewalld IPSet
9
+ # DOMAIN="example.ddns.net"
10
+ # IPSET_NAME="trusted-hosts"
11
+ #
12
+ # echo "Resolving IP for '$DOMAIN'..."
13
+ # IP_ADDR=$(getent hosts "$DOMAIN" | awk '{print $1}')
14
+ # if [ -n "$IP_ADDR" ]; then
15
+ # echo "Adding IP $IP_ADDR to IPSet '$IPSET_NAME'..."
16
+ # firewall-cmd --quiet --ipset="$IPSET_NAME" --add-entry="$IP_ADDR" 2>/dev/null || true
17
+ # fi
18
+
19
+ echo "Post-deploy completed for example machine."
firewalls/__init__.py ADDED
@@ -0,0 +1,25 @@
1
+ """Firewalls management package."""
2
+
3
+ import datetime
4
+ import gettext
5
+ from pathlib import Path
6
+ from zoneinfo import ZoneInfo
7
+
8
+ __version__ = "0.1.0"
9
+ __version_datetime__ = datetime.datetime(2026, 10, 26, 13, 2, tzinfo=ZoneInfo("Europe/Madrid"))
10
+ __version_date__ = __version_datetime__.date()
11
+
12
+ LOCALE_DIR = Path(__file__).resolve().parent / "locale"
13
+ try:
14
+ _translation = gettext.translation("firewalls", localedir=LOCALE_DIR, fallback=True)
15
+ _ = _translation.gettext
16
+ except Exception:
17
+ _ = lambda s: s
18
+
19
+ __all__ = [
20
+ "__version__",
21
+ "__version_datetime__",
22
+ "__version_date__",
23
+ "_",
24
+ "LOCALE_DIR",
25
+ ]