1
0
mirror of https://github.com/billz/raspap-webgui.git synced 2023-10-10 13:37:24 +02:00

Merge pull request #3 from RaspAP/feature/openvpn-cfgs

Multiple OpenVPN configs
This commit is contained in:
Bill Zimmerman 2021-02-10 12:49:23 +01:00 committed by GitHub
commit 031f91dfc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 390 additions and 68 deletions

View File

@ -0,0 +1,33 @@
<?php
require_once '../../includes/config.php';
require_once '../../includes/functions.php';
if (isset($_POST['cfg_id'])) {
$ovpncfg_id = $_POST['cfg_id'];
$ovpncfg_path = pathinfo(RASPI_OPENVPN_CLIENT_LOGIN, PATHINFO_DIRNAME).'/';
$ovpncfg_files = $ovpncfg_path .$ovpncfg_id.'_*.conf';
// move currently active profile
$meta = file_get_meta(RASPI_OPENVPN_CLIENT_LOGIN,'#\sfilename\s(.*)');
$ovpncfg_client = $ovpncfg_path .$meta.'_client.conf';
$ovpncfg_login = $ovpncfg_path .$meta.'_login.conf';
exec("sudo mv ".RASPI_OPENVPN_CLIENT_CONFIG." $ovpncfg_client", $return);
exec("sudo mv ".RASPI_OPENVPN_CLIENT_LOGIN." $ovpncfg_login", $return);
// replace with selected profile
$ovpncfg_client = $ovpncfg_path .$ovpncfg_id.'_client.conf';
$ovpncfg_login = $ovpncfg_path .$ovpncfg_id.'_login.conf';
exec("sudo mv $ovpncfg_client ".RASPI_OPENVPN_CLIENT_CONFIG, $return);
exec("sudo mv $ovpncfg_login ".RASPI_OPENVPN_CLIENT_LOGIN, $return);
// restart service
exec("sudo /bin/systemctl stop openvpn-client@client", $return);
sleep(1);
exec("sudo /bin/systemctl enable openvpn-client@client", $return);
sleep(1);
exec("sudo /bin/systemctl start openvpn-client@client", $return);
echo json_encode($return);
}

View File

@ -0,0 +1,13 @@
<?php
require_once '../../includes/config.php';
require_once '../../includes/functions.php';
if (isset($_POST['cfg_id'])) {
$ovpncfg_id = $_POST['cfg_id'];
$ovpncfg_files = pathinfo(RASPI_OPENVPN_CLIENT_LOGIN, PATHINFO_DIRNAME).'/'.$ovpncfg_id.'_*.conf';
exec("sudo rm $ovpncfg_files", $return);
$jsonData = ['return'=>$return];
echo json_encode($jsonData);
}

View File

