introduce firewall stage (#61)

as described in lorax documentation, we need to support raw
ports/protocols and services as defined by firewalld:
https://weldr.io/lorax/lorax-composer.html#customizations-firewall
This commit is contained in:
msehnout 2019-08-07 09:34:22 +02:00 committed by GitHub
parent 9371eb9eaa
commit dc1466eeca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 89 additions and 2 deletions

31
stages/org.osbuild.firewall Executable file
View file

@ -0,0 +1,31 @@
#!/usr/bin/python3
import json
import subprocess
import sys
def main(tree, options):
# Takes a list of <port|application protocol>:<transport protocol> 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)

34
test/firewall-test.json Normal file
View file

@ -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"
}
}
}

View file

@ -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)