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
66 lines
2.7 KiB
Swift
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()
|
|
}
|
|
}
|
|
}
|
|
}
|