diff --git a/includes/wireguard.php b/includes/wireguard.php index 233dd33b..ea2b1fe9 100755 --- a/includes/wireguard.php +++ b/includes/wireguard.php @@ -1,28 +1,33 @@ 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); diff --git a/templates/wg/general.php b/templates/wg/general.php index 9b8b8246..e7e0399a 100644 --- a/templates/wg/general.php +++ b/templates/wg/general.php @@ -39,9 +39,18 @@ ">
iptables Postup and PostDown rules for the interface selected below."); ?>
-
+ iptables PostUp and PreDown rules for the configured interface."); ?>