From de073a47953fc52b62615906f9be3b913c397796 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Sat, 2 Mar 2024 10:59:08 -0300 Subject: [PATCH] Firewall export first commit --- firewall/tools.py | 88 ++++++++++++++++++++++ firewall/views.py | 13 +++- templates/firewall/firewall_rule_list.html | 3 - wireguard_webadmin/urls.py | 3 +- 4 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 firewall/tools.py diff --git a/firewall/tools.py b/firewall/tools.py new file mode 100644 index 0000000..4a9247f --- /dev/null +++ b/firewall/tools.py @@ -0,0 +1,88 @@ +from firewall.models import FirewallRule +from wireguard.models import Peer, PeerAllowedIP + +def get_peer_addresses(peers, include_networks): + addresses = [] + # Indica se algum peer está completamente sem PeerAllowedIP + missing_ip = False + for peer in peers.all(): + peer_ips = peer.peerallowedip_set.all().order_by('priority') + if not include_networks: + peer_ips = peer_ips.filter(priority=0) + + if peer_ips.exists(): + addresses.extend([f"{peer_ip.allowed_ip}/{peer_ip.netmask}" for peer_ip in peer_ips]) + else: + missing_ip = True + + return addresses, missing_ip + +def generate_iptable_rules(): + iptables_rules = [] + rules = FirewallRule.objects.all().order_by('firewall_chain', 'sort_order') + + for rule in rules: + source_addresses, source_missing_ip = get_peer_addresses(rule.source_peer, rule.source_peer_include_networks) + destination_addresses, destination_missing_ip = get_peer_addresses(rule.destination_peer, rule.destination_peer_include_networks) + + # Adiciona source_ip/destination_ip às listas, se definidos + if rule.source_ip: + source_addresses.append(f"{rule.source_ip}/{rule.source_netmask}") + if rule.destination_ip: + destination_addresses.append(f"{rule.destination_ip}/{rule.destination_netmask}") + + # Caso especial: se não houver endereços de source e destination, cria uma lista vazia para garantir a execução do loop + if not source_addresses: + source_addresses = [None] + if not destination_addresses: + destination_addresses = [None] + + protocols = ['tcp', 'udp'] if rule.protocol == 'both' else [rule.protocol] if rule.protocol else [''] + + for protocol in protocols: + for source in source_addresses: + for destination in destination_addresses: + description = f" - {rule.description}" if rule.description else "" + comment = f"\n# {rule.sort_order} - {rule.uuid}{description}" + # Pula a geração de regra se um dos peers estiver faltando IP e for relevante para essa combinação + if (source is None and source_missing_ip) or (destination is None and destination_missing_ip): + iptables_rule = f"{comment} - Missing ip for selected peer\n" + iptables_rules.append(iptables_rule) + continue + comment += '\n' + if rule.firewall_chain == "forward": + rule_base = "iptables -t filter -A FORWARD " + elif rule.firewall_chain == "postrouting": + rule_base = "iptables -t nat -A POSTROUTING " + else: + rule_base = f"#iptables -A {rule.firewall_chain.upper()} " + rule_protocol = f"-p {protocol} " if protocol else "" + rule_destination_port = f"--dport {rule.destination_port} " if rule.destination_port else "" + rule_source = f"-s {source} " if source else "" + rule_destination = f"-d {destination} " if destination else "" + rule_action = f"-j {rule.rule_action.upper()}" + + states = [] + if rule.state_new: + states.append("NEW") + if rule.state_related: + states.append("RELATED") + if rule.state_established: + states.append("ESTABLISHED") + if rule.state_invalid: + states.append("INVALID") + if rule.state_untracked: + states.append("UNTRACKED") + + not_state = "! " if rule.not_state and states else "" + rule_state = f"-m state {not_state}--state {','.join(states)} " if states else "" + + not_source = "! " if rule.not_source and source else "" + not_destination = "! " if rule.not_destination and destination else "" + + + iptables_rule = f"{comment}{rule_base}{not_source}{rule_source}{not_destination}{rule_destination}{rule_state}{rule_protocol}{rule_destination_port}{rule_action}\n" + iptables_rules.append(iptables_rule) + + return "".join(iptables_rules) + diff --git a/firewall/views.py b/firewall/views.py index 6a85caa..d838b72 100644 --- a/firewall/views.py +++ b/firewall/views.py @@ -1,3 +1,4 @@ +from django.http import JsonResponse from django.shortcuts import render, get_object_or_404, redirect from django.db.models import Max from firewall.models import RedirectRule, FirewallRule, FirewallSettings @@ -5,7 +6,7 @@ from firewall.forms import RedirectRuleForm, FirewallRuleForm, FirewallSettingsF from django.contrib import messages from wireguard.models import WireGuardInstance from user_manager.models import UserAcl -from wgwadmlibrary.tools import list_network_interfaces +from firewall.tools import generate_iptable_rules def view_redirect_rule_list(request): @@ -160,3 +161,13 @@ def view_manage_firewall_settings(request): return render(request, 'firewall/manage_firewall_settings.html', context=context) + +def view_generate_iptables_script(request): + data = {'status': 'ok'} + firewall_rule_list = FirewallRule.objects.all().order_by('firewall_chain', 'sort_order') + for rule in firewall_rule_list: + print(str(rule.sort_order) + ' - ' + str(rule.uuid)) + + rules_text = generate_iptable_rules() + print(rules_text) + return JsonResponse(data) diff --git a/templates/firewall/firewall_rule_list.html b/templates/firewall/firewall_rule_list.html index 4a42c2b..41f6b74 100644 --- a/templates/firewall/firewall_rule_list.html +++ b/templates/firewall/firewall_rule_list.html @@ -22,9 +22,6 @@ display: none; } - - - {% endblock%} diff --git a/wireguard_webadmin/urls.py b/wireguard_webadmin/urls.py index 60c31d5..43621ed 100644 --- a/wireguard_webadmin/urls.py +++ b/wireguard_webadmin/urls.py @@ -23,7 +23,7 @@ from user_manager.views import view_user_list, view_manage_user from accounts.views import view_create_first_user, view_login, view_logout from wireguard_tools.views import export_wireguard_configs, download_config_or_qrcode, restart_wireguard_interfaces from api.views import wireguard_status, cron_check_updates, cron_update_peer_latest_handshake -from firewall.views import view_redirect_rule_list, manage_redirect_rule, view_firewall_rule_list, manage_firewall_rule, view_manage_firewall_settings +from firewall.views import view_redirect_rule_list, manage_redirect_rule, view_firewall_rule_list, manage_firewall_rule, view_manage_firewall_settings, view_generate_iptables_script urlpatterns = [ @@ -51,4 +51,5 @@ urlpatterns = [ path('firewall/rule_list/', view_firewall_rule_list, name='firewall_rule_list'), path('firewall/manage_firewall_rule/', manage_firewall_rule, name='manage_firewall_rule'), path('firewall/firewall_settings/', view_manage_firewall_settings, name='firewall_settings'), + path('firewall/generate_firewall_script/', view_generate_iptables_script, name='generate_iptables_script'), ]