Files
RouterOS/RouterOSAssistant/Features/Wizard/Steps/Setup/FirewallStepView.swift
T
KayandClaude Sonnet 5 772549c991 M6: Firewall-Schritt (opt-in Sicherheits-Grundschutz)
Standardmäßig aus (Toggle wie VLAN) -- höchstes Risiko aller bisherigen
Schritte, falsche Regeln können Fernzugriff kappen. Preset ist
Mikrotiks eigener Standard-Ansatz (unverändert seit Jahren in
RouterOS-Werkskonfigurationen): NAT/Masquerade auf WAN, established/
related erlauben, invalid verwerfen, unaufgeforderte WAN-Verbindungen
zu LAN-Geräten blocken (außer explizitem Port-Forward via
connection-nat-state=!dstnat).

Jede neue Regel bekommt ein place-before mit aufsteigendem Index,
damit sie vor eventuell schon vorhandenen Regeln des Routers landet --
sonst könnte eine bereits vorhandene "alles blocken"-Regel unsere
neuen Regeln wirkungslos machen. NAT und Filter sind getrennte,
unabhängig nummerierte RouterOS-Listen.

Vor dem Anwenden zeigt der Schritt die Anzahl bereits vorhandener
Filter-/NAT-Regeln (neuer fetchFirewallRuleCounts()-Aufruf in
RouterOSTransport/RestTransport/SSHTransport/ConnectionService) --
Transparenz, bevor auf einem möglicherweise schon konfigurierten
Router weitere Regeln landen. Nutzer-Entscheidung, extra Lese-Aufruf
in Kauf zu nehmen statt nur Warntext.

Build + Test-Compile (build-for-testing) sind grün. Der eigentliche
Testlauf (xcodebuild test) hängt aktuell an einem macOS-Gatekeeper-
Netzwerk-Check für ad-hoc-signierte Binaries (amfid: "adhoc signed or
signed by an unknown certificate chain", GK performScan über
syspolicyd) -- kein Code-Bug, tritt nur bei CLI-Testläufen auf, nicht
beim normalen Xcode-Cmd+R-Weg. Nutzer verifiziert M6 deshalb direkt in
Xcode.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HReLXMbmPvtQ23p1iWiJNW
2026-09-12 19:57:53 +02:00

66 lines
2.7 KiB
Swift

import SwiftUI
struct FirewallStepView: View {
@ObservedObject var viewModel: SetupViewModel
var body: some View {
Form {
Section {
Toggle(
"Firewall-Grundschutz einrichten (empfohlen)",
isOn: Binding(
get: { viewModel.firewallSectionEnabled },
set: { viewModel.setFirewallSectionEnabled($0) }
)
)
Text(
"Richtet einen Standard-Schutz ein: Internetfreigabe (NAT) für dein Heimnetz, "
+ "und blockiert unaufgeforderte Zugriffe aus dem Internet auf deinen Router "
+ "und deine Geräte. Bestehende, selbst eingerichtete Regeln bleiben erhalten — "
+ "die neuen Regeln werden vorangestellt."
)
.font(.caption)
.foregroundStyle(.secondary)
}
if viewModel.firewallSectionEnabled {
Section("Bereits vorhandene Regeln") {
if viewModel.isLoadingFirewallRuleCounts {
ProgressView()
} else if let counts = viewModel.existingFirewallRuleCounts {
LabeledContent("Filter-Regeln", value: "\(counts.filterRuleCount)")
LabeledContent("NAT-Regeln", value: "\(counts.natRuleCount)")
if counts.filterRuleCount > 0 || counts.natRuleCount > 0 {
Text(
"Dein Router hat bereits eigene Firewall-Regeln. Die neuen Regeln werden "
+ "vorangestellt, bestehende bleiben erhalten — prüfe nach dem Anwenden "
+ "trotzdem die Reihenfolge, z.B. über Winbox oder "
+ "\"/ip firewall filter print\"."
)
.font(.caption)
.foregroundStyle(.orange)
}
} else if let error = viewModel.firewallRuleCountsError {
Text(error).font(.caption).foregroundStyle(.red)
}
}
}
Section {
HStack {
Button("Zurück") { viewModel.goBack() }
Spacer()
Button("Weiter") { viewModel.goNext() }
}
}
}
.formStyle(.grouped)
.navigationTitle("Firewall (optional)")
.onAppear {
if viewModel.firewallSectionEnabled {
viewModel.loadExistingFirewallRuleCounts()
}
}
}
}