Enable wg kill switch

This commit is contained in:
billz
2025-07-14 02:18:56 -07:00
parent 810218b67e
commit b5e79b9148
2 changed files with 86 additions and 24 deletions

View File

@@ -1,28 +1,33 @@
<?php
require_once 'config.php';
require_once 'includes/wifi_functions.php';
require_once 'includes/config.php';
getWifiInterface();
/**
* Displays wireguard server & peer configuration
*/
function DisplayWireGuardConfig()
{
$status = new \RaspAP\Messages\StatusMessage;
$parseFlag = true;
$status = new \RaspAP\Messages\StatusMessage;
if (!RASPI_MONITOR_ENABLED) {
$optRules = isset($_POST['wgRules']) ? $_POST['wgRules'] : null;
$optInterface = isset($_POST['wgInterface']) ? $_POST['wgInterface'] : null;
$optConf = isset($_POST['wgCnfOpt']) ? $_POST['wgCnfOpt'] : null;
$optSrvEnable = isset($_POST['wgSrvEnable']) ? $_POST['wgSrvEnable'] : null;
$optLogEnable = isset($_POST['wgLogEnable']) ? $_POST['wgLogEnable'] : null;
$optKSwitch = isset($_POST['wgKSwitch']) ? $_POST['wgKSwitch'] : null;
if (isset($_POST['savewgsettings']) && $optConf == 'manual' && $optSrvEnable == 1 ) {
SaveWireGuardConfig($status);
} elseif (isset($_POST['savewgsettings']) && $optConf == 'upload' && is_uploaded_file($_FILES["wgFile"]["tmp_name"])) {
SaveWireGuardUpload($status, $_FILES['wgFile'], $optRules, $optInterface);
SaveWireGuardUpload($status, $_FILES['wgFile'], $optRules, $optKSwitch, $optInterface);
} elseif (isset($_POST['savewgsettings']) && isset($_POST['wg_penabled']) ) {
SaveWireGuardConfig($status);
} elseif (isset($_POST['startwg'])) {
$status->addMessage('Attempting to start WireGuard', 'info');
exec('sudo /bin/systemctl enable wg-quick@wg0', $return);
exec('sudo /bin/systemctl start wg-quick@wg0', $return);
foreach ($return as $line) {
$status->addMessage($line, 'info');
@@ -30,6 +35,7 @@ function DisplayWireGuardConfig()
} elseif (isset($_POST['stopwg'])) {
$status->addMessage('Attempting to stop WireGuard', 'info');
exec('sudo /bin/systemctl stop wg-quick@wg0', $return);
exec('sudo /bin/systemctl disable wg-quick@wg0', $return);
foreach ($return as $line) {
$status->addMessage($line, 'info');
}
@@ -70,11 +76,18 @@ function DisplayWireGuardConfig()
$wg_state = ($wgstatus[0] == 'active' ? true : false );
$public_ip = get_public_ip();
// retrieve wg log
$wg_log = "";
// fetch uploaded file configs
exec("sudo ls ".RASPI_WIREGUARD_PATH, $clist);
$configs = preg_grep('/^((?!wg0).)*\.conf/', $clist);
exec("sudo readlink ".RASPI_WIREGUARD_CONFIG." | xargs basename", $ret);
$conf_default = empty($ret) ? "none" : $ret[0];
// fetch wg log
exec('sudo chmod o+r /tmp/wireguard.log');
if (file_exists('/tmp/wireguard.log')) {
exec('sudo chmod o+r /tmp/wireguard.log');
$wg_log = file_get_contents('/tmp/wireguard.log');
$log = file_get_contents('/tmp/wireguard.log');
} else {
$log = '';
}
$peer_id = $peer_id ?? "1";
@@ -90,6 +103,7 @@ function DisplayWireGuardConfig()
"public_ip",
"interfaces",
"optRules",
"optKSwitch",
"optLogEnable",
"peer_id",
"wg_srvpubkey",
@@ -104,7 +118,9 @@ function DisplayWireGuardConfig()
"wg_pendpoint",
"wg_pallowedips",
"wg_pkeepalive",
"wg_log"
"configs",
"conf_default",
"log"
)
);
}
@@ -116,10 +132,11 @@ function DisplayWireGuardConfig()
* @param object $status
* @param object $file
* @param boolean $optRules
* @param boolean $optKSwitch
* @param string $optInterface
* @return object $status
*/
function SaveWireGuardUpload($status, $file, $optRules, $optInterface)
function SaveWireGuardUpload($status, $file, $optRules, $optKSwitch, $optInterface)
{
define('KB', 1024);
$tmp_destdir = '/tmp/';
@@ -148,19 +165,56 @@ function SaveWireGuardUpload($status, $file, $optRules, $optInterface)
$tmp_wgconfig = $results['full_path'];
$tmp_contents = file_get_contents($tmp_wgconfig);
// Set iptables rules
if (isset($optRules) && !preg_match('/PostUp|PostDown/m',$tmp_contents)) {
$rules[] = 'PostUp = '.getDefaultNetValue('wireguard','server','PostUp');
$rules[] = 'PostDown = '.getDefaultNetValue('wireguard','server','PostDown');
$rules[] = '';
$rules = join(PHP_EOL, $rules);
$rules = preg_replace('/wlan0/m', $optInterface, $rules);
$tmp_contents = preg_replace('/^\s*$/ms', $rules, $tmp_contents, 1);
file_put_contents($tmp_wgconfig, $tmp_contents);
// Check for existing iptables rules
if ((isset($optRules) || isset($optKSwitch)) && preg_match('/PostUp|PostDown|PreDown/m',$tmp_contents)) {
$status->addMessage('Existing iptables rules found in WireGuard configuration - not added', 'info');
} else {
// Set rules from default config
if (isset($optRules)) {
$rules[] = 'PostUp = '.getDefaultNetValue('wireguard','server','PostUp');
$rules[] = 'PostDown = '.getDefaultNetValue('wireguard','server','PostDown');
$rules = preg_replace('/wlan0/m', $optInterface, $rules);
}
if (isset($optKSwitch)) {
// Get ap static ip_addr from system config, fallback to default if undefined
$jsonData = json_decode(getNetConfig($optInterface), true);
$ip_addr = ($jsonData['StaticIP'] == '') ? getDefaultNetValue('dhcp', $optInterface, 'static ip_address') : $jsonData['StaticIP'];
$mask = ($jsonData['SubnetMask'] == '') ? getDefaultNetValue('dhcp', $optInterface, 'subnetmask') : $jsonData['SubnetMask'];
// if empty, try to detect IP/mask from system
if (empty($ip_addr) || empty($mask)) {
$ipDetails = shell_exec("ip -4 -o addr show dev " . escapeshellarg($optInterface));
if (preg_match('/inet (\d+\.\d+\.\d+\.\d+)\/(\d+)/', $ipDetails, $matches)) {
$ip_addr = $matches[1];
$cidr = $matches[2];
} else {
$ip_addr = '0.0.0.0';
$cidr = '24';
}
} else {
$cidr = mask2cidr($mask);
}
$cidr_ip = strpos($ip_addr, '/') === false ? "$ip_addr/$cidr" : $ip_addr;
$rules[] = 'PostUp = '.getDefaultNetValue('wireguard','server','PostUpEx');
$rules[] = 'PreDown = '.getDefaultNetValue('wireguard','server','PreDown');
$rules = preg_replace('/%s/m', $cidr_ip, $rules);
}
if ((isset($rules) && count($rules) > 0)) {
$rules[] = '';
$rules = join(PHP_EOL, $rules);
$tmp_contents = preg_replace('/^\s*$/ms', $rules, $tmp_contents, 1);
file_put_contents($tmp_wgconfig, $tmp_contents);
$status->addMessage('iptables rules added to WireGuard configuration', 'info');
}
}
// Move processed file from tmp to destination
system("sudo mv $tmp_wgconfig ". RASPI_WIREGUARD_CONFIG, $return);
// Move processed file from /tmp and create symlink
$client_wg = RASPI_WIREGUARD_PATH.pathinfo($file['name'], PATHINFO_FILENAME).'.conf';
chmod($tmp_wgconfig, 0644);
system("sudo mv $tmp_wgconfig $client_wg", $return);
system("sudo rm ".RASPI_WIREGUARD_CONFIG, $return);
system("sudo ln -s $client_wg ".RASPI_WIREGUARD_CONFIG, $return);
if ($return ==0) {
$status->addMessage('WireGuard configuration uploaded successfully', 'info');
@@ -225,7 +279,7 @@ function SaveWireGuardConfig($status)
$wg_pendpoint_seg = substr($_POST['wg_pendpoint'],0,strpos($_POST['wg_pendpoint'],':'));
$host_port = explode(':', $wg_pendpoint_seg);
$hostname = $host_port[0];
if (!filter_var($hostname, FILTER_VALIDATE_IP) &&
if (!filter_var($hostname, FILTER_VALIDATE_IP) &&
!filter_var($hostname, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
$status->addMessage('Invalid value for endpoint address', 'danger');
$good_input = false;
@@ -295,11 +349,10 @@ function SaveWireGuardConfig($status)
}
$config[] = '';
$config = join(PHP_EOL, $config);
file_put_contents("/tmp/wgdata", $config);
system('sudo cp /tmp/wgdata '.RASPI_WIREGUARD_PATH.'client.conf', $return);
} else {
# remove selected conf + keys
# remove selected conf + keys
system('sudo rm '. RASPI_WIREGUARD_PATH .'wg-peer-private.key', $return);
system('sudo rm '. RASPI_WIREGUARD_PATH .'wg-peer-public.key', $return);
system('sudo rm '. RASPI_WIREGUARD_PATH.'client.conf', $return);

View File

@@ -39,9 +39,18 @@
<i class="fas fa-question-circle text-muted" data-bs-toggle="tooltip" data-bs-placement="auto" title="<?php echo _("Recommended if you wish to forward network traffic from the wg0 interface to clients connected on a desired interface. The active AP interface is the default."); ?>"></i>
<p id="wg-description">
<small><?php echo _("This option adds <strong>iptables</strong> <code>Postup</code> and <code>PostDown</code> rules for the interface selected below."); ?></small>
<div class="col-sm-6">
</p>
<div class="col-sm-6 mb-3">
<?php SelectorOptions('wgInterface', $interfaces, $_SESSION['ap_interface'], 'cbxinterface'); ?>
</div>
</div>
<div class="form-check form-switch">
<?php $checked = $optKSwitch == 1 ? 'checked="checked"' : '' ?>
<input class="form-check-input" id="chxwgkswitch" name="wgKSwitch" type="checkbox" value="1" <?php echo $checked ?> />
<label class="form-check-label" for="chxwgkswitch"><?php echo _("Enable kill switch"); ?></label>
<i class="fas fa-question-circle text-muted" data-bs-toggle="tooltip" data-bs-placement="auto" title="<?php echo _("Recommended if you wish to prevent the flow of unencrypted packets through non-WireGuard interfaces."); ?>"></i>
<p id="wg-description">
<small><?php echo _("This option adds <strong>iptables</strong> <code>PostUp</code> and <code>PreDown</code> rules for the configured interface."); ?></small>
</p>
</div>
</div>