@ -248,6 +248,40 @@ $('#hostapdModal').on('shown.bs.modal', function (e) {
$('#configureClientModal').on('shown.bs.modal', function (e) {
});
$('#ovpn-confirm-delete').on('click', '.btn-delete', function (e) {
var cfg_id = $(this).data('recordId');
$.post('ajax/openvpn/del_ovpncfg.php',{'cfg_id':cfg_id},function(data){
jsonData = JSON.parse(data);
$("#ovpn-confirm-delete").modal('hide');
var row = $(document.getElementById("openvpn-client-row-" + cfg_id));
row.fadeOut( "slow", function() {
row.remove();
});
});
});
$('#ovpn-confirm-delete').on('show.bs.modal', function (e) {
var data = $(e.relatedTarget).data();
$('.btn-delete', this).data('recordId', data.recordId);
});
$('#ovpn-confirm-activate').on('click', '.btn-activate', function (e) {
var cfg_id = $(this).data('recordId');
$.post('ajax/openvpn/activate_ovpncfg.php',{'cfg_id':cfg_id},function(data){
jsonData = JSON.parse(data);
$("#ovpn-confirm-activate").modal('hide');
setTimeout(function(){
window.location.reload();
},300);
});
});
$('#ovpn-confirm-activate').on('shown.bs.modal', function (e) {
var data = $(e.relatedTarget).data();
$('.btn-activate', this).data('recordId', data.recordId);
});
/*
Sets the wirelss channel select options based on hw_mode and country_code.

View File

@ -224,6 +224,84 @@ function safefilerewrite($fileName, $dataToSave)
}
}
/**
* Prepends data to a file if not exists
*
* @param string $filename
* @param string $dataToSave
* @return boolean
*/
function file_prepend_data($filename, $dataToSave)
{
$context = stream_context_create();
$file = fopen($filename, 'r', 1, $context);
$file_data = readfile($file);
if (!preg_match('/^'.$dataToSave.'/', $file_data)) {
$tmp_file = tempnam(sys_get_temp_dir(), 'php_prepend_');
file_put_contents($tmp_file, $dataToSave);
file_put_contents($tmp_file, $file, FILE_APPEND);
fclose($file);
unlink($filename);
rename($tmp_file, $filename);
return true;
} else {
return false;
}
}
/**
* Fetches a meta value from a file
*
* @param string $filename
* @param string $pattern
* @return string
*/
function file_get_meta($filename, $pattern)
{
if(file_exists($filename)) {
$context = stream_context_create();
$file_data = file_get_contents($filename, false, $context);
preg_match('/^'.$pattern.'/', $file_data, $matched);
return $matched[1];
} else {
return false;
}
}
/**
* Renames an openvpn client config with the 'filename' header comment
*
* @param string file
* @return boolean
*/
function file_move_config($file)
{
if(file_exists($file)) {
$file_data = file_get_contents($file);
preg_match('/^#\sfilename\s(.*)/i', $file_data, $matched);
$renamed = pathinfo($file, PATHINFO_DIRNAME).'/'.
$matched[1] .'_'.pathinfo($file, PATHINFO_FILENAME).'.'.
pathinfo($file, PATHINFO_EXTENSION);
if (!file_exists($renamed)) {
$return = system("sudo mv $file $renamed", $return);
} else {
return false;
}
}
}
/**
* Callback function for array_filter
*
* @param string $var
* @return filtered value
*/
function filter_comments($var)
{
return $var[0] != '#';
}
/**
* Saves a CSRF token in the session
*/

View File

@ -20,7 +20,9 @@ function DisplayOpenVPNConfig()
if (isset($_POST['authPassword'])) {
$authPassword = strip_tags(trim($_POST['authPassword']));
}
$return = SaveOpenVPNConfig($status, $_FILES['customFile'], $authUser, $authPassword);
if (is_uploaded_file( $_FILES["customFile"]["tmp_name"])) {
$return = SaveOpenVPNConfig($status, $_FILES['customFile'], $authUser, $authPassword);
}
} elseif (isset($_POST['StartOpenVPN'])) {
$status->addMessage('Attempting to start OpenVPN', 'info');
exec('sudo /bin/systemctl start openvpn-client@client', $return);
@ -47,8 +49,24 @@ function DisplayOpenVPNConfig()
// parse client auth credentials
if (!empty($auth)) {
$authUser = $auth[0];
$authPassword = $auth[1];
$auth = array_filter($auth, 'filter_comments');
$authUser = current($auth);
$authPassword = next($auth);
}
$clients = preg_grep('~\login.(conf)$~', scandir(pathinfo(RASPI_OPENVPN_CLIENT_LOGIN, PATHINFO_DIRNAME)));
$logEnable = 0;
if (!empty($_POST) && !isset($_POST['log-openvpn'])) {
$logOutput = "";
$f = @fopen("/tmp/openvpn.log", "r+");
if ($f !== false) {
ftruncate($f, 0);
fclose($f);
}
} elseif (isset($_POST['log-openvpn']) || filesize('/tmp/openvpn.log') >0) {
$logEnable = 1;
exec("sudo /etc/raspap/openvpn/openvpnlog.sh", $logOutput);
$logOutput = file_get_contents('/tmp/openvpn.log');
}
echo renderTemplate(
@ -56,9 +74,12 @@ function DisplayOpenVPNConfig()
"status",
"serviceStatus",
"openvpnstatus",
"logEnable",
"logOutput",
"public_ip",
"authUser",
"authPassword"
"authPassword",
"clients"
)
);
}
@ -136,18 +157,27 @@ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword)
) {
throw new RuntimeException('Unable to move uploaded file');
}
// Good file upload, update auth credentials if present
$prepend = '# filename '.pathinfo($file['name'], PATHINFO_FILENAME) .PHP_EOL;
if (!empty($authUser) && !empty($authPassword)) {
$auth_flag = 1;
// Move tmp authdata to /etc/openvpn/login.conf
$auth = $authUser .PHP_EOL . $authPassword .PHP_EOL;
$auth.= $authUser .PHP_EOL . $authPassword .PHP_EOL;
file_put_contents($tmp_authdata, $auth);
file_prepend_data($tmp_authdata, $prepend);
file_move_config(RASPI_OPENVPN_CLIENT_LOGIN);
chmod($tmp_authdata, 0644);
system("sudo cp $tmp_authdata " . RASPI_OPENVPN_CLIENT_LOGIN, $return);
if ($return !=0) {
$status->addMessage('Unable to save client auth credentials', 'danger');
}
}
// Prepend filname tag to .ovpn client config
file_prepend_data($tmp_ovpnclient, $prepend);
// Set iptables rules and, optionally, auth-user-pass
exec("sudo /etc/raspap/openvpn/configauth.sh $tmp_ovpnclient $auth_flag " .$_SESSION['ap_interface'], $return);
foreach ($return as $line) {
@ -155,6 +185,8 @@ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword)
}
// Copy tmp client config to /etc/openvpn/client
file_move_config(RASPI_OPENVPN_CLIENT_CONFIG);
chmod($tmp_ovpnclient, 0644);
system("sudo cp $tmp_ovpnclient " . RASPI_OPENVPN_CLIENT_CONFIG, $return);
if ($return ==0) {
$status->addMessage('OpenVPN client.conf uploaded successfully', 'info');

View File

@ -313,9 +313,10 @@ function _create_openvpn_scripts() {
_install_log "Creating OpenVPN control scripts"
sudo mkdir $raspap_dir/openvpn || _install_status 1 "Unable to create directory '$raspap_dir/openvpn'"
# Move service auth control shell scripts
# Move service auth control & logging shell scripts
sudo cp "$webroot_dir/installers/"configauth.sh "$raspap_dir/openvpn" || _install_status 1 "Unable to move auth control script"
# Make configauth.sh writable by www-data group
sudo cp "$webroot_dir/installers/"openvpnlog.sh "$raspap_dir/openvpn" || _install_status 1 "Unable to move logging script"
# Make scripts executable by www-data group
sudo chown -c root:"$raspap_user" "$raspap_dir/openvpn/"*.sh || _install_status 1 "Unable change owner and/or group"
sudo chmod 750 "$raspap_dir/openvpn/"*.sh || _install_status 1 "Unable to change file permissions"
_install_status 0

3
installers/openvpnlog.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
touch /tmp/openvpn.log
grep -m 100 openvpn /var/log/syslog | sudo tee /tmp/openvpn.log

View File

@ -20,6 +20,8 @@ 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/client.conf
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/authdata /etc/openvpn/client/login.conf
www-data ALL=(ALL) NOPASSWD:/bin/mv /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
www-data ALL=(ALL) NOPASSWD:/bin/rm /etc/dnsmasq.d/090_*.conf
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/dhcpddata /etc/dhcpcd.conf
@ -34,6 +36,7 @@ www-data ALL=(ALL) NOPASSWD:/etc/raspap/hostapd/disablelog.sh
www-data ALL=(ALL) NOPASSWD:/etc/raspap/hostapd/servicestart.sh
www-data ALL=(ALL) NOPASSWD:/etc/raspap/lighttpd/configport.sh
www-data ALL=(ALL) NOPASSWD:/etc/raspap/openvpn/configauth.sh
www-data ALL=(ALL) NOPASSWD:/etc/raspap/openvpn/openvpnlog.sh
www-data ALL=(ALL) NOPASSWD:/bin/chmod o+r /tmp/hostapd.log
www-data ALL=(ALL) NOPASSWD:/bin/chmod o+r /tmp/dnsmasq.log
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/dnsmasqdata /etc/dnsmasq.d/090_adblock.conf

Binary file not shown.

View File

@ -677,6 +677,42 @@ msgstr "Attempting to start openvpn"
msgid "Attempting to stop openvpn"
msgstr "Attempting to stop openvpn"
msgid "Configurations"
msgstr "Configurations"
msgid "Currently available OpenVPN client configurations are displayed below."
msgstr "Currently available OpenVPN client configurations are displayed below."
msgid "Activating a configuraton will restart the <code>openvpn-client</code> service."
msgstr "Activating a configuraton will restart the <code>openvpn-client</code> service."
msgid "Delete OpenVPN client"
msgstr "Delete OpenVPN client"
msgid "Delete client configuration? This cannot be undone."
msgstr "Delete client configuration? This cannot be undone."
msgid "Activate OpenVPN client"
msgstr "Activate OpenVPN client"
msgid "Activate client configuration? This will restart the openvpn-client service."
msgstr "Activate client configuration? This will restart the openvpn-client service."
msgid "Activate"
msgstr "Activate"
msgid "Cancel"
msgstr "Cancel"
msgid "Enable this option to log <code>openvpn</code> activity."
msgstr "Enable this option to log <code>openvpn</code> activity."
msgid "Cancel"
msgstr "Cancel"
msgid "Cancel"
msgstr "Cancel"
#: includes/torproxy.php
msgid "TOR is not running"
msgstr "TOR is not running"

View File

@ -1,3 +1,15 @@
<?php ob_start() ?>
<?php if (!RASPI_MONITOR_ENABLED) : ?>
<input type="submit" class="btn btn-outline btn-primary" name="SaveOpenVPNSettings" value="Save settings" />
<?php if ($openvpnstatus[0] == 0) {
echo '<input type="submit" class="btn btn-success" name="StartOpenVPN" value="Start OpenVPN" />' , PHP_EOL;
} else {
echo '<input type="submit" class="btn btn-warning" name="StopOpenVPN" value="Stop OpenVPN" />' , PHP_EOL;
}
?>
<?php endif ?>
<?php $buttons = ob_get_clean(); ob_end_clean() ?>
<div class="row">
<div class="col-lg-12">
<div class="card">
@ -21,70 +33,59 @@
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li class="nav-item"><a class="nav-link active" id="clienttab" href="#openvpnclient" data-toggle="tab"><?php echo _("Client settings"); ?></a></li>
<li class="nav-item"><a class="nav-link" id="logoutputtab" href="#openvpnlogoutput" data-toggle="tab"><?php echo _("Logfile output"); ?></a></li>
<li class="nav-item"><a class="nav-link" id="configstab" href="#openvpnconfigs" data-toggle="tab"><?php echo _("Configurations"); ?></a></li>
<li class="nav-item"><a class="nav-link" id="loggingtab" href="#openvpnlogging" data-toggle="tab"><?php echo _("Logging"); ?></a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="openvpnclient">
<h4 class="mt-3"><?php echo _("Client settings"); ?></h4>
<div class="row">
<div class="col">
<div class="row">
<div class="col-lg-12 mt-2 mb-2">
<div class="info-item"><?php echo _("IPv4 Address"); ?></div>
<div class="info-item"><?php echo htmlspecialchars($public_ip, ENT_QUOTES); ?><a class="text-gray-500" href="https://ipapi.co/<?php echo($public_ip); ?>" target="_blank" rel="noopener noreferrer"><i class="fas fa-external-link-alt ml-2"></i></a></div>
</div>
</div>
<div class="row">
<div class="form-group col-lg-12">
<label for="code"><?php echo _("Username"); ?></label>
<input type="text" class="form-control" name="authUser" value="<?php echo htmlspecialchars($authUser, ENT_QUOTES); ?>" />
</div>
</div>
<div class="row">
<div class="form-group col-lg-12">
<label for="code"><?php echo _("Password"); ?></label>
<input type="password" class="form-control" name="authPassword" value="<?php echo htmlspecialchars($authPassword, ENT_QUOTES); ?>" />
</div>
</div>
<div class="row">
<div class="form-group col-lg-12">
<div class="custom-file">
<input type="file" class="custom-file-input" name="customFile" id="customFile">
<label class="custom-file-label" for="customFile"><?php echo _("Select OpenVPN configuration file (.ovpn)"); ?></label>
</div>
</div>
</div>
</div><!-- col-->
<div class="col-sm">
<a href="https://go.nordvpn.net/aff_c?offer_id=15&aff_id=36402&url_id=902"><img src="app/img/180x150.png" class="rounded float-left mb-3 mt-3"></a>
</div>
</div><!-- main row -->
</div>
<div class="tab-pane fade" id="openvpnlogoutput">
<h4 class="mt-3"><?php echo _("Client log"); ?></h4>
<div class="row">
<div class="form-group col-md-8">
<?php
echo '<textarea class="logoutput"></textarea>';
?>
</div>
</div>
</div>
<?php if (!RASPI_MONITOR_ENABLED) : ?>
<input type="submit" class="btn btn-outline btn-primary" name="SaveOpenVPNSettings" value="Save settings" />
<?php if ($openvpnstatus[0] == 0) {
echo '<input type="submit" class="btn btn-success" name="StartOpenVPN" value="Start OpenVPN" />' , PHP_EOL;
} else {
echo '<input type="submit" class="btn btn-warning" name="StopOpenVPN" value="Stop OpenVPN" />' , PHP_EOL;
}
?>
<?php endif ?>
</form>
</div>
<?php echo renderTemplate("openvpn/general", $__template_data) ?>
<?php echo renderTemplate("openvpn/configs", $__template_data) ?>
<?php echo renderTemplate("openvpn/logging", $__template_data) ?>
</div><!-- /.tab-content -->
<?php echo $buttons ?>
</form>
</div>
</div><!-- /.card-body -->
<div class="card-footer"> Information provided by openvpn</div>
</div><!-- /.card -->
</div><!-- /.col-lg-12 -->
<div class="card-footer"><?php echo _("Information provided by openvpn"); ?></div>
</div><!-- /.card -->
</div><!-- /.col-lg-12 -->
</div><!-- /.row -->
<!-- modal confirm-delete-->
<div class="modal fade" id="ovpn-confirm-delete" tabindex="-1" role="dialog" aria-labelledby="ModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<div class="modal-title" id="ModalLabel"><i class="far fa-trash-alt mr-2"></i><?php echo _("Delete OpenVPN client"); ?></div>
</div>
<div class="modal-body">
<div class="col-md-12 mb-3 mt-1"><?php echo _("Delete client configuration? This cannot be undone."); ?></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal"><?php echo _("Cancel"); ?></button>
<button type="button" class="btn btn-outline-danger btn-delete"><?php echo _("Delete"); ?></button>
</div>
</div>
</div>
</div>
<!-- modal confirm-enable -->
<div class="modal fade" id="ovpn-confirm-activate" tabindex="-1" role="dialog" aria-labelledby="ModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<div class="modal-title" id="ModalLabel"><i class="far fa-check-circle mr-2"></i><?php echo _("Activate OpenVPN client"); ?></div>
</div>
<div class="modal-body">
<div class="col-md-12 mb-3 mt-1"><?php echo _("Activate client configuration? This will restart the openvpn-client service."); ?></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal"><?php echo _("Cancel"); ?></button>
<button type="button" class="btn btn-outline-success btn-activate"><?php echo _("Activate"); ?></button>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,35 @@
<div class="tab-pane fade" id="openvpnconfigs">
<div class="row">
<div class="col-md">
<h4 class="mt-3 mb-3"><?php echo _("Configurations"); ?></h4>
<p id="openvpnconfigs-description" class="mb-3">
<small><?php echo _("Currently available OpenVPN client configurations are displayed below.") ?></small>
<br><small class="text-muted"><?php echo _("Activating a configuraton will restart the <code>openvpn-client</code> service.") ?></small>
</p>
<div class="openvpn-configs js-openvpn-configs-container">
<?php foreach ($clients as $client) :
if ($client == "login.conf") {
$label = file_get_meta(RASPI_OPENVPN_CLIENT_LOGIN,'#\sfilename\s(.*)');
$btn_class = "active";
} else {
$label = trim(pathinfo($client, PATHINFO_FILENAME), "_login");
$client = $label;
$btn_class = "disabled";
}?>
<div class="row mt-2" id="openvpn-client-row-<?php echo htmlspecialchars($client, ENT_QUOTES); ?>" >
<div class="col-md-6 col-xs-4">
<label><?php echo htmlspecialchars($label, ENT_QUOTES); ?></label>
</div>
<div class="col-md-auto px-lg-3 col-xs-2">
<button type="button" class="btn btn-outline-success <?php echo $btn_class; ?> js-activate-openvpn-client" data-record-id="<?php echo htmlspecialchars($client, ENT_QUOTES); ?>" data-toggle="modal" data-target="#ovpn-confirm-activate" /><i class="far fa-check-circle"></i></button>
</div>
<div class="col-md-auto col-xs-2">
<button type="button" class="btn btn-outline-danger js-remove-openvpn-client" data-record-id="<?php echo htmlspecialchars($client, ENT_QUOTES); ?>" data-toggle="modal" data-target="#ovpn-confirm-delete" /><i class="far fa-trash-alt"></i></button>
</div>
</div><!-- ./row openvpn-client -->
<?php endforeach ?>
</div><!-- /.openvpn-configs -->
<div class="mb-3"></div>
</div><!-- /.tab-pane | manage configs tab -->
</div>
</div>

View File

@ -0,0 +1,37 @@
<div class="tab-pane active" id="openvpnclient">
<h4 class="mt-3"><?php echo _("Client settings"); ?></h4>
<div class="row">
<div class="col">
<div class="row">
<div class="col-lg-12 mt-2 mb-2">
<div class="info-item"><?php echo _("IPv4 Address"); ?></div>
<div class="info-item"><?php echo htmlspecialchars($public_ip, ENT_QUOTES); ?><a class="text-gray-500" href="https://ipapi.co/<?php echo($public_ip); ?>" target="_blank" rel="noopener noreferrer"><i class="fas fa-external-link-alt ml-2"></i></a></div>
</div>
</div>
<div class="row">
<div class="form-group col-lg-12">
<label for="code"><?php echo _("Username"); ?></label>
<input type="text" class="form-control" name="authUser" value="<?php echo htmlspecialchars($authUser, ENT_QUOTES); ?>" />
</div>
</div>
<div class="row">
<div class="form-group col-lg-12">
<label for="code"><?php echo _("Password"); ?></label>
<input type="password" class="form-control" name="authPassword" value="<?php echo htmlspecialchars($authPassword, ENT_QUOTES); ?>" />
</div>
</div>
<div class="row">
<div class="form-group col-lg-12">
<div class="custom-file">
<input type="file" class="custom-file-input" name="customFile" id="customFile">
<label class="custom-file-label" for="customFile"><?php echo _("Select OpenVPN configuration file (.ovpn)"); ?></label>
</div>
</div>
</div>
</div><!-- col-->
<div class="col-sm">
<a href="https://go.nordvpn.net/aff_c?offer_id=15&aff_id=36402&url_id=902"><img src="app/img/180x150.png" class="rounded float-left mb-3 mt-3"></a>
</div>
</div><!-- /.row -->
</div><!-- /.tab-pane | general tab -->

View File

@ -0,0 +1,16 @@
<!-- logging tab -->
<div class="tab-pane fade" id="openvpnlogging">
<h4 class="mt-3 mb-3"><?php echo _("Logging") ?></h4>
<p><?php echo _("Enable this option to log <code>openvpn</code> activity.") ?></p>
<div class="custom-control custom-switch">
<input class="custom-control-input" id="log-openvpn" type="checkbox" name="log-openvpn" value="1" <?php echo $logEnable ? ' checked="checked"' : "" ?> aria-describedby="log-openvpn">
<label class="custom-control-label" for="log-openvpn"><?php echo _("Enable logging") ?></label>
</div>
<div class="row">
<div class="form-group col-md-8 mt-2">
<textarea class="logoutput"><?php echo htmlspecialchars($logOutput, ENT_QUOTES); ?></textarea>
</div>
</div>
</div><!-- /.tab-pane -->