Add nftables firewall ruleset preview per server (review-only)
New firewall package generates an nftables snippet (INPUT accept for the listen port, FORWARD rules for the WireGuard interface, optional LAN forwarding via a new ServerSetting.LanInterface field). Text only - nothing is applied to the live firewall. Exposed as GET /servers/:id/firewall-preview and a "Firewall Preview" button in the All Servers page. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
0000643187
commit
28eb08df41
+56
-1
@@ -102,6 +102,11 @@ All Servers
|
||||
<label for="_settings_table" class="control-label">Table</label>
|
||||
<input type="text" class="form-control" id="_settings_table" placeholder="auto">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="_settings_lan_interface" class="control-label">LAN Interface</label>
|
||||
<input type="text" class="form-control" id="_settings_lan_interface" placeholder="e.g. eth0, br-lan">
|
||||
<small class="form-text text-muted">Optional. Used only for the Firewall Preview - lets peers forward to this interface.</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer justify-content-between">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
@@ -170,6 +175,29 @@ All Servers
|
||||
<!-- /.modal-dialog -->
|
||||
</div>
|
||||
<!-- /.modal -->
|
||||
|
||||
<div class="modal fade" id="modal_firewall_preview">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Firewall Preview (nftables)</h4>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="text-muted">Preview only - nothing is applied to the running firewall. Review, then apply manually if desired.</p>
|
||||
<pre id="_firewall_preview_text" style="max-height: 50vh; overflow:auto;"></pre>
|
||||
</div>
|
||||
<div class="modal-footer justify-content-between">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.modal-content -->
|
||||
</div>
|
||||
<!-- /.modal-dialog -->
|
||||
</div>
|
||||
<!-- /.modal -->
|
||||
{{end}}
|
||||
|
||||
{{define "bottom_js"}}
|
||||
@@ -203,6 +231,9 @@ All Servers
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" data-toggle="modal"
|
||||
data-target="#modal_server_interface" data-serverid="${obj.id}">Interface</button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-outline-info btn-sm btn-firewall-preview" data-serverid="${obj.id}">Firewall Preview</button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-outline-danger btn-sm btn-delete-server" data-serverid="${obj.id}" data-servername="${safeName}">Delete</button>
|
||||
</div>
|
||||
@@ -307,6 +338,7 @@ All Servers
|
||||
modal.find("#_settings_config_file_path").val("");
|
||||
modal.find("#_settings_firewall_mark").val("");
|
||||
modal.find("#_settings_table").val("");
|
||||
modal.find("#_settings_lan_interface").val("");
|
||||
|
||||
$.ajax({
|
||||
cache: false,
|
||||
@@ -319,6 +351,7 @@ All Servers
|
||||
modal.find("#_settings_config_file_path").val(settings.config_file_path);
|
||||
modal.find("#_settings_firewall_mark").val(settings.firewall_mark);
|
||||
modal.find("#_settings_table").val(settings.table);
|
||||
modal.find("#_settings_lan_interface").val(settings.lan_interface);
|
||||
},
|
||||
error: function (jqXHR, exception) {
|
||||
const responseJson = jQuery.parseJSON(jqXHR.responseText);
|
||||
@@ -333,7 +366,8 @@ All Servers
|
||||
"endpoint_address": $("#_settings_endpoint_address").val(),
|
||||
"config_file_path": $("#_settings_config_file_path").val(),
|
||||
"firewall_mark": $("#_settings_firewall_mark").val(),
|
||||
"table": $("#_settings_table").val()
|
||||
"table": $("#_settings_table").val(),
|
||||
"lan_interface": $("#_settings_lan_interface").val()
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
@@ -473,6 +507,27 @@ All Servers
|
||||
});
|
||||
});
|
||||
|
||||
// Firewall preview button: rendered dynamically, use event delegation
|
||||
$(document).ready(function () {
|
||||
$('#servers-list').on('click', '.btn-firewall-preview', function () {
|
||||
const serverId = $(this).data('serverid');
|
||||
$("#_firewall_preview_text").text("Loading...");
|
||||
$("#modal_firewall_preview").modal('show');
|
||||
$.ajax({
|
||||
cache: false,
|
||||
method: 'GET',
|
||||
url: '{{.basePath}}/servers/' + serverId + '/firewall-preview',
|
||||
dataType: 'text',
|
||||
success: function (data) {
|
||||
$("#_firewall_preview_text").text(data);
|
||||
},
|
||||
error: function (jqXHR, exception) {
|
||||
$("#_firewall_preview_text").text("Could not load firewall preview.");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Delete server button: rendered dynamically, use event delegation
|
||||
$(document).ready(function () {
|
||||
$('#servers-list').on('click', '.btn-delete-server', function () {
|
||||
|
||||
Reference in New Issue
Block a user