diff --git a/app/js/custom.js b/app/js/custom.js index 4ba0436b..dc886d07 100644 --- a/app/js/custom.js +++ b/app/js/custom.js @@ -307,7 +307,6 @@ $('#ovpn-confirm-activate').on('shown.bs.modal', function (e) { }); $('#ovpn-userpw,#ovpn-certs').on('click', function (e) { -// e.stopPropagation(); if (this.id == 'ovpn-userpw') { $('#PanelCerts').hide(); $('#PanelUserPW').show(); @@ -317,6 +316,20 @@ $('#ovpn-userpw,#ovpn-certs').on('click', function (e) { } }); +$(document).ready(function(){ + $("#PanelManual").hide(); +}); + +$('#wg-upload,#wg-manual').on('click', function (e) { + if (this.id == 'wg-upload') { + $('#PanelManual').hide(); + $('#PanelUpload').show(); + } else if (this.id == 'wg-manual') { + $('#PanelUpload').hide(); + $('#PanelManual').show(); + } +}); + // Add the following code if you want the name of the file appear on select $(".custom-file-input").on("change", function() { var fileName = $(this).val().split("\\").pop(); diff --git a/app/lib/uploader.php b/app/lib/uploader.php new file mode 100644 index 00000000..6e19d9e8 --- /dev/null +++ b/app/lib/uploader.php @@ -0,0 +1,505 @@ + + * @author Aivis Silins + * @link https://github.com/aivis/PHP-file-upload-class + * @license https://github.com/raspap/raspap-webgui/blob/master/LICENSE + */ + +namespace RaspAP\Uploader; + +class Upload +{ + + /** + * Default directory persmissions (destination) + */ + protected $default_permissions = 0750; + + /** + * File post array + * + * @var array + */ + protected $file_post = array(); + + /** + * Destination directory + * + * @var string + */ + protected $destination; + + /** + * Fileinfo + * + * @var object + */ + protected $finfo; + + /** + * Data about file + * + * @var array + */ + public $file = array(); + + /** + * Max. file size + * + * @var int + */ + protected $max_file_size; + + /** + * Allowed mime types + * + * @var array + */ + protected $mimes = array(); + + /** + * Temp path + * + * @var string + */ + protected $tmp_name; + + /** + * Validation errors + * + * @var array + */ + protected $validation_errors = array(); + + /** + * Filename (new) + * + * @var string + */ + protected $filename; + + /** + * Internal callbacks (filesize check, mime, etc) + * + * @var array + */ + private $callbacks = array(); + + /** + * Root dir + * + * @var string + */ + protected $root; + + /** + * Return upload object + * + * $destination = 'path/to/file/destination/'; + * + * @param string $destination + * @param string $root + * @return Upload + */ + public static function factory($destination, $root = false) + { + return new Upload($destination, $root); + } + + /** + * Define root constant and set & create destination path + * + * @param string $destination + * @param string $root + */ + public function __construct($destination, $root = false) + { + if ($root) { + $this->root = $root; + } else { + $this->root = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR; + } + + // set & create destination path + if (!$this->set_destination($destination)) { + throw new Exception('Upload: Unable to create destination. '.$this->root . $this->destination); + } + //create finfo object + $this->finfo = new \finfo(); + } + + /** + * Set target filename + * + * @param string $filename + */ + public function set_filename($filename) + { + $this->filename = $filename; + } + + /** + * Check & Save file + * + * Return data about current upload + * + * @return array + */ + public function upload($filename = false) + { + if($filename ) { + $this->set_filename($filename); + } + + $this->set_filename($filename); + + if ($this->check()) { + $this->save(); + } + + // return state data + return $this->get_state(); + } + + /** + * Save file on server + * Return state data + * + * @return array + */ + public function save() + { + $this->save_file(); + return $this->get_state(); + } + + /** + * Validate file (execute callbacks) + * Returns TRUE if validation successful + * + * @return bool + */ + public function check() + { + //execute callbacks (check filesize, mime, also external callbacks + $this->validate(); + + //add error messages + $this->file['errors'] = $this->get_errors(); + + //change file validation status + $this->file['status'] = empty($this->validation_errors); + + return $this->file['status']; + } + + /** + * Get current state data + * + * @return array + */ + public function get_state() + { + return $this->file; + } + + /** + * Save file on server + */ + protected function save_file() + { + //create & set new filename + if(empty($this->filename)) { + $this->create_new_filename(); + } + + //set filename + $this->file['filename'] = $this->filename; + + //set full path + $this->file['full_path'] = $this->root . $this->destination . $this->filename; + $this->file['path'] = $this->destination . $this->filename; + + $status = move_uploaded_file($this->tmp_name, $this->file['full_path']); + + //checks whether upload successful + if (!$status) { + throw new Exception('Upload: Failed to upload file.'); + } + + //done + $this->file['status'] = true; + } + + /** + * Set data about file + */ + protected function set_file_data() + { + $file_size = $this->get_file_size(); + $this->file = array( + 'status' => false, + 'destination' => $this->destination, + 'size_in_bytes' => $file_size, + 'size_in_mb' => $this->bytes_to_mb($file_size), + 'mime' => $this->get_file_mime(), + 'filename' => $this->file_post['name'], + 'tmp_name' => $this->file_post['tmp_name'], + 'post_data' => $this->file_post, + ); + } + + /** + * Set validation error + * + * @param string $message + */ + public function set_error($message) + { + $this->validation_errors[] = $message; + } + + /** + * Return validation errors + * + * @return array + */ + public function get_errors() + { + return $this->validation_errors; + } + + /** + * Set external callback methods + * + * @param object $instance_of_callback_object + * @param array $callback_methods + */ + public function callbacks($instance_of_callback_object, $callback_methods) + { + if (empty($instance_of_callback_object)) { + throw new Exception('Upload: $instance_of_callback_object cannot be empty.'); + + } + + if (!is_array($callback_methods)) { + throw new Exception('Upload: $callback_methods data type need to be array.'); + } + + $this->external_callback_object = $instance_of_callback_object; + $this->external_callback_methods = $callback_methods; + } + + /** + * Execute callbacks + */ + protected function validate() + { + //get curent errors + $errors = $this->get_errors(); + + if (empty($errors)) { + + //set data about current file + $this->set_file_data(); + + //execute internal callbacks + $this->execute_callbacks($this->callbacks, $this); + + //execute external callbacks + $this->execute_callbacks($this->external_callback_methods, $this->external_callback_object); + } + } + + /** + * Execute callbacks + */ + protected function execute_callbacks($callbacks, $object) + { + foreach($callbacks as $method) { + $object->$method($this); + + } + } + + /** + * File mime type validation callback + * + * @param object $object + */ + protected function check_mime_type($object) + { + if (!empty($object->mimes)) { + if (!in_array($object->file['mime'], $object->mimes)) { + $object->set_error('Mime type not allowed.'); + } + } + } + + /** + * Set allowed mime types + * + * @param array $mimes + */ + public function set_allowed_mime_types($mimes) + { + $this->mimes = $mimes; + //if mime types is set -> set callback + $this->callbacks[] = 'check_mime_type'; + } + + /** + * File size validation callback + * + * @param object $object + */ + protected function check_file_size($object) + { + if (!empty($object->max_file_size)) { + $file_size_in_mb = $this->bytes_to_mb($object->file['size_in_bytes']); + if ($object->max_file_size <= $file_size_in_mb) { + $object->set_error('File exceeds maximum allowed size.'); + } + } + } + + /** + * Set max file size + * + * @param int $size + */ + public function set_max_file_size($size) + { + $this->max_file_size = $size; + + //if max file size is set -> set callback + $this->callbacks[] = 'check_file_size'; + } + + /** + * Set File array to object + * + * @param array $file + */ + public function file($file) + { + $this->set_file_array($file); + } + + /** + * Set file array + * + * @param array $file + */ + protected function set_file_array($file) + { + //checks whether file array is valid + if (!$this->check_file_array($file)) { + //file not selected or some bigger problems (broken files array) + $this->set_error('Please select file.'); + } + + //set file data + $this->file_post = $file; + + //set tmp path + $this->tmp_name = $file['tmp_name']; + } + + /** + * Checks whether Files post array is valid + * + * @return bool + */ + protected function check_file_array($file) + { + return isset($file['error']) + && !empty($file['name']) + && !empty($file['type']) + && !empty($file['tmp_name']) + && !empty($file['size']); + } + + /** + * Get file mime type + * + * @return string + */ + protected function get_file_mime() + { + return $this->finfo->file($this->tmp_name, FILEINFO_MIME_TYPE); + } + + /** + * Get file size + * + * @return int + */ + protected function get_file_size() + { + return filesize($this->tmp_name); + } + + /** + * Set destination path (return TRUE on success) + * + * @param string $destination + * @return bool + */ + protected function set_destination($destination) + { + $this->destination = $destination . DIRECTORY_SEPARATOR; + return $this->destination_exist() ? true : $this->create_destination(); + } + + /** + * Checks whether destination folder exists + * + * @return bool + */ + protected function destination_exist() + { + return is_writable($this->root . $this->destination); + } + + /** + * Create path to destination + * + * @param string $dir + * @return bool + */ + protected function create_destination() + { + return mkdir($this->root . $this->destination, $this->default_permissions, true); + } + + /** + * Set unique filename + * + * @return string + */ + protected function create_new_filename() + { + $filename = sha1(mt_rand(1, 9999) . $this->destination . uniqid()) . time(); + $this->set_filename($filename); + } + + /** + * Convert bytes to MB + * + * @param int $bytes + * @return int + */ + protected function bytes_to_mb($bytes) + { + return round(($bytes / 1048576), 2); + } +} + diff --git a/includes/functions.php b/includes/functions.php index 93c609a3..8ccd2430 100755 --- a/includes/functions.php +++ b/includes/functions.php @@ -721,13 +721,15 @@ function validateCidr($cidr) } // Validates a host or FQDN -function validate_host($host) { +function validate_host($host) +{ return preg_match('/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i', $host); } // Gets night mode toggle value // @return boolean -function getNightmode(){ +function getNightmode() +{ if ($_COOKIE['theme'] == 'lightsout.css') { return true; } else { @@ -736,7 +738,8 @@ function getNightmode(){ } // search array for matching string and return only first matching group -function preg_only_match($pat,$haystack) { +function preg_only_match($pat,$haystack) +{ $match = ""; if(!empty($haystack) && !empty($pat)) { if(!is_array($haystack)) $haystack = array($haystack); @@ -754,10 +757,34 @@ function qr_encode($str) return preg_replace('/(?file['filename']) > 255) { + $object->set_error('File name is too long.'); + } + } +} + +/* Resolves public IP address + * + * @return string $public_ip + */ +function get_public_ip() +{ + exec('wget https://ipinfo.io/ip -qO -', $public_ip); + return $public_ip[0]; +} + diff --git a/includes/openvpn.php b/includes/openvpn.php index 67084df4..a89c3e18 100755 --- a/includes/openvpn.php +++ b/includes/openvpn.php @@ -3,6 +3,7 @@ require_once 'includes/status_messages.php'; require_once 'includes/config.php'; require_once 'includes/wifi_functions.php'; +require_once 'app/lib/uploader.php'; getWifiInterface(); @@ -41,11 +42,9 @@ function DisplayOpenVPNConfig() } exec('pidof openvpn | wc -l', $openvpnstatus); - exec('wget https://ipinfo.io/ip -qO -', $return); - $serviceStatus = $openvpnstatus[0] == 0 ? "down" : "up"; $auth = file(RASPI_OPENVPN_CLIENT_LOGIN, FILE_IGNORE_NEW_LINES); - $public_ip = $return[0]; + $public_ip = get_public_ip(); // parse client auth credentials if (!empty($auth)) { @@ -100,8 +99,8 @@ function DisplayOpenVPNConfig() */ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword) { - $tmp_ovpnclient = '/tmp/ovpnclient.ovpn'; - $tmp_authdata = '/tmp/authdata'; + define('KB', 1024); + $tmp_destdir = '/tmp/'; $auth_flag = 0; try { @@ -110,66 +109,28 @@ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword) throw new RuntimeException('Invalid parameters'); } - // Parse returned errors - switch ($file['error']) { - case UPLOAD_ERR_OK: - break; - case UPLOAD_ERR_NO_FILE: - throw new RuntimeException('OpenVPN configuration file not sent'); - case UPLOAD_ERR_INI_SIZE: - case UPLOAD_ERR_FORM_SIZE: - throw new RuntimeException('Exceeded filesize limit'); - default: - throw new RuntimeException('Unknown errors'); - } + $upload = \RaspAP\Uploader\Upload::factory('ovpn',$tmp_destdir); + $upload->set_max_file_size(64*KB); + $upload->set_allowed_mime_types(array('ovpn' => 'text/plain')); + $upload->file($file); - // Validate extension - $ext = pathinfo($file['name'], PATHINFO_EXTENSION); - if ($ext != 'ovpn') { - throw new RuntimeException('Invalid file extension'); - } + $validation = new validation; + $upload->callbacks($validation, array('check_name_length')); + $results = $upload->upload(); - // Validate MIME type - $finfo = new finfo(FILEINFO_MIME_TYPE); - if (false === $ext = array_search( - $finfo->file($file['tmp_name']), - array( - 'ovpn' => 'text/plain' - ), - true - ) - ) { - throw new RuntimeException('Invalid file format'); - } - - // Validate filesize - define('KB', 1024); - if ($file['size'] > 64*KB) { - throw new RuntimeException('File size limit exceeded'); - } - - // Use safe filename, save to /tmp - if (!move_uploaded_file( - $file['tmp_name'], - sprintf( - '/tmp/%s.%s', - 'ovpnclient', - $ext - ) - ) - ) { - throw new RuntimeException('Unable to move uploaded file'); + if (!empty($results['errors'])) { + throw new RuntimeException($results['errors'][0]); } // Good file upload, update auth credentials if present if (!empty($authUser) && !empty($authPassword)) { $auth_flag = 1; - // Move tmp authdata to /etc/openvpn/login.conf - $auth.= $authUser .PHP_EOL . $authPassword .PHP_EOL; + $tmp_authdata = $tmp_destdir .'ovpn/authdata'; + $auth = $authUser .PHP_EOL . $authPassword .PHP_EOL; file_put_contents($tmp_authdata, $auth); chmod($tmp_authdata, 0644); $client_auth = RASPI_OPENVPN_CLIENT_PATH.pathinfo($file['name'], PATHINFO_FILENAME).'_login.conf'; - system("sudo cp $tmp_authdata $client_auth", $return); + system("sudo mv $tmp_authdata $client_auth", $return); system("sudo rm ".RASPI_OPENVPN_CLIENT_LOGIN, $return); system("sudo ln -s $client_auth ".RASPI_OPENVPN_CLIENT_LOGIN, $return); if ($return !=0) { @@ -178,14 +139,16 @@ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword) } // Set iptables rules and, optionally, auth-user-pass - exec("sudo /etc/raspap/openvpn/configauth.sh $tmp_ovpnclient $auth_flag " .$_SESSION['ap_interface'], $return); + $tmp_ovpn = $results['full_path']; + exec("sudo /etc/raspap/openvpn/configauth.sh $tmp_ovpn $auth_flag " .$_SESSION['ap_interface'], $return); foreach ($return as $line) { $status->addMessage($line, 'info'); } + // Move uploaded ovpn config from /tmp and create symlink $client_ovpn = RASPI_OPENVPN_CLIENT_PATH.pathinfo($file['name'], PATHINFO_FILENAME).'_client.conf'; - chmod($tmp_ovpnclient, 0644); - system("sudo cp $tmp_ovpnclient $client_ovpn", $return); + chmod($tmp_ovpn, 0644); + system("sudo mv $tmp_ovpn $client_ovpn", $return); system("sudo rm ".RASPI_OPENVPN_CLIENT_CONFIG, $return); system("sudo ln -s $client_ovpn ".RASPI_OPENVPN_CLIENT_CONFIG, $return); @@ -201,3 +164,4 @@ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword) return $status; } } + diff --git a/includes/wireguard.php b/includes/wireguard.php index c7f56cdd..cb66341b 100644 --- a/includes/wireguard.php +++ b/includes/wireguard.php @@ -10,8 +10,13 @@ function DisplayWireGuardConfig() { $status = new StatusMessages(); if (!RASPI_MONITOR_ENABLED) { - if (isset($_POST['savewgsettings'])) { + $optRules = $_POST['wgRules']; + $optConf = $_POST['wgCnfOpt']; + $optSrvEnable = $_POST['wgSrvEnable']; + 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); } elseif (isset($_POST['startwg'])) { $status->addMessage('Attempting to start WireGuard', 'info'); exec('sudo /bin/systemctl start wg-quick@wg0', $return); @@ -27,7 +32,7 @@ function DisplayWireGuardConfig() } } - // fetch wg config + // fetch server config exec('sudo cat '. RASPI_WIREGUARD_CONFIG, $return); $conf = ParseConfig($return); $wg_srvpubkey = exec('sudo cat '. RASPI_WIREGUARD_PATH .'wg-server-public.key', $return); @@ -39,7 +44,7 @@ function DisplayWireGuardConfig() $wg_senabled = true; } - // todo: iterate multiple peer configs + // fetch client config exec('sudo cat '. RASPI_WIREGUARD_PATH.'client.conf', $preturn); $conf = ParseConfig($preturn); $wg_pipaddress = ($conf['Address'] == '') ? getDefaultNetValue('wireguard','peer','Address') : $conf['Address']; @@ -55,12 +60,15 @@ function DisplayWireGuardConfig() exec('pidof wg-crypt-wg0 | wc -l', $wgstatus); $serviceStatus = $wgstatus[0] == 0 ? "down" : "up"; $wg_state = ($wgstatus[0] > 0); + $public_ip = get_public_ip(); echo renderTemplate( "wireguard", compact( "status", "wg_state", "serviceStatus", + "public_ip", + "optRules", "wg_log", "peer_id", "wg_srvpubkey", @@ -79,6 +87,71 @@ function DisplayWireGuardConfig() ); } +/** + * Validates uploaded .conf file, adds iptables post-up and + * post-down rules. + * + * @param object $status + * @param object $file + * @param boolean $optRules + * @return object $status + */ +function SaveWireGuardUpload($status, $file, $optRules) +{ + define('KB', 1024); + $tmp_destdir = '/tmp/'; + $auth_flag = 0; + + try { + // If undefined or multiple files, treat as invalid + if (!isset($file['error']) || is_array($file['error'])) { + throw new RuntimeException('Invalid parameters'); + } + + $upload = \RaspAP\Uploader\Upload::factory('wg',$tmp_destdir); + $upload->set_max_file_size(64*KB); + $upload->set_allowed_mime_types(array('text/plain')); + $upload->file($file); + + $validation = new validation; + $upload->callbacks($validation, array('check_name_length')); + $results = $upload->upload(); + + if (!empty($results['errors'])) { + throw new RuntimeException($results['errors'][0]); + } + + // Valid upload, get file contents + $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', $_SESSION['ap_interface'], $rules); + $tmp_contents = preg_replace('/^\s*$/ms', $rules, $tmp_contents, 1); + file_put_contents($tmp_wgconfig, $tmp_contents); + } + + // Move processed file from tmp to destination + system("sudo mv $tmp_wgconfig ". RASPI_WIREGUARD_CONFIG, $return); + + if ($return ==0) { + $status->addMessage('WireGuard configuration uploaded successfully', 'info'); + } else { + $status->addMessage('Unable to save WireGuard configuration', 'danger'); + } + return $status; + + } catch (RuntimeException $e) { + $status->addMessage($e->getMessage(), 'danger'); + return $status; + } +} + /** * Validate user input, save wireguard configuration * diff --git a/installers/raspap.sudoers b/installers/raspap.sudoers index 2621d4e2..7ce40f28 100644 --- a/installers/raspap.sudoers +++ b/installers/raspap.sudoers @@ -20,8 +20,7 @@ www-data ALL=(ALL) NOPASSWD:/bin/systemctl start openvpn-client@client www-data ALL=(ALL) NOPASSWD:/bin/systemctl enable openvpn-client@client www-data ALL=(ALL) NOPASSWD:/bin/systemctl stop openvpn-client@client www-data ALL=(ALL) NOPASSWD:/bin/systemctl disable openvpn-client@client -www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/ovpnclient.ovpn /etc/openvpn/client/*.conf -www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/authdata /etc/openvpn/client/*.conf +www-data ALL=(ALL) NOPASSWD:/bin/mv /tmp/ovpn/* /etc/openvpn/client/*.conf www-data ALL=(ALL) NOPASSWD:/usr/bin/ln -s /etc/openvpn/client/*.conf /etc/openvpn/client/*.conf www-data ALL=(ALL) NOPASSWD:/bin/rm /etc/openvpn/client/*.conf www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/dnsmasqdata /etc/dnsmasq.d/090_*.conf @@ -49,6 +48,7 @@ www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/dnsmasqdata /etc/dnsmasq.d/090_adblock. www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/dnsmasq_custom /etc/raspap/adblock/custom.txt www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/wgdata /etc/wireguard/*.conf www-data ALL=(ALL) NOPASSWD:/bin/mv /tmp/wg-*.key /etc/wireguard/wg-*.key +www-data ALL=(ALL) NOPASSWD:/bin/mv /tmp/wg/* /etc/wireguard/*.conf www-data ALL=(ALL) NOPASSWD:/etc/raspap/adblock/update_blocklist.sh www-data ALL=(ALL) NOPASSWD:/usr/bin/socat - /dev/ttyUSB[0-9] www-data ALL=(ALL) NOPASSWD:/usr/local/sbin/onoff_huawei_hilink.sh * diff --git a/locale/en_US/LC_MESSAGES/messages.mo b/locale/en_US/LC_MESSAGES/messages.mo index f51f7c62..b1d57510 100644 Binary files a/locale/en_US/LC_MESSAGES/messages.mo and b/locale/en_US/LC_MESSAGES/messages.mo differ diff --git a/locale/en_US/LC_MESSAGES/messages.po b/locale/en_US/LC_MESSAGES/messages.po index b1defed5..c1b9ff47 100644 --- a/locale/en_US/LC_MESSAGES/messages.po +++ b/locale/en_US/LC_MESSAGES/messages.po @@ -1026,14 +1026,44 @@ msgstr "Invalid custom host found on line " msgid "Tunnel settings" msgstr "Tunnel settings" +msgid "Configuration Method" +msgstr "Configuration Method" + +msgid "Upload file" +msgstr "Upload file" + +msgid "Create manually" +msgstr "Create manually" + +msgid "Upload a WireGuard config" +msgstr "Upload a WireGuard config" + +msgid "This option uploads and installs an existing WireGuard .conf file on this device." +msgstr "This option uploads and installs an existing WireGuard .conf file on this device." + +msgid "Apply iptables rules for AP interface" +msgstr "Apply iptables rules for AP interface" + +msgid "Recommended if you wish to forward network traffic from the wg0 interface to clients connected on the AP interface." +msgstr "Recommended if you wish to forward network traffic from the wg0 interface to clients connected on the AP interface." + +msgid "This option adds iptables Postup and PostDown rules for the configured AP interface (%s)." +msgstr "This option adds iptables Postup and PostDown rules for the configured AP interface (%s)." + +msgid "Select WireGuard configuration file (.conf)" +msgstr "Select WireGuard configuration file (.conf)" + +msgid "Create a local WireGuard config" +msgstr "Create a local WireGuard config" + msgid "Enable server" msgstr "Enable server" -msgid "Enable this option to encrypt traffic by creating a tunnel between RaspAP and configured peers." -msgstr "Enable this option to encrypt traffic by creating a tunnel between RaspAP and configured peers." +msgid "Enable this option to secure network traffic by creating an encrypted tunnel between RaspAP and configured peers." +msgstr "Enable this option to secure network traffic by creating an encrypted tunnel between RaspAP and configured peers." -msgid "This option adds wg0.conf to the WireGuard configuration." -msgstr "This option adds wg0.conf to the WireGuard configuration." +msgid "This setting generates a new WireGuard .conf file on this device." +msgstr "This setting generates a new WireGuard .conf file on this device." msgid "Local public key" msgstr "Local public key" diff --git a/templates/wg/general.php b/templates/wg/general.php index 06d09811..15d2f9e3 100644 --- a/templates/wg/general.php +++ b/templates/wg/general.php @@ -3,53 +3,106 @@

-
-
- aria-describedby="server-description"> - -
-

- - wg0.conf to the WireGuard configuration.") ?> -

-
- -
-
- -
-
- -
- - -
+
+
+
+
- -
-
- - -
+
+
+ + +
+
+ +
-
-
- - -
-
+
+
-
-
- - -
-
+
+
+
+

+ .conf file on this device.") ?> +

+
+
+ +
+
+ + /> + + "> +

+ iptables Postup and PostDown rules for the configured AP interface (%s)."), $_SESSION['ap_interface']) ?> +

+
+
+ +
+
+
+ + +
+
+
+ +
+
+ +
+
+
+
+
+ aria-describedby="server-description"> + +
+

+ + + .conf file on this device.") ?> + +

+
+
+ +
+ +
+ +
+ + +
+
+
+ +
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ +
+
+
-
-
-