diff --git a/plinth/modules/firewall/__init__.py b/plinth/modules/firewall/__init__.py index 36b50925c..a4c2161ee 100644 --- a/plinth/modules/firewall/__init__.py +++ b/plinth/modules/firewall/__init__.py @@ -101,6 +101,7 @@ class FirewallApp(app_module.App): config = privileged.get_config() results.append(_diagnose_default_zone(config)) results.append(_diagnose_firewall_backend(config)) + results.append(_diagnose_direct_passthroughs(config)) return results @@ -275,3 +276,14 @@ def _diagnose_firewall_backend(config): testname = gettext('Firewall backend is nftables') result = 'passed' if config['backend'] == 'nftables' else 'failed' return [testname, result] + + +def _diagnose_direct_passthroughs(config): + """Diagnose direct passthroughs for local service protection. + + Currently, we just check that the number of passthroughs is at least 12, + which are the number that are added by firewall's setup. + """ + testname = gettext('Direct passthrough rules exist') + result = 'passed' if len(config['passthroughs']) >= 12 else 'failed' + return [testname, result] diff --git a/plinth/modules/firewall/privileged.py b/plinth/modules/firewall/privileged.py index 8d86d3800..f673b50dc 100644 --- a/plinth/modules/firewall/privileged.py +++ b/plinth/modules/firewall/privileged.py @@ -136,9 +136,11 @@ def get_config(): """Return firewalld configuration for diagnostics.""" config = {} + # Get the default zone. output = subprocess.check_output(['firewall-cmd', '--get-default-zone']) config['default_zone'] = output.decode().strip() + # Load Augeas lens. conf_file = '/etc/firewalld/firewalld.conf' aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) @@ -146,6 +148,12 @@ def get_config(): aug.set('/augeas/context', '/files' + conf_file) aug.load() + # Get the firewall backend. config['backend'] = aug.get('FirewallBackend') + # Get the list of direct passthroughs. + output = subprocess.check_output( + ['firewall-cmd', '--direct', '--get-all-passthroughs']) + config['passthroughs'] = output.decode().strip().split('\n') + return config