diff --git a/stages/org.osbuild.firewall b/stages/org.osbuild.firewall new file mode 100755 index 00000000..8e76ee60 --- /dev/null +++ b/stages/org.osbuild.firewall @@ -0,0 +1,31 @@ +#!/usr/bin/python3 + +import json +import subprocess +import sys + + +def main(tree, options): + # Takes a list of : pairs + ports = options["ports"] + # These must be defined for firewalld. It has a set of pre-defined services here: /usr/lib/firewalld/services/, but + # you can also define you own XML files in /etc/firewalld. + enabled_services = options["enabled_services"] + disabled_services = options["disabled_services"] + + # firewall-offline-cmd does not implement --root option so we must chroot it + subprocess.run(["chroot", + tree, + "firewall-offline-cmd"] + + list(map(lambda x: f"--port={x}", ports)) + + list(map(lambda x: f"--service={x}", enabled_services)) + + list(map(lambda x: f"--remove-service={x}", disabled_services)), + check=True) + + return 0 + + +if __name__ == '__main__': + args = json.load(sys.stdin) + r = main(args["tree"], args["options"]) + sys.exit(r) diff --git a/test/firewall-test.json b/test/firewall-test.json new file mode 100644 index 00000000..05cd3e4f --- /dev/null +++ b/test/firewall-test.json @@ -0,0 +1,34 @@ +{ + "name": "Example Image", + "stages": [ + { + "name": "org.osbuild.dnf", + "options": { + "releasever": "30", + "repos": { + "fedora": { + "name": "Fedora", + "metalink": "https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch", + "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch" + } + }, + "packages": ["@Core", "firewalld"] + } + }, + { + "name": "org.osbuild.firewall", + "options": { + "ports": ["53:tcp", "88:udp"], + "enabled_services": ["http", "ftp"], + "disabled_services": ["telnet"] + } + } + ], + "assembler": { + "name": "org.osbuild.tar", + "options": { + "filename": "firewall-output.tar.xz", + "compression": "xz" + } + } +} diff --git a/test/run-tests.py b/test/run-tests.py index 8507f724..ce982cba 100644 --- a/test/run-tests.py +++ b/test/run-tests.py @@ -70,14 +70,34 @@ def build_timezone_image(): run_osbuild(rel_path("timezone-test.json")) -def test_timezone(): +def build_firewall_image(): + run_osbuild(rel_path("firewall-test.json")) + + +def extract_to_tempdir(image_file): extract_dir = tempfile.mkdtemp(prefix="osbuild-") - subprocess.run(["tar", "xf", OUTPUT_DIR + "/timezone-output.tar.xz"], cwd=extract_dir, check=True) + subprocess.run(["tar", "xf", OUTPUT_DIR + image_file], cwd=extract_dir, check=True) + return extract_dir + + +def test_timezone(): + extract_dir = extract_to_tempdir("timezone-output.tar.xz") ls = subprocess.run(["ls", "-l", "etc/localtime"], cwd=extract_dir, check=True, stdout=subprocess.PIPE) ls_output = ls.stdout.decode("utf-8") assert "Europe/Prague" in ls_output +def test_firewall(): + extract_dir = extract_to_tempdir("firewall-output.tar.xz") + cat = subprocess.run(["cat", "etc/firewalld/zones/public.xml"], cwd=extract_dir, check=True, stdout=subprocess.PIPE) + cat_output = cat.stdout.decode("utf-8") + assert 'service name="http"' in cat_output + assert 'service name="ftp"' in cat_output + assert 'service name="telnet"' not in cat_output + assert 'port port="53" protocol="tcp"' in cat_output + assert 'port port="88" protocol="udp"' in cat_output + + def evaluate_test(test): try: test() @@ -98,3 +118,5 @@ if __name__ == '__main__': build_timezone_image() evaluate_test(test_timezone) + build_firewall_image() + evaluate_test(test_firewall)