mirror of
https://github.com/RaspAP/raspap-webgui.git
synced 2024-11-21 23:20:22 +00:00
commit
b386f5285a
97 changed files with 7563 additions and 513 deletions
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
29
BACKERS.md
29
BACKERS.md
|
@ -15,23 +15,25 @@ You can [become a sponsor](https://github.com/sponsors/RaspAP) using your indivi
|
|||
> ℹ️ **Important**: If you're sponsoring [RaspAP](https://github.com/RaspAP/sponsors) through a GitHub organization, please send a short email to [sponsors@raspap.com](mailto:sponsors@raspap.com) with the name of your organization and the account that should be added as a collaborator.
|
||||
|
||||
### Exclusive features
|
||||
When backers were asked which feature they'd most like to see added to RaspAP, the ability to manage multiple OpenVPN client configurations topped the list of requests. We think this is a great idea, so we're adding this as the first feature exclusive to insiders.
|
||||
The following features are currently available exclusively to sponsors. A tangible side benefit of sponsorship is that Insiders are able to help steer future development of RaspAP. This is done through Insiders' access to discussions, feature requests, issues and pull requests in the private GitHub repository.
|
||||
|
||||
✅ [Multiple OpenVPN client configs](https://docs.raspap.com/openvpn/#multiple-client-configs)
|
||||
✅ [OpenVPN certificate authentication](https://docs.raspap.com/openvpn/#certificate-authentication)
|
||||
✅ OpenVPN service logging
|
||||
✅ Night mode toggle
|
||||
✅ Restrict network to static clients
|
||||
✅ [WireGuard support](https://docs.raspap.com/wireguard/)
|
||||
✅ [Set AP transmit power](https://docs.raspap.com/ap-basics/#transmit-power)
|
||||
✅ [Network device management](https://docs.raspap.com/net-devices/)
|
||||
✅ [Firewall settings](https://docs.raspap.com/firewall/)
|
||||
✅ [WPA3-Personal AP security](https://docs.raspap.com/ap-basics/#wpa3-personal)
|
||||
✅ [802.11w Protected Management Frames](https://docs.raspap.com/ap-basics/#80211w)
|
||||
✅ [Printable Wi-Fi signs](https://docs.raspap.com/ap-basics/#printable-signs)
|
||||
⚙️ Traffic shaping (in progress)
|
||||
|
||||
Look for the list above to grow as we add more exclusive features. Be sure to visit this page from time to time to learn about what's new, check the [Insiders docs page](https://docs.raspap.com/insiders/) and follow [@RaspAP on Twitter](https://twitter.com/rasp_ap) to stay updated.
|
||||
|
||||
Look for the list above to grow as we add more exclusive features.
|
||||
|
||||
### Funding targets
|
||||
## Funding targets
|
||||
Below is a list of funding targets. When a funding target is reached, the features that are tied to it are merged back into RaspAP and released to the public for general availability.
|
||||
|
||||
#### $500
|
||||
The first **Insiders Edition** includes the exclusive features listed above.
|
||||
### $1000
|
||||
The second **Insiders Edition** includes the features listed above.
|
||||
|
||||
### $500
|
||||
The [first Insiders Edition goal](https://docs.raspap.com/insiders/#500-1st-insiders-edition) was reached in December 2021. Thank you sponsors!
|
||||
|
||||
### Frequently asked questions
|
||||
|
||||
|
@ -73,4 +75,3 @@ Yes. Whether you're an individual or a company, you may use RaspAP Insiders prec
|
|||
|
||||
* Please **don't distribute the source code** of Insiders. You may freely use it for public, private or commercial projects, fork it, mirror it, do whatever you want with it, but please don't release the source code, as it would counteract the sponsorware strategy.
|
||||
* If you cancel your subscription, you're removed as a collaborator and will miss out on future updates of Insiders. However, you may *use the latest version* that's available to you as long as you like. Just remember that [GitHub deletes private forks](https://docs.github.com/en/github/setting-up-and-managing-your-github-user-account/removing-a-collaborator-from-a-personal-repository).
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
![](https://i.imgur.com/xeKD93p.png)
|
||||
[![Release 2.6.7](https://img.shields.io/badge/release-v2.6.7-green)](https://github.com/raspap/raspap-webgui/releases) [![Awesome](https://awesome.re/badge.svg)](https://github.com/thibmaek/awesome-raspberry-pi) [![Join Insiders](https://img.shields.io/static/v1?label=Join%20Insiders&message=%E2%9D%A4&logo=GitHub&color=ff69b4)](https://github.com/sponsors/RaspAP) ![https://travis-ci.com/github/raspap/raspap-webgui/](https://api.travis-ci.org/RaspAP/raspap-webgui.svg) [![Crowdin](https://badges.crowdin.net/raspap/localized.svg)](https://crowdin.com/project/raspap) [![Twitter URL](https://img.shields.io/twitter/url?label=%40RaspAP&logoColor=%23d8224c&url=https%3A%2F%2Ftwitter.com%2Frasp_ap)](https://twitter.com/rasp_ap) [![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/RaspAP?style=social)](https://www.reddit.com/r/RaspAP/)
|
||||
[![Release 2.8.4](https://img.shields.io/badge/release-v2.8.4-green)](https://github.com/raspap/raspap-webgui/releases) [![Awesome](https://awesome.re/badge.svg)](https://github.com/thibmaek/awesome-raspberry-pi) [![Join Insiders](https://img.shields.io/static/v1?label=Join%20Insiders&message=%E2%9D%A4&logo=GitHub&color=ff69b4)](https://github.com/sponsors/RaspAP) ![https://travis-ci.com/github/raspap/raspap-webgui/](https://api.travis-ci.org/RaspAP/raspap-webgui.svg) [![Crowdin](https://badges.crowdin.net/raspap/localized.svg)](https://crowdin.com/project/raspap) [![Twitter URL](https://img.shields.io/twitter/url?label=%40RaspAP&logoColor=%23d8224c&url=https%3A%2F%2Ftwitter.com%2Frasp_ap)](https://twitter.com/rasp_ap) [![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/RaspAP?style=social)](https://www.reddit.com/r/RaspAP/)
|
||||
|
||||
RaspAP is feature-rich wireless router software that _just works_ on many popular [Debian-based devices](#supported-operating-systems), including the Raspberry Pi. Our popular [Quick installer](#quick-installer) creates a known-good default configuration for all current Raspberry Pis with onboard wireless. A fully responsive, mobile-ready interface gives you control over the relevant services and networking options. Advanced DHCP settings, WireGuard and OpenVPN support, [SSL certificates](https://docs.raspap.com/ssl-quick/), security audits, [captive portal integration](https://docs.raspap.com/captive/), themes and [multilingual options](https://docs.raspap.com/translations/) are included.
|
||||
|
||||
|
@ -122,9 +122,9 @@ RaspAP was originally made for Raspbian, but now also installs on the following
|
|||
|
||||
| Distribution | Release | Architecture | Support |
|
||||
|---|:---:|:---:|:---:|
|
||||
| Raspberry Pi OS | (32-bit) Lite Buster | ARM | Official |
|
||||
| Armbian | Buster | [ARM](https://docs.armbian.com/#supported-socs) | Official |
|
||||
| Debian | Buster | ARM / x86_64 | Beta |
|
||||
| Raspberry Pi OS | (32-bit) Lite Bullseye | ARM | Official |
|
||||
| Armbian | Bullseye | [ARM](https://docs.armbian.com/#supported-socs) | Official |
|
||||
| Debian | Bullseye | ARM / x86_64 | Beta |
|
||||
| Ubuntu | 18.04 LTS / 19.10 | ARM / x86_64 | Beta |
|
||||
|
||||
![](https://i.imgur.com/luiyYNw.png)
|
||||
|
|
|
@ -42,10 +42,10 @@ $jsonobj = json_decode($jsonstdoutvnstat[0], true);
|
|||
$timeunits = filter_input(INPUT_GET, 'tu');
|
||||
if ($timeunits === 'm') {
|
||||
// months
|
||||
$jsonData = $jsonobj['interfaces'][0]['traffic']['months'];
|
||||
$jsonData = $jsonobj['interfaces'][0]['traffic']['month'];
|
||||
} else {
|
||||
// default: days
|
||||
$jsonData = $jsonobj['interfaces'][0]['traffic']['days'];
|
||||
$jsonData = $jsonobj['interfaces'][0]['traffic']['day'];
|
||||
}
|
||||
|
||||
$datasizeunits = filter_input(INPUT_GET, 'dsu');
|
||||
|
|
|
@ -34,19 +34,16 @@ if (filter_input(INPUT_GET, 'tu') == 'h') {
|
|||
23 => array('date' => '23:00', 'rx' => 0, 'tx' => 0)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
exec(sprintf('vnstat -i %s --json h', escapeshellarg($interface)), $jsonstdoutvnstat, $exitcodedaily);
|
||||
if ($exitcodedaily !== 0) {
|
||||
exit('vnstat error');
|
||||
}
|
||||
|
||||
$jsonobj = json_decode($jsonstdoutvnstat[0], true)['interfaces'][0];
|
||||
$jsonData = $jsonobj['traffic']['hours'];
|
||||
$jsonData = $jsonobj['traffic']['hour'];
|
||||
for ($i = count($jsonData) - 1; $i >= 0; --$i) {
|
||||
$data_template[$jsonData[$i]['id']]['rx'] = round($jsonData[$i]['rx'] / 1024, 0);
|
||||
$data_template[$jsonData[$i]['id']]['tx'] = round($jsonData[$i]['tx'] / 1024, 0);
|
||||
$data_template[$jsonData[$i]['time']['hour']]['rx'] = round($jsonData[$i]['rx'] / 1024, 0);
|
||||
$data_template[$jsonData[$i]['time']['hour']]['tx'] = round($jsonData[$i]['tx'] / 1024, 0);
|
||||
}
|
||||
|
||||
$data = array();
|
||||
|
|
|
@ -52,7 +52,7 @@ if (isset($interface)) {
|
|||
$dhcpdata['StaticRouters'] = $static_routers[1];
|
||||
$dhcpdata['StaticDNS'] = $static_dns[1];
|
||||
$dhcpdata['FallbackEnabled'] = empty($fallback) ? false: true;
|
||||
$dhcpdata['DefaultRoute'] = empty($gateway) || $gateway[0] == "gateway";
|
||||
$dhcpdata['DefaultRoute'] = $gateway[0] == "gateway";
|
||||
|
||||
echo json_encode($dhcpdata);
|
||||
}
|
||||
|
|
9
ajax/networking/get_wgcfg.php
Normal file
9
ajax/networking/get_wgcfg.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
require '../../includes/csrf.php';
|
||||
require_once '../../includes/config.php';
|
||||
|
||||
// fetch wg client.conf
|
||||
exec('sudo cat '. RASPI_WIREGUARD_PATH.'client.conf', $return);
|
||||
echo implode(PHP_EOL,$return);
|
||||
|
22
ajax/networking/get_wgkey.php
Normal file
22
ajax/networking/get_wgkey.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
require '../../includes/csrf.php';
|
||||
require_once '../../includes/config.php';
|
||||
|
||||
$entity = $_POST['entity'];
|
||||
|
||||
if (isset($entity)) {
|
||||
|
||||
// generate public/private key pairs for entity
|
||||
$pubkey = RASPI_WIREGUARD_PATH.$entity.'-public.key';
|
||||
$privkey = RASPI_WIREGUARD_PATH.$entity.'-private.key';
|
||||
$pubkey_tmp = '/tmp/'.$entity.'-public.key';
|
||||
$privkey_tmp = '/tmp/'.$entity.'-private.key';
|
||||
|
||||
exec("sudo wg genkey | tee $privkey_tmp | wg pubkey > $pubkey_tmp", $return);
|
||||
$wgdata['pubkey'] = str_replace("\n",'',file_get_contents($pubkey_tmp));
|
||||
exec("sudo mv $privkey_tmp $privkey", $return);
|
||||
exec("sudo mv $pubkey_tmp $pubkey", $return);
|
||||
|
||||
echo json_encode($wgdata);
|
||||
}
|
93
ajax/networking/save_net_dev_config.php
Normal file
93
ajax/networking/save_net_dev_config.php
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
/*
|
||||
Save settings of network devices (type, name, PW, APN ...)
|
||||
|
||||
Called by js saveNetDeviceSettings (App/js/custom.js)
|
||||
*/
|
||||
|
||||
|
||||
require '../../includes/csrf.php';
|
||||
|
||||
require_once '../../includes/config.php';
|
||||
require_once '../../includes/functions.php';
|
||||
|
||||
if (isset($_POST['interface'])) {
|
||||
$int = $_POST['interface'];
|
||||
$cfg = [];
|
||||
$file = $RASPI_MOBILEDATA_CONFIG;
|
||||
$cfgfile="/etc/wvdial.conf";
|
||||
if ( $int == "mobiledata") {
|
||||
$cfg['pin'] = $_POST["pin-mobile"];
|
||||
$cfg['apn'] = $_POST["apn-mobile"];
|
||||
$cfg['apn_user'] = $_POST["apn-user-mobile"];
|
||||
$cfg['apn_pw'] = $_POST["apn-pw-mobile"];
|
||||
$cfg['router_user'] = $cfg['apn_user'] ;
|
||||
$cfg['router_pw'] = $cfg['apn_pw'] ;
|
||||
if (file_exists($cfgfile)) {
|
||||
if($cfg["pin"] !== "") exec('sudo /bin/sed -i "s/CPIN=\".*\"/CPIN=\"'.$cfg["pin"].'\"/gi" '.$cfgfile);
|
||||
if($cfg["apn"] !== "") exec('sudo /bin/sed -i "s/\"IP\"\,\".*\"/\"IP\"\,\"'.$cfg["apn"].'\"/gi" '.$cfgfile);
|
||||
if($cfg["apn_user"] !== "") exec('sudo /bin/sed -i "s/^username = .*$/Username = '.$cfg["apn_user"].'/gi" '.$cfgfile);
|
||||
if($cfg["apn_pw"] !== "") exec('sudo /bin/sed -i "s/^password = .*$/Password = '.$cfg["apn_pw"].'/gi" '.$cfgfile);
|
||||
}
|
||||
if (write_php_ini($cfg, RASPI_MOBILEDATA_CONFIG)) {
|
||||
$jsonData = ['return'=>0,'output'=>['Successfully saved mobile data settings']];
|
||||
} else {
|
||||
$jsonData = ['return'=>1,'output'=>['Error saving mobile data settings']];
|
||||
}
|
||||
} else if ( preg_match("/netdevices/",$int)) {
|
||||
if(!isset($_POST['opts']) ) {
|
||||
$jsonData = ['return'=>0,'output'=>['No valid data to add/delete udev rule ']];
|
||||
echo json_encode($jsonData);
|
||||
return;
|
||||
} else {
|
||||
$opts=explode(" ",$_POST['opts'] );
|
||||
$dev=$opts[0];
|
||||
$vid=$_POST["int-vid-".$dev];
|
||||
$pid=$_POST["int-pid-".$dev];
|
||||
$mac=$_POST["int-mac-".$dev];
|
||||
$name=trim($_POST["int-name-".$dev]);
|
||||
// limit device name to letters and numbers. Total length max 20
|
||||
$name=preg_replace("/[^a-z0-9]/", "", strtolower($name));
|
||||
$name=substr($name, 0, min(strlen($name),20));
|
||||
$type=$_POST["int-type-".$dev];
|
||||
$newtype=$_POST["int-new-type-".$dev];
|
||||
$udevfile=$_SESSION["udevrules"]["udev_rules_file"]; // default file /etc/udev/rules.d/80-net-devices.rules";
|
||||
|
||||
// find the rule prototype and prefix
|
||||
$rule = "";
|
||||
foreach($_SESSION["udevrules"]["network_devices"] as $devt) {
|
||||
if($devt["type"]==$newtype) {
|
||||
$rulenew = $devt["udev_rule"];
|
||||
$prefix = $devt["name_prefix"];
|
||||
}
|
||||
}
|
||||
|
||||
// check for an existing rule and delete lines with same MAC or same VID/PID
|
||||
if (!empty($vid) && !empty($pid)) {
|
||||
$rule = '^.*ATTRS{idVendor}==\"' . $vid . '\".*ATTRS{idProduct}==\"' . $pid . '\".*$';
|
||||
exec('sudo sed -i "/'.$rule.'/Id" '.$udevfile); // clear all entries with this VID/PID
|
||||
$rule = '^.*ATTRS{idProduct}==\"' . $pid . '\".*ATTRS{idVendor}==\"' . $vid . '\".*$';
|
||||
exec('sudo sed -i "/'.$rule.'/Id" '.$udevfile); // clear all entries with this VID/PID
|
||||
}
|
||||
if (!empty($mac)) {
|
||||
exec('sudo sed -i "/^.*'.$mac.'.*$/d" '.$udevfile); // clear all entries with same MAC
|
||||
}
|
||||
// create new entry
|
||||
if ( ($type != $newtype) || !empty($name) ) { // new device type or new name
|
||||
if (empty($name)) $name = $prefix."%n";
|
||||
if (!empty($mac)) $rule = preg_replace("/\\\$MAC\\\$/i", $mac, $rulenew);
|
||||
if (!empty($vid)) $rule = preg_replace("/\\\$IDVENDOR\\\$/i", $vid, $rule);
|
||||
if (!empty($pid)) $rule = preg_replace("/\\\$IDPRODUCT\\\$/i", $pid, $rule);
|
||||
if (!empty($name)) $rule = preg_replace("/\\\$DEVNAME\\\$/i",$name,$rule);
|
||||
if (!empty($rule)) exec('echo \''.$rule.'\' | sudo /usr/bin/tee -a '.$udevfile);
|
||||
}
|
||||
$jsonData = ['return'=>0,'output'=>['Settings changed for device '.$dev. '<br>Changes will only be in effect after reconnecting the device' ] ];
|
||||
}
|
||||
} else {
|
||||
$jsonData = ['return'=>1,'output'=>['Unknown network configuration']];
|
||||
}
|
||||
} else {
|
||||
$jsonData = ['return'=>2,'output'=>'Unable to detect interface'];
|
||||
}
|
||||
|
||||
echo json_encode($jsonData);
|
|
@ -14,6 +14,7 @@ knownWifiStations($networks);
|
|||
nearbyWifiStations($networks, !isset($_REQUEST["refresh"]));
|
||||
connectedWifiStations($networks);
|
||||
sortNetworksByRSSI($networks);
|
||||
foreach ($networks as $ssid => $network) $networks[$ssid]["ssidutf8"] = ssid2utf8( $ssid );
|
||||
|
||||
$connected = array_filter($networks, function($n) { return $n['connected']; } );
|
||||
$known = array_filter($networks, function($n) { return !$n['connected'] && $n['configured']; } );
|
||||
|
|
26
ajax/openvpn/activate_ovpncfg.php
Normal file
26
ajax/openvpn/activate_ovpncfg.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
require_once '../../includes/config.php';
|
||||
require_once '../../includes/functions.php';
|
||||
|
||||
if (isset($_POST['cfg_id'])) {
|
||||
$ovpncfg_id = $_POST['cfg_id'];
|
||||
$ovpncfg_client = RASPI_OPENVPN_CLIENT_PATH.$ovpncfg_id.'_client.conf';
|
||||
$ovpncfg_login = RASPI_OPENVPN_CLIENT_PATH.$ovpncfg_id.'_login.conf';
|
||||
|
||||
// remove existing client config +login and symbolically link the selected one
|
||||
system("sudo rm ".RASPI_OPENVPN_CLIENT_CONFIG, $return);
|
||||
system("sudo ln -s $ovpncfg_client ".RASPI_OPENVPN_CLIENT_CONFIG, $return);
|
||||
system("sudo rm ".RASPI_OPENVPN_CLIENT_LOGIN, $return);
|
||||
system("sudo ln -s $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);
|
||||
}
|
||||
|
13
ajax/openvpn/del_ovpncfg.php
Normal file
13
ajax/openvpn/del_ovpncfg.php
Normal 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);
|
||||
}
|
||||
|
|
@ -79,6 +79,9 @@ h5.card-title {
|
|||
font-family: Verdana, Geneva, sans-serif;
|
||||
}
|
||||
|
||||
.sidebar-light hr.sidebar-divider {
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
|
||||
ul.nav-tabs, .nav-tabs .nav-link {
|
||||
background-color: #f6f6ef;
|
||||
|
@ -163,6 +166,7 @@ ul.nav-tabs, .nav-tabs .nav-link {
|
|||
.info-item-xs {
|
||||
font-size: 0.7rem;
|
||||
margin-left: 0.3rem;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.info-item-wifi {
|
||||
|
@ -200,6 +204,10 @@ ul.nav-tabs, .nav-tabs .nav-link {
|
|||
}
|
||||
}
|
||||
|
||||
.fas.fa-circle {
|
||||
font-size: 0.5rem;
|
||||
}
|
||||
|
||||
.logoutput {
|
||||
width:100%;
|
||||
height:300px;
|
||||
|
|
28
app/img/wg-qr-code.php
Normal file
28
app/img/wg-qr-code.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
require_once '../../includes/config.php';
|
||||
require_once '../../includes/defaults.php';
|
||||
require_once '../../includes/functions.php';
|
||||
|
||||
// prevent direct file access
|
||||
if (!isset($_SERVER['HTTP_REFERER'])) {
|
||||
header('HTTP/1.0 403 Forbidden');
|
||||
exit;
|
||||
}
|
||||
|
||||
exec("sudo cat " .RASPI_WIREGUARD_PATH.'client.conf', $return);
|
||||
$peer_conf = implode(PHP_EOL,$return);
|
||||
$peer_conf.= PHP_EOL;
|
||||
$command = "qrencode -t svg -m 0 -o - " . mb_escapeshellarg($peer_conf);
|
||||
$svg = shell_exec($command);
|
||||
$etag = hash('sha256', $peer_conf);
|
||||
$content_length = strlen($svg);
|
||||
$last_modified = date("Y-m-d H:i:s");
|
||||
|
||||
header("Content-Type: image/svg+xml");
|
||||
header("Content-Length: $content_length");
|
||||
header("Last-Modified: $last_modified");
|
||||
header("ETag: \"$etag\"");
|
||||
header("X-QR-Code-Content: $peer_conf");
|
||||
echo shell_exec($command);
|
||||
|
|
@ -10,11 +10,6 @@ if (!isset($_SERVER['HTTP_REFERER'])) {
|
|||
exit;
|
||||
}
|
||||
|
||||
function qr_encode($str)
|
||||
{
|
||||
return preg_replace('/(?<!\\\)([\":;,])/', '\\\\\1', $str);
|
||||
}
|
||||
|
||||
$hostapd = parse_ini_file(RASPI_HOSTAPD_CONFIG, false, INI_SCANNER_RAW);
|
||||
|
||||
// assume wpa encryption and get the passphrase
|
||||
|
@ -52,7 +47,8 @@ $content_length = strlen($svg);
|
|||
header("Content-Type: image/svg+xml");
|
||||
header("Content-Length: $content_length");
|
||||
header("Last-Modified: $last_modified");
|
||||
header("Content-Disposition: attachment; filename=\"qr.svg\"");
|
||||
header("ETag: \"$etag\"");
|
||||
header("X-QR-Code-Content: $data");
|
||||
echo shell_exec($command);
|
||||
echo $svg;
|
||||
|
||||
|
|
131
app/js/custom.js
131
app/js/custom.js
|
@ -1,6 +1,5 @@
|
|||
function msgShow(retcode,msg) {
|
||||
if(retcode == 0) {
|
||||
var alertType = 'success';
|
||||
if(retcode == 0) { var alertType = 'success';
|
||||
} else if(retcode == 2 || retcode == 1) {
|
||||
var alertType = 'danger';
|
||||
}
|
||||
|
@ -123,6 +122,11 @@ $(document).on("click", "#gen_wpa_passphrase", function(e) {
|
|||
$('#txtwpapassphrase').val(genPassword(63));
|
||||
});
|
||||
|
||||
// Enable Bootstrap tooltips
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
})
|
||||
|
||||
function genPassword(pwdLen) {
|
||||
var pwdChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
var rndPass = Array(pwdLen).fill(pwdChars).map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');
|
||||
|
@ -252,6 +256,69 @@ $('#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('record-id');
|
||||
$.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);
|
||||
});
|
||||
|
||||
$('#ovpn-userpw,#ovpn-certs').on('click', function (e) {
|
||||
if (this.id == 'ovpn-userpw') {
|
||||
$('#PanelCerts').hide();
|
||||
$('#PanelUserPW').show();
|
||||
} else if (this.id == 'ovpn-certs') {
|
||||
$('#PanelUserPW').hide();
|
||||
$('#PanelCerts').show();
|
||||
}
|
||||
});
|
||||
|
||||
$(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();
|
||||
$(this).siblings(".custom-file-label").addClass("selected").html(fileName);
|
||||
});
|
||||
|
||||
/*
|
||||
Sets the wirelss channel select options based on hw_mode and country_code.
|
||||
|
||||
|
@ -320,6 +387,55 @@ function updateBlocklist() {
|
|||
function clearBlocklistStatus() {
|
||||
$('#cbxblocklist-status').removeClass('check-updated').addClass('check-hidden');
|
||||
}
|
||||
|
||||
// Handler for the wireguard generate key button
|
||||
$('.wg-keygen').click(function(){
|
||||
var entity_pub = $(this).parent('div').prev('input[type="text"]');
|
||||
var entity_priv = $(this).parent('div').next('input[type="hidden"]');
|
||||
var updated = entity_pub.attr('name')+"-pubkey-status";
|
||||
$.post('ajax/networking/get_wgkey.php',{'entity':entity_pub.attr('name') },function(data){
|
||||
var jsonData = JSON.parse(data);
|
||||
entity_pub.val(jsonData.pubkey);
|
||||
$('#' + updated).removeClass('check-hidden').addClass('check-updated').delay(500).animate({ opacity: 1 }, 700);
|
||||
})
|
||||
})
|
||||
|
||||
// Handler for wireguard client.conf download
|
||||
$('.wg-client-dl').click(function(){
|
||||
var req = new XMLHttpRequest();
|
||||
var url = 'ajax/networking/get_wgcfg.php';
|
||||
req.open('get', url, true);
|
||||
req.responseType = 'blob';
|
||||
req.setRequestHeader('Content-type', 'text/plain; charset=UTF-8');
|
||||
req.onreadystatechange = function (event) {
|
||||
if(req.readyState == 4 && req.status == 200) {
|
||||
var blob = req.response;
|
||||
var link=document.createElement('a');
|
||||
link.href=window.URL.createObjectURL(blob);
|
||||
link.download = 'client.conf';
|
||||
link.click();
|
||||
}
|
||||
}
|
||||
req.send();
|
||||
})
|
||||
|
||||
// Event listener for Bootstrap's form validation
|
||||
window.addEventListener('load', function() {
|
||||
// Fetch all the forms we want to apply custom Bootstrap validation styles to
|
||||
var forms = document.getElementsByClassName('needs-validation');
|
||||
// Loop over them and prevent submission
|
||||
var validation = Array.prototype.filter.call(forms, function(form) {
|
||||
form.addEventListener('submit', function(event) {
|
||||
//console.log(event.submitter);
|
||||
if (form.checkValidity() === false) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
form.classList.add('was-validated');
|
||||
}, false);
|
||||
});
|
||||
}, false);
|
||||
|
||||
// Static Array method
|
||||
Array.range = (start, end) => Array.from({length: (end - start)}, (v, k) => k + start);
|
||||
|
||||
|
@ -369,6 +485,17 @@ function set_theme(theme) {
|
|||
setCookie('theme',theme,90);
|
||||
}
|
||||
|
||||
$(function() {
|
||||
$('#night-mode').change(function() {
|
||||
var state = $(this).is(':checked');
|
||||
if (state == true && getCookie('theme') != 'lightsout.css') {
|
||||
set_theme('lightsout.css');
|
||||
} else {
|
||||
set_theme('custom.php');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function setCookie(cname, cvalue, exdays) {
|
||||
var d = new Date();
|
||||
d.setTime(d.getTime() + (exdays*24*60*60*1000));
|
||||
|
|
|
@ -42,7 +42,7 @@ class Sysinfo
|
|||
|
||||
public function usedMemory()
|
||||
{
|
||||
$used = shell_exec("free -m | awk '/Mem:/ { total=$2 ; used=$3 } END { print used/total*100}'");
|
||||
$used = shell_exec("free -m | awk 'NR==2{ total=$2 ; used=$3 } END { print used/total*100}'");
|
||||
return floor($used);
|
||||
}
|
||||
|
||||
|
|
505
app/lib/uploader.php
Normal file
505
app/lib/uploader.php
Normal file
|
@ -0,0 +1,505 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Simple PHP upload class
|
||||
*
|
||||
* Adapted from aivis/PHP-file-upload-class
|
||||
*
|
||||
* @description File upload class for RaspAP
|
||||
* @author Bill Zimmerman <billzimmerman@gmail.com>
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# RaspAP default config
|
||||
log-facility=/tmp/dnsmasq.log
|
||||
log-facility=/var/log/dnsmasq.log
|
||||
conf-dir=/etc/dnsmasq.d
|
||||
|
||||
|
|
4
config/client_config/70-mobile-data-sticks.rules
Normal file
4
config/client_config/70-mobile-data-sticks.rules
Normal file
|
@ -0,0 +1,4 @@
|
|||
# mobile data modem - ttyUSB0 device appears
|
||||
SUBSYSTEM=="tty", KERNEL=="ttyUSB0", TAG+="systemd", ENV{SYSTEMD_WANTS}="start start_ppp0_device.service"
|
||||
|
||||
|
3
config/client_config/80-raspap-net-devices.rules
Normal file
3
config/client_config/80-raspap-net-devices.rules
Normal file
|
@ -0,0 +1,3 @@
|
|||
SUBSYSTEM=="net", ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="14db", NAME="hilink%n", TAG+="systemd", ENV{SYSTEMD_WANTS}="start start_huawei_hilink@hilink%n.service"
|
||||
|
||||
|
505
config/client_config/huawei_hilink_api.sh
Normal file
505
config/client_config/huawei_hilink_api.sh
Normal file
|
@ -0,0 +1,505 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Huawei Hilink API
|
||||
# =================
|
||||
# - communication with Hilink devices via HTTP
|
||||
# - send a standard http request with a xml formatted string to the device (default IP 192.169.8.1)
|
||||
# - Howto:
|
||||
# o "source" this script in your own script from the command line
|
||||
# o if hilink_host ip/name differs, set "hilink_host=192.168.178.1" before calling any function
|
||||
# o if the device is locked by a password, set hilink_user="admin"; hilink_password"1234secret"
|
||||
# _login is called automatically
|
||||
# only password type 4 is supported
|
||||
# o if the SIM is requiring a PIN, set "hilink_pin=1234"
|
||||
# o connect device to network: _switchMobileData ON ( or 1 )
|
||||
# o disconnect device: _switchMobileData OFF ( or 0 )
|
||||
# o get informations about the device: _getDeviceInformation and _getStatus and _getNetProvider
|
||||
# all functions return XML formatted data in $response.
|
||||
# o _getAllInformations: returns all available informations as key/value pairs (outputs text)
|
||||
# o Check if device is connected: "if _isConnected; then .... fi"
|
||||
# o $response can be parsed by calling _valueFromResponse
|
||||
# e.g "_valueFromResponse msisdn" to get the phone number after a call to _getDeviceInformation
|
||||
#
|
||||
#
|
||||
# Usage of functions
|
||||
# - call the function with parameters (if required)
|
||||
# - return code: 0 - success; 1 - failed
|
||||
# - $status: status information (OK, ERROR)
|
||||
# - $response: xml response to be parsed for the required information
|
||||
#
|
||||
#
|
||||
# required software: curl, base64, sha256sum, sed
|
||||
#
|
||||
# ToDo: improve error handling
|
||||
#
|
||||
# zbchristian 2021
|
||||
#
|
||||
|
||||
# Initialization procedure
|
||||
# ========================
|
||||
#
|
||||
# hilink_host=192.168.8.1 # ip address of device
|
||||
# hilink_user="admin" # user name if locked (default admin)
|
||||
# hilink_password="1234Secret" # password if locked
|
||||
# hilink_pin="1234" # PIN of SIM
|
||||
# _initHilinkAPI # initialize the API
|
||||
#
|
||||
# Termination
|
||||
# ===========
|
||||
# cleanup the API before quitting the shell
|
||||
# _closeHilinkAPI (optional: add parameter "save" to save the session/token data for subsequent calls. Valid for a few minutes.)
|
||||
#
|
||||
# BE AWARE, THAT THE API USES SOME GLOBAL VARIABLES : hilink_host, user, password, pin, response, status
|
||||
# USE THESE ONLY TO COMMUNICATE WITH THE API.
|
||||
# DO NOT USE THE VARIABLE PRE_FIX "hilink_" FOR YOUR OWN VARIABLES
|
||||
#
|
||||
|
||||
hilink_host_default="192.168.8.1"
|
||||
hilink_save_file="/tmp/hilink_api_saved.dat"
|
||||
hilink_save_age=60
|
||||
hilink_header_file="/tmp/hilink_login_hdr.txt"
|
||||
|
||||
# initialize
|
||||
function _initHilinkAPI() {
|
||||
local age
|
||||
if [ -z "$hilink_host" ]; then hilink_host=$hilink_host_default; fi
|
||||
if ! _hostReachable; then return 1; fi
|
||||
if [ -f $hilink_save_file ]; then # found file with saved data
|
||||
_getSavedData
|
||||
age=$(( $(date +%s) - $(stat $hilink_save_file -c %Y) ))
|
||||
if [[ $age -gt $hilink_save_age ]]; then
|
||||
rm -f $hilink_save_file
|
||||
_logout
|
||||
_sessToken
|
||||
fi
|
||||
fi
|
||||
if [ -z "$hilink_sessID" ] || [ -z "$hilink_token" ]; then _sessToken; fi
|
||||
_login
|
||||
return $?
|
||||
}
|
||||
|
||||
function _getSavedData() {
|
||||
local dat
|
||||
if [ -f $hilink_save_file ]; then # restore saved session data
|
||||
dat=$(cat $hilink_save_file)
|
||||
hilink_sessID=$(echo "$dat" | sed -nr 's/sessionid: ([a-z0-9]*)/\1/ip')
|
||||
hilink_token=$(echo "$dat" | sed -nr 's/token: ([a-z0-9]*)/\1/ip')
|
||||
hilink_tokenlist=( $(echo "$dat" | sed -nr 's/tokenlist: ([a-z0-9 ]*)/\1/ip') )
|
||||
fi
|
||||
}
|
||||
|
||||
# Cleanup
|
||||
# parameter: "save" - will store sessionid and tokens in file
|
||||
function _closeHilinkAPI() {
|
||||
local opt
|
||||
if [ -z "$hilink_host" ]; then hilink_host=$hilink_host_default; fi
|
||||
if ! _hostReachable; then return 1; fi
|
||||
rm -f $hilink_save_file
|
||||
[ ! -z "$1" ] && opt="${1,,}"
|
||||
if [ ! -z "$opt" ] && [ "$opt" = "save" ]; then
|
||||
echo "sessionid: $hilink_sessID" > $hilink_save_file
|
||||
echo "token: $hilink_token" >> $hilink_save_file
|
||||
echo "tokenlist: ${hilink_tokenlist[@]}" >> $hilink_save_file
|
||||
fi
|
||||
_logout
|
||||
hilink_tokenlist=""
|
||||
hilink_sessID=""
|
||||
hilink_token=""
|
||||
return 0
|
||||
}
|
||||
|
||||
# get status (connection status, DNS, )
|
||||
# parameter: none
|
||||
function _getStatus() {
|
||||
if _login; then
|
||||
if _sendRequest "api/monitoring/status"; then
|
||||
if [ ! -z "$1" ]; then _valueFromResponse "$1"; fi
|
||||
fi
|
||||
return $?
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
function _isConnected() {
|
||||
local conn
|
||||
conn=$(_getStatus "connectionstatus")
|
||||
status="NO"
|
||||
if [ ! -z "$conn" ] && [ $conn -eq 901 ]; then
|
||||
status="YES"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# get device information (device name, imei, imsi, msisdn-phone number, MAC, WAN IP ...)
|
||||
# parameter: name of parameter to return
|
||||
function _getDeviceInformation() {
|
||||
if _login; then
|
||||
if _sendRequest "api/device/information"; then
|
||||
if [ ! -z "$1" ]; then _valueFromResponse "$1"; fi
|
||||
fi
|
||||
return $?
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# get net provider information
|
||||
# parameter: name of parameter to return
|
||||
function _getNetProvider() {
|
||||
if _login; then
|
||||
if _sendRequest "api/net/current-plmn"; then
|
||||
if [ ! -z "$1" ]; then _valueFromResponse "$1"; fi
|
||||
fi
|
||||
return $?
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# get signal level
|
||||
# parameter: name of parameter to return
|
||||
function _getSignal() {
|
||||
if _login; then
|
||||
if _sendRequest "api/device/signal"; then
|
||||
if [ ! -z "$1" ]; then _valueFromResponse "$1"; fi
|
||||
fi
|
||||
return $?
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
function _getAllInformations() {
|
||||
if _getDeviceInformation; then _keyValuePairs; fi
|
||||
if _getSignal; then _keyValuePairs; fi
|
||||
if _getNetProvider; then _keyValuePairs; fi
|
||||
}
|
||||
|
||||
# get status of mobile data connection
|
||||
# parameter: none
|
||||
function _getMobileDataStatus() {
|
||||
if _login; then
|
||||
if _sendRequest "api/dialup/mobile-dataswitch"; then
|
||||
status=$(_valueFromResponse "dataswitch")
|
||||
if [ $? -eq 0 ] && [ ! -z "$status" ]; then echo "$status"; fi
|
||||
fi
|
||||
return $?
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
# PIN of SIM can be passed either as $hilink_pin, or as parameter
|
||||
# parameter: PIN number of SIM card
|
||||
function _enableSIM() {
|
||||
#SimState:
|
||||
#255 - no SIM,
|
||||
#256 - error CPIN,
|
||||
#257 - ready,
|
||||
#258 - PIN disabled,
|
||||
#259 - check PIN,
|
||||
#260 - PIN required,
|
||||
#261 - PUK required
|
||||
local simstate
|
||||
if [ ! -z "$1" ]; then hilink_pin="$1"; fi
|
||||
if ! _login; then return 1; fi
|
||||
if _sendRequest "api/pin/status"; then
|
||||
simstate=$(echo $response | sed -rn 's/.*<simstate>([0-9]*)<\/simstate>.*/\1/pi')
|
||||
if [[ $simstate -eq 257 ]]; then status="SIM ready"; return 0; fi
|
||||
if [[ $simstate -eq 260 ]]; then
|
||||
status="PIN required"
|
||||
if [ ! -z "$hilink_pin" ]; then _setPIN "$hilink_pin"; fi
|
||||
return $?
|
||||
fi
|
||||
if [[ $simstate -eq 255 ]]; then status="NO SIM"; return 1; fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# obtain session and verification token - stored in vars $hilink_sessID and $token
|
||||
# parameter: none
|
||||
function _sessToken() {
|
||||
hilink_tokenlist=""
|
||||
hilink_token=""
|
||||
hilink_sessID=""
|
||||
response=$(curl -s http://$hilink_host/api/webserver/SesTokInfo -m 5 2> /dev/null)
|
||||
if [ -z "$response" ]; then echo "No access to device at $hilink_host"; return 1; fi
|
||||
status=$(echo "$response" | sed -nr 's/.*<code>([0-9]*)<\/code>.*/\1/ip')
|
||||
if [ -z "$status" ]; then
|
||||
hilink_token=$(echo $response | sed -r 's/.*<TokInfo>(.*)<\/TokInfo>.*/\1/')
|
||||
hilink_sessID=$(echo $response | sed -r 's/.*<SesInfo>(.*)<\/SesInfo>.*/\1/')
|
||||
if [ ! -z "$hilink_sessID" ] && [ ! -z "$hilink_token" ]; then
|
||||
hilink_sessID="SessionID=$hilink_sessID"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# unlock device (if locked) with user name and password
|
||||
# requires stored hilink_user="admin"; hilink_password"1234secret";hilink_host=$hilink_host_default
|
||||
# parameter: none
|
||||
function _login() {
|
||||
local ret encpw pwtype pwtype3 hashedpw pwtype4
|
||||
if _loginState; then return 0; fi # login not required, or already done
|
||||
_sessToken
|
||||
# get password type
|
||||
if ! _sendRequest "api/user/state-login"; then return 1; fi
|
||||
pwtype=$(echo "$response" | sed -rn 's/.*<password_type>([0-9])<\/password_type>.*/\1/pi')
|
||||
if [ -z "$pwtype" ];then pwtype=4; fi # fallback is type 4
|
||||
ret=1
|
||||
if [[ ! -z "$hilink_user" ]] && [[ ! -z "$hilink_password" ]]; then
|
||||
# password encoding
|
||||
# type 3 : base64(pw) encoded
|
||||
# type 4 : base64(sha256sum(user + base64(sha256sum(pw)) + token))
|
||||
pwtype3=$(echo -n "$hilink_password" | base64 --wrap=0)
|
||||
hashedpw=$(echo -n "$hilink_password" | sha256sum -b | sed -nr 's/^([0-9a-z]*).*$/\1/ip' )
|
||||
hashedpw=$(echo -n "$hashedpw" | base64 --wrap=0)
|
||||
pwtype4=$(echo -n "$hilink_user$hashedpw$hilink_token" | sha256sum -b | sed -nr 's/^([0-9a-z]*).*$/\1/ip' )
|
||||
encpw=$(echo -n "$pwtype4" | base64 --wrap=0)
|
||||
if [ $pwtype -ne 4 ]; then encpw=$pwtype3; fi
|
||||
hilink_xmldata="<?xml version='1.0' encoding='UTF-8'?><request><Username>$hilink_user</Username><Password>$encpw</Password><password_type>$pwtype</password_type></request>"
|
||||
hilink_xtraopts="--dump-header $hilink_header_file"
|
||||
rm -f $hilink_header_file
|
||||
_sendRequest "api/user/login"
|
||||
if [ ! -z "$status" ] && [ "$status" = "OK" ]; then
|
||||
# store the list of 30 tokens. Each token is valid for a single request
|
||||
hilink_tokenlist=( $(cat $hilink_header_file | sed -rn 's/^__RequestVerificationToken:\s*([0-9a-z#]*).*$/\1/pi' | sed 's/#/ /g') )
|
||||
_getToken
|
||||
hilink_sessID=$(cat $hilink_header_file | grep -ioP 'SessionID=([a-z0-9]*)')
|
||||
if [ ! -z "$hilink_sessID" ] && [ ! -z "$hilink_token" ]; then ret=0; fi
|
||||
fi
|
||||
rm -f $hilink_header_file
|
||||
fi
|
||||
return $ret
|
||||
}
|
||||
|
||||
# logout of hilink device
|
||||
# parameter: none
|
||||
function _logout() {
|
||||
if _loginState; then
|
||||
hilink_xmldata="<?xml version: '1.0' encoding='UTF-8'?><request><Logout>1</Logout></request>"
|
||||
if _sendRequest "api/user/logout"; then
|
||||
hilink_tokenlist=""
|
||||
hilink_sessID=""
|
||||
hilink_token=""
|
||||
hilink_login_enabled=""
|
||||
fi
|
||||
return $?
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# parameter: none
|
||||
function _loginState() {
|
||||
local state
|
||||
status="OK"
|
||||
if [ -z "$hilink_login_enabled" ]; then _checkLoginEnabled; fi
|
||||
if [ $hilink_login_enabled -eq 1 ]; then return 0; fi # login is disabled
|
||||
_sendRequest "api/user/state-login"
|
||||
state=`echo "$response" | sed -rn 's/.*<state>(.*)<\/state>.*/\1/pi'`
|
||||
if [ ! -z "$state" ] && [ $state -eq 0 ]; then # already logged in
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
function _checkLoginEnabled() {
|
||||
local state
|
||||
if _sendRequest "api/user/hilink_login"; then
|
||||
hilink_login_enabled=0
|
||||
state=$(echo $response | sed -rn 's/.*<hilink_login>(.*)<\/hilink_login>.*/\1/pi')
|
||||
if [ ! -z "$state" ] && [ $state -eq 0 ]; then # no login enabled
|
||||
hilink_login_enabled=1
|
||||
fi
|
||||
else
|
||||
hilink_login_enabled=""
|
||||
fi
|
||||
}
|
||||
|
||||
# switch mobile data on/off 1/0
|
||||
# if SIM is locked, $hilink_pin has to be set
|
||||
# parameter: state - ON/OFF or 1/0
|
||||
function _switchMobileData() {
|
||||
local mode
|
||||
if [ -z "$1" ]; then return 1; fi
|
||||
_login
|
||||
mode="${1,,}"
|
||||
[ "$mode" = "on" ] && mode=1
|
||||
[ "$mode" = "off" ] && mode=0
|
||||
if [[ $mode -ge 0 ]]; then
|
||||
if _enableSIM "$hilink_pin"; then
|
||||
hilink_xmldata="<?xml version: '1.0' encoding='UTF-8'?><request><dataswitch>$mode</dataswitch></request>"
|
||||
_sendRequest "api/dialup/mobile-dataswitch"
|
||||
return $?
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# parameter: PIN of SIM card
|
||||
function _setPIN() {
|
||||
local pin
|
||||
if [ -z "$1" ]; then return 1; fi
|
||||
pin="$1"
|
||||
hilink_xmldata="<?xml version: '1.0' encoding='UTF-8'?><request><OperateType>0</OperateType><CurrentPin>$pin</CurrentPin><NewPin></NewPin><PukCode></PukCode></request>"
|
||||
_sendRequest "api/pin/operate"
|
||||
return $?
|
||||
}
|
||||
|
||||
# Send request to host at http://$hilink_host/$apiurl
|
||||
# data in $hilink_xmldata and options in $hilink_xtraopts
|
||||
# parameter: apiurl (e.g. "api/user/login")
|
||||
function _sendRequest() {
|
||||
local ret apiurl
|
||||
status="ERROR"
|
||||
if [ -z "$1" ]; then return 1; fi
|
||||
apiurl="$1"
|
||||
ret=1
|
||||
if [ -z "$hilink_sessID" ] || [ -z "$hilink_token" ]; then _sessToken; fi
|
||||
if [ -z "$hilink_xmldata" ];then
|
||||
response=$(curl -s http://$hilink_host/$apiurl -m 10 \
|
||||
-H "Cookie: $hilink_sessID")
|
||||
else
|
||||
response=$(curl -s -X POST http://$hilink_host/$apiurl -m 10 \
|
||||
-H "Content-Type: text/xml" \
|
||||
-H "Cookie: $hilink_sessID" \
|
||||
-H "__RequestVerificationToken: $hilink_token" \
|
||||
-d "$hilink_xmldata" $hilink_xtraopts 2> /dev/null)
|
||||
_getToken
|
||||
fi
|
||||
if [ ! -z "$response" ];then
|
||||
response=$(echo $response | tr -d '\012\015') # delete newline chars
|
||||
status=$(echo "$response" | sed -nr 's/.*<code>([0-9]*)<\/code>.*/\1/ip') # check for error code
|
||||
if [ -z "$status" ]; then
|
||||
status="OK"
|
||||
response=$(echo "$response" | sed -nr 's/.*<response>(.*)<\/response>.*/\1/ip')
|
||||
[ -z "$response" ] && response="none"
|
||||
ret=0
|
||||
else
|
||||
status="ERROR $status"
|
||||
fi
|
||||
else
|
||||
status="ERROR"
|
||||
fi
|
||||
if [[ "$status" =~ ERROR ]]; then _handleError; fi
|
||||
hilink_xtraopts=""
|
||||
hilink_xmldata=""
|
||||
return $ret
|
||||
}
|
||||
|
||||
# handle the list of tokens available after login
|
||||
# parameter: none
|
||||
function _getToken() {
|
||||
if [ ! -z "$hilink_tokenlist" ] && [ ${#hilink_tokenlist[@]} -gt 0 ]; then
|
||||
hilink_token=${hilink_tokenlist[0]} # get first token in list
|
||||
hilink_tokenlist=("${hilink_tokenlist[@]:1}") # remove used token from list
|
||||
if [ ${#hilink_tokenlist[@]} -eq 0 ]; then
|
||||
_logout # use the last token to logout
|
||||
fi
|
||||
else
|
||||
_sessToken # old token has been used - need new session
|
||||
fi
|
||||
}
|
||||
|
||||
# Analyse $status for error code
|
||||
# return error text in $status
|
||||
function _handleError() {
|
||||
local ret txt
|
||||
txt=$(_getErrorText)
|
||||
if [ -z "$code" ]; then return 1; fi
|
||||
ret=0
|
||||
case "$code" in
|
||||
101|108003|108007)
|
||||
ret=1
|
||||
status="$txt"
|
||||
;;
|
||||
108001|108002|108006)
|
||||
ret=1
|
||||
status="$txt"
|
||||
;;
|
||||
125001|125002|125003)
|
||||
_sessToken
|
||||
ret=0
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
return "$ret"
|
||||
}
|
||||
|
||||
declare -A hilink_err_api
|
||||
hilink_err_api[101]="Unable to get session ID/token"
|
||||
hilink_err_api[108001]="Invalid username/password"
|
||||
hilink_err_api[108002]=${hilink_err_api[108001]}
|
||||
hilink_err_api[108006]=${hilink_err_api[108001]}
|
||||
hilink_err_api[108003]="User already logged in - need to wait a bit"
|
||||
hilink_err_api[108007]="Too many login attempts - need to wait a bit"
|
||||
hilink_err_api[125001]="Invalid session/request token"
|
||||
hilink_err_api[125002]=${hilink_err_api[125001]}
|
||||
hilink_err_api[125003]=${hilink_err_api[125001]}
|
||||
|
||||
# check error and return error text
|
||||
# status passsed in $status, or $1
|
||||
function _getErrorText() {
|
||||
local err code errortext
|
||||
err="$status"
|
||||
code="0"
|
||||
if [ ! -z "$1" ]; then err="$1"; fi
|
||||
if [ -z "$err" ]; then return 1; fi
|
||||
errortext="$err"
|
||||
if [[ "$err" =~ ERROR\ *([0-9]*) ]] && [ ! -z "${BASH_REMATCH[1]}" ]; then
|
||||
code=${BASH_REMATCH[1]}
|
||||
if [ ! -z "$code" ] && [ ! -z "${hilink_err_api[$code]}" ]; then
|
||||
errortext="${hilink_err_api[$code]}"
|
||||
fi
|
||||
fi
|
||||
echo $errortext
|
||||
return 0
|
||||
}
|
||||
|
||||
function _hostReachable() {
|
||||
local avail
|
||||
avail=$( timeout 0.5 ping -c 1 $hilink_host | sed -rn 's/.*time=.*/1/p' )
|
||||
if [ -z "$avail" ]; then status="ERROR: Not reachable"; return 1; fi
|
||||
status="OK"
|
||||
return 0;
|
||||
}
|
||||
|
||||
# helper function to parse $response (xml format) for a value
|
||||
# call another function first!
|
||||
# parameter: tag-name
|
||||
function _valueFromResponse() {
|
||||
local par value
|
||||
if [ -z "$response" ] || [ -z "$1" ]; then return 1; fi
|
||||
par="$1"
|
||||
value=$(echo $response | sed -rn 's/.*<'$par'>(.*)<\/'$par'>.*/\1/pi')
|
||||
if [ -z "$value" ]; then return 1; fi
|
||||
echo "$value"
|
||||
return 0
|
||||
}
|
||||
|
||||
# list all keys of the current xml response
|
||||
function _keysFromResponse() {
|
||||
if [ -z "$response" ]; then return 1; fi
|
||||
echo $response | grep -oiP "(?<=<)[a-z_-]*(?=>)"
|
||||
return 0
|
||||
}
|
||||
|
||||
# return all key=value pairs of the current xml response
|
||||
function _keyValuePairs() {
|
||||
if [ -z "$response" ]; then return 1; fi
|
||||
echo $response | sed -n 's/<\([^>]*\)>\(.*\)<\/\1>[^<]*/\1=\"\2\"\n/gpi'
|
||||
return 0
|
||||
}
|
||||
|
||||
hilink_token=""
|
||||
hilink_tokenlist=""
|
||||
hilink_sessID=""
|
||||
hilink_xmldata=""
|
||||
hilink_xtraopts=""
|
||||
hilink_host=$hilink_host_default
|
||||
hilink_user="admin"
|
||||
hilink_password=""
|
||||
hilink_pin=""
|
||||
response=""
|
||||
status=""
|
||||
|
109
config/client_config/info_huawei.sh
Normal file
109
config/client_config/info_huawei.sh
Normal file
|
@ -0,0 +1,109 @@
|
|||
#!/bin/bash
|
||||
# get info about device and signal of Huawei mobile USB devices
|
||||
# parm:
|
||||
# $1 : requested information (manufacturer, device, imei, imsi, telnumber, ipaddress, mode, signal, operator)
|
||||
# $2 : (optional) type - hilink or modem (default: hilink)
|
||||
# $3 : (optional) for hilink: ip address of the device (default: 192.168.8.1)
|
||||
# for modem: tty interface for communication (default: /dev/ttypUSB2)
|
||||
# $4 : more options can be added for Hilink devices ('-u user -P password -p pin'). These are passed to the corresponding script
|
||||
#
|
||||
# requires: bc
|
||||
# calls the scripts info_huawei_hilink.sh and info_huawei_modem.sh (same path as this script)
|
||||
#
|
||||
# zbchristian 2020
|
||||
#
|
||||
path=$(dirname "$0")
|
||||
opt="device"
|
||||
if [ ! -z "$1" ]; then opt=${1,,}; fi
|
||||
type="hilink"
|
||||
if [ ! -z "$2" ]; then type=${2,,}; fi
|
||||
|
||||
parms=""
|
||||
if [ "$type" = "hilink" ]; then
|
||||
connect="-h 192.168.8.1"
|
||||
if [ ! -z "$3" ]; then connect="-h $3"; fi
|
||||
if [ ! -z "$4" ]; then parms="$4"; fi
|
||||
script="$path/info_huawei_hilink.sh"
|
||||
else
|
||||
connect="/dev/ttyUSB2"
|
||||
if [ ! -z "$3" ]; then connect=$3; fi
|
||||
script="$path/info_huawei_modem.sh"
|
||||
fi
|
||||
res=$($script $opt $connect $parms)
|
||||
|
||||
# some results require special treatment
|
||||
case $opt in
|
||||
|
||||
# manufacturer)
|
||||
# if [ "$res" = "none" ]; then res="Huawei"; fi
|
||||
# ;;
|
||||
|
||||
# device)
|
||||
# if [ ! "$res" = "none" ]; then res="Huawei $res";
|
||||
# else res="Huawei"; fi
|
||||
# ;;
|
||||
|
||||
mode)
|
||||
if [ ! "$res" = "none" ]; then
|
||||
if [ "$type" = "hilink" ]; then
|
||||
if [ "$res" = "LTE" ]; then res="4G"
|
||||
elif [ "$res" = "WCDMA" ]; then res="3G";
|
||||
else res="2G"; fi
|
||||
else
|
||||
if [ $res -eq 7 ]; then res="4G"
|
||||
elif [ $res -lt 7 ] && [ $res -gt 2 ] ; then res="3G";
|
||||
else res="2G"; fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
signal)
|
||||
# return signal strength/quality in %
|
||||
if [ "$type" = "hilink" ]; then
|
||||
# signal request tries to get RSRQ value
|
||||
# try to get RSRQ (4G), EC/IO (3G) or RSSI (2G) value
|
||||
if [ "$res" = "none" ]; then res=$($script "ecio"); fi
|
||||
if [ ! "$res" = "none" ]; then
|
||||
# for rsrq and ecio assume: -3dB (100%) downto -20dB (0%)
|
||||
qual=${res//dB/}
|
||||
if [[ ! "$qual" =~ [-0-9\.]* ]]; then qual=-100; fi
|
||||
qual=$(bc <<< "scale=0;res=$qual-0.5;res/1") # just round to next integer
|
||||
if [ $qual -le -20 ]; then qual=0;
|
||||
elif [ $qual -ge -3 ]; then qual=100;
|
||||
else qual=$(bc <<< "scale=0;res=100.0/17.0*$qual+2000.0/17.0;res/1"); fi
|
||||
else
|
||||
# try rssi: >-70dBm (100%) downto -100dBm (0%)
|
||||
res=$($script "rssi");
|
||||
if [ ! "$res" = "none" ]; then
|
||||
if [[ ! $res =~ [-0-9\.]* ]]; then res="-120 dBm"; fi
|
||||
qual=${res//dBm/}
|
||||
qual=$(bc <<< "scale=0;res=$qual+0.5;res/1") # just round to next integer
|
||||
if [ $qual -le -110 ]; then qual=0;
|
||||
elif [ $qual -ge -70 ]; then qual=100;
|
||||
else qual=$(bc <<< "scale=0;res=2.5*$qual+275;res/1"); fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# modem returns RSSI as number 0-31 - 0 = -113dB (0%), 1 = -111dB, 31 = >=51dB (100%)
|
||||
qual=$(bc <<< "scale=0;res=$res*3.5+0.5;res/1")
|
||||
if [ $qual -gt 100 ]; then res=100; fi
|
||||
fi
|
||||
if [ ! "$res" = "none" ]; then res="$res (${qual}%)"; fi
|
||||
;;
|
||||
|
||||
operator)
|
||||
# check if operator/network is just a 5 digit number -> extract network name from table
|
||||
if [[ $res =~ ^[0-9]{5}$ ]]; then
|
||||
mcc=${res:0:3}
|
||||
mnc=${res:3:2}
|
||||
op=$(cat $path/mcc-mnc-table.csv | sed -rn 's/^'$mcc'\,[0-9]*\,'$mnc'\,(.*\,){4}(.*)$/\2/p')
|
||||
if [ ! -z "$op" ]; then res="$op ($res)"; fi
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
echo $res
|
||||
|
95
config/client_config/info_huawei_hilink.sh
Normal file
95
config/client_config/info_huawei_hilink.sh
Normal file
|
@ -0,0 +1,95 @@
|
|||
#!/bin/bash
|
||||
# Information about HUAWEI hilink
|
||||
# -------------------------------
|
||||
# get info about the device and signal
|
||||
# parameter: $1 - "connected", "device", "ipaddress", "mode", "signal" (see case statement below)
|
||||
# -u,--user - username
|
||||
# -P,--password - password
|
||||
# -p,--pin - SIM pin
|
||||
# -h,--host - host ip address for API calls (optional)
|
||||
# returns the value of the parameter, or "none" if not found or empty
|
||||
#
|
||||
# All device informations are buffered for 5 secs to speed up subsequent calls
|
||||
#
|
||||
# zbchristian 2021
|
||||
|
||||
function _setAPIParams() {
|
||||
if [ ! -z "$hostip" ]; then hilink_host="$hostip"; fi
|
||||
if [ ! -z "$username" ]; then hilink_user="$username"; fi
|
||||
if [ ! -z "$password" ]; then hilink_password="$password"; fi
|
||||
if [ ! -z "$simpin" ]; then hilink_pin="$simpin"; fi
|
||||
}
|
||||
|
||||
if [ -z "$1" ]; then echo "none"; exit; fi
|
||||
property="${1,,}"
|
||||
shift
|
||||
hostip="192.168.8.1"
|
||||
while [ -n "$1" ]; do
|
||||
case "$1" in
|
||||
-u|--user) username="$2"; shift ;;
|
||||
-P|--password) password="$2"; shift ;;
|
||||
-p|--pin) simpin="$2"; shift ;;
|
||||
-h|--host) hostip="$2"; shift ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
status="no valid option given"
|
||||
result="none"
|
||||
hostip="192.168.8.1"
|
||||
if [ "$opt" = "connected" ]; then
|
||||
source /usr/local/sbin/huawei_hilink_api.sh
|
||||
_setAPIParams
|
||||
if ! _initHilinkAPI; then echo "none"; exit; fi
|
||||
result=$(_getMobileDataStatus)
|
||||
_closeHilinkAPI
|
||||
else
|
||||
info_file="/tmp/huawei_infos_${hostip}_$(id -u).dat"
|
||||
if [ -f "$info_file" ]; then
|
||||
age=$(( $(date +%s) - $(stat $info_file -c %Y) ))
|
||||
if [[ $age -gt 10 ]]; then rm -f $info_file; fi
|
||||
fi
|
||||
|
||||
if [ -f "$info_file" ]; then
|
||||
infos=$(cat $info_file)
|
||||
else
|
||||
source /usr/local/sbin/huawei_hilink_api.sh
|
||||
_setAPIParams
|
||||
if ! _initHilinkAPI; then echo "none"; exit; fi
|
||||
infos=$(_getAllInformations)
|
||||
_closeHilinkAPI
|
||||
if [ ! -z "$infos" ]; then echo -n "$infos" > $info_file; fi
|
||||
fi
|
||||
|
||||
case "$property" in
|
||||
device|devicename)
|
||||
key="devicename"
|
||||
;;
|
||||
ipaddress|wanipaddress)
|
||||
key="wanipaddress"
|
||||
;;
|
||||
mode)
|
||||
key="workmode"
|
||||
;;
|
||||
telnumber)
|
||||
key="msisdn"
|
||||
;;
|
||||
imei|imsi|rssi|rsrq|rsrp|sinr|ecio)
|
||||
key="$property"
|
||||
;;
|
||||
signal)
|
||||
key="rsrq"
|
||||
;;
|
||||
operator|fullname)
|
||||
key="fullname"
|
||||
;;
|
||||
*)
|
||||
key="device"
|
||||
;;
|
||||
esac
|
||||
if [ -z "$key" ]; then result="none"; fi
|
||||
result=$(echo "$infos" | sed -rn 's/'$key'=\"([^ \s]*)\"/\1/ip')
|
||||
if [ -z "$result" ]; then result="none"; fi
|
||||
fi
|
||||
echo -n "$result"
|
||||
|
52
config/client_config/info_huawei_modem.sh
Normal file
52
config/client_config/info_huawei_modem.sh
Normal file
|
@ -0,0 +1,52 @@
|
|||
#!/bin/bash
|
||||
# Information about HUAWEI modem - via AT commands
|
||||
# ------------------------------------------------
|
||||
# get info about the device and signal
|
||||
# parameter: $1 - see opts list below
|
||||
# $2 - tty device name for the communicaton (optional)
|
||||
# returns the value of the parameter, or "none" if not found or empty
|
||||
#
|
||||
# requires: socat
|
||||
#
|
||||
# zbchristian 2020
|
||||
|
||||
opts=("manufacturer" "device" "imei" "imsi" "telnumber" "mode" "signal" "operator")
|
||||
|
||||
# at command to extract information
|
||||
atcmds=("AT+CGMI" "AT+CGMM" "AT+CGSN" "AT+CIMI" "AT+CNUM" "AT+COPS?" "AT+CSQ" "AT+COPS?")
|
||||
# regexp pattern to extract wanted information from result string
|
||||
pats=( " " " " " " " " ".*\,\"([0-9\+]*)\".*" '.*\,([0-9])$' ".*: ([0-9]*).*" '.*\,\"([^ ]*)\".*$')
|
||||
|
||||
# tty device for communication - usually 3 tty devices are created and the 3rd ttyUSB2 is available, even, when the device is connected
|
||||
dev="/dev/ttyUSB2"
|
||||
|
||||
atsilent="AT^CURC=0"
|
||||
|
||||
if [ ! -z $2 ]; then dev=$2; fi
|
||||
|
||||
idx=-1
|
||||
opt=${opts[0]}
|
||||
if [ ! -z $1 ]; then opt=$1; fi
|
||||
|
||||
for i in "${!opts[@]}"; do
|
||||
if [[ ${opts[$i]} == $opt ]]; then idx=$i; fi
|
||||
done
|
||||
if [[ $idx == -1 ]];then echo "none"; exit; fi
|
||||
|
||||
atcmd=${atcmds[$idx]}
|
||||
pat=${pats[$idx]}
|
||||
|
||||
|
||||
result=`(echo $atsilent; echo $atcmd) | sudo /usr/bin/socat - $dev`
|
||||
# escape the AT command to be used in the regexp
|
||||
atesc=${atcmd//[\+]/\\+}
|
||||
atesc=${atesc//[\?]/\\?}
|
||||
result=`echo $result | sed -rn 's/.*'"$atesc"'\s([^ ]+|[^ ]+ [^ ]+)\sOK.*$/\1/pg'`
|
||||
if [[ $pat != " " ]]; then
|
||||
result=`echo $result | sed -rn 's/'"$pat"'/\1/pg'`
|
||||
fi
|
||||
|
||||
if [ -z "$result" ]; then result="none"; fi
|
||||
|
||||
echo $result
|
||||
|
13
config/client_config/interfaces
Normal file
13
config/client_config/interfaces
Normal file
|
@ -0,0 +1,13 @@
|
|||
# interfaces(5) file used by ifup(8) and ifdown(8)
|
||||
|
||||
# Please note that this file is written to be used with dhcpcd
|
||||
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'
|
||||
|
||||
# Include files from /etc/network/interfaces.d:
|
||||
source-directory /etc/network/interfaces.d
|
||||
|
||||
auto ppp0
|
||||
iface ppp0 inet wvdial
|
||||
provider connect
|
||||
pre-up /usr/local/sbin/ppp0_setpin.sh
|
||||
up /usr/local/sbin/ppp0_route.sh
|
1691
config/client_config/mcc-mnc-table.csv
Normal file
1691
config/client_config/mcc-mnc-table.csv
Normal file
File diff suppressed because it is too large
Load diff
58
config/client_config/onoff_huawei_hilink.sh
Normal file
58
config/client_config/onoff_huawei_hilink.sh
Normal file
|
@ -0,0 +1,58 @@
|
|||
#!/bin/bash
|
||||
# connect/disconnect Huawei mobile data stick in Hilink mode (e.g. E3372h)
|
||||
# ========================================================================
|
||||
#
|
||||
# options: -u, --user - user name (default "admin")
|
||||
# -P, --password - password
|
||||
# -h, --host - host ip address (default 192.168.8.1)
|
||||
# -d, --devname - device name (IP is extracted using default route)
|
||||
# -p, --pin - PIN of SIM card
|
||||
# -c, --connect - connect 0/1 to set datamode off/on
|
||||
#
|
||||
# required software: curl, base64, sha256sum
|
||||
#
|
||||
# zbchristian 2021
|
||||
|
||||
# include the hilink API (defaults: hilink_user=admin, hilink_host=192.168.8.1)
|
||||
source /usr/local/sbin/huawei_hilink_api.sh
|
||||
|
||||
# include the raspap helper functions
|
||||
source /usr/local/sbin/raspap_helpers.sh
|
||||
|
||||
datamode=""
|
||||
devname=""
|
||||
while [ -n "$1" ]; do
|
||||
case "$1" in
|
||||
-u|--user) hilink_user="$2"; shift ;;
|
||||
-P|--password) hilink_password="$2"; shift ;;
|
||||
-p|--pin) if [[ $2 =~ ^[0-9]{4,8} ]]; then hilink_pin="$2"; fi; shift ;;
|
||||
-h|--host) hilink_host="$2"; shift ;;
|
||||
-d|--devname) devname="$2"; shift ;;
|
||||
-c|--connect) if [ "$2" = "1" ]; then datamode=1; else datamode=0; fi; shift ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ ! -z "$devname" ]; then # get host IP for given device name
|
||||
gw=$(ip route list | sed -rn "s/default via (([0-9]{1,3}\.){3}[0-9]{1,3}).*dev $devname.*/\1/p")
|
||||
if [ -z "$gw" ]; then exit; fi # device name not found in routing list -> abort
|
||||
hilink_host="$gw"
|
||||
fi
|
||||
|
||||
if [ -z "$hilink_password" ] || [ -z "$hilink_pin" ]; then
|
||||
_getAuthRouter
|
||||
if [ ! -z "$raspap_user" ]; then hilink_user="$raspap_user"; fi
|
||||
if [ ! -z "$raspap_password" ]; then hilink_password="$raspap_password"; fi
|
||||
if [ ! -z "$raspap_pin" ]; then hilink_pin="$raspap_pin"; fi
|
||||
fi
|
||||
|
||||
echo "Hilink: switch device at $hilink_host to mode $datamode" | systemd-cat
|
||||
|
||||
status="usage: -c 1/0 to disconnect/connect"
|
||||
if [ -z "$datamode" ] || [ ! _initHilinkAPI ]; then echo "Hilink: failed - return status: $status"; exit; fi
|
||||
|
||||
if ! _switchMobileData "$datamode"; then echo -n "Hilink: could not switch the data mode on/off . Error: ";_getErrorText; fi
|
||||
|
||||
if ! _closeHilinkAPI; then echo -n "Hilink: failed - return status: $status . Error: ";_getErrorText; fi
|
||||
|
||||
|
21
config/client_config/ppp0_route.sh
Normal file
21
config/client_config/ppp0_route.sh
Normal file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# get gateway and ip address of UTMS modem connected to ppp0
|
||||
# add a default route
|
||||
# called by /etc/network/interfaces.d/ppp0, when device is coming up
|
||||
#
|
||||
ppp0rt=""
|
||||
let i=1
|
||||
while [ -z "$ppp0rt" ] ; do
|
||||
let i+=1
|
||||
if [ $i -gt 20 ]; then
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
ppp0rt=`ip route list | grep -m 1 ppp0`
|
||||
done
|
||||
gate=`echo $ppp0rt | sed -rn 's/(([0-9]{1,3}\.){3}[0-9]{1,3}).*ppp0.*src (([0-9]{1,3}\.){3}[0-9]{1,3})/\1/p'`
|
||||
src=`echo $ppp0rt | sed -rn 's/(([0-9]{1,3}\.){3}[0-9]{1,3}).*ppp0.*src (([0-9]{1,3}\.){3}[0-9]{1,3})/\3/p'`
|
||||
|
||||
ip route add default via $gate proto dhcp src $src metric 10
|
||||
exit 0
|
21
config/client_config/ppp0_setpin.sh
Normal file
21
config/client_config/ppp0_setpin.sh
Normal file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
# in case /dev/ttyUSB0 does not exist, wait for it at most 30 seconds
|
||||
let i=1
|
||||
while ! test -c /dev/ttyUSB0; do
|
||||
let i+=1
|
||||
if [ $i -gt 2 ]; then
|
||||
logger -s -t setpin "/dev/ttyUSB0 does not exist"
|
||||
exit 3
|
||||
fi
|
||||
logger -s -t setpin "waiting 3 seconds for /dev/ttyUSB0"
|
||||
sleep 3
|
||||
done
|
||||
# check for pin and set it if necessary
|
||||
wvdial pinstatus 2>&1 | grep -q '^+CPIN: READY'
|
||||
if [ $? -eq 0 ]; then
|
||||
logger -s -t setpin "SIM card is ready to use :-)"
|
||||
else
|
||||
logger -s -t setpin "setting PIN"
|
||||
wvdial pin 2>/dev/null
|
||||
fi
|
||||
exit 0
|
51
config/client_config/raspap_helpers.sh
Normal file
51
config/client_config/raspap_helpers.sh
Normal file
|
@ -0,0 +1,51 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Helper functions to extract informations from RaspAP config/settings
|
||||
#
|
||||
# zbchristian 2021
|
||||
#
|
||||
# get the values of a RaspAP config variable
|
||||
# call: _getRaspapConfig RASPAP_MOBILEDATA_CONFIG
|
||||
|
||||
raspap_webroot="/var/www/html"
|
||||
|
||||
function _getWebRoot() {
|
||||
local path
|
||||
path=$(cat /etc/lighttpd/lighttpd.conf | sed -rn "s/server.document-root \s*= \"([^ \s]*)\"/\1/p")
|
||||
if [ ! -z "$path" ]; then raspap_webroot="$path"; fi
|
||||
if [ -z "$path" ]; then return 1; else return 0; fi
|
||||
}
|
||||
|
||||
# expand an RaspAP config variable utilizing PHP
|
||||
function _getRaspapConfig() {
|
||||
local conf var
|
||||
raspap_config=""
|
||||
var="$1"
|
||||
if [ ! -z "$var" ]; then
|
||||
if ! _getWebRoot; then return 1; fi
|
||||
conf="$raspap_webroot/includes/config.php"
|
||||
if [ -f "$conf" ]; then
|
||||
conf=$(php -r 'include "'$conf'"; echo '$var';' 2> /dev/null)
|
||||
if [ ! -z "$conf" ] && [ -d ${conf%/*} ]; then raspap_config="$conf"; fi
|
||||
fi
|
||||
fi
|
||||
if [ -z "$raspap_config" ]; then return 1; else return 0; fi
|
||||
}
|
||||
|
||||
# Username and password for mobile data devices is stored in a file (RASPAP_MOBILEDATA_CONFIG)
|
||||
function _getAuthRouter() {
|
||||
local mfile mdata pin user pw
|
||||
if ! _getRaspapConfig "RASPI_MOBILEDATA_CONFIG"; then return 1; fi
|
||||
mfile="$raspap_config"
|
||||
if [ -f $mfile ]; then
|
||||
mdata=$(cat "$mfile")
|
||||
pin=$(echo "$mdata" | sed -rn 's/pin = ([^ \s]*)/\1/ip')
|
||||
if [ ! -z "$pin" ]; then raspap_pin="$pin"; fi
|
||||
user=$(echo "$mdata" | sed -rn 's/router_user = ([^ \s]*)/\1/ip')
|
||||
if [ ! -z "$user" ]; then raspap_user="$user"; fi
|
||||
pw=$(echo "$mdata" | sed -rn 's/router_pw = ([^ \s]*)/\1/ip')
|
||||
if [ ! -z "$pw" ]; then raspap_password="$pw"; fi
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
13
config/client_config/start_huawei_hilink@.service
Normal file
13
config/client_config/start_huawei_hilink@.service
Normal file
|
@ -0,0 +1,13 @@
|
|||
[Unit]
|
||||
Description=Bring up HUAWEI mobile hilink device
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=no
|
||||
ExecStart=/bin/sleep 15
|
||||
ExecStart=/usr/local/sbin/onoff_huawei_hilink.sh -c 1 -d %i
|
||||
|
||||
[Install]
|
||||
Alias=start_ltemodem.service
|
||||
WantedBy=multi-user.target
|
||||
|
16
config/client_config/start_ppp0_device.service
Normal file
16
config/client_config/start_ppp0_device.service
Normal file
|
@ -0,0 +1,16 @@
|
|||
[Unit]
|
||||
Description=Start ppp0 interface
|
||||
BindsTo=dev-ttyUSB0.device
|
||||
After=dev-ttyUSB0.device
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/sbin/ifup ppp0
|
||||
ExecStop=/sbin/ifdown ppp0
|
||||
|
||||
[Install]
|
||||
Alias=startppp0.service
|
||||
WantedBy=multi-user.target
|
||||
|
||||
|
21
config/client_config/wvdial.conf
Normal file
21
config/client_config/wvdial.conf
Normal file
|
@ -0,0 +1,21 @@
|
|||
[Dialer Defaults]
|
||||
Modem Type = Analog Modem
|
||||
ISDN = 0
|
||||
Baud = 9600
|
||||
Modem = /dev/ttyUSB0
|
||||
|
||||
[Dialer pin]
|
||||
Init1 = AT+CPIN="XXXX"
|
||||
|
||||
[Dialer connect]
|
||||
Init1 = ATZ
|
||||
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
|
||||
Init3 = AT+CGDCONT=1,"IP","web.vodafone.de"
|
||||
New PPPD = yes
|
||||
Phone = *99#
|
||||
Password = me
|
||||
Username = vodafone
|
||||
Stupid Mode = 1
|
||||
|
||||
[Dialer pinstatus]
|
||||
Init1 = AT+CPIN?
|
64
config/client_udev_prototypes.json
Normal file
64
config/client_udev_prototypes.json
Normal file
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"info": "UDEV rules for different client types. $...$ expressions will be replaces automatically ($MAC$, $IDVENDOR$, $IDPRODUCT$, $DEVNAME$)",
|
||||
"udev_rules_file": "/etc/udev/rules.d/80-raspap-net-devices.rules",
|
||||
"script_path": "/usr/local/sbin",
|
||||
"network_devices": [
|
||||
{
|
||||
"type": "eth",
|
||||
"type_info": "ethernet port",
|
||||
"clientid": 0,
|
||||
"comment": "standard ethernet port",
|
||||
"name_prefix": "eth",
|
||||
"udev_rule": "SUBSYSTEM==\"net\", ACTION==\"add\", ATTR{address}==\"$MAC$\", NAME=\"$DEVNAME$\", ENV{raspapType}=\"eth\" "
|
||||
},
|
||||
{
|
||||
"type": "usb",
|
||||
"type_info": "usb network interface",
|
||||
"clientid": 1,
|
||||
"comment": "network interface - e.g. USB tethering of an Android phone ",
|
||||
"name_prefix": "usb",
|
||||
"udev_rule": "SUBSYSTEM==\"net\", ACTION==\"add\", SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"$IDVENDOR$\", ATTRS{idProduct}==\"$IDPRODUCT$\", NAME=\"$DEVNAME$\", ENV{raspapType}=\"eth\" "
|
||||
},
|
||||
{
|
||||
"type": "wlan",
|
||||
"type_info": "wireless adapter",
|
||||
"clientid": 2,
|
||||
"comment": "standard wireless interface",
|
||||
"name_prefix": "wlan",
|
||||
"udev_rule": "SUBSYSTEM==\"net\", ACTION==\"add\", ATTR{address}==\"$MAC$\", NAME=\"$DEVNAME$\", ENV{raspapType}=\"wlan\" "
|
||||
},
|
||||
{
|
||||
"type": "ppp",
|
||||
"type_info": "mobile data modem",
|
||||
"clientid": 3,
|
||||
"name_prefix": "ppp",
|
||||
"comment": "recognized mobile data modems are automatically named as ppp0-9. Renaming is not possible. Dialin service relies on the name",
|
||||
"udev_rule": "SUBSYSTEM==\"tty\", KERNEL==\"ttyUSB0\", TAG+=\"systemd\", ENV{SYSTEMD_WANTS}=\"start start_ppp0_device.service\" "
|
||||
},
|
||||
{
|
||||
"type": "hilink",
|
||||
"type_info": "Huawei Hilink",
|
||||
"clientid": 4,
|
||||
"comment": "Huawei mobile data device in router mode. Control via HTTP. Device is connecting via service",
|
||||
"name_prefix": "hilink",
|
||||
"default_ip": "192.168.8.1",
|
||||
"udev_rule": "SUBSYSTEM==\"net\", ACTION==\"add\", SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"$IDVENDOR$\", ATTRS{idProduct}==\"$IDPRODUCT$\", NAME=\"$DEVNAME$\", ENV{raspapType}=\"hilink\", TAG+=\"systemd\", ENV{SYSTEMD_WANTS}=\"start start_huawei_hilink@hilink%n.service\" "
|
||||
},
|
||||
{
|
||||
"type": "phone",
|
||||
"type_info": "USB tethered phone",
|
||||
"clientid": 5,
|
||||
"comment": "ethernet access provided by tethering from phone via USB",
|
||||
"name_prefix": "phone",
|
||||
"udev_rule": "SUBSYSTEM==\"net\", ACTION==\"add\", SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"$IDVENDOR$\", ATTRS{idProduct}==\"$IDPRODUCT$\", NAME=\"$DEVNAME$\", ENV{raspapType}=\"phone\" "
|
||||
},
|
||||
{
|
||||
"type": "tun",
|
||||
"type_info": "tunnel device",
|
||||
"clientid": -1,
|
||||
"comment": "tunneling device used by OpenVPN",
|
||||
"name_prefix": "tun"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -15,12 +15,15 @@ define('RASPI_ADBLOCK_LISTPATH', '/etc/raspap/adblock/');
|
|||
define('RASPI_ADBLOCK_CONFIG', RASPI_DNSMASQ_PREFIX.'adblock.conf');
|
||||
define('RASPI_HOSTAPD_CONFIG', '/etc/hostapd/hostapd.conf');
|
||||
define('RASPI_DHCPCD_CONFIG', '/etc/dhcpcd.conf');
|
||||
define('RASPI_DHCPCD_LOG', '/var/log/dnsmasq.log');
|
||||
define('RASPI_WPA_SUPPLICANT_CONFIG', '/etc/wpa_supplicant/wpa_supplicant.conf');
|
||||
define('RASPI_HOSTAPD_CTRL_INTERFACE', '/var/run/hostapd');
|
||||
define('RASPI_WPA_CTRL_INTERFACE', '/var/run/wpa_supplicant');
|
||||
define('RASPI_OPENVPN_CLIENT_PATH', '/etc/openvpn/client/');
|
||||
define('RASPI_OPENVPN_CLIENT_CONFIG', '/etc/openvpn/client/client.conf');
|
||||
define('RASPI_OPENVPN_CLIENT_LOGIN', '/etc/openvpn/client/login.conf');
|
||||
define('RASPI_OPENVPN_SERVER_CONFIG', '/etc/openvpn/server/server.conf');
|
||||
define('RASPI_WIREGUARD_PATH', '/etc/wireguard/');
|
||||
define('RASPI_WIREGUARD_CONFIG', RASPI_WIREGUARD_PATH.'wg0.conf');
|
||||
define('RASPI_TORPROXY_CONFIG', '/etc/tor/torrc');
|
||||
define('RASPI_LIGHTTPD_CONFIG', '/etc/lighttpd/lighttpd.conf');
|
||||
define('RASPI_ACCESS_CHECK_IP', '1.1.1.1');
|
||||
|
|
|
@ -33,6 +33,25 @@
|
|||
"uap0": {
|
||||
"dhcp-range": [ "192.168.200.50,192.168.200.150,12h" ]
|
||||
}
|
||||
},
|
||||
"wireguard": {
|
||||
"server": {
|
||||
"Address": [ "10.8.2.1/24" ],
|
||||
"ListenPort": [ "51820" ],
|
||||
"DNS": [ "9.9.9.9" ],
|
||||
"PostUp": [ "iptables -A FORWARD -i wlan0 -o wg0 -j ACCEPT; iptables -A FORWARD -i wg0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE" ],
|
||||
"PostDown": [ "iptables -D FORWARD -i wlan0 -o wg0 -j ACCEPT; iptables -D FORWARD -i wg0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -D POSTROUTING -o wg0 -j MASQUERADE" ]
|
||||
},
|
||||
"peer": {
|
||||
"Address": [ "10.8.1.2/24" ],
|
||||
"Endpoint": [ "10.8.2.1:51820" ],
|
||||
"ListenPort": [ "21841" ],
|
||||
"AllowedIPs": ["10.8.2.0/24"],
|
||||
"PersistentKeepalive": [ "15" ]
|
||||
}
|
||||
},
|
||||
"txpower": {
|
||||
"dbm": [ "auto", "30", "20", "17", "10", "6", "3", "1", "0" ]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
205
config/iptables_rules.json
Normal file
205
config/iptables_rules.json
Normal file
|
@ -0,0 +1,205 @@
|
|||
{
|
||||
"info": "IPTABLES rules. $...$ expressions will be replaces automatically ($INTERFACE$, $PORT$, $IPADDRESS$)",
|
||||
"rules_v4_file": "/etc/iptables/rules.v4",
|
||||
"rules_v6_file": "/etc/iptables/rules.v6",
|
||||
"order": [ "pre_rules", "restriction_rules", "main_rules", "exception_rules" ],
|
||||
"pre_rules": [
|
||||
{
|
||||
"name": "firewall policies",
|
||||
"fw-state": true,
|
||||
"comment": "Policy rules (firewall)",
|
||||
"rules": [
|
||||
"-P INPUT DROP",
|
||||
"-P FORWARD ACCEPT",
|
||||
"-P OUTPUT ACCEPT",
|
||||
"-t nat -P PREROUTING ACCEPT",
|
||||
"-t nat -P POSTROUTING ACCEPT",
|
||||
"-t nat -P INPUT ACCEPT",
|
||||
"-t nat -P OUTPUT ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "policies",
|
||||
"fw-state": false,
|
||||
"comment": "Policy rules",
|
||||
"rules": [
|
||||
"-P INPUT ACCEPT",
|
||||
"-P FORWARD ACCEPT",
|
||||
"-P OUTPUT ACCEPT",
|
||||
"-t nat -P PREROUTING ACCEPT",
|
||||
"-t nat -P POSTROUTING ACCEPT",
|
||||
"-t nat -P INPUT ACCEPT",
|
||||
"-t nat -P OUTPUT ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "loopback",
|
||||
"fw-state": true,
|
||||
"comment": "allow loopback device",
|
||||
"rules": [
|
||||
"-A INPUT -i lo -j ACCEPT",
|
||||
"-A OUTPUT -o lo -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ping",
|
||||
"fw-state": true,
|
||||
"ip-version": 4,
|
||||
"comment": "allow ping request and echo",
|
||||
"rules": [
|
||||
"-A INPUT -p icmp --icmp-type 8/0 -j ACCEPT",
|
||||
"-A INPUT -p icmp --icmp-type 0/0 -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ping IPv6",
|
||||
"fw-state": true,
|
||||
"ip-version": 6,
|
||||
"comment": "allow ping request and echo for IPv6",
|
||||
"rules": [
|
||||
"-A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT",
|
||||
"-A INPUT -p icmpv6 --icmpv6-type echo-reply -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ntp",
|
||||
"fw-state": true,
|
||||
"comment": "allow ntp request via udp (tcp should work w/o rule)",
|
||||
"rules": [
|
||||
"-A INPUT -p udp --sport 123 -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "dns",
|
||||
"fw-state": true,
|
||||
"comment": "allow dns request via tcp and udp",
|
||||
"rules": [
|
||||
"-A INPUT -p udp -m multiport --sport 53,853 -j ACCEPT",
|
||||
"-A INPUT -p tcp -m multiport --sport 53,853 -j ACCEPT"
|
||||
]
|
||||
}
|
||||
],
|
||||
"main_rules": [
|
||||
{
|
||||
"name": "accesspoint",
|
||||
"fw-state": true,
|
||||
"comment": "Access point interface by default no restrictions",
|
||||
"dependson": [
|
||||
{ "var": "ap-device", "type": "string", "replace": "$INTERFACE$" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -i $INTERFACE$ -j ACCEPT",
|
||||
"-A OUTPUT -o $INTERFACE$ -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "NAT for access point",
|
||||
"comment": "Masquerading needed for access point",
|
||||
"rules": [
|
||||
"-t nat -A POSTROUTING -j MASQUERADE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "clients",
|
||||
"fw-state": true,
|
||||
"comment": "Rules for client interfaces (includes tun device)",
|
||||
"rules": [
|
||||
"-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "openvpn",
|
||||
"comment": "Rules for tunnel device (tun)",
|
||||
"ip-version": 4,
|
||||
"dependson": [
|
||||
{ "var": "openvpn-enable", "type": "bool" },
|
||||
{ "var": "openvpn-serverip", "type": "string", "replace": "$IPADDRESS$" },
|
||||
{ "var": "ap-device", "type": "string", "replace": "$INTERFACE$" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -p udp -s $IPADDRESS$ -j ACCEPT",
|
||||
"-A FORWARD -i tun+ -o $INTERFACE$ -m state --state RELATED,ESTABLISHED -j ACCEPT",
|
||||
"-A FORWARD -i $INTERFACE$ -o tun+ -j ACCEPT",
|
||||
"-t nat -A POSTROUTING -o tun+ -j MASQUERADE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "wireguard",
|
||||
"comment": "Rules for wireguard device (wg)",
|
||||
"ip-version": 4,
|
||||
"dependson": [
|
||||
{ "var": "wireguard-enable", "type": "bool" },
|
||||
{ "var": "wireguard-serverip", "type": "string", "replace": "$IPADDRESS$" },
|
||||
{ "var": "client-device", "type": "string", "replace": "$INTERFACE$" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -p udp -s $IPADDRESS$ -j ACCEPT",
|
||||
"-A FORWARD -i wg+ -j ACCEPT",
|
||||
"-t nat -A POSTROUTING -o $INTERFACE$ -j MASQUERADE"
|
||||
]
|
||||
}
|
||||
],
|
||||
"exception_rules": [
|
||||
{
|
||||
"name": "ssh",
|
||||
"fw-state": true,
|
||||
"comment": "Allow ssh access to RaspAP on port 22",
|
||||
"dependson": [
|
||||
{ "var": "ssh-enable", "type": "bool" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -p tcp --dport 22 -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "http",
|
||||
"fw-state": true,
|
||||
"comment": "Allow access to RaspAP GUI (https)",
|
||||
"dependson": [
|
||||
{ "var": "http-enable", "type": "bool" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "interface",
|
||||
"fw-state": true,
|
||||
"comment": "Exclude interface from firewall",
|
||||
"dependson": [
|
||||
{ "var": "excl-devices", "type": "list", "replace": "$INTERFACE$" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -i $INTERFACE$ -j ACCEPT",
|
||||
"-A OUTPUT -o $INTERFACE$ -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ipaddress",
|
||||
"fw-state": true,
|
||||
"ip-version": 4,
|
||||
"comment": "allow access from/to IP",
|
||||
"dependson": [
|
||||
{ "var": "excluded-ips", "type": "list", "replace": "$IPADDRESS$" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -s $IPADDRESS$ -j ACCEPT",
|
||||
"-A INPUT -d $IPADDRESS$ -j ACCEPT"
|
||||
]
|
||||
}
|
||||
],
|
||||
"restriction_rules": [
|
||||
{
|
||||
"name": "ipaddress",
|
||||
"fw-state": true,
|
||||
"ip-version": 4,
|
||||
"dependson": [
|
||||
{ "var": "restricted-ips", "type": "list", "replace": "$IPADDRESS$" }
|
||||
],
|
||||
"comment": "Block access from IP-address",
|
||||
"rules": [
|
||||
"-A INPUT -s $IPADDRESS$ -j DROP"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
BIN
dist/raspap/css/fonts/RaspAP.eot
vendored
Executable file
BIN
dist/raspap/css/fonts/RaspAP.eot
vendored
Executable file
Binary file not shown.
12
dist/raspap/css/fonts/RaspAP.svg
vendored
Executable file
12
dist/raspap/css/fonts/RaspAP.svg
vendored
Executable file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Generated by IcoMoon</metadata>
|
||||
<defs>
|
||||
<font id="RaspAP" horiz-adv-x="1024">
|
||||
<font-face units-per-em="1024" ascent="960" descent="-64" />
|
||||
<missing-glyph horiz-adv-x="1024" />
|
||||
<glyph unicode=" " horiz-adv-x="512" d="" />
|
||||
<glyph unicode="" glyph-name="wireguard" d="M1023.147 463.147c0 0 23.595 496.853-522.453 496.853-482.859 0-497.963-476.587-497.963-476.587s-70.997-547.413 509.141-547.413c556.501 0 511.275 527.147 511.275 527.147zM347.947 636.757c102.4 62.72 233.344 24.363 282.368-69.888 9.301-17.877 10.496-45.355 4.608-64.128-20.352-64.683-68.309-100.949-134.187-116.395 19.413 16.64 34.859 35.499 39.808 61.525 1.195 5.504 1.88 11.827 1.88 18.31 0 20.027-6.533 38.528-17.584 53.488l0.174-0.246c-16.797 22.874-43.588 37.556-73.809 37.556-11.257 0-22.038-2.037-31.995-5.763l0.63 0.207c-40.533-15.36-62.72-52.395-58.752-97.877 3.712-42.24 35.797-69.632 95.787-80.043-8.96-4.736-15.872-8.235-22.613-11.989-27.988-15.524-51.374-35.995-69.74-60.451l-0.404-0.562c-6.101-8.192-10.24-8.875-19.541-3.2-120.619 73.771-128.384 258.859 3.371 339.456zM257.707 180.992c-19.413-4.949-38.187-12.203-57.984-18.688 9.685 65.365 86.229 125.568 150.997 118.699-18.043-24.598-29.583-54.982-31.551-87.945l-0.022-0.46c-21.504-3.968-41.813-6.613-61.44-11.605zM669.995 819.2c19.115-0.725 38.315-0.427 57.472-0.853 5.287-0.363 10.162-1.075 14.91-2.128l-0.659 0.123c-4.574-6.938-9.348-12.986-14.582-18.599l0.076 0.082c-6.827-6.4-14.549-12.629-24.448-2.944-2.347 2.347-7.979 1.792-12.075 1.877-19.072 0.213-38.144 0.853-57.173 0.128-17.856-0.589-34.82-2.396-51.386-5.353l2.149 0.318c-3.072-0.555-7.595-10.667-6.229-14.421 3.328-8.832 8.149-18.56 15.317-24.192 26.411-20.907 54.485-39.595 81.067-60.288 25.771-20.139 49.792-42.24 64.427-72.533 19.029-39.595 19.627-81.067 11.392-122.752-13.739-69.547-48.939-127.147-105.941-169.045-22.955-16.853-51.413-26.453-77.696-38.528-23.168-10.667-46.933-19.84-70.144-30.379-41.813-19.029-65.28-64.427-58.411-111.573 6.357-43.307 44.373-79.445 87.851-86.912 52.181-8.96 106.069 25.003 118.827 78.080 14.336 59.605-18.048 112.896-78.72 129.024l-10.923 2.816c16.213 7.253 30.208 12.416 43.179 19.541q33.835 18.645 66.475 39.467c6.4 4.096 9.856 4.096 15.36-0.597 41.685-36.096 66.56-80.981 73.557-135.979 11.52-91.093-31.573-174.763-112.896-217.643-125.781-66.347-279.765 9.173-307.541 148.651-23.808 119.467 60.501 227.84 162.005 248.747 43.648 9.003 83.541 27.179 114.56 60.8 20.053 21.675 29.739 40.277 33.067 48.683 5.86 14.568 9.259 31.458 9.259 49.142 0 0.094 0 0.187 0 0.281v-0.014c-0.72 15.473-4.371 29.921-10.408 43.044l0.296-0.719c-10.581 24.149-51.2 62.549-61.227 70.656l-95.573 74.837c-3.371 2.773-7.168 2.56-15.36 2.005-9.813-0.683-34.773-2.048-45.525 0.768 8.704 6.613 32.427 16.213 42.667 23.893-30.976 20.907-66.304 13.397-98.773 19.627 7.509 13.995 44.629 35.456 65.749 37.888-1.455 13.545-3.483 25.484-6.166 37.173l0.406-2.101c-1.28 4.736-6.571 9.387-11.221 12.075-11.179 6.571-23.083 11.989-35.968 18.517 10.935 7.156 24.244 11.558 38.555 11.945l0.101 0.002c1.66 0.068 3.608 0.107 5.566 0.107 11.77 0 23.21-1.408 34.163-4.064l-0.987 0.202c23.040-5.248 41.387-1.792 59.691 13.824-14.421 5.803-28.843 11.093-42.795 17.365-16.163 7.396-29.343 14.415-42.082 22.091l1.89-1.056c36.267-5.035 71.296-18.645 108.373-13.653l0.939 5.035-86.101 20.053c51.328 4.693 99.115 5.461 144.384-16.555 12.757-6.229 26.027-11.349 38.272-18.432 5.973-3.413 9.941-10.24 14.848-15.573 3.84-4.181 6.997-9.813 11.776-12.373 18.091-9.6 37.973-9.984 58.283-9.515l0.427 6.827c20.437-6.4 43.392-29.952 43.392-47.147-33.109 0-66.133 0.128-99.2-0.171-3.541 0-7.040-2.603-10.539-4.011 3.328-1.963 6.613-5.461 10.027-5.589zM627.328 868.139c-1.461-0.899-2.42-2.488-2.42-4.302 0-1.516 0.67-2.876 1.731-3.799l0.006-0.005c1.344-2.305 3.804-3.83 6.62-3.83 1.429 0 2.767 0.393 3.91 1.076l-0.035-0.019c3.2 1.621 6.315 3.328 10.155 5.333-3.072 2.645-5.547 4.864-8.107 6.955-4.523 3.712-8.235 1.365-11.861-1.408z" />
|
||||
<glyph unicode="" glyph-name="raspap" horiz-adv-x="1031" d="M540.058 281.983c0-104.182-84.446-188.637-188.625-188.637-104.176 0-188.62 84.455-188.62 188.637 0 104.171 84.444 188.625 188.62 188.625 104.179 0 188.625-84.455 188.625-188.625zM351.437 550.062c-147.818 0-268.074-120.259-268.074-268.080 0-147.826 120.257-268.091 268.074-268.091s268.077 120.265 268.077 268.091c0 147.821-120.259 268.080-268.077 268.080zM351.437-58.985c-188 0-340.95 152.958-340.95 340.967 0 188.003 152.95 340.956 340.95 340.956 188.003 0 340.953-152.953 340.953-340.956 0-188.009-152.95-340.967-340.953-340.967zM404.82 698.222c185.52 0 339.484-137.497 365.479-315.929l79.208-5.253c-24.125 224.046-214.339 399.077-444.686 399.077-10.909 0-21.723-0.412-32.433-1.186l5.16-77.823c9.017 0.661 18.093 1.113 27.272 1.113zM404.989 874.303c285.73 0 520.41-222.659 539.731-503.584l78.375-5.205c-16.843 326.355-287.644 586.685-618.106 586.685-14.884 0-29.644-0.561-44.264-1.6l5.157-77.719c12.919 0.928 25.958 1.424 39.106 1.424z" />
|
||||
</font></defs></svg>
|
After Width: | Height: | Size: 5 KiB |
BIN
dist/raspap/css/fonts/RaspAP.ttf
vendored
Executable file
BIN
dist/raspap/css/fonts/RaspAP.ttf
vendored
Executable file
Binary file not shown.
BIN
dist/raspap/css/fonts/RaspAP.woff
vendored
Executable file
BIN
dist/raspap/css/fonts/RaspAP.woff
vendored
Executable file
Binary file not shown.
54
dist/raspap/css/style.css
vendored
Normal file
54
dist/raspap/css/style.css
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*!
|
||||
* RaspAP-Brands Brand Icons - https://raspap.com
|
||||
* License - https://github.com/billz/RaspAP-Brands-webgui/blob/master/LICENSE
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'RaspAP';
|
||||
src: url('fonts/RaspAP.eot?e76qs3');
|
||||
src: url('fonts/RaspAP.eot?e76qs3#iefix') format('embedded-opentype'),
|
||||
url('fonts/RaspAP.ttf?e76qs3') format('truetype'),
|
||||
url('fonts/RaspAP.woff?e76qs3') format('woff'),
|
||||
url('fonts/RaspAP.svg?e76qs3#RaspAP') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
}
|
||||
|
||||
[class^="ra-"], [class*=" ra-"] {
|
||||
/* use !important to prevent issues with browser extensions that change ..webfonts */
|
||||
font-family: 'RaspAP' !important;
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
|
||||
/* Better Font Rendering =========== */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.ra-wireguard:before {
|
||||
font-size: 1.2rem;
|
||||
content: "\e900";
|
||||
color: #d1d3e2;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.card-header .ra-wireguard:before {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.sidebar .nav-item.active .nav-link
|
||||
span.ra-wireguard:before {
|
||||
color: #6e707e;
|
||||
}
|
||||
|
||||
.ra-raspap:before {
|
||||
font-size: 4.35rem;
|
||||
content: "\e901";
|
||||
color: #d8224c;
|
||||
margin-left: 0.1em;
|
||||
}
|
||||
|
|
@ -78,8 +78,8 @@ function DisplayAdBlockConfig()
|
|||
$adblock_custom_content = file_get_contents(RASPI_ADBLOCK_LISTPATH .'custom.txt');
|
||||
|
||||
$adblock_log = '';
|
||||
exec('sudo chmod o+r /tmp/dnsmasq.log');
|
||||
$handle = fopen("/tmp/dnsmasq.log", "r");
|
||||
exec('sudo chmod o+r '.RASPI_DHCPCD_LOG);
|
||||
$handle = fopen(RASPI_DHCPCD_LOG, "r");
|
||||
if ($handle) {
|
||||
while (($line = fgets($handle)) !== false) {
|
||||
if (preg_match('/(0.0.0.0)/', $line)) {
|
||||
|
|
|
@ -61,7 +61,7 @@ function DisplayWPAConfig()
|
|||
if (strlen($network['passphrase']) >=8 && strlen($network['passphrase']) <= 63) {
|
||||
unset($wpa_passphrase);
|
||||
unset($line);
|
||||
exec('wpa_passphrase '.escapeshellarg($ssid). ' ' . escapeshellarg($network['passphrase']), $wpa_passphrase);
|
||||
exec('wpa_passphrase '. ssid2utf8( escapeshellarg($ssid) ) . ' ' . escapeshellarg($network['passphrase']), $wpa_passphrase);
|
||||
foreach ($wpa_passphrase as $line) {
|
||||
if (preg_match('/^\s*}\s*$/', $line)) {
|
||||
if (array_key_exists('priority', $network)) {
|
||||
|
@ -69,7 +69,11 @@ function DisplayWPAConfig()
|
|||
}
|
||||
fwrite($wpa_file, $line.PHP_EOL);
|
||||
} else {
|
||||
fwrite($wpa_file, $line.PHP_EOL);
|
||||
if ( preg_match('/\\\\x[0-9A-Fa-f]{2}/',$ssid) && strpos($line, "ssid=\"") !== false ) {
|
||||
fwrite($wpa_file, "\tssid=P\"".$ssid."\"".PHP_EOL);
|
||||
} else {
|
||||
fwrite($wpa_file, $line.PHP_EOL);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -6,7 +6,7 @@ if (!defined('RASPI_CONFIG')) {
|
|||
|
||||
$defaults = [
|
||||
'RASPI_BRAND_TEXT' => 'RaspAP',
|
||||
'RASPI_VERSION' => '2.6.7',
|
||||
'RASPI_VERSION' => '2.8.4',
|
||||
'RASPI_CONFIG_NETWORK' => RASPI_CONFIG.'/networking/defaults.json',
|
||||
'RASPI_ADMIN_DETAILS' => RASPI_CONFIG.'/raspap.auth',
|
||||
'RASPI_WIFI_AP_INTERFACE' => 'wlan0',
|
||||
|
@ -20,12 +20,15 @@ $defaults = [
|
|||
'RASPI_ADBLOCK_CONFIG' => RASPI_DNSMASQ_PREFIX.'adblock.conf',
|
||||
'RASPI_HOSTAPD_CONFIG' => '/etc/hostapd/hostapd.conf',
|
||||
'RASPI_DHCPCD_CONFIG' => '/etc/dhcpcd.conf',
|
||||
'RASPI_DHCPCD_LOG' => '/var/log/dnsmasq.log',
|
||||
'RASPI_WPA_SUPPLICANT_CONFIG' => '/etc/wpa_supplicant/wpa_supplicant.conf',
|
||||
'RASPI_HOSTAPD_CTRL_INTERFACE' => '/var/run/hostapd',
|
||||
'RASPI_WPA_CTRL_INTERFACE' => '/var/run/wpa_supplicant',
|
||||
'RASPI_OPENVPN_CLIENT_PATH' => '/etc/openvpn/client/',
|
||||
'RASPI_OPENVPN_CLIENT_CONFIG' => '/etc/openvpn/client/client.conf',
|
||||
'RASPI_OPENVPN_CLIENT_LOGIN' => '/etc/openvpn/client/login.conf',
|
||||
'RASPI_OPENVPN_SERVER_CONFIG' => '/etc/openvpn/server/server.conf',
|
||||
'RASPI_WIREGUARD_PATH' => '/etc/wireguard/',
|
||||
'RASPI_WIREGUARD_CONFIG' => RASPI_WIREGUARD_PATH.'wg0.conf',
|
||||
'RASPI_TORPROXY_CONFIG' => '/etc/tor/torrc',
|
||||
'RASPI_LIGHTTPD_CONFIG' => '/etc/lighttpd/lighttpd.conf',
|
||||
'RASPI_ACCESS_CHECK_IP' => '1.1.1.1',
|
||||
|
@ -42,6 +45,7 @@ $defaults = [
|
|||
'RASPI_DHCP_ENABLED' => true,
|
||||
'RASPI_ADBLOCK_ENABLED' => false,
|
||||
'RASPI_OPENVPN_ENABLED' => false,
|
||||
'RASPI_WIREGUARD_ENABLED' => false,
|
||||
'RASPI_TORPROXY_ENABLED' => false,
|
||||
'RASPI_CONFAUTH_ENABLED' => true,
|
||||
'RASPI_CHANGETHEME_ENABLED' => true,
|
||||
|
|
|
@ -226,7 +226,7 @@ function updateDnsmasqConfig($iface,$status)
|
|||
|
||||
// write default 090_raspap.conf
|
||||
$config = '# RaspAP default config'.PHP_EOL;
|
||||
$config .='log-facility=/tmp/dnsmasq.log'.PHP_EOL;
|
||||
$config .='log-facility='.RASPI_DHCPCD_LOG.PHP_EOL;
|
||||
$config .='conf-dir=/etc/dnsmasq.d'.PHP_EOL;
|
||||
// handle log option
|
||||
if ($_POST['log-dhcp'] == "1") {
|
||||
|
|
368
includes/firewall.php
Normal file
368
includes/firewall.php
Normal file
|
@ -0,0 +1,368 @@
|
|||
<?php
|
||||
|
||||
require_once 'includes/status_messages.php';
|
||||
require_once 'includes/functions.php';
|
||||
|
||||
define('RASPAP_IPTABLES_SCRIPT', "/tmp/iptables_raspap.sh");
|
||||
define('RASPAP_IP6TABLES_SCRIPT', "/tmp/ip6tables_raspap.sh");
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $rule
|
||||
* @param array $conf
|
||||
* @return array $don
|
||||
*/
|
||||
function getDependson(&$rule, &$conf)
|
||||
{
|
||||
if (isset($rule["dependson"][0]) ) {
|
||||
$don = &$rule["dependson"];
|
||||
if (!empty($don[0]) && isset($conf[$don[0]["var"]]) ) {
|
||||
if (!isset($don[0]["type"]) ) { $don[0]["type"]="bool";
|
||||
}
|
||||
return $don;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $sect
|
||||
* @param array $conf
|
||||
* @return boolean $active
|
||||
*/
|
||||
function isRuleEnabled(&$sect, &$conf)
|
||||
{
|
||||
$fw_on = isset($conf["firewall-enable"]) && $conf["firewall-enable"];
|
||||
$active = isset($sect["fw-state"]) && $sect["fw-state"]==1;
|
||||
$active = $fw_on ? $active : !$active;
|
||||
$active = $active || !isset($sect["fw-state"]);
|
||||
if (($don = getDependson($sect, $conf)) !== false
|
||||
&& $don[0]["type"] == "bool" && !$conf[$don[0]["var"]]
|
||||
) { $active = false;
|
||||
}
|
||||
return $active;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $sect
|
||||
* @param array $conf
|
||||
* @return string $str
|
||||
*/
|
||||
function createRuleStr(&$sect, &$conf)
|
||||
{
|
||||
if (!is_array($sect["rules"]) ) { return "";
|
||||
}
|
||||
$rules = $sect["rules"];
|
||||
$depon = getDependson($sect, $conf);
|
||||
$rs = array();
|
||||
foreach ( $rules as $rule ) {
|
||||
if (preg_match('/\$[a-z0-9]*\$/i', $rule) ) {
|
||||
$r = array($rule);
|
||||
foreach ( $depon as $dep ) {
|
||||
$rr = array();
|
||||
$repl=$val="";
|
||||
switch ( $dep["type"] ) {
|
||||
case "list":
|
||||
if (isset($dep["var"]) && !empty($conf[$dep["var"]]) ) { $val = explode(' ', $conf[$dep["var"]]);
|
||||
}
|
||||
if (!empty($val) && isset($dep["replace"]) ) { $repl=$dep["replace"];
|
||||
}
|
||||
break;
|
||||
case "string":
|
||||
if (isset($dep["var"]) ) { $val=$conf[$dep["var"]];
|
||||
}
|
||||
if (!empty($val) && isset($dep["replace"]) ) { $repl=$dep["replace"];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!empty($repl) && !empty($val) ) {
|
||||
if (is_array($val) ) {
|
||||
foreach ( $val as $v ) { $rr = array_merge($rr, str_replace($repl, $v, $r));
|
||||
}
|
||||
}
|
||||
else { $rr = array_merge($rr, str_replace($repl, $val, $r));
|
||||
}
|
||||
}
|
||||
$r = !empty($rr) ? $rr : $r;
|
||||
}
|
||||
$rs = array_merge($rs, $rr);
|
||||
} else {
|
||||
$rs[] = $rule;
|
||||
}
|
||||
}
|
||||
$str="";
|
||||
foreach ( $rs as $r ) {
|
||||
if (!preg_match('/\$[a-z0-9]*\$/i', $r) ) { $str .= '$IPT '.$r."\n";
|
||||
}
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $rule
|
||||
* @return boolean
|
||||
*/
|
||||
function isIPv4(&$rule)
|
||||
{
|
||||
return !isset($rule["ip-version"]) || strstr($rule["ip-version"], "4") !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $rule
|
||||
* @return boolean
|
||||
*/
|
||||
function isIPv6(&$rule)
|
||||
{
|
||||
return !isset($rule["ip-version"]) || strstr($rule["ip-version"], "6") !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function configureFirewall()
|
||||
{
|
||||
$json = file_get_contents(RASPI_IPTABLES_CONF);
|
||||
$ipt = json_decode($json, true);
|
||||
$conf = ReadFirewallConf();
|
||||
$txt = "#!/bin/bash\n";
|
||||
file_put_contents(RASPAP_IPTABLES_SCRIPT, $txt);
|
||||
file_put_contents(RASPAP_IP6TABLES_SCRIPT, $txt);
|
||||
file_put_contents(RASPAP_IPTABLES_SCRIPT, 'IPT="iptables"'."\n", FILE_APPEND);
|
||||
file_put_contents(RASPAP_IP6TABLES_SCRIPT, 'IPT="ip6tables"'."\n", FILE_APPEND);
|
||||
$txt = "\$IPT -F\n";
|
||||
$txt .= "\$IPT -X\n";
|
||||
$txt .= "\$IPT -t nat -F\n";
|
||||
file_put_contents(RASPAP_IPTABLES_SCRIPT, $txt, FILE_APPEND);
|
||||
file_put_contents(RASPAP_IP6TABLES_SCRIPT, $txt, FILE_APPEND);
|
||||
if (empty($conf) || empty($ipt) ) { return false;
|
||||
}
|
||||
$count=0;
|
||||
foreach ( $ipt["order"] as $idx ) {
|
||||
if (isset($ipt[$idx]) ) {
|
||||
foreach ( $ipt[$idx] as $i => $sect ) {
|
||||
if (isRuleEnabled($sect, $conf) ) {
|
||||
$str_rules= createRuleStr($sect, $conf);
|
||||
if (!empty($str_rules) ) {
|
||||
if (isIPv4($sect) ) { file_put_contents(RASPAP_IPTABLES_SCRIPT, $str_rules, FILE_APPEND);
|
||||
}
|
||||
if (isIPv6($sect) ) { file_put_contents(RASPAP_IP6TABLES_SCRIPT, $str_rules, FILE_APPEND);
|
||||
}
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($count > 0 ) {
|
||||
exec("chmod +x ".RASPAP_IPTABLES_SCRIPT);
|
||||
exec("sudo ".RASPAP_IPTABLES_SCRIPT);
|
||||
exec("sudo iptables-save | sudo tee /etc/iptables/rules.v4");
|
||||
unlink(RASPAP_IPTABLES_SCRIPT);
|
||||
exec("chmod +x ".RASPAP_IP6TABLES_SCRIPT);
|
||||
exec("sudo ".RASPAP_IP6TABLES_SCRIPT);
|
||||
exec("sudo ip6tables-save | sudo tee /etc/iptables/rules.v6");
|
||||
unlink(RASPAP_IP6TABLES_SCRIPT);
|
||||
}
|
||||
return ($count > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $conf
|
||||
* @return string $ret
|
||||
*/
|
||||
function WriteFirewallConf($conf)
|
||||
{
|
||||
$ret = false;
|
||||
if (is_array($conf) ) { write_php_ini($conf, RASPI_FIREWALL_CONF);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array $conf
|
||||
*/
|
||||
function ReadFirewallConf()
|
||||
{
|
||||
$conf = array();
|
||||
if (file_exists(RASPI_FIREWALL_CONF) ) {
|
||||
$conf = parse_ini_file(RASPI_FIREWALL_CONF);
|
||||
}
|
||||
if ( !isset($conf["firewall-enable"]) ) {
|
||||
$conf["firewall-enable"] = false;
|
||||
$conf["ssh-enable"] = false;
|
||||
$conf["http-enable"] = false;
|
||||
$conf["excl-devices"] = "";
|
||||
$conf["excluded-ips"] = "";
|
||||
$conf["ap-device"] = "";
|
||||
$conf["client-device"] = "";
|
||||
$conf["restricted-ips"] = "";
|
||||
}
|
||||
exec('ifconfig | grep -E -i "^tun[0-9]"', $ret);
|
||||
$conf["openvpn-enable"] = !empty($ret);
|
||||
unset($ret);
|
||||
exec('ifconfig | grep -E -i "^wg[0-9]"', $ret);
|
||||
$conf["wireguard-enable"] = !empty($ret);
|
||||
return $conf;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string $ips
|
||||
*/
|
||||
function getVPN_IPs()
|
||||
{
|
||||
$ips = "";
|
||||
// get openvpn and wireguard server IPs
|
||||
if (RASPI_OPENVPN_ENABLED && ($fconf = glob(RASPI_OPENVPN_CLIENT_PATH ."/*.conf")) !== false && !empty($fconf) ) {
|
||||
foreach ( $fconf as $f ) {
|
||||
unset($result);
|
||||
exec('cat '.$f.' | sed -rn "s/^remote\s*([a-z0-9\.\-\_:]*)\s*([0-9]*)\s*$/\1 \2/ip" ', $result);
|
||||
if (!empty($result) ) {
|
||||
$result = explode(" ", $result[0]);
|
||||
$ip = (isset($result[0])) ? $result[0] : "";
|
||||
$port = (isset($result[1])) ? $result[1] : "";
|
||||
if (!empty($ip) ) {
|
||||
$ip = gethostbyname($ip);
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP) && strpos($ips, $ip) === false ) { $ips .= " $ip";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// get wireguard server IPs
|
||||
if (RASPI_WIREGUARD_ENABLED && ($fconf = glob(RASPI_WIREGUARD_PATH ."/*.conf")) !== false && !empty($fconf) ) {
|
||||
foreach ( $fconf as $f ) {
|
||||
unset($result);
|
||||
exec('sudo /bin/cat '.$f.' | sed -rn "s/^endpoint\s*=\s*\[?([a-z0-9\.\-\_:]*)\]?:([0-9]*)\s*$/\1 \2/ip" ', $result);
|
||||
if (!empty($result) ) {
|
||||
$result = explode(" ", $result[0]);
|
||||
$ip = (isset($result[0])) ? $result[0] : "";
|
||||
$port = (isset($result[1])) ? $result[1] : "";
|
||||
if (!empty($ip) ) {
|
||||
$ip = gethostbyname($ip);
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP) && strpos($ips, $ip) === false ) { $ips .= " $ip";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return trim($ips);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array $fw_conf
|
||||
*/
|
||||
function getFirewallConfiguration()
|
||||
{
|
||||
$fw_conf = ReadFirewallConf();
|
||||
|
||||
$json = file_get_contents(RASPI_IPTABLES_CONF);
|
||||
getWifiInterface();
|
||||
$ap_device = $_SESSION['ap_interface'];
|
||||
$clients = getClients();
|
||||
$str_clients = "";
|
||||
foreach( $clients["device"] as $dev ) {
|
||||
if (!$dev["isAP"] ) {
|
||||
if (!empty($str_clients) ) { $str_clients .= ", ";
|
||||
}
|
||||
$str_clients .= $dev["name"];
|
||||
}
|
||||
}
|
||||
$fw_conf["ap-device"] = $ap_device;
|
||||
$fw_conf["client-list"] = $str_clients;
|
||||
$id=findCurrentClientIndex($clients);
|
||||
if ($id >= 0 ) { $fw_conf["client-device"] = $clients["device"][$id]["name"];
|
||||
}
|
||||
return $fw_conf;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function updateFirewall()
|
||||
{
|
||||
$fw_conf = getFirewallConfiguration();
|
||||
if ( isset($fw_conf["firewall-enable"]) ) {
|
||||
WriteFirewallConf($fw_conf);
|
||||
configureFirewall();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function DisplayFirewallConfig()
|
||||
{
|
||||
$status = new StatusMessages();
|
||||
|
||||
$fw_conf = getFirewallConfiguration();
|
||||
$ap_device = $fw_conf["ap-device"];
|
||||
$str_clients = $fw_conf["client-list"];
|
||||
|
||||
if (!empty($_POST)) {
|
||||
$fw_conf["ssh-enable"] = isset($_POST['ssh-enable']);
|
||||
$fw_conf["http-enable"] = isset($_POST['http-enable']);
|
||||
$fw_conf["firewall-enable"] = isset($_POST['firewall-enable']) || isset($_POST['apply-firewall']);
|
||||
if (isset($_POST['firewall-enable']) ) { $status->addMessage(_('Firewall is now enabled'), 'success');
|
||||
}
|
||||
if (isset($_POST['apply-firewall']) ) { $status->addMessage(_('Firewall settings changed'), 'success');
|
||||
}
|
||||
if (isset($_POST['firewall-disable']) ) { $status->addMessage(_('Firewall is now disabled'), 'warning');
|
||||
}
|
||||
if (isset($_POST['save-firewall']) ) { $status->addMessage(_('Firewall settings saved. Firewall is still disabled.'), 'success');
|
||||
}
|
||||
if (isset($_POST['excl-devices']) ) {
|
||||
$excl = filter_var($_POST['excl-devices'], FILTER_SANITIZE_STRING);
|
||||
$excl = str_replace(',', ' ', $excl);
|
||||
$excl = trim(preg_replace('/\s+/', ' ', $excl));
|
||||
if ($fw_conf["excl-devices"] != $excl ) {
|
||||
$status->addMessage(_('Exclude devices '. $excl), 'success');
|
||||
$fw_conf["excl-devices"] = $excl;
|
||||
}
|
||||
}
|
||||
if (isset($_POST['excluded-ips']) ) {
|
||||
$excl = filter_var($_POST['excluded-ips'], FILTER_SANITIZE_STRING);
|
||||
$excl = str_replace(',', ' ', $excl);
|
||||
$excl = trim(preg_replace('/\s+/', ' ', $excl));
|
||||
if (!empty($excl) ) {
|
||||
$excl = explode(' ', $excl);
|
||||
$str_excl = "";
|
||||
foreach ( $excl as $ip ) {
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP) ) { $str_excl .= "$ip ";
|
||||
} else { $status->addMessage(_('Exclude IP address '. $ip . ' failed - not a valid IP address'), 'warning');
|
||||
}
|
||||
}
|
||||
}
|
||||
$str_excl = trim($str_excl);
|
||||
if ($fw_conf["excluded-ips"] != $str_excl ) {
|
||||
$status->addMessage(_('Exclude IP address(es) '. $str_excl), 'success');
|
||||
$fw_conf["excluded-ips"] = $str_excl;
|
||||
}
|
||||
}
|
||||
WriteFirewallConf($fw_conf);
|
||||
configureFirewall();
|
||||
}
|
||||
$vpn_ips = getVPN_IPs();
|
||||
echo renderTemplate(
|
||||
"firewall", compact(
|
||||
"status",
|
||||
"ap_device",
|
||||
"str_clients",
|
||||
"fw_conf",
|
||||
"vpn_ips"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -152,15 +152,16 @@ function getDefaultNetValue($svc,$iface,$key)
|
|||
* Returns default options for the specified service
|
||||
*
|
||||
* @param string $svc
|
||||
* @param string $key
|
||||
* @return object $json
|
||||
*/
|
||||
function getDefaultNetOpts($svc)
|
||||
function getDefaultNetOpts($svc,$key)
|
||||
{
|
||||
$json = json_decode(file_get_contents(RASPI_CONFIG_NETWORK), true);
|
||||
if ($json === null) {
|
||||
return false;
|
||||
} else {
|
||||
return $json[$svc]['options'];
|
||||
return $json[$svc][$key];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,6 +225,62 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
@ -615,7 +672,7 @@ function getThemeOpt()
|
|||
function getColorOpt()
|
||||
{
|
||||
if (!isset($_COOKIE['color'])) {
|
||||
$color = "#d8224c";
|
||||
$color = "#2b8080";
|
||||
} else {
|
||||
$color = $_COOKIE['color'];
|
||||
}
|
||||
|
@ -636,11 +693,70 @@ function getBridgedState()
|
|||
return $arrHostapdConf['BridgedEnable'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the format of a CIDR notation string
|
||||
*
|
||||
* @param string $cidr
|
||||
* @return bool
|
||||
*/
|
||||
function validateCidr($cidr)
|
||||
{
|
||||
$parts = explode('/', $cidr);
|
||||
if(count($parts) != 2) {
|
||||
return false;
|
||||
}
|
||||
$ip = $parts[0];
|
||||
$netmask = intval($parts[1]);
|
||||
|
||||
if($netmask < 0) {
|
||||
return false;
|
||||
}
|
||||
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
return $netmask <= 32;
|
||||
}
|
||||
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
return $netmask <= 128;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
if ($_COOKIE['theme'] == 'lightsout.css') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// search array for matching string and return only first matching group
|
||||
function preg_only_match($pat,$haystack)
|
||||
{
|
||||
$match = "";
|
||||
if(!empty($haystack) && !empty($pat)) {
|
||||
if(!is_array($haystack)) $haystack = array($haystack);
|
||||
$str = preg_grep($pat,$haystack);
|
||||
if (!empty($str) && preg_match($pat,array_shift($str),$match) === 1 ) $match = $match[1];
|
||||
}
|
||||
return $match;
|
||||
}
|
||||
|
||||
// Sanitizes a string for QR encoding
|
||||
// @param string $str
|
||||
// @return string
|
||||
function qr_encode($str)
|
||||
{
|
||||
return preg_replace('/(?<!\\\)([\":;,])/', '\\\\\1', $str);
|
||||
}
|
||||
|
||||
function evalHexSequence($string) {
|
||||
$evaluator = function ($input) {
|
||||
return hex2bin($input[1]);
|
||||
|
@ -648,3 +764,30 @@ function evalHexSequence($string) {
|
|||
return preg_replace_callback('/\\\x(..)/', $evaluator, $string);
|
||||
}
|
||||
|
||||
function hexSequence2lower($string) {
|
||||
return preg_replace_callback('/\\\\x([0-9A-F]{2})/', function($b){ return '\x'.strtolower($b[1]); }, $string);
|
||||
}
|
||||
|
||||
/* File upload callback object
|
||||
*
|
||||
*/
|
||||
class validation
|
||||
{
|
||||
public function check_name_length($object)
|
||||
{
|
||||
if (strlen($object->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];
|
||||
}
|
||||
|
||||
|
|
307
includes/get_clients.php
Normal file
307
includes/get_clients.php
Normal file
|
@ -0,0 +1,307 @@
|
|||
<?php
|
||||
|
||||
require_once 'includes/functions.php';
|
||||
require_once 'includes/wifi_functions.php';
|
||||
|
||||
function getClients($simple=true)
|
||||
{
|
||||
exec('ifconfig -a | grep -oP "^(?!lo)(\w*)"', $rawdevs); // all devices except loopback
|
||||
$path=RASPI_CLIENT_SCRIPT_PATH;
|
||||
$cl=array();
|
||||
if (!empty($rawdevs) && is_array($rawdevs)) {
|
||||
$cl["clients"]=count($rawdevs);
|
||||
// search for possibly not connected modem
|
||||
exec("find /sys/bus/usb/devices/usb*/ -name dev ", $devtty); // search for ttyUSB
|
||||
$devtty = preg_only_match("/(ttyUSB0)/", $devtty);
|
||||
if (empty(preg_only_match("/(ppp)[0-9]/", $rawdevs))) {
|
||||
if (!empty($devtty)) {
|
||||
$rawdevs[]="ppp0";
|
||||
exec("udevadm info --name='$devtty' 2> /dev/null");
|
||||
}
|
||||
}
|
||||
foreach ($rawdevs as $i => $dev) {
|
||||
$cl["device"][$i]["name"]=$dev;
|
||||
$nam = (preg_match("/^(\w+)[0-9]$/",$dev,$nam) === 1) ? $nam=$nam[1] : "";
|
||||
$cl["device"][$i]["type"]=$ty=getClientType($dev);
|
||||
unset($udevinfo);
|
||||
exec("udevadm info /sys/class/net/$dev 2> /dev/null", $udevinfo);
|
||||
if ($nam == "ppp" && isset($devtty)) {
|
||||
exec("udevadm info --name='$devtty' 2> /dev/null", $udevinfo);
|
||||
}
|
||||
if (!empty($udevinfo) && is_array($udevinfo)) {
|
||||
$model = preg_only_match("/ID_MODEL_ENC=(.*)$/", $udevinfo);
|
||||
if (empty($model) || preg_match("/^[0-9a-f]{4}$/", $model) === 1) {
|
||||
$model = preg_only_match("/ID_MODEL_FROM_DATABASE=(.*)$/", $udevinfo);
|
||||
}
|
||||
if (empty($model)) {
|
||||
$model = preg_only_match("/ID_OUI_FROM_DATABASE=(.*)$/", $udevinfo);
|
||||
}
|
||||
$vendor = preg_only_match("/ID_VENDOR_ENC=(.*)$/", $udevinfo);
|
||||
if (empty($vendor) || preg_match("/^[0-9a-f]{4}$/", $vendor) === 1) {
|
||||
$vendor = preg_only_match("/ID_VENDOR_FROM_DATABASE=(.*)$/", $udevinfo);
|
||||
}
|
||||
$driver = preg_only_match("/ID_NET_DRIVER=(.*)$/", $udevinfo);
|
||||
$vendorid = preg_only_match("/ID_VENDOR_ID=(.*)$/", $udevinfo);
|
||||
$productid = preg_only_match("/ID_MODEL_ID=(.*)$/", $udevinfo);
|
||||
}
|
||||
$cl["device"][$i]["model"] = preg_replace("/\\\\x20/", " ", $model);
|
||||
$cl["device"][$i]["vendor"] = preg_replace("/\\\\x20/", " ", $vendor);
|
||||
$cl["device"][$i]["vid"] = $vendorid;
|
||||
$cl["device"][$i]["pid"] = $productid;
|
||||
unset($mac);
|
||||
exec("cat /sys/class/net/$dev/address 2> /dev/null", $mac);
|
||||
$cl["device"][$i]["mac"] = empty($mac) ? "":$mac[0];
|
||||
unset($ip);
|
||||
exec("ifconfig $dev 2> /dev/null", $ip);
|
||||
$cl["device"][$i]["ipaddress"] = preg_only_match("/.*inet ([0-9\.]+) .*/", $ip);
|
||||
|
||||
switch($ty) {
|
||||
case "eth":
|
||||
unset($res);
|
||||
exec("ip link show $dev 2> /dev/null | grep -oP ' UP '", $res);
|
||||
if (empty($res) && empty($ipadd)) {
|
||||
$cl["device"][$i]["connected"] = "n";
|
||||
} else {
|
||||
$cl["device"][$i]["connected"] = "y";
|
||||
}
|
||||
break;
|
||||
case "wlan":
|
||||
unset($retiw);
|
||||
exec("iwconfig $dev 2> /dev/null | sed -rn 's/.*(mode:master).*/1/ip'", $retiw);
|
||||
$cl["device"][$i]["isAP"] = !empty($retiw);
|
||||
unset($retiw);
|
||||
exec("iw dev $dev link 2> /dev/null", $retiw);
|
||||
if (!$simple && !empty($ssid=preg_only_match("/.*SSID:\s*([^\"]*).*/", $retiw)) ) {
|
||||
$cl["device"][$i]["connected"] = "y";
|
||||
$cl["device"][$i]["ssid"] = $ssid;
|
||||
$cl["device"][$i]["ssidutf8"] = ssid2utf8($ssid);
|
||||
$cl["device"][$i]["ap-mac"] = preg_only_match("/^Connected to ([0-9a-f\:]*).*$/", $retiw);
|
||||
$sig = preg_only_match("/.*signal: (.*)$/", $retiw);
|
||||
$val = preg_only_match("/^([0-9\.-]*).*$/", $sig);
|
||||
if (!is_numeric($val)) {
|
||||
$val = -100;
|
||||
}
|
||||
if ($val >= -50 ) {
|
||||
$qual=100;
|
||||
} else if ($val < -100) {
|
||||
$qual=0;
|
||||
} else {
|
||||
$qual=round($val*2+200);
|
||||
}
|
||||
$cl["device"][$i]["signal"] = "$sig (".$qual."%)";
|
||||
$cl["device"][$i]["bitrate"] = preg_only_match("/.*bitrate: ([0-9\.]* \w*\/s).*$/", $retiw);
|
||||
$cl["device"][$i]["freq"] = preg_only_match("/.*freq: (.*)$/", $retiw);
|
||||
$cl["device"][$i]["ap-mac"] = preg_only_match("/^Connected to ([0-9a-f\:]*).*$/", $retiw);
|
||||
} else {
|
||||
$cl["device"][$i]["connected"] = "n";
|
||||
}
|
||||
break;
|
||||
case "ppp":
|
||||
unset($res);
|
||||
exec("ip link show $dev 2> /dev/null | grep -oP '( UP | UNKNOWN)'", $res);
|
||||
if ($simple) {
|
||||
if (empty($res)) {
|
||||
$cl["device"][$i]["connected"] = "n";
|
||||
$cl["device"][$i]["signal"] = "-100 dB (0%)";
|
||||
} else {
|
||||
$cl["device"][$i]["connected"] = "y";
|
||||
$cl["device"][$i]["signal"] = "-0 dB (0%)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (empty($res) && empty($ipadd)) {
|
||||
$cl["device"][$i]["connected"] = "n";
|
||||
} else {
|
||||
$cl["device"][$i]["connected"] = "y";
|
||||
}
|
||||
unset($res);
|
||||
exec("$path/info_huawei.sh mode modem", $res);
|
||||
$cl["device"][$i]["mode"] = $res[0];
|
||||
unset($res);
|
||||
exec("$path/info_huawei.sh device modem", $res);
|
||||
if ($res[0] != "none" ) {
|
||||
$cl["device"][$i]["model"] = $res[0];
|
||||
}
|
||||
unset($res);
|
||||
exec("$path/info_huawei.sh signal modem", $res);
|
||||
$cl["device"][$i]["signal"] = $res[0];
|
||||
unset($res);
|
||||
exec("$path/info_huawei.sh operator modem", $res);
|
||||
$cl["device"][$i]["operator"] = $res[0];
|
||||
break;
|
||||
case "hilink":
|
||||
$pin=$user=$pw="";
|
||||
getMobileLogin($pin,$pw,$user);
|
||||
$opts=$pin.' '.$user.' '.$pw;
|
||||
unset($res);
|
||||
// exec("ip link show $dev 2> /dev/null | grep -oP ' UP '",$res);
|
||||
exec("ifconfig -a | grep -i $dev -A 1 | grep -oP '(?<=inet )([0-9]{1,3}\.){3}'", $apiadd);
|
||||
$apiadd = !empty($apiadd) ? $apiadd[0]."1" : "";
|
||||
unset($res);
|
||||
exec("$path/info_huawei.sh mode hilink $apiadd \"$opts\" ", $res);
|
||||
$cl["device"][$i]["mode"] = $res[0];
|
||||
unset($res);
|
||||
exec("$path/info_huawei.sh device hilink $apiadd \"$opts\" ", $res);
|
||||
if ($res[0] != "none" ) {
|
||||
$cl["device"][$i]["model"] = $res[0];
|
||||
}
|
||||
unset($res);
|
||||
exec("$path/info_huawei.sh signal hilink $apiadd \"$opts\" ", $res);
|
||||
$cl["device"][$i]["signal"] = $res[0];
|
||||
unset($ipadd);
|
||||
exec("$path/info_huawei.sh ipaddress hilink $apiadd \"$opts\" ", $ipadd);
|
||||
if (!empty($ipadd) && $ipadd[0] !== "none" ) {
|
||||
$cl["device"][$i]["connected"] = "y";
|
||||
$cl["device"][$i]["wan_ip"] = $ipadd[0];
|
||||
} else {
|
||||
$cl["device"][$i]["connected"] = "n";
|
||||
$cl["device"][$i]["wan_ip"] = "-";
|
||||
}
|
||||
unset($res);
|
||||
exec("$path/info_huawei.sh operator hilink $apiadd \"$opts\" ", $res);
|
||||
$cl["device"][$i]["operator"] = $res[0];
|
||||
break;
|
||||
case "phone":
|
||||
case "usb":
|
||||
$cl["device"][$i]["connected"] = "y";
|
||||
break;
|
||||
default:
|
||||
}
|
||||
if (!isset($cl["device"][$i]["signal"])) {
|
||||
$cl["device"][$i]["signal"]= $cl["device"][$i]["connected"] == "n" ? "-100 dB (0%)": "0 dB (100%)";;
|
||||
}
|
||||
if (!isset($cl["device"][$i]["isAP"])) {
|
||||
$cl["device"][$i]["isAP"]=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $cl;
|
||||
}
|
||||
|
||||
function getClientType($dev) {
|
||||
loadClientConfig();
|
||||
// check if device type stored in DEVTYPE or raspapType (from UDEV rule) protperty of the device
|
||||
exec("udevadm info /sys/class/net/$dev 2> /dev/null", $udevadm);
|
||||
$type="none";
|
||||
if (!empty($udevadm)) {
|
||||
$type=preg_only_match("/raspapType=(\w*)/i",$udevadm);
|
||||
if (empty($type)) {
|
||||
$type=preg_only_match("/DEVTYPE=(\w*)/i",$udevadm);
|
||||
}
|
||||
}
|
||||
if (empty($type) || $type == "none" || array_search($type, $_SESSION["net-device-name-prefix"]) === false) {
|
||||
// no device type yet -> get device type from device name
|
||||
if (preg_match("/^(\w+)[0-9]$/",$dev,$nam) === 1) $nam=$nam[1];
|
||||
else $nam="none";
|
||||
if (($n = array_search($nam, $_SESSION["net-device-name-prefix"])) === false) $n = count($_SESSION["net-device-types"])-1;
|
||||
$type = $_SESSION["net-device-types"][$n];
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
|
||||
function getMobileLogin(&$pin,&$pw,&$user) {
|
||||
if (file_exists(($f = RASPI_MOBILEDATA_CONFIG))) {
|
||||
$dat = parse_ini_file($f);
|
||||
$pin = (isset($dat["pin"]) && preg_match("/^[0-9]*$/", $dat["pin"])) ? "-p ".$dat["pin"] : "";
|
||||
$user = (isset($dat["router_user"]) && !empty($dat["router_user"]) ) ? "-u ".$dat["router_user"] : "";
|
||||
$pw = (isset($dat["router_pw"]) && !empty($dat["router_pw"]) ) ? "-P ".$dat["router_pw"] : "";
|
||||
}
|
||||
}
|
||||
|
||||
function loadClientConfig()
|
||||
{
|
||||
// load network device config file for UDEV rules into $_SESSION
|
||||
if (!isset($_SESSION["udevrules"])) {
|
||||
$_SESSION["net-device-types"]=array();
|
||||
$_SESSION["net-device-name-prefix"]=array();
|
||||
try {
|
||||
$udevrules = file_get_contents(RASPI_CLIENT_CONFIG_PATH);
|
||||
$_SESSION["udevrules"] = json_decode($udevrules, true);
|
||||
// get device types
|
||||
foreach ($_SESSION["udevrules"]["network_devices"] as $dev) {
|
||||
$_SESSION["net-device-name-prefix"][]=$dev["name_prefix"];
|
||||
$_SESSION["net-device-types"][]=$dev["type"];
|
||||
$_SESSION["net-device-types-info"][]=$dev["type_info"];
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$_SESSION["udevrules"]= null;
|
||||
}
|
||||
$_SESSION["net-device-types"][]="none";
|
||||
$_SESSION["net-device-types-info"][]="unknown";
|
||||
$_SESSION["net-device-name-prefix"][]="none";
|
||||
}
|
||||
}
|
||||
|
||||
function findCurrentClientIndex($clients)
|
||||
{
|
||||
$devid = -1;
|
||||
if (!empty($clients)) {
|
||||
$ncl=$clients["clients"];
|
||||
if ($ncl > 0) {
|
||||
$ty=-1;
|
||||
foreach ($clients["device"] as $i => $dev) {
|
||||
$id=array_search($dev["type"], $_SESSION["net-device-types"]);
|
||||
if ($id >=0 && $_SESSION["udevrules"]["network_devices"][$id]["clientid"] > $ty && !$dev["isAP"]) {
|
||||
$ty=$id;
|
||||
$devid=$i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $devid;
|
||||
}
|
||||
|
||||
function waitClientConnected($dev, $timeout=10)
|
||||
{
|
||||
do {
|
||||
exec('ifconfig -a | grep -i '.$dev.' -A 1 | grep -oP "(?<=inet )([0-9]{1,3}\.){3}[0-9]{1,3}"', $res);
|
||||
$connected= !empty($res);
|
||||
if (!$connected) {
|
||||
sleep(1);
|
||||
}
|
||||
} while (!$connected && --$timeout > 0);
|
||||
return $connected;
|
||||
}
|
||||
|
||||
function setClientState($state)
|
||||
{
|
||||
$clients=getClients();
|
||||
if (($idx = findCurrentClientIndex($clients)) >= 0) {
|
||||
$dev = $clients["device"][$idx];
|
||||
exec('ifconfig -a | grep -i '.$dev["name"].' -A 1 | grep -oP "(?<=inet )([0-9]{1,3}\.){3}[0-9]{1,3}"', $res);
|
||||
if (!empty($res)) {
|
||||
$connected=$res[0];
|
||||
}
|
||||
switch($dev["type"]) {
|
||||
case "wlan":
|
||||
if ($state =="up") {
|
||||
exec('sudo ip link set '.$dev["name"].' up');
|
||||
}
|
||||
if (!empty($connected) && $state =="down") {
|
||||
exec('sudo ip link set '.$dev["name"].' down');
|
||||
}
|
||||
break;
|
||||
case "hilink":
|
||||
preg_match("/^([0-9]{1,3}\.){3}/", $connected, $ipadd);
|
||||
$ipadd = $ipadd[0].'1'; // ip address of the Hilink api
|
||||
$mode = ($state == "up") ? 1 : 0;
|
||||
$pin=$user=$pw="";
|
||||
getMobileLogin($pin,$pw,$user);
|
||||
exec('sudo '.RASPI_CLIENT_SCRIPT_PATH.'/onoff_huawei_hilink.sh -c '.$mode.' -h '.$ipadd.' '.$pin.' '.$user.' '.$pw);
|
||||
break;
|
||||
case "ppp":
|
||||
if ($state == "up") {
|
||||
exec('sudo ifup '.$dev["name"]);
|
||||
}
|
||||
if (!empty($connected) && $state == "down") {
|
||||
exec('sudo ifdown '.$dev["name"]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ($state=="up") {
|
||||
waitClientConnected($dev["name"], 15);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,12 +25,17 @@ function DisplayHostAPDConfig()
|
|||
];
|
||||
$arrSecurity = array(1 => 'WPA', 2 => 'WPA2', 3 => 'WPA+WPA2', 'none' => _("None"));
|
||||
$arrEncType = array('TKIP' => 'TKIP', 'CCMP' => 'CCMP', 'TKIP CCMP' => 'TKIP+CCMP');
|
||||
$arrTxPower = getDefaultNetOpts('txpower','dbm');
|
||||
$managedModeEnabled = false;
|
||||
exec("ip -o link show | awk -F': ' '{print $2}'", $interfaces);
|
||||
sort($interfaces);
|
||||
|
||||
exec("iw reg get | awk '/country / { sub(/:/,\"\",$2); print $2 }'", $country_code);
|
||||
|
||||
$cmd = "iw dev ".$_SESSION['ap_interface']." info | awk '$1==\"txpower\" {print $2}'";
|
||||
exec($cmd, $txpower);
|
||||
$txpower = intval($txpower[0]);
|
||||
|
||||
if (!RASPI_MONITOR_ENABLED) {
|
||||
if (isset($_POST['SaveHostAPDSettings'])) {
|
||||
SaveHostAPDConfig($arrSecurity, $arrEncType, $arr80211Standard, $interfaces, $status);
|
||||
|
@ -85,9 +90,20 @@ function DisplayHostAPDConfig()
|
|||
$arrConfig['disassoc_low_ack_bool'] = 1;
|
||||
}
|
||||
// assign country_code from iw reg if not set in config
|
||||
if (!isset($arrConfig['country_code']) && isset($country_code[0])) {
|
||||
if (empty($arrConfig['country_code']) && isset($country_code[0])) {
|
||||
$arrConfig['country_code'] = $country_code[0];
|
||||
}
|
||||
// set txpower with iw if value is non-default ('auto')
|
||||
if (isset($_POST['txpower']) && ($_POST['txpower'] != 'auto')) {
|
||||
$sdBm = $_POST['txpower'] * 100;
|
||||
exec('sudo /sbin/iw dev '.$_POST['interface'].' set txpower fixed '.$sdBm, $return);
|
||||
$status->addMessage('Setting transmit power to '.$_POST['txpower'].' dBm.', 'success');
|
||||
$txpower = $_POST['txpower'];
|
||||
} elseif ($_POST['txpower'] == 'auto') {
|
||||
exec('sudo /sbin/iw dev '.$_POST['interface'].' set txpower auto', $return);
|
||||
$status->addMessage('Setting transmit power to '.$_POST['txpower'].'.', 'success');
|
||||
$txpower = $_POST['txpower'];
|
||||
}
|
||||
|
||||
echo renderTemplate(
|
||||
"hostapd", compact(
|
||||
|
@ -101,6 +117,8 @@ function DisplayHostAPDConfig()
|
|||
"selectedHwMode",
|
||||
"arrSecurity",
|
||||
"arrEncType",
|
||||
"arrTxPower",
|
||||
"txpower",
|
||||
"arrHostapdConf"
|
||||
)
|
||||
);
|
||||
|
@ -207,7 +225,6 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
|
|||
|
||||
// Verify input
|
||||
if (empty($_POST['ssid']) || strlen($_POST['ssid']) > 32) {
|
||||
// Not sure of all the restrictions of SSID
|
||||
$status->addMessage('SSID must be between 1 and 32 characters', 'danger');
|
||||
$good_input = false;
|
||||
}
|
||||
|
@ -237,8 +254,6 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
|
|||
}
|
||||
|
||||
if (! in_array($_POST['interface'], $interfaces)) {
|
||||
// The user is probably up to something here but it may also be a
|
||||
// genuine error.
|
||||
$status->addMessage('Unknown interface '.htmlspecialchars($_POST['interface'], ENT_QUOTES), 'danger');
|
||||
$good_input = false;
|
||||
}
|
||||
|
@ -302,29 +317,28 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
|
|||
// Set dhcp values from system config, fallback to default if undefined
|
||||
$jsonData = json_decode(getNetConfig($ap_iface), true);
|
||||
$ip_address = ($jsonData['StaticIP'] == '') ? getDefaultNetValue('dhcp',$ap_iface,'static ip_address') : $jsonData['StaticIP'];
|
||||
$domain_name_server = ($jsonData['StaticDNS'] =='') ? getDefaultNetValue('dhcp',$ap_iface,'static domain_name_server') : $jsonData['StaticDNS'];
|
||||
$domain_name_server = ($jsonData['StaticDNS'] =='') ? getDefaultNetValue('dhcp','wlan0','static domain_name_server') : $jsonData['StaticDNS'];
|
||||
$routers = ($jsonData['StaticRouters'] == '') ? getDefaultNetValue('dhcp',$ap_iface,'static routers') : $jsonData['StaticRouters'];
|
||||
$netmask = ($jsonData['SubnetMask'] == '' || $jsonData['SubnetMask'] == '0.0.0.0') ? getDefaultNetValue('dhcp',$ap_iface,'subnetmask') : $jsonData['SubnetMask'];
|
||||
$ip_address.= (!preg_match('/.*\/\d+/', $ip_address)) ? '/'.mask2cidr($netmask) : null;
|
||||
|
||||
if ($bridgedEnable == 1) {
|
||||
$config = array_keys(getDefaultNetOpts('dhcp'));
|
||||
$config = array_keys(getDefaultNetOpts('dhcp','options'));
|
||||
$config[] = PHP_EOL.'# RaspAP br0 configuration';
|
||||
$config[] = 'denyinterfaces eth0 wlan0';
|
||||
$config[] = 'interface br0';
|
||||
$config[] = PHP_EOL;
|
||||
} elseif ($wifiAPEnable == 1) {
|
||||
$config = array_keys(getDefaultNetOpts('dhcp'));
|
||||
$config = array_keys(getDefaultNetOpts('dhcp','options'));
|
||||
$config[] = PHP_EOL.'# RaspAP uap0 configuration';
|
||||
$config[] = 'interface uap0';
|
||||
$config[] = 'static ip_address='.$ip_address;
|
||||
$config[] = 'nohook wpa_supplicant';
|
||||
$config[] = PHP_EOL;
|
||||
} else {
|
||||
// Default wlan0 config
|
||||
$def_ip = array();
|
||||
$config = [ '# RaspAP wlan0 configuration' ];
|
||||
$config[] = 'interface wlan0';
|
||||
$config = [ '# RaspAP '.$ap_iface.' configuration' ];
|
||||
$config[] = 'interface '.$ap_iface;
|
||||
$config[] = 'static ip_address='.$ip_address;
|
||||
$config[] = 'static routers='.$routers;
|
||||
$config[] = 'static domain_name_server='.$domain_name_server;
|
||||
|
|
|
@ -11,10 +11,23 @@ function getRouteInfo($checkAccess)
|
|||
$rInfo = array();
|
||||
// get all default routes
|
||||
exec('ip route list | sed -rn "s/default via (([0-9]{1,3}\.){3}[0-9]{1,3}).*dev (\w*).*src (([0-9]{1,3}\.){3}[0-9]{1,3}).*/\3 \4 \1/p"', $routes);
|
||||
exec('ip route list | sed -rn "s/default dev (\w*) scope link/\1/p"', $devs);
|
||||
$devpat = array("tun", "ppp"); // routing in case of VPN and PPP connection are different
|
||||
foreach ($devpat as $pat) {
|
||||
exec('ip route list | grep -oP "'.$pat.'[0-9]" | sort -u', $devs);
|
||||
}
|
||||
if (!empty($devs)) {
|
||||
foreach ($devs as $dev)
|
||||
exec('ip route list | sed -rn "s/(([0-9]{1,3}\.){3}[0-9]{1,3}).*dev.*("' . $dev . '").*scope link src (([0-9]{1,3}\.){3}[0-9]{1,3}).*/\3 \4 \1/p"', $routes);
|
||||
foreach ($devs as $dev) {
|
||||
unset($gateway);
|
||||
unset($ipadd);
|
||||
exec('ip route list | sed -rn "s/^.*via (([0-9]{1,3}\.){3}[0-9]{1,3}) dev "' . $dev . '".*$/\1/p" | head -n 1', $gateway);
|
||||
if (empty($gateway)) {
|
||||
exec('ip route list | sed -rn "s/(([0-9]{1,3}\.){3}[0-9]{1,3}).*dev.*"' . $dev . '".*scope link src.*/\1/p"', $gateway);
|
||||
}
|
||||
exec('ifconfig -a | grep -i ' . $dev . ' -A 1 | grep -oP "(?<=inet )([0-9]{1,3}\.){3}[0-9]{1,3}"', $ipadd);
|
||||
if (!empty($gateway) && !empty($ipadd)) {
|
||||
$routes[]="$dev $ipadd[0] $gateway[0]";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($routes)) {
|
||||
foreach ($routes as $i => $route) {
|
||||
|
@ -41,5 +54,4 @@ function getRouteInfo($checkAccess)
|
|||
}
|
||||
return $rInfo;
|
||||
}
|
||||
?>
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
@ -20,7 +21,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);
|
||||
|
@ -39,16 +42,32 @@ 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)) {
|
||||
$authUser = $auth[0];
|
||||
$authPassword = $auth[1];
|
||||
$auth = array_filter($auth, 'filter_comments');
|
||||
$authUser = current($auth);
|
||||
$authPassword = next($auth);
|
||||
}
|
||||
$clients = preg_grep('/_client.(conf)$/', scandir(pathinfo(RASPI_OPENVPN_CLIENT_CONFIG, PATHINFO_DIRNAME)));
|
||||
exec("readlink ".RASPI_OPENVPN_CLIENT_CONFIG." | xargs basename", $ret);
|
||||
$conf_default = empty($ret) ? "none" : $ret[0];
|
||||
|
||||
$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 +75,13 @@ function DisplayOpenVPNConfig()
|
|||
"status",
|
||||
"serviceStatus",
|
||||
"openvpnstatus",
|
||||
"logEnable",
|
||||
"logOutput",
|
||||
"public_ip",
|
||||
"authUser",
|
||||
"authPassword"
|
||||
"authPassword",
|
||||
"clients",
|
||||
"conf_default"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -76,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 {
|
||||
|
@ -86,76 +109,49 @@ 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);
|
||||
|
||||
$validation = new validation;
|
||||
$upload->callbacks($validation, array('check_name_length'));
|
||||
$results = $upload->upload();
|
||||
|
||||
if (!empty($results['errors'])) {
|
||||
throw new RuntimeException($results['errors'][0]);
|
||||
}
|
||||
|
||||
// Validate extension
|
||||
$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
|
||||
if ($ext != 'ovpn') {
|
||||
throw new RuntimeException('Invalid file extension');
|
||||
}
|
||||
|
||||
// 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');
|
||||
}
|
||||
// Good file upload, update auth credentials if present
|
||||
if (!empty($authUser) && !empty($authPassword)) {
|
||||
$auth_flag = 1;
|
||||
// Move tmp authdata to /etc/openvpn/login.conf
|
||||
$tmp_authdata = $tmp_destdir .'ovpn/authdata';
|
||||
$auth = $authUser .PHP_EOL . $authPassword .PHP_EOL;
|
||||
file_put_contents($tmp_authdata, $auth);
|
||||
system("sudo cp $tmp_authdata " . RASPI_OPENVPN_CLIENT_LOGIN, $return);
|
||||
chmod($tmp_authdata, 0644);
|
||||
$client_auth = RASPI_OPENVPN_CLIENT_PATH.pathinfo($file['name'], PATHINFO_FILENAME).'_login.conf';
|
||||
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) {
|
||||
$status->addMessage('Unable to save client auth credentials', 'danger');
|
||||
}
|
||||
}
|
||||
|
||||
// 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');
|
||||
}
|
||||
|
||||
// Copy tmp client config to /etc/openvpn/client
|
||||
system("sudo cp $tmp_ovpnclient " . RASPI_OPENVPN_CLIENT_CONFIG, $return);
|
||||
// Move uploaded ovpn config from /tmp and create symlink
|
||||
$client_ovpn = RASPI_OPENVPN_CLIENT_PATH.pathinfo($file['name'], PATHINFO_FILENAME).'_client.conf';
|
||||
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);
|
||||
|
||||
if ($return ==0) {
|
||||
$status->addMessage('OpenVPN client.conf uploaded successfully', 'info');
|
||||
} else {
|
||||
|
@ -168,3 +164,4 @@ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword)
|
|||
return $status;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -147,6 +147,7 @@ function DisplaySystem()
|
|||
'pl_PL.UTF-8' => 'Polskie',
|
||||
'pt_BR.UTF-8' => 'Português',
|
||||
'ru_RU.UTF-8' => 'Русский',
|
||||
'ro_RO.UTF-8' => 'Română',
|
||||
'sv_SE.UTF-8' => 'Svenska',
|
||||
'tr_TR.UTF-8' => 'Türkçe',
|
||||
'vi_VN.UTF-8' => 'Tiếng Việt (Vietnamese)'
|
||||
|
|
|
@ -7,13 +7,11 @@ function DisplayThemeConfig(&$extraFooterScripts)
|
|||
{
|
||||
$themes = [
|
||||
"default" => "RaspAP (default)",
|
||||
"hackernews" => "HackerNews",
|
||||
"lightsout" => "Lights Out"
|
||||
"hackernews" => "HackerNews"
|
||||
];
|
||||
$themeFiles = [
|
||||
"default" => "custom.php",
|
||||
"hackernews" => "hackernews.css",
|
||||
"lightsout" => "lightsout.css"
|
||||
"hackernews" => "hackernews.css"
|
||||
];
|
||||
$selectedTheme = array_search($_COOKIE['theme'], $themeFiles);
|
||||
|
||||
|
|
|
@ -6,9 +6,11 @@ function knownWifiStations(&$networks)
|
|||
{
|
||||
// Find currently configured networks
|
||||
exec(' sudo cat ' . RASPI_WPA_SUPPLICANT_CONFIG, $known_return);
|
||||
$index = 0;
|
||||
foreach ($known_return as $line) {
|
||||
if (preg_match('/network\s*=/', $line)) {
|
||||
$network = array('visible' => false, 'configured' => true, 'connected' => false);
|
||||
$network = array('visible' => false, 'configured' => true, 'connected' => false, 'index' => $index);
|
||||
++$index;
|
||||
} elseif (isset($network) && $network !== null) {
|
||||
if (preg_match('/^\s*}\s*$/', $line)) {
|
||||
$networks[$ssid] = $network;
|
||||
|
@ -18,6 +20,7 @@ function knownWifiStations(&$networks)
|
|||
switch (strtolower($lineArr[0])) {
|
||||
case 'ssid':
|
||||
$ssid = trim($lineArr[1], '"');
|
||||
$ssid = str_replace('P"','',$ssid);
|
||||
$network['ssid'] = $ssid;
|
||||
break;
|
||||
case 'psk':
|
||||
|
@ -68,11 +71,16 @@ function nearbyWifiStations(&$networks, $cached = true)
|
|||
exec('cat '.RASPI_HOSTAPD_CONFIG.' | sed -rn "s/ssid=(.*)\s*$/\1/p" ', $ap_ssid);
|
||||
$ap_ssid = $ap_ssid[0];
|
||||
|
||||
$index = 0;
|
||||
if ( !empty($networks) ) {
|
||||
$lastnet = end($networks);
|
||||
if ( isset($lastnet['index']) ) $index = $lastnet['index'] + 1;
|
||||
}
|
||||
|
||||
foreach (explode("\n", $scan_results) as $network) {
|
||||
$arrNetwork = preg_split("/[\t]+/", $network); // split result into array
|
||||
|
||||
$ssid = trim($arrNetwork[4]);
|
||||
$ssid = evalHexSequence($ssid);
|
||||
|
||||
// exclude raspap ssid
|
||||
if (empty($ssid) || $ssid == $ap_ssid) {
|
||||
|
@ -84,8 +92,6 @@ function nearbyWifiStations(&$networks, $cached = true)
|
|||
continue;
|
||||
}
|
||||
|
||||
$networks[$ssid]['ssid'] = $ssid;
|
||||
|
||||
// If network is saved
|
||||
if (array_key_exists($ssid, $networks)) {
|
||||
$networks[$ssid]['visible'] = true;
|
||||
|
@ -93,13 +99,16 @@ function nearbyWifiStations(&$networks, $cached = true)
|
|||
// TODO What if the security has changed?
|
||||
} else {
|
||||
$networks[$ssid] = array(
|
||||
'ssid' => $ssid,
|
||||
'configured' => false,
|
||||
'protocol' => ConvertToSecurity($arrNetwork[3]),
|
||||
'channel' => ConvertToChannel($arrNetwork[1]),
|
||||
'passphrase' => '',
|
||||
'visible' => true,
|
||||
'connected' => false
|
||||
'connected' => false,
|
||||
'index' => $index
|
||||
);
|
||||
++$index;
|
||||
}
|
||||
|
||||
// Save RSSI, if the current value is larger than the already stored
|
||||
|
@ -116,7 +125,7 @@ function connectedWifiStations(&$networks)
|
|||
exec('iwconfig ' .$_SESSION['wifi_client_interface'], $iwconfig_return);
|
||||
foreach ($iwconfig_return as $line) {
|
||||
if (preg_match('/ESSID:\"([^"]+)\"/i', $line, $iwconfig_ssid)) {
|
||||
$networks[$iwconfig_ssid[1]]['connected'] = true;
|
||||
$networks[hexSequence2lower($iwconfig_ssid[1])]['connected'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,3 +189,12 @@ function reinitializeWPA($force)
|
|||
return $result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace escaped bytes (hex) by binary - assume UTF8 encoding
|
||||
*
|
||||
* @param string $ssid
|
||||
*/
|
||||
function ssid2utf8($ssid) {
|
||||
return evalHexSequence($ssid);
|
||||
}
|
||||
|
||||
|
|
310
includes/wireguard.php
Normal file
310
includes/wireguard.php
Normal file
|
@ -0,0 +1,310 @@
|
|||
<?php
|
||||
|
||||
require_once 'includes/status_messages.php';
|
||||
require_once 'config.php';
|
||||
|
||||
/**
|
||||
* Displays wireguard server & peer configuration
|
||||
*/
|
||||
function DisplayWireGuardConfig()
|
||||
{
|
||||
$status = new StatusMessages();
|
||||
if (!RASPI_MONITOR_ENABLED) {
|
||||
$optRules = $_POST['wgRules'];
|
||||
$optConf = $_POST['wgCnfOpt'];
|
||||
$optSrvEnable = $_POST['wgSrvEnable'];
|
||||
$optLogEnable = $_POST['wgLogEnable'];
|
||||
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['savewgsettings']) && isset($_POST['wg_penabled']) ) {
|
||||
SaveWireGuardConfig($status);
|
||||
} elseif (isset($_POST['startwg'])) {
|
||||
$status->addMessage('Attempting to start WireGuard', 'info');
|
||||
exec('sudo /bin/systemctl start wg-quick@wg0', $return);
|
||||
foreach ($return as $line) {
|
||||
$status->addMessage($line, 'info');
|
||||
}
|
||||
} elseif (isset($_POST['stopwg'])) {
|
||||
$status->addMessage('Attempting to stop WireGuard', 'info');
|
||||
exec('sudo /bin/systemctl stop wg-quick@wg0', $return);
|
||||
foreach ($return as $line) {
|
||||
$status->addMessage($line, 'info');
|
||||
}
|
||||
}
|
||||
CheckWireGuardLog( $optLogEnable, $status );
|
||||
}
|
||||
|
||||
// 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);
|
||||
$wg_srvport = ($conf['ListenPort'] == '') ? getDefaultNetValue('wireguard','server','ListenPort') : $conf['ListenPort'];
|
||||
$wg_srvipaddress = ($conf['Address'] == '') ? getDefaultNetValue('wireguard','server','Address') : $conf['Address'];
|
||||
$wg_srvdns = ($conf['DNS'] == '') ? getDefaultNetValue('wireguard','server','DNS') : $conf['DNS'];
|
||||
$wg_peerpubkey = exec('sudo cat '. RASPI_WIREGUARD_PATH .'wg-peer-public.key', $return);
|
||||
if (sizeof($conf) >0) {
|
||||
$wg_senabled = true;
|
||||
}
|
||||
|
||||
// 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'];
|
||||
$wg_plistenport = ($conf['ListenPort'] == '') ? getDefaultNetValue('wireguard','peer','ListenPort') : $conf['ListenPort'];
|
||||
$wg_pendpoint = ($conf['Endpoint'] == '') ? getDefaultNetValue('wireguard','peer','Endpoint') : $conf['Endpoint'];
|
||||
$wg_pallowedips = ($conf['AllowedIPs'] == '') ? getDefaultNetValue('wireguard','peer','AllowedIPs') : $conf['AllowedIPs'];
|
||||
$wg_pkeepalive = ($conf['PersistentKeepalive'] == '') ? getDefaultNetValue('wireguard','peer','PersistentKeepalive') : $conf['PersistentKeepalive'];
|
||||
if (sizeof($conf) >0) {
|
||||
$wg_penabled = true;
|
||||
}
|
||||
|
||||
// fetch service status
|
||||
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",
|
||||
"optLogEnable",
|
||||
"peer_id",
|
||||
"wg_srvpubkey",
|
||||
"wg_srvport",
|
||||
"wg_srvipaddress",
|
||||
"wg_srvdns",
|
||||
"wg_senabled",
|
||||
"wg_penabled",
|
||||
"wg_pipaddress",
|
||||
"wg_plistenport",
|
||||
"wg_peerpubkey",
|
||||
"wg_pendpoint",
|
||||
"wg_pallowedips",
|
||||
"wg_pkeepalive"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @param object $status
|
||||
* @return boolean
|
||||
*/
|
||||
function SaveWireGuardConfig($status)
|
||||
{
|
||||
// Set defaults
|
||||
$good_input = true;
|
||||
$peer_id = 1;
|
||||
// Validate server input
|
||||
if ($_POST['wgSrvEnable'] == 1) {
|
||||
if (isset($_POST['wg_srvport'])) {
|
||||
if (strlen($_POST['wg_srvport']) > 5 || !is_numeric($_POST['wg_srvport'])) {
|
||||
$status->addMessage('Invalid value for server local port', 'danger');
|
||||
$good_input = false;
|
||||
}
|
||||
}
|
||||
if (isset($_POST['wg_plistenport'])) {
|
||||
if (strlen($_POST['wg_plistenport']) > 5 || !is_numeric($_POST['wg_plistenport'])) {
|
||||
$status->addMessage('Invalid value for peer local port', 'danger');
|
||||
$good_input = false;
|
||||
}
|
||||
}
|
||||
if (isset($_POST['wg_srvipaddress'])) {
|
||||
if (!validateCidr($_POST['wg_srvipaddress'])) {
|
||||
$status->addMessage('Invalid value for server IP address', 'danger');
|
||||
$good_input = false;
|
||||
}
|
||||
}
|
||||
if (isset($_POST['wg_srvdns'])) {
|
||||
if (!filter_var($_POST['wg_srvdns'],FILTER_VALIDATE_IP)) {
|
||||
$status->addMessage('Invalid value for DNS', 'danger');
|
||||
$good_input = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Validate peer input
|
||||
if ($_POST['wg_penabled'] == 1) {
|
||||
if (isset($_POST['wg_pipaddress'])) {
|
||||
if (!validateCidr($_POST['wg_pipaddress'])) {
|
||||
$status->addMessage('Invalid value for peer IP address', 'danger');
|
||||
$good_input = false;
|
||||
}
|
||||
}
|
||||
if (isset($_POST['wg_pendpoint']) && strlen(trim($_POST['wg_pendpoint']) >0 )) {
|
||||
$wg_pendpoint_seg = substr($_POST['wg_pendpoint'],0,strpos($_POST['wg_pendpoint'],':'));
|
||||
if (!filter_var($wg_pendpoint_seg,FILTER_VALIDATE_IP)) {
|
||||
$status->addMessage('Invalid value for endpoint address', 'danger');
|
||||
$good_input = false;
|
||||
}
|
||||
}
|
||||
if (isset($_POST['wg_pallowedips']) && strlen(trim($_POST['wg_pallowedips']) >0)) {
|
||||
if (!validateCidr($_POST['wg_pallowedips'])) {
|
||||
$status->addMessage('Invalid value for allowed IPs', 'danger');
|
||||
$good_input = false;
|
||||
}
|
||||
}
|
||||
if (isset($_POST['wg_pkeepalive']) && strlen(trim($_POST['wg_pkeepalive']) >0 )) {
|
||||
if (strlen($_POST['wg_pkeepalive']) > 4 || !is_numeric($_POST['wg_pkeepalive'])) {
|
||||
$status->addMessage('Invalid value for persistent keepalive', 'danger');
|
||||
$good_input = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save settings
|
||||
if ($good_input) {
|
||||
// server (wg0.conf)
|
||||
if ($_POST['wgSrvEnable'] == 1) {
|
||||
// fetch server private key from filesytem
|
||||
$wg_srvprivkey = exec('sudo cat '. RASPI_WIREGUARD_PATH .'wg-server-private.key', $return);
|
||||
$config[] = '[Interface]';
|
||||
$config[] = 'Address = '.$_POST['wg_srvipaddress'];
|
||||
$config[] = 'ListenPort = '.$_POST['wg_srvport'];
|
||||
$config[] = 'DNS = '.$_POST['wg_srvdns'];
|
||||
$config[] = 'PrivateKey = '.$wg_srvprivkey;
|
||||
$config[] = 'PostUp = '.getDefaultNetValue('wireguard','server','PostUp');
|
||||
$config[] = 'PostDown = '.getDefaultNetValue('wireguard','server','PostDown');
|
||||
$config[] = '';
|
||||
$config[] = '[Peer]';
|
||||
$config[] = 'PublicKey = '.$_POST['wg-peer'];
|
||||
$config[] = 'AllowedIPs = '.$_POST['wg_pallowedips'];
|
||||
if ($_POST['wg_pkeepalive'] !== '') {
|
||||
$config[] = 'PersistentKeepalive = '.trim($_POST['wg_pkeepalive']);
|
||||
}
|
||||
$config[] = '';
|
||||
$config = join(PHP_EOL, $config);
|
||||
|
||||
file_put_contents("/tmp/wgdata", $config);
|
||||
system('sudo cp /tmp/wgdata '.RASPI_WIREGUARD_CONFIG, $return);
|
||||
} else {
|
||||
# remove selected conf + keys
|
||||
system('sudo rm '. RASPI_WIREGUARD_PATH .'wg-server-private.key', $return);
|
||||
system('sudo rm '. RASPI_WIREGUARD_PATH .'wg-server-public.key', $return);
|
||||
system('sudo rm '. RASPI_WIREGUARD_CONFIG, $return);
|
||||
}
|
||||
// client1 (client.conf)
|
||||
if ($_POST['wg_penabled'] == 1) {
|
||||
// fetch peer private key from filesystem
|
||||
$wg_peerprivkey = exec('sudo cat '. RASPI_WIREGUARD_PATH .'wg-peer-private.key', $return);
|
||||
$config = [];
|
||||
$config[] = '[Interface]';
|
||||
$config[] = 'Address = '.trim($_POST['wg_pipaddress']);
|
||||
$config[] = 'PrivateKey = '.$wg_peerprivkey;
|
||||
$config[] = 'ListenPort = '.$_POST['wg_plistenport'];
|
||||
$config[] = '';
|
||||
$config[] = '[Peer]';
|
||||
$config[] = 'PublicKey = '.$_POST['wg-server'];
|
||||
$config[] = 'AllowedIPs = '.$_POST['wg_pallowedips'];
|
||||
$config[] = 'Endpoint = '.$_POST['wg_pendpoint'];
|
||||
if ($_POST['wg_pkeepalive'] !== '') {
|
||||
$config[] = 'PersistentKeepalive = '.trim($_POST['wg_pkeepalive']);
|
||||
}
|
||||
$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
|
||||
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);
|
||||
}
|
||||
|
||||
foreach ($return as $line) {
|
||||
$status->addMessage($line, 'info');
|
||||
}
|
||||
if ($return == 0) {
|
||||
$status->addMessage('WireGuard configuration updated successfully', 'success');
|
||||
} else {
|
||||
$status->addMessage('WireGuard configuration failed to be updated', 'danger');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return object $status
|
||||
*/
|
||||
function CheckWireGuardLog( $opt, $status )
|
||||
{
|
||||
// handle log option
|
||||
if ( $opt == "1") {
|
||||
exec("sudo journalctl --identifier wg-quick > /tmp/wireguard.log");
|
||||
$status->addMessage('WireGuard debug log updated', 'success');
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
|
30
index.php
30
index.php
|
@ -7,15 +7,15 @@
|
|||
* Enables use of simple web interface rather than SSH to control WiFi and related services on the Raspberry Pi.
|
||||
* Recommended distribution is Raspberry Pi OS (32-bit) Lite. Specific instructions to install the supported software are
|
||||
* in the README and original post by @SirLagz. For a quick run through, the packages required for the WebGUI are:
|
||||
* lighttpd (version 1.4.53 installed via apt)
|
||||
* php-cgi (version 7.3.19-1 installed via apt)
|
||||
* lighttpd (version 1.4.59 installed via apt)
|
||||
* php-cgi (version 7.4.25 installed via apt)
|
||||
* along with their supporting packages, php7.3 will also need to be enabled.
|
||||
*
|
||||
* @author Lawrence Yau <sirlagz@gmail.com>
|
||||
* @author Bill Zimmerman <billzimmerman@gmail.com>
|
||||
* @license GNU General Public License, version 3 (GPL-3.0)
|
||||
* @version 2.6.7
|
||||
* @link https://github.com/raspap/raspap-webgui/
|
||||
* @version 2.8.4
|
||||
* @link https://github.com/RaspAP/raspap-webgui/
|
||||
* @link https://raspap.com/
|
||||
* @see http://sirlagz.net/2013/02/08/raspap-webgui/
|
||||
*
|
||||
|
@ -45,6 +45,7 @@ require_once 'includes/themes.php';
|
|||
require_once 'includes/data_usage.php';
|
||||
require_once 'includes/about.php';
|
||||
require_once 'includes/openvpn.php';
|
||||
require_once 'includes/wireguard.php';
|
||||
require_once 'includes/torproxy.php';
|
||||
|
||||
$config = getConfig();
|
||||
|
@ -82,6 +83,9 @@ $bridgedEnabled = getBridgedState();
|
|||
<!-- Custom Fonts -->
|
||||
<link href="dist/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||
|
||||
<!-- RaspAP Fonts -->
|
||||
<link href="dist/raspap/css/style.css" rel="stylesheet" type="text/css">
|
||||
|
||||
<!-- Custom CSS -->
|
||||
<link href="<?php echo $theme_url; ?>" title="main" rel="stylesheet">
|
||||
|
||||
|
@ -161,6 +165,11 @@ $bridgedEnabled = getBridgedState();
|
|||
<?php if (RASPI_OPENVPN_ENABLED) : ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="openvpn_conf"><i class="fas fa-key fa-fw mr-2"></i><span class="nav-label"><?php echo _("OpenVPN"); ?></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if (RASPI_WIREGUARD_ENABLED) : ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="wg_conf"><span class="ra-wireguard mr-2"></span><span class="nav-label"><?php echo _("WireGuard"); ?></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if (RASPI_TORPROXY_ENABLED) : ?>
|
||||
|
@ -214,8 +223,13 @@ $bridgedEnabled = getBridgedState();
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<!-- Topbar Navbar -->
|
||||
<p class="text-left brand-title mt-3 ml-2"><?php //echo _("WiFi Configuration Portal"); ?></p>
|
||||
<p class="text-left brand-title mt-3 ml-2"></p>
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<!-- Nav Item - Night mode -->
|
||||
<div class="custom-control custom-switch mt-4">
|
||||
<input type="checkbox" class="custom-control-input" id="night-mode" <?php echo getNightmode() ? 'checked' : null ; ?> >
|
||||
<label class="custom-control-label" for="night-mode"><i class="far fa-moon mr-1 text-muted"></i></label>
|
||||
</div>
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
<!-- Nav Item - User -->
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
|
@ -254,6 +268,12 @@ $bridgedEnabled = getBridgedState();
|
|||
case "/openvpn_conf":
|
||||
DisplayOpenVPNConfig();
|
||||
break;
|
||||
case "/wg_conf":
|
||||
DisplayWireGuardConfig();
|
||||
break;
|
||||
case "/torproxy_conf":
|
||||
DisplayTorProxyConfig();
|
||||
break;
|
||||
case "/torproxy_conf":
|
||||
DisplayTorProxyConfig();
|
||||
break;
|
||||
|
|
|
@ -43,9 +43,9 @@ function _install_raspap() {
|
|||
_update_system_packages
|
||||
_install_dependencies
|
||||
_enable_php_lighttpd
|
||||
_check_for_old_configs
|
||||
_create_raspap_directories
|
||||
_optimize_php
|
||||
_check_for_old_configs
|
||||
_download_latest_files
|
||||
_change_file_ownership
|
||||
_create_hostapd_scripts
|
||||
|
@ -139,10 +139,10 @@ function _get_linux_distro() {
|
|||
# Sets php package option based on Linux version, abort if unsupported distro
|
||||
function _set_php_package() {
|
||||
case $RELEASE in
|
||||
18.04|19.10) # Ubuntu Server
|
||||
18.04|19.10|11*) # Ubuntu Server & Debian 11
|
||||
php_package="php7.4-cgi"
|
||||
phpcgiconf="/etc/php/7.4/cgi/php.ini" ;;
|
||||
10*)
|
||||
10*|11*)
|
||||
php_package="php7.3-cgi"
|
||||
phpcgiconf="/etc/php/7.3/cgi/php.ini" ;;
|
||||
9*)
|
||||
|
@ -159,7 +159,7 @@ function _set_php_package() {
|
|||
function _install_dependencies() {
|
||||
_install_log "Installing required packages"
|
||||
_set_php_package
|
||||
if [ "$php_package" = "php7.4-cgi" ]; then
|
||||
if [ "$php_package" = "php7.4-cgi" ] && [ ${OS,,} = "ubuntu" ]; then
|
||||
echo "Adding apt-repository ppa:ondrej/php"
|
||||
sudo apt-get install $apt_option software-properties-common || _install_status 1 "Unable to install dependency"
|
||||
sudo add-apt-repository $apt_option ppa:ondrej/php || _install_status 1 "Unable to add-apt-repository ppa:ondrej/php"
|
||||
|
@ -352,21 +352,19 @@ function _prompt_install_openvpn() {
|
|||
|
||||
# Prompt to install WireGuard
|
||||
function _prompt_install_wireguard() {
|
||||
if [ "$insiders" == 1 ]; then
|
||||
_install_log "Configure WireGuard support"
|
||||
echo -n "Install WireGuard and enable VPN tunnel configuration? [Y/n]: "
|
||||
if [ "$assume_yes" == 0 ]; then
|
||||
read answer < /dev/tty
|
||||
if [ "$answer" != "${answer#[Nn]}" ]; then
|
||||
echo -e
|
||||
else
|
||||
_install_wireguard
|
||||
fi
|
||||
elif [ "$wg_option" == 1 ]; then
|
||||
_install_wireguard
|
||||
_install_log "Configure WireGuard support"
|
||||
echo -n "Install WireGuard and enable VPN tunnel configuration? [Y/n]: "
|
||||
if [ "$assume_yes" == 0 ]; then
|
||||
read answer < /dev/tty
|
||||
if [ "$answer" != "${answer#[Nn]}" ]; then
|
||||
echo -e
|
||||
else
|
||||
echo "(Skipped)"
|
||||
_install_wireguard
|
||||
fi
|
||||
elif [ "$wg_option" == 1 ]; then
|
||||
_install_wireguard
|
||||
else
|
||||
echo "(Skipped)"
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -427,6 +425,10 @@ function _download_latest_files() {
|
|||
if [ "$upgrade" == 1 ]; then
|
||||
_install_log "Applying existing configuration to ${webroot_dir}/includes"
|
||||
sudo mv /tmp/config.php $webroot_dir/includes || _install_status 1 "Unable to move config.php to ${webroot_dir}/includes"
|
||||
|
||||
if [ -f /tmp/raspap.auth ]; then
|
||||
sudo mv /tmp/raspap.auth $raspap_dir || _install_status 1 "Unable to restore authentification credentials file to ${raspap_dir}"
|
||||
fi
|
||||
fi
|
||||
|
||||
_install_status 0
|
||||
|
@ -447,6 +449,10 @@ function _check_for_old_configs() {
|
|||
if [ "$upgrade" == 1 ]; then
|
||||
_install_log "Moving existing configuration to /tmp"
|
||||
sudo mv $webroot_dir/includes/config.php /tmp || _install_status 1 "Unable to move config.php to /tmp"
|
||||
|
||||
if [ -f $raspap_dir/raspap.auth ]; then
|
||||
sudo mv $raspap_dir/raspap.auth /tmp || _install_status 1 "Unable to backup raspap.auth to /tmp"
|
||||
fi
|
||||
else
|
||||
_install_log "Backing up existing configs to ${raspap_dir}/backups"
|
||||
if [ -f /etc/network/interfaces ]; then
|
||||
|
@ -609,7 +615,7 @@ function _optimize_php() {
|
|||
if [ "$upgrade" == 0 ]; then
|
||||
_install_log "Optimize PHP configuration"
|
||||
if [ ! -f "$phpcgiconf" ]; then
|
||||
_install_status 1 "PHP configuration could not be found."
|
||||
_install_status 2 "PHP configuration could not be found."
|
||||
return
|
||||
fi
|
||||
|
||||
|
@ -669,7 +675,7 @@ function _install_complete() {
|
|||
# Prompt to reboot if wired ethernet (eth0) is connected.
|
||||
# With default_configuration this will create an active AP on restart.
|
||||
if ip a | grep -q ': eth0:.*state UP'; then
|
||||
echo -n "The system needs to be rebooted as a final step. Reboot now? [y/N]: "
|
||||
echo -n "The system needs to be rebooted as a final step. Reboot now? [Y/n]: "
|
||||
read answer < /dev/tty
|
||||
if [ "$answer" != "${answer#[Nn]}" ]; then
|
||||
echo "Installation reboot aborted."
|
||||
|
|
|
@ -35,7 +35,7 @@ echo "Checking iptables rules"
|
|||
rules=(
|
||||
"-A POSTROUTING -o tun0 -j MASQUERADE"
|
||||
"-A FORWARD -i tun0 -o ${interface} -m state --state RELATED,ESTABLISHED -j ACCEPT"
|
||||
"-A FORWARD -i wlan0 -o tun0 -j ACCEPT"
|
||||
"-A FORWARD -i ${interface} -o tun0 -j ACCEPT"
|
||||
)
|
||||
|
||||
for rule in "${rules[@]}"; do
|
||||
|
|
40
installers/install_feature_clients.sh
Normal file
40
installers/install_feature_clients.sh
Normal file
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# RaspAP feature installation: handling of mobile data clients and client configuration
|
||||
# to be sources by the RaspAP installer script
|
||||
# Author: @zbchristian <christian@zeitnitz.eu>
|
||||
# Author URI: https://github.com/zbchristian/
|
||||
# License: GNU General Public License v3.0
|
||||
# License URI: https://github.com/raspap/raspap-webgui/blob/master/LICENSE
|
||||
|
||||
# path for mobile modem scripts
|
||||
readonly raspap_clients_scripts="/usr/local/sbin"
|
||||
#
|
||||
# table of mobile network operators - links the 5 digit operator code (from the modem) with a clear text operator name
|
||||
readonly raspap_clients_operator_table="https://raw.githubusercontent.com/musalbas/mcc-mnc-table/master/mcc-mnc-table.csv"
|
||||
|
||||
function _install_feature_clients() {
|
||||
name="feature clients"
|
||||
|
||||
_install_log "Install $name"
|
||||
|
||||
_install_log " - required packages for mobile data clients"
|
||||
sudo apt-get -y install wvdial socat bc || _install_status 1 "Unable to install dependencies for $name"
|
||||
|
||||
_install_log " - copy configuration files and scripts"
|
||||
# Move scripts
|
||||
sudo cp "$webroot_dir/config/client_config/"*.sh "$raspap_clients_scripts/" || _install_status 1 "Unable to move client scripts ($name)"
|
||||
sudo chmod a+rx "$raspap_clients_scripts/"*.sh || _install_status 1 "Unable to chmod client scripts ($name)"
|
||||
# wget $raspap_clients_operator_table -o "$raspap_clients_scripts/"mcc-mnc-table.csv || _install_status 1 "Unable to wget operator table ($name)"
|
||||
sudo cp "$webroot_dir/config/client_config/mcc-mnc-table.csv" "$raspap_clients_scripts/" || _install_status 1 "Unable to move client data ($name)"
|
||||
# wvdial settings
|
||||
sudo cp "$webroot_dir/config/client_config/wvdial.conf" "/etc/" || _install_status 1 "Unable to install client configuration ($name)"
|
||||
sudo cp "$webroot_dir/config/client_config/interfaces" "/etc/network/interfaces" || _install_status 1 "Unable to install interface settings ($name)"
|
||||
# udev rules/services to auto start mobile data services
|
||||
sudo cp "$webroot_dir/config/client_config/70-mobile-data-sticks.rules" "/etc/udev/rules.d/" || _install_status 1 "Unable to install client udev rules ($name)"
|
||||
sudo cp "$webroot_dir/config/client_config/80-raspap-net-devices.rules" "/etc/udev/rules.d/" || _install_status 1 "Unable to install client udev rules ($name)"
|
||||
sudo cp "$webroot_dir/config/client_config/"*.service "/etc/systemd/system/" || _install_status 1 "Unable to install client startup services ($name)"
|
||||
# client configuration and udev rule templates
|
||||
sudo cp "$webroot_dir/config/client_udev_prototypes.json" "/etc/raspap/networking/" || _install_status 1 "Unable to install client configuration ($name)"
|
||||
_install_status 0
|
||||
}
|
20
installers/install_feature_firewall.sh
Normal file
20
installers/install_feature_firewall.sh
Normal file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# RaspAP feature installation: Firewall
|
||||
# to be sources by the RaspAP installer script
|
||||
# Author: @zbchristian <christian@zeitnitz.eu>
|
||||
# Author URI: https://github.com/zbchristian/
|
||||
# License: GNU General Public License v3.0
|
||||
# License URI: https://github.com/raspap/raspap-webgui/blob/master/LICENSE
|
||||
|
||||
function _install_feature_firewall() {
|
||||
name="feature firewall"
|
||||
|
||||
_install_log "Install $name"
|
||||
# create config dir
|
||||
sudo mkdir "$raspap_network/firewall" || _install_status 1 "Unable to create firewall config directory"
|
||||
# copy firewall configuration
|
||||
sudo cp "$webroot_dir/config/iptables_rules.json" "$raspap_network/firewall/" || _install_status 1 "Unable to copy iptables templates"
|
||||
sudo chown $raspap_user:$raspap_user -R "$raspap_network/firewall" || _install_status 1 "Unable to change ownership of firewall directory and files "
|
||||
_install_status 0
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/bash
|
||||
touch /tmp/openvpn.log
|
||||
grep -m 100 openvpn /var/log/syslog | sudo tee /tmp/openvpn.log
|
||||
journalctl |grep -m 200 openvpn | sudo tee /tmp/openvpn.log
|
||||
|
|
|
@ -20,8 +20,9 @@ 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/client.conf
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/authdata /etc/openvpn/client/login.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
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/rm /etc/dnsmasq.d/090_*.conf
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/dhcpddata /etc/dhcpcd.conf
|
||||
|
@ -30,15 +31,35 @@ www-data ALL=(ALL) NOPASSWD:/sbin/reboot
|
|||
www-data ALL=(ALL) NOPASSWD:/sbin/ip link set wlan[0-9] down
|
||||
www-data ALL=(ALL) NOPASSWD:/sbin/ip link set wlan[0-9] up
|
||||
www-data ALL=(ALL) NOPASSWD:/sbin/ip -s a f label wlan[0-9]
|
||||
www-data ALL=(ALL) NOPASSWD:/sbin/ifup *
|
||||
www-data ALL=(ALL) NOPASSWD:/sbin/ifdown *
|
||||
www-data ALL=(ALL) NOPASSWD:/sbin/iw
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/cp /etc/raspap/networking/dhcpcd.conf /etc/dhcpcd.conf
|
||||
www-data ALL=(ALL) NOPASSWD:/etc/raspap/hostapd/enablelog.sh
|
||||
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/chmod o+r /var/log/dnsmasq.log
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/chmod o+r /tmp/wireguard.log
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/dnsmasqdata /etc/dnsmasq.d/090_adblock.conf
|
||||
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 *
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/sed -i * /etc/wvdial.conf
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/sed -i * /etc/udev/rules.d/80-raspap-net-devices.rules
|
||||
www-data ALL=(ALL) NOPASSWD:/usr/bin/tee -a /etc/udev/rules.d/80-raspap-net-devices.rules
|
||||
www-data ALL=(ALL) NOPASSWD:/usr/bin/journalctl --identifier wg-quick
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/systemctl * wg-quick@wg0
|
||||
www-data ALL=(ALL) NOPASSWD:/usr/bin/wg
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/cat /etc/wireguard/*.conf
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/cat /etc/wireguard/wg-*.key
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/rm /etc/wireguard/*.conf
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/rm /etc/wireguard/wg-*.key
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ function _remove_installed_packages() {
|
|||
fi
|
||||
echo -n "Remove the following installed packages? lighttpd hostapd iptables-persistent $php_package $dhcpcd_package vnstat qrencode [y/N]: "
|
||||
read answer
|
||||
if [ "$answer" != 'n' ] && [ "$answer" != 'N' ]; then
|
||||
if [ "$answer" == 'y' ] || [ "$answer" == 'Y' ]; then
|
||||
echo "Removing packages."
|
||||
sudo apt-get remove lighttpd hostapd iptables-persistent $php_package $dhcpcd_package vnstat qrencode || _install_error "Unable to remove installed packages"
|
||||
sudo apt-get autoremove || _install_error "Unable to run apt autoremove"
|
||||
|
|
29
installers/update_firewall.sh
Normal file
29
installers/update_firewall.sh
Normal file
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
# include the raspap helper functions
|
||||
source /usr/local/sbin/raspap_helpers.sh
|
||||
|
||||
_getWebRoot
|
||||
|
||||
echo -n "Update firewall ... "
|
||||
|
||||
cat << EOF > /tmp/updateFirewall.php
|
||||
<?php
|
||||
//set_include_path('/var/www/html/');
|
||||
\$_SESSION['locale']="en_GB.UTF-8";
|
||||
|
||||
require_once 'includes/config.php';
|
||||
require_once 'includes/defaults.php';
|
||||
require_once RASPI_CONFIG.'/raspap.php';
|
||||
require_once 'includes/locale.php';
|
||||
require_once 'includes/wifi_functions.php';
|
||||
require_once 'includes/get_clients.php';
|
||||
require_once 'includes/firewall.php';
|
||||
|
||||
updateFirewall();
|
||||
|
||||
?>
|
||||
EOF
|
||||
|
||||
sudo php -d include_path=$raspap_webroot /tmp/updateFirewall.php
|
||||
rm /tmp/updateFirewall.php
|
||||
echo "done."
|
Binary file not shown.
|
@ -3,8 +3,8 @@ msgstr ""
|
|||
"Project-Id-Version: raspap\n"
|
||||
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
||||
"PO-Revision-Date: 2021-01-13 08:19\n"
|
||||
"Last-Translator: Svend Skipper Andersen\n"
|
||||
"PO-Revision-Date: 2020-04-14 08:51\n"
|
||||
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||
"Language-Team: Danish\n"
|
||||
"Language: da_DK\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -12,10 +12,8 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: raspap\n"
|
||||
"X-Crowdin-Project-ID: 395801\n"
|
||||
"X-Crowdin-Language: da\n"
|
||||
"X-Crowdin-File: /master/locale/en_US/LC_MESSAGES/messages.po\n"
|
||||
"X-Crowdin-File-ID: 10\n"
|
||||
|
||||
#: index.php
|
||||
msgid "RaspAP Wifi Configuration Portal"
|
||||
|
@ -253,12 +251,6 @@ msgstr "Klientliste"
|
|||
msgid "Interface"
|
||||
msgstr "Interface"
|
||||
|
||||
msgid "Enable DHCP for this interface"
|
||||
msgstr "Aktivér DHCP for denne grænseflade"
|
||||
|
||||
msgid "Enable this option if you want RaspAP to assign IP addresses on the selected interface."
|
||||
msgstr "Aktivér denne indstilling hvis du ønsker at RaspAP skal tildele IP-adresser på den valgte grænseflade."
|
||||
|
||||
msgid "DNS Server"
|
||||
msgstr "DNS-server"
|
||||
|
||||
|
@ -352,9 +344,6 @@ msgstr "Format"
|
|||
msgid "Choose a hosted server"
|
||||
msgstr "Vælg en hostet server"
|
||||
|
||||
msgid "Enable these options to log DHCP server activity."
|
||||
msgstr "Aktivér disse indstillinger for at logge DHCP-serveraktivitet."
|
||||
|
||||
msgid "Log DHCP requests"
|
||||
msgstr "Log DHCP anmodninger"
|
||||
|
||||
|
@ -455,31 +444,10 @@ msgstr "Maksimal klientantal"
|
|||
msgid "Configures the max_num_sta option of hostapd. The default and maximum is 2007. If empty or 0, the default applies."
|
||||
msgstr "Konfigurerer max_num_sta i hostapd. Standard og maksimum er 2007. Hvis tom eller 0, bruges standard."
|
||||
|
||||
msgid "Beacon interval"
|
||||
msgstr "Beaconinterval"
|
||||
|
||||
msgid "Disable <code>disassoc_low_ack</code>"
|
||||
msgstr "Deaktivér <code>disassoc_low_ack</code>"
|
||||
|
||||
msgid "Do not disassociate stations based on excessive transmission failures."
|
||||
msgstr "Undlad at frakoble stationer baseret på overdrevne transmissionsfejl."
|
||||
|
||||
msgid "Executing RaspAP service start"
|
||||
msgstr "Udfører RaspAP servicestart"
|
||||
|
||||
msgid "Close"
|
||||
msgstr "Luk"
|
||||
|
||||
msgid "Enable this option to log <code>hostapd</code> activity."
|
||||
msgstr "Aktivér denne indstilling for at logge <code>hostapd</code> aktivitet."
|
||||
|
||||
#: includes/networking.php
|
||||
msgid "Summary"
|
||||
msgstr "Oversigt"
|
||||
|
||||
msgid "Internet connection"
|
||||
msgstr "Internetforbindelse"
|
||||
|
||||
msgid "Current settings"
|
||||
msgstr "Nuværende indstillinger"
|
||||
|
||||
|
@ -507,9 +475,6 @@ msgstr "Deaktiveret"
|
|||
msgid "Static IP Options"
|
||||
msgstr "Statiske IP-indstillinger"
|
||||
|
||||
msgid "Metric"
|
||||
msgstr "Metrisk"
|
||||
|
||||
msgid "Apply settings"
|
||||
msgstr "Anvend indstillinger"
|
||||
|
||||
|
@ -562,12 +527,6 @@ msgstr "Systemet genstarter nu!"
|
|||
msgid "System Shutting Down Now!"
|
||||
msgstr "Systemet lukker ned nu!"
|
||||
|
||||
msgid "Web server port"
|
||||
msgstr "Webserverport"
|
||||
|
||||
msgid "Web server bind address"
|
||||
msgstr "Webserver bind-adresse"
|
||||
|
||||
#: includes/themes.php
|
||||
msgid "Theme settings"
|
||||
msgstr "Temaindstillinger"
|
||||
|
@ -575,9 +534,6 @@ msgstr "Temaindstillinger"
|
|||
msgid "Select a theme"
|
||||
msgstr "Vælg et tema"
|
||||
|
||||
msgid "Color"
|
||||
msgstr "Farve"
|
||||
|
||||
#: includes/data_usage.php
|
||||
msgid "Data usage"
|
||||
msgstr "Dataforbrug"
|
||||
|
@ -778,24 +734,3 @@ msgstr "Statistikker"
|
|||
msgid "Information provided by adblock"
|
||||
msgstr "Information leveret af adblock"
|
||||
|
||||
msgid "Enable custom blocklist"
|
||||
msgstr "Aktiver brugerdefineret blokliste"
|
||||
|
||||
msgid "Define custom hosts to be blocked by entering an IPv4 or IPv6 address followed by any whitespace (spaces or tabs) and the host name."
|
||||
msgstr "Definer brugerdefinerede værter, der skal blokeres ved at indtaste en IPv4- eller IPv6-adresse efterfulgt af blanke tegn (mellemrum eller faneblade) og værtsnavnet."
|
||||
|
||||
msgid "<b>IPv4 example:</b> 0.0.0.0 badhost.com"
|
||||
msgstr "<b>IPv4 eksempel:</b> 0.0.0.0 badhost.com"
|
||||
|
||||
msgid "This option adds an <code>addn-hosts</code> directive to the dnsmasq configuration."
|
||||
msgstr "Denne indstilling tilføjer et <code>addn-værts</code> direktiv til dnsmasq-konfigurationen."
|
||||
|
||||
msgid "Custom blocklist not defined"
|
||||
msgstr "Brugerdefineret blokliste ikke defineret"
|
||||
|
||||
msgid "Invalid custom IP address found on line "
|
||||
msgstr "Ugyldig brugerdefineret IP-adresse fundet på linje "
|
||||
|
||||
msgid "Invalid custom host found on line "
|
||||
msgstr "Ugyldig brugerdefineret vært fundet på linje "
|
||||
|
||||
|
|
Binary file not shown.
|
@ -1104,11 +1104,11 @@ msgstr "Allowed IPs"
|
|||
msgid "Persistent keepalive"
|
||||
msgstr "Persistent keepalive"
|
||||
|
||||
msgid "Display WireGuard status"
|
||||
msgstr "Display WireGuard status"
|
||||
msgid "Enable this option to display an updated <code>wg-quick</code> debug log."
|
||||
msgstr "Enable this option to display an updated <code>wg-quick</code> debug log."
|
||||
|
||||
msgid "Enable this option to display an updated WireGuard status."
|
||||
msgstr "Enable this option to display an updated WireGuard status."
|
||||
msgid "WireGuard debug log updated"
|
||||
msgstr "WireGuard debug log updated"
|
||||
|
||||
msgid "Scan this QR code with your client to connect to this tunnel"
|
||||
msgstr "Scan this QR code with your client to connect to this tunnel"
|
||||
|
@ -1140,3 +1140,73 @@ msgstr "WireGuard configuration updated successfully"
|
|||
msgid "WireGuard configuration failed to be updated"
|
||||
msgstr "WireGuard configuration failed to be updated"
|
||||
|
||||
#: templates/firewall.php
|
||||
|
||||
msgid "Client Firewall"
|
||||
msgstr "Client Firewall"
|
||||
|
||||
msgid "Firewall is ENABLED"
|
||||
msgstr "Firewall is ENABLED"
|
||||
|
||||
msgid "Firewall is OFF"
|
||||
msgstr "Firewall is OFF"
|
||||
|
||||
msgid "The default firewall will only allow outgoing and already established traffic."
|
||||
msgstr "The default firewall will only allow outgoing and already established traffic."
|
||||
|
||||
msgid "No incoming UDP traffic is allowed."
|
||||
msgstr "No incoming UDP traffic is allowed."
|
||||
|
||||
msgid "There are no restrictions for the access point <code>%s</code>."
|
||||
msgstr "There are no restrictions for the access point <code>%s</code>."
|
||||
|
||||
msgid "Exception: Service"
|
||||
msgstr "Exception: Service"
|
||||
|
||||
msgid "allow SSH access on port 22"
|
||||
msgstr "allow SSH access on port 22"
|
||||
|
||||
msgid "allow access to the RaspAP GUI on port 80 or 443"
|
||||
msgstr "allow access to the RaspAP GUI on port 80 or 443"
|
||||
|
||||
msgid "Allow incoming connections for some services from the internet side."
|
||||
msgstr "Allow incoming connections for some services from the internet side."
|
||||
|
||||
msgid "Exception: network device"
|
||||
msgstr "Exception: network device"
|
||||
|
||||
msgid "Exclude device(s)"
|
||||
msgstr "Exclude device(s)"
|
||||
|
||||
msgid "Exclude the given network device(s) (separated by a blank or comma) from firewall rules."
|
||||
msgstr "Exclude the given network device(s) (separated by a blank or comma) from firewall rules."
|
||||
|
||||
msgid "Current client devices: <code>%s</code>"
|
||||
msgstr "Current client devices: <code>%s</code>"
|
||||
|
||||
msgid "The access point <code>%s</code> is per default excluded."
|
||||
msgstr "The access point <code>%s</code> is per default excluded."
|
||||
|
||||
msgid "Exception: IP-Address"
|
||||
msgstr "Exception: IP-Address"
|
||||
|
||||
msgid "Allow incoming connections from"
|
||||
msgstr "Allow incoming connections from"
|
||||
|
||||
msgid "For the given IP-addresses (separated by a blank or comma) the incoming connection (via TCP and UDP) is accepted."
|
||||
msgstr "For the given IP-addresses (separated by a blank or comma) the incoming connection (via TCP and UDP) is accepted."
|
||||
|
||||
msgid "This is required for an OpenVPN via UDP or Wireguard connection."
|
||||
msgstr "This is required for an OpenVPN via UDP or Wireguard connection."
|
||||
|
||||
msgid "The list of configured VPN server IP addresses: <code><b>%s</b></code>"
|
||||
msgstr "The list of configured VPN server IP addresses: <code><b>%s</b></code>"
|
||||
|
||||
msgid "Disable Firewall"
|
||||
msgstr "Disable Firewall"
|
||||
|
||||
msgid "Enable Firewall"
|
||||
msgstr "Enable Firewall"
|
||||
|
||||
msgid "Apply changes"
|
||||
msgstr "Apply changes"
|
||||
|
|
Binary file not shown.
|
@ -1,22 +1,19 @@
|
|||
# RaspAP Portable Object file
|
||||
# Project home: https://github.com/billz/raspap-webgui
|
||||
# Licensed under the GNU General Public License v3.0
|
||||
# This file is distributed under the same license as the RaspAP package
|
||||
# FIRST AUTHOR billzimmerman@gmail.com, 2017
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 1.2.1\n"
|
||||
"Project-Id-Version: raspap\n"
|
||||
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
||||
"PO-Revision-Date: 2019-10-21 23:15+0000\n"
|
||||
"Last-Translator: Luis Franco <luis_franco1990@hotmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: es_MX\n"
|
||||
"PO-Revision-Date: 2020-04-14 08:51\n"
|
||||
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||
"Language-Team: Spanish\n"
|
||||
"Language: es_ES\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: raspap\n"
|
||||
"X-Crowdin-Language: es-ES\n"
|
||||
"X-Crowdin-File: /master/locale/en_US/LC_MESSAGES/messages.po\n"
|
||||
|
||||
#: index.php
|
||||
msgid "RaspAP Wifi Configuration Portal"
|
||||
|
@ -35,7 +32,13 @@ msgid "WiFi client"
|
|||
msgstr "Cliente wiFi"
|
||||
|
||||
msgid "Hotspot"
|
||||
msgstr "Hotspot"
|
||||
msgstr ""
|
||||
|
||||
msgid "Memory Use"
|
||||
msgstr ""
|
||||
|
||||
msgid "CPU Temp"
|
||||
msgstr ""
|
||||
|
||||
msgid "Networking"
|
||||
msgstr "Red de trabajo"
|
||||
|
@ -44,10 +47,10 @@ msgid "DHCP Server"
|
|||
msgstr "Servidor DHCP"
|
||||
|
||||
msgid "OpenVPN"
|
||||
msgstr "OpenVPN"
|
||||
msgstr ""
|
||||
|
||||
msgid "TOR proxy"
|
||||
msgstr "TOR proxy"
|
||||
msgstr ""
|
||||
|
||||
msgid "Authentication"
|
||||
msgstr "Autentificacion"
|
||||
|
@ -97,7 +100,7 @@ msgid "Client settings"
|
|||
msgstr "Configuracion de Cliente"
|
||||
|
||||
msgid "SSID"
|
||||
msgstr "SSID"
|
||||
msgstr ""
|
||||
|
||||
msgid "Channel"
|
||||
msgstr "Canal"
|
||||
|
@ -178,8 +181,8 @@ msgstr "Paquetes Trasnferidos"
|
|||
msgid "Transferred Bytes"
|
||||
msgstr "Bytes Trasnferidos"
|
||||
|
||||
msgid "Wireless Information"
|
||||
msgstr "Informacion Inalambrica"
|
||||
msgid "Wireless Client"
|
||||
msgstr ""
|
||||
|
||||
msgid "Connected To"
|
||||
msgstr "Conectado a"
|
||||
|
@ -248,6 +251,9 @@ msgstr "Lista de Clientes"
|
|||
msgid "Interface"
|
||||
msgstr "Interfaz"
|
||||
|
||||
msgid "DNS Server"
|
||||
msgstr "Servidor DNS"
|
||||
|
||||
msgid "Starting IP Address"
|
||||
msgstr "Dirección IP de incio"
|
||||
|
||||
|
@ -318,31 +324,31 @@ msgid "Dnsmasq is not running"
|
|||
msgstr "Dnsmasq no esta iniciado"
|
||||
|
||||
msgid "Upstream DNS servers"
|
||||
msgstr "Upstream DNS servers"
|
||||
msgstr ""
|
||||
|
||||
msgid "Only ever query DNS servers configured below"
|
||||
msgstr "Only ever query DNS servers configured below"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable this option if you want RaspAP to <b>send DNS queries to the servers configured below exclusively</b>. By default RaspAP also uses its upstream DHCP server's name servers."
|
||||
msgstr "Enable this option if you want RaspAP to <b>send DNS queries to the servers configured below exclusively</b>. By default RaspAP also uses its upstream DHCP server's name servers."
|
||||
msgstr ""
|
||||
|
||||
msgid "This option adds <code>no-resolv</code> to the dnsmasq configuration."
|
||||
msgstr "This option adds <code>no-resolv</code> to the dnsmasq configuration."
|
||||
msgstr ""
|
||||
|
||||
msgid "Add upstream DNS server"
|
||||
msgstr "Add upstream DNS server"
|
||||
msgstr ""
|
||||
|
||||
msgid "Format"
|
||||
msgstr "Format"
|
||||
msgstr ""
|
||||
|
||||
msgid "Choose a hosted server"
|
||||
msgstr "Choose a hosted server"
|
||||
msgstr ""
|
||||
|
||||
msgid "Log DHCP requests"
|
||||
msgstr "Log DHCP requests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Log DNS queries"
|
||||
msgstr "Log DNS queries"
|
||||
msgstr ""
|
||||
|
||||
#: includes/hostapd.php
|
||||
msgid "Basic"
|
||||
|
@ -367,7 +373,7 @@ msgid "Encryption Type"
|
|||
msgstr "Tipo de Encriptacion"
|
||||
|
||||
msgid "PSK"
|
||||
msgstr "PSK"
|
||||
msgstr ""
|
||||
|
||||
msgid "Advanced settings"
|
||||
msgstr "Configuracion Avanzada"
|
||||
|
@ -426,6 +432,9 @@ msgstr "Salida del archivo de registro"
|
|||
msgid "WiFi client AP mode"
|
||||
msgstr "Modo AP de WiFi de cliente"
|
||||
|
||||
msgid "Bridged AP mode"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hide SSID in broadcast"
|
||||
msgstr "Ocultar SSID en la transmisión"
|
||||
|
||||
|
@ -445,9 +454,6 @@ msgstr "Configuracion Actual"
|
|||
msgid "Default Gateway"
|
||||
msgstr "Puerta de Enlace predeterminada"
|
||||
|
||||
msgid "DNS Server"
|
||||
msgstr "Servidor DNS"
|
||||
|
||||
msgid "Alternate DNS Server"
|
||||
msgstr "Servidor DNS Alterno"
|
||||
|
||||
|
@ -606,7 +612,7 @@ msgid "Diffie Hellman parameters"
|
|||
msgstr "Parámetros Diffie Hellman"
|
||||
|
||||
msgid "KeepAlive"
|
||||
msgstr "KeepAlive"
|
||||
msgstr ""
|
||||
|
||||
msgid "Server log"
|
||||
msgstr "Registro del servidor"
|
||||
|
@ -660,6 +666,10 @@ msgstr "Intentando iniciar TOR"
|
|||
msgid "Attempting to stop TOR"
|
||||
msgstr "Intentando detener TOR"
|
||||
|
||||
#: template/dashboard.php
|
||||
msgid "Bridged AP mode is enabled. For Hostname and IP, see your router's admin page."
|
||||
msgstr ""
|
||||
|
||||
#: common form controls
|
||||
msgid "Save settings"
|
||||
msgstr "Guardar Configuraciones"
|
||||
|
@ -682,3 +692,45 @@ msgstr "arriba"
|
|||
msgid "down"
|
||||
msgstr "abajo"
|
||||
|
||||
msgid "adblock"
|
||||
msgstr ""
|
||||
|
||||
msgid "Ad Blocking"
|
||||
msgstr ""
|
||||
|
||||
msgid "Start Ad Blocking"
|
||||
msgstr ""
|
||||
|
||||
msgid "Restart Ad Blocking"
|
||||
msgstr ""
|
||||
|
||||
msgid "Blocklist settings"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable blocklists"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable this option if you want RaspAP to <b>block DNS requests for ads, tracking and other virtual garbage</b>. Blocklists are gathered from multiple, actively maintained sources and automatically updated, cleaned, optimized and moderated on a daily basis."
|
||||
msgstr ""
|
||||
|
||||
msgid "This option adds <code>conf-file</code> and <code>addn-hosts</code> to the dnsmasq configuration."
|
||||
msgstr ""
|
||||
|
||||
msgid "Choose a blocklist provider"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hostnames blocklist last updated"
|
||||
msgstr ""
|
||||
|
||||
msgid "Domains blocklist last updated"
|
||||
msgstr ""
|
||||
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
msgid "Statistics"
|
||||
msgstr ""
|
||||
|
||||
msgid "Information provided by adblock"
|
||||
msgstr ""
|
||||
|
||||
|
|
Binary file not shown.
|
@ -1,26 +1,19 @@
|
|||
# RaspAP Portable Object file
|
||||
# Project home: https://github.com/billz/raspap-webgui
|
||||
# Licensed under the GNU General Public License v3.0
|
||||
# This file is distributed under the same license as the RaspAP package
|
||||
# FIRST AUTHOR billzimmerman@gmail.com, 2017
|
||||
#
|
||||
# Translators:
|
||||
# William Zimmerman <billzimmerman@gmail.com>, 2019
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 1.2.1\n"
|
||||
"Project-Id-Version: raspap\n"
|
||||
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
||||
"PO-Revision-Date: 2019-10-25 17:42+0000\n"
|
||||
"Last-Translator: William Zimmerman <billzimmerman@gmail.com>, 2019\n"
|
||||
"Language-Team: Japanese (https://www.transifex.com/na-360/teams/104285/ja/)\n"
|
||||
"PO-Revision-Date: 2020-04-17 06:37\n"
|
||||
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||
"Language-Team: Japanese\n"
|
||||
"Language: ja_JP\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ja\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Crowdin-Project: raspap\n"
|
||||
"X-Crowdin-Language: ja\n"
|
||||
"X-Crowdin-File: /master/locale/en_US/LC_MESSAGES/messages.po\n"
|
||||
|
||||
#: index.php
|
||||
msgid "RaspAP Wifi Configuration Portal"
|
||||
|
@ -41,6 +34,12 @@ msgstr "WiFiクライアント"
|
|||
msgid "Hotspot"
|
||||
msgstr "ホットスポット"
|
||||
|
||||
msgid "Memory Use"
|
||||
msgstr "メモリ使用率"
|
||||
|
||||
msgid "CPU Temp"
|
||||
msgstr "CPU温度"
|
||||
|
||||
msgid "Networking"
|
||||
msgstr "ネットワーク"
|
||||
|
||||
|
@ -115,9 +114,7 @@ msgstr "パスフレーズ"
|
|||
msgid "Wifi settings updated successfully"
|
||||
msgstr "Wifi設定が正常に更新されました"
|
||||
|
||||
msgid ""
|
||||
"Wifi settings updated but cannot restart (cannot execute 'wpa_cli "
|
||||
"reconfigure')"
|
||||
msgid "Wifi settings updated but cannot restart (cannot execute 'wpa_cli reconfigure')"
|
||||
msgstr "Wifi設定は更新されましたが、再起動できません(「wpa_cli reconfigure」を実行できません)"
|
||||
|
||||
msgid "Wifi settings failed to be updated"
|
||||
|
@ -147,11 +144,8 @@ msgstr "隠す"
|
|||
msgid "Not configured"
|
||||
msgstr "設定されていません"
|
||||
|
||||
msgid ""
|
||||
"<strong>Note:</strong> WEP access points appear as 'Open'. RaspAP does not "
|
||||
"currently support connecting to WEP"
|
||||
msgstr ""
|
||||
"<strong>注:</strong> WEPアクセスポイントは「オープン」と表示されます。RaspAPは現在、WEPへの接続をサポートしていません"
|
||||
msgid "<strong>Note:</strong> WEP access points appear as 'Open'. RaspAP does not currently support connecting to WEP"
|
||||
msgstr "<strong>注:</strong> WEPアクセスポイントは「オープン」と表示されます。RaspAPは現在、WEPへの接続をサポートしていません"
|
||||
|
||||
#: includes/dashboard.php
|
||||
msgid "Interface Information"
|
||||
|
@ -187,8 +181,8 @@ msgstr "転送されたパケット"
|
|||
msgid "Transferred Bytes"
|
||||
msgstr "転送されたバイト"
|
||||
|
||||
msgid "Wireless Information"
|
||||
msgstr "ワイヤレスの情報"
|
||||
msgid "Wireless Client"
|
||||
msgstr "無線クライアント"
|
||||
|
||||
msgid "Connected To"
|
||||
msgstr "接続"
|
||||
|
@ -330,31 +324,31 @@ msgid "Dnsmasq is not running"
|
|||
msgstr "Dnsmasqが実行されていません"
|
||||
|
||||
msgid "Upstream DNS servers"
|
||||
msgstr "Upstream DNS servers"
|
||||
msgstr "アップストリームDNSサーバー"
|
||||
|
||||
msgid "Only ever query DNS servers configured below"
|
||||
msgstr "Only ever query DNS servers configured below"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable this option if you want RaspAP to <b>send DNS queries to the servers configured below exclusively</b>. By default RaspAP also uses its upstream DHCP server's name servers."
|
||||
msgstr "Enable this option if you want RaspAP to <b>send DNS queries to the servers configured below exclusively</b>. By default RaspAP also uses its upstream DHCP server's name servers."
|
||||
msgstr ""
|
||||
|
||||
msgid "This option adds <code>no-resolv</code> to the dnsmasq configuration."
|
||||
msgstr "This option adds <code>no-resolv</code> to the dnsmasq configuration."
|
||||
msgstr ""
|
||||
|
||||
msgid "Add upstream DNS server"
|
||||
msgstr "Add upstream DNS server"
|
||||
msgstr "アップストリームDNSサーバーを追加"
|
||||
|
||||
msgid "Format"
|
||||
msgstr "Format"
|
||||
msgstr ""
|
||||
|
||||
msgid "Choose a hosted server"
|
||||
msgstr "Choose a hosted server"
|
||||
msgstr ""
|
||||
|
||||
msgid "Log DHCP requests"
|
||||
msgstr "Log DHCP requests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Log DNS queries"
|
||||
msgstr "Log DNS queries"
|
||||
msgstr ""
|
||||
|
||||
#: includes/hostapd.php
|
||||
msgid "Basic"
|
||||
|
@ -438,17 +432,17 @@ msgstr "ログファイル出力"
|
|||
msgid "WiFi client AP mode"
|
||||
msgstr "WiFiクライアントAPモード"
|
||||
|
||||
msgid "Bridged AP mode"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hide SSID in broadcast"
|
||||
msgstr "ブロードキャストでSSIDを非表示"
|
||||
|
||||
msgid "Maximum number of clients"
|
||||
msgstr "クライアントの最大数"
|
||||
|
||||
msgid ""
|
||||
"Configures the max_num_sta option of hostapd. The default and maximum is "
|
||||
"2007. If empty or 0, the default applies."
|
||||
msgstr ""
|
||||
"hostapdのmax_num_staオプションを構成します。 デフォルトおよび最大値は2007です。空欄または0の場合、デフォルトが適用されます。"
|
||||
msgid "Configures the max_num_sta option of hostapd. The default and maximum is 2007. If empty or 0, the default applies."
|
||||
msgstr "hostapdのmax_num_staオプションを構成します。 デフォルトおよび最大値は2007です。空欄または0の場合、デフォルトが適用されます。"
|
||||
|
||||
#: includes/networking.php
|
||||
msgid "Summary"
|
||||
|
@ -672,6 +666,10 @@ msgstr "TORを実行しようとしています"
|
|||
msgid "Attempting to stop TOR"
|
||||
msgstr "TORを停止しようとしています"
|
||||
|
||||
#: template/dashboard.php
|
||||
msgid "Bridged AP mode is enabled. For Hostname and IP, see your router's admin page."
|
||||
msgstr ""
|
||||
|
||||
#: common form controls
|
||||
msgid "Save settings"
|
||||
msgstr "設定を保存"
|
||||
|
@ -693,3 +691,46 @@ msgstr "上"
|
|||
|
||||
msgid "down"
|
||||
msgstr "下"
|
||||
|
||||
msgid "adblock"
|
||||
msgstr "adblock"
|
||||
|
||||
msgid "Ad Blocking"
|
||||
msgstr "広告ブロック"
|
||||
|
||||
msgid "Start Ad Blocking"
|
||||
msgstr "広告ブロックを開始する"
|
||||
|
||||
msgid "Restart Ad Blocking"
|
||||
msgstr "広告ブロックを再開する"
|
||||
|
||||
msgid "Blocklist settings"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable blocklists"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable this option if you want RaspAP to <b>block DNS requests for ads, tracking and other virtual garbage</b>. Blocklists are gathered from multiple, actively maintained sources and automatically updated, cleaned, optimized and moderated on a daily basis."
|
||||
msgstr ""
|
||||
|
||||
msgid "This option adds <code>conf-file</code> and <code>addn-hosts</code> to the dnsmasq configuration."
|
||||
msgstr ""
|
||||
|
||||
msgid "Choose a blocklist provider"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hostnames blocklist last updated"
|
||||
msgstr ""
|
||||
|
||||
msgid "Domains blocklist last updated"
|
||||
msgstr ""
|
||||
|
||||
msgid "Update now"
|
||||
msgstr "今すぐ更新する"
|
||||
|
||||
msgid "Statistics"
|
||||
msgstr "統計"
|
||||
|
||||
msgid "Information provided by adblock"
|
||||
msgstr ""
|
||||
|
||||
|
|
Binary file not shown.
|
@ -1,26 +1,19 @@
|
|||
# RaspAP Portable Object file
|
||||
# Project home: https://github.com/billz/raspap-webgui
|
||||
# Licensed under the GNU General Public License v3.0
|
||||
# This file is distributed under the same license as the RaspAP package
|
||||
# FIRST AUTHOR billzimmerman@gmail.com, 2017
|
||||
#
|
||||
# Translators:
|
||||
# William Zimmerman <billzimmerman@gmail.com>, 2019
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 1.2.1\n"
|
||||
"Project-Id-Version: raspap\n"
|
||||
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
||||
"PO-Revision-Date: 2019-10-25 17:42+0000\n"
|
||||
"Last-Translator: William Zimmerman <billzimmerman@gmail.com>, 2019\n"
|
||||
"Language-Team: Korean (https://www.transifex.com/na-360/teams/104285/ko/)\n"
|
||||
"PO-Revision-Date: 2020-04-14 08:51\n"
|
||||
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||
"Language-Team: Korean\n"
|
||||
"Language: ko_KR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ko\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Crowdin-Project: raspap\n"
|
||||
"X-Crowdin-Language: ko\n"
|
||||
"X-Crowdin-File: /master/locale/en_US/LC_MESSAGES/messages.po\n"
|
||||
|
||||
#: index.php
|
||||
msgid "RaspAP Wifi Configuration Portal"
|
||||
|
@ -41,6 +34,12 @@ msgstr "WiFi 클라이언트"
|
|||
msgid "Hotspot"
|
||||
msgstr "핫스팟"
|
||||
|
||||
msgid "Memory Use"
|
||||
msgstr ""
|
||||
|
||||
msgid "CPU Temp"
|
||||
msgstr ""
|
||||
|
||||
msgid "Networking"
|
||||
msgstr "네트워킹"
|
||||
|
||||
|
@ -101,7 +100,7 @@ msgid "Client settings"
|
|||
msgstr "클라이언트 설정 "
|
||||
|
||||
msgid "SSID"
|
||||
msgstr "SSID"
|
||||
msgstr ""
|
||||
|
||||
msgid "Channel"
|
||||
msgstr "채널 "
|
||||
|
@ -115,9 +114,7 @@ msgstr "암호 "
|
|||
msgid "Wifi settings updated successfully"
|
||||
msgstr "Wifi 설정이 성공적으로 업데이트되었습니다"
|
||||
|
||||
msgid ""
|
||||
"Wifi settings updated but cannot restart (cannot execute 'wpa_cli "
|
||||
"reconfigure')"
|
||||
msgid "Wifi settings updated but cannot restart (cannot execute 'wpa_cli reconfigure')"
|
||||
msgstr "Wifi 설정이 업데이트되었지만 재시작할 수 없습니다('wpa_cli reconfigure'를 실행할 수 없습니다)"
|
||||
|
||||
msgid "Wifi settings failed to be updated"
|
||||
|
@ -147,11 +144,8 @@ msgstr "숨기기 "
|
|||
msgid "Not configured"
|
||||
msgstr "환결설정 안됨"
|
||||
|
||||
msgid ""
|
||||
"<strong>Note:</strong> WEP access points appear as 'Open'. RaspAP does not "
|
||||
"currently support connecting to WEP"
|
||||
msgstr ""
|
||||
"<strong>주의:</strong> WEP 접근점은 'Open'으로 표시됩니다. RaspAP은 현재 WEP 연결을 지원하지 않습니다"
|
||||
msgid "<strong>Note:</strong> WEP access points appear as 'Open'. RaspAP does not currently support connecting to WEP"
|
||||
msgstr "<strong>주의:</strong> WEP 접근점은 'Open'으로 표시됩니다. RaspAP은 현재 WEP 연결을 지원하지 않습니다"
|
||||
|
||||
#: includes/dashboard.php
|
||||
msgid "Interface Information"
|
||||
|
@ -187,8 +181,8 @@ msgstr "전송된 패킷"
|
|||
msgid "Transferred Bytes"
|
||||
msgstr "전송된 바이트량"
|
||||
|
||||
msgid "Wireless Information"
|
||||
msgstr "무선 정보"
|
||||
msgid "Wireless Client"
|
||||
msgstr ""
|
||||
|
||||
msgid "Connected To"
|
||||
msgstr "연결"
|
||||
|
@ -330,31 +324,31 @@ msgid "Dnsmasq is not running"
|
|||
msgstr "Dnsmasq가 실행 중이 아닙니다 "
|
||||
|
||||
msgid "Upstream DNS servers"
|
||||
msgstr "Upstream DNS servers"
|
||||
msgstr ""
|
||||
|
||||
msgid "Only ever query DNS servers configured below"
|
||||
msgstr "Only ever query DNS servers configured below"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable this option if you want RaspAP to <b>send DNS queries to the servers configured below exclusively</b>. By default RaspAP also uses its upstream DHCP server's name servers."
|
||||
msgstr "Enable this option if you want RaspAP to <b>send DNS queries to the servers configured below exclusively</b>. By default RaspAP also uses its upstream DHCP server's name servers."
|
||||
msgstr ""
|
||||
|
||||
msgid "This option adds <code>no-resolv</code> to the dnsmasq configuration."
|
||||
msgstr "This option adds <code>no-resolv</code> to the dnsmasq configuration."
|
||||
msgstr ""
|
||||
|
||||
msgid "Add upstream DNS server"
|
||||
msgstr "Add upstream DNS server"
|
||||
msgstr ""
|
||||
|
||||
msgid "Format"
|
||||
msgstr "Format"
|
||||
msgstr ""
|
||||
|
||||
msgid "Choose a hosted server"
|
||||
msgstr "Choose a hosted server"
|
||||
msgstr ""
|
||||
|
||||
msgid "Log DHCP requests"
|
||||
msgstr "Log DHCP requests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Log DNS queries"
|
||||
msgstr "Log DNS queries"
|
||||
msgstr ""
|
||||
|
||||
#: includes/hostapd.php
|
||||
msgid "Basic"
|
||||
|
@ -379,7 +373,7 @@ msgid "Encryption Type"
|
|||
msgstr "암호화 유형"
|
||||
|
||||
msgid "PSK"
|
||||
msgstr "PSK"
|
||||
msgstr ""
|
||||
|
||||
msgid "Advanced settings"
|
||||
msgstr "고급 설정 "
|
||||
|
@ -438,18 +432,17 @@ msgstr "로그파일 출력"
|
|||
msgid "WiFi client AP mode"
|
||||
msgstr "WiFi 클라이언트 AP 모드 "
|
||||
|
||||
msgid "Bridged AP mode"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hide SSID in broadcast"
|
||||
msgstr "방송 중에 SSID 숨기기 "
|
||||
|
||||
msgid "Maximum number of clients"
|
||||
msgstr "클라이언트 최대 개수"
|
||||
|
||||
msgid ""
|
||||
"Configures the max_num_sta option of hostapd. The default and maximum is "
|
||||
"2007. If empty or 0, the default applies."
|
||||
msgstr ""
|
||||
"hostapd의 max_num_sta option을 구성합니다. 기본값 및 최대값은 2007입니다. 비었거나 0인 경우 기본값이 "
|
||||
"적용됩니다."
|
||||
msgid "Configures the max_num_sta option of hostapd. The default and maximum is 2007. If empty or 0, the default applies."
|
||||
msgstr "hostapd의 max_num_sta option을 구성합니다. 기본값 및 최대값은 2007입니다. 비었거나 0인 경우 기본값이 적용됩니다."
|
||||
|
||||
#: includes/networking.php
|
||||
msgid "Summary"
|
||||
|
@ -673,6 +666,10 @@ msgstr "TOR 시작 시도 중입니다 "
|
|||
msgid "Attempting to stop TOR"
|
||||
msgstr "TOR 중지 시도 중입니다 "
|
||||
|
||||
#: template/dashboard.php
|
||||
msgid "Bridged AP mode is enabled. For Hostname and IP, see your router's admin page."
|
||||
msgstr ""
|
||||
|
||||
#: common form controls
|
||||
msgid "Save settings"
|
||||
msgstr "설정 저장"
|
||||
|
@ -694,3 +691,46 @@ msgstr "작동"
|
|||
|
||||
msgid "down"
|
||||
msgstr "다운"
|
||||
|
||||
msgid "adblock"
|
||||
msgstr ""
|
||||
|
||||
msgid "Ad Blocking"
|
||||
msgstr ""
|
||||
|
||||
msgid "Start Ad Blocking"
|
||||
msgstr ""
|
||||
|
||||
msgid "Restart Ad Blocking"
|
||||
msgstr ""
|
||||
|
||||
msgid "Blocklist settings"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable blocklists"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable this option if you want RaspAP to <b>block DNS requests for ads, tracking and other virtual garbage</b>. Blocklists are gathered from multiple, actively maintained sources and automatically updated, cleaned, optimized and moderated on a daily basis."
|
||||
msgstr ""
|
||||
|
||||
msgid "This option adds <code>conf-file</code> and <code>addn-hosts</code> to the dnsmasq configuration."
|
||||
msgstr ""
|
||||
|
||||
msgid "Choose a blocklist provider"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hostnames blocklist last updated"
|
||||
msgstr ""
|
||||
|
||||
msgid "Domains blocklist last updated"
|
||||
msgstr ""
|
||||
|
||||
msgid "Update now"
|
||||
msgstr ""
|
||||
|
||||
msgid "Statistics"
|
||||
msgstr ""
|
||||
|
||||
msgid "Information provided by adblock"
|
||||
msgstr ""
|
||||
|
||||
|
|
BIN
locale/ro_RO/LC_MESSAGES/messages.mo
Normal file
BIN
locale/ro_RO/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
1206
locale/ro_RO/LC_MESSAGES/messages.po
Normal file
1206
locale/ro_RO/LC_MESSAGES/messages.po
Normal file
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
@ -3,8 +3,8 @@ msgstr ""
|
|||
"Project-Id-Version: raspap\n"
|
||||
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
||||
"PO-Revision-Date: 2020-05-19 15:29\n"
|
||||
"Last-Translator: Denis Trifiniuc\n"
|
||||
"PO-Revision-Date: 2020-04-14 08:51\n"
|
||||
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||
"Language-Team: Russian\n"
|
||||
"Language: ru_RU\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -35,10 +35,10 @@ msgid "Hotspot"
|
|||
msgstr "Точка доступа"
|
||||
|
||||
msgid "Memory Use"
|
||||
msgstr "Использование RAM"
|
||||
msgstr ""
|
||||
|
||||
msgid "CPU Temp"
|
||||
msgstr "Температура ЦП"
|
||||
msgstr ""
|
||||
|
||||
msgid "Networking"
|
||||
msgstr "Сетевые"
|
||||
|
@ -47,10 +47,10 @@ msgid "DHCP Server"
|
|||
msgstr "DHCP сервер"
|
||||
|
||||
msgid "OpenVPN"
|
||||
msgstr "OpenVPN"
|
||||
msgstr ""
|
||||
|
||||
msgid "TOR proxy"
|
||||
msgstr "TOR proxy"
|
||||
msgstr ""
|
||||
|
||||
msgid "Authentication"
|
||||
msgstr "авторизации"
|
||||
|
@ -100,7 +100,7 @@ msgid "Client settings"
|
|||
msgstr "Настройки клиента"
|
||||
|
||||
msgid "SSID"
|
||||
msgstr "SSID"
|
||||
msgstr ""
|
||||
|
||||
msgid "Channel"
|
||||
msgstr "Канал"
|
||||
|
@ -182,7 +182,7 @@ msgid "Transferred Bytes"
|
|||
msgstr "Передано Байт"
|
||||
|
||||
msgid "Wireless Client"
|
||||
msgstr "WiFi клиент"
|
||||
msgstr ""
|
||||
|
||||
msgid "Connected To"
|
||||
msgstr "Подключено к"
|
||||
|
@ -324,31 +324,31 @@ msgid "Dnsmasq is not running"
|
|||
msgstr "Dnsmasq не запущена"
|
||||
|
||||
msgid "Upstream DNS servers"
|
||||
msgstr "Пользовательские DNS-серверы"
|
||||
msgstr ""
|
||||
|
||||
msgid "Only ever query DNS servers configured below"
|
||||
msgstr "Использовать только DNS-серверы, настроенные ниже"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable this option if you want RaspAP to <b>send DNS queries to the servers configured below exclusively</b>. By default RaspAP also uses its upstream DHCP server's name servers."
|
||||
msgstr "Включите эту опцию, если вы хотите, чтобы RaspAP <b>отправлял DNS-запросы только на серверы, настроенные ниже</b>. По умолчанию RaspAP также использует восходящие DNS-серверы, назначенные через DHCP."
|
||||
msgstr ""
|
||||
|
||||
msgid "This option adds <code>no-resolv</code> to the dnsmasq configuration."
|
||||
msgstr "Этот параметр добавляет <code>no-resolv</code> в конфигурацию dnsmasq."
|
||||
msgstr ""
|
||||
|
||||
msgid "Add upstream DNS server"
|
||||
msgstr "Добавить сервер DNS"
|
||||
msgstr ""
|
||||
|
||||
msgid "Format"
|
||||
msgstr "Формат"
|
||||
msgstr ""
|
||||
|
||||
msgid "Choose a hosted server"
|
||||
msgstr "Общедоступный DNS-сервер"
|
||||
msgstr ""
|
||||
|
||||
msgid "Log DHCP requests"
|
||||
msgstr "Журнал DHCP-запросов"
|
||||
msgstr ""
|
||||
|
||||
msgid "Log DNS queries"
|
||||
msgstr "Журнал DNS-запросов"
|
||||
msgstr ""
|
||||
|
||||
#: includes/hostapd.php
|
||||
msgid "Basic"
|
||||
|
@ -373,7 +373,7 @@ msgid "Encryption Type"
|
|||
msgstr "Тип шифрования"
|
||||
|
||||
msgid "PSK"
|
||||
msgstr "PSK"
|
||||
msgstr ""
|
||||
|
||||
msgid "Advanced settings"
|
||||
msgstr "Расширенные настройки"
|
||||
|
@ -433,7 +433,7 @@ msgid "WiFi client AP mode"
|
|||
msgstr "Режим AP WiFi-клиента"
|
||||
|
||||
msgid "Bridged AP mode"
|
||||
msgstr "Режим моста ТОЧКИ ДОСТУПА"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hide SSID in broadcast"
|
||||
msgstr "Скрыть SSID при трансляции"
|
||||
|
@ -668,7 +668,7 @@ msgstr "Попытка остановить TOR"
|
|||
|
||||
#: template/dashboard.php
|
||||
msgid "Bridged AP mode is enabled. For Hostname and IP, see your router's admin page."
|
||||
msgstr "Мостовой режим ТОЧКИ ДОСТУПА включен. Для хоста и IP-адреса см. страницу администрирования маршрутизатора."
|
||||
msgstr ""
|
||||
|
||||
#: common form controls
|
||||
msgid "Save settings"
|
||||
|
@ -693,44 +693,44 @@ msgid "down"
|
|||
msgstr "вниз"
|
||||
|
||||
msgid "adblock"
|
||||
msgstr "Adblock"
|
||||
msgstr ""
|
||||
|
||||
msgid "Ad Blocking"
|
||||
msgstr "Ad Blocking"
|
||||
msgstr ""
|
||||
|
||||
msgid "Start Ad Blocking"
|
||||
msgstr "Запустить Ad Blocking"
|
||||
msgstr ""
|
||||
|
||||
msgid "Restart Ad Blocking"
|
||||
msgstr "Перезапустить Ad Blocking"
|
||||
msgstr ""
|
||||
|
||||
msgid "Blocklist settings"
|
||||
msgstr "Настройки блокировки"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable blocklists"
|
||||
msgstr "Включить блокировку"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable this option if you want RaspAP to <b>block DNS requests for ads, tracking and other virtual garbage</b>. Blocklists are gathered from multiple, actively maintained sources and automatically updated, cleaned, optimized and moderated on a daily basis."
|
||||
msgstr "Включите эту опцию, если вы хотите, чтобы RaspAP <b>блокировал DNS запросы для рекламы, отслеживания и другого виртуального мусора</b>. Блокирующие списки собираются из множества активно поддерживаемых источников и автоматически обновляются, очищаются, оптимизируются и модерируются ежедневно."
|
||||
msgstr ""
|
||||
|
||||
msgid "This option adds <code>conf-file</code> and <code>addn-hosts</code> to the dnsmasq configuration."
|
||||
msgstr "Эта опция добавляет в конфигурацию dnsmasq <code>conf-file</code> и <code>addn-hosts</code>."
|
||||
msgstr ""
|
||||
|
||||
msgid "Choose a blocklist provider"
|
||||
msgstr "Выберите поставщика черного списка"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hostnames blocklist last updated"
|
||||
msgstr "Имена черного списка последнее обновление"
|
||||
msgstr ""
|
||||
|
||||
msgid "Domains blocklist last updated"
|
||||
msgstr "Последнее обновление списка блокировки доменов"
|
||||
msgstr ""
|
||||
|
||||
msgid "Update now"
|
||||
msgstr "Обновить сейчас"
|
||||
msgstr ""
|
||||
|
||||
msgid "Statistics"
|
||||
msgstr "Статистика"
|
||||
msgstr ""
|
||||
|
||||
msgid "Information provided by adblock"
|
||||
msgstr "Информация получена от Adblock"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
<div class="form-group col-md-8 mt-2">
|
||||
<?php
|
||||
if ($conf['log-dhcp'] == 1 || $conf['log-queries'] == 1) {
|
||||
exec('sudo chmod o+r /tmp/dnsmasq.log');
|
||||
$log = file_get_contents('/tmp/dnsmasq.log');
|
||||
exec('sudo /bin/chmod o+r '.RASPI_DHCPCD_LOG);
|
||||
$log = file_get_contents(RASPI_DHCPCD_LOG);
|
||||
echo '<textarea class="logoutput">'.htmlspecialchars($log, ENT_QUOTES).'</textarea>';
|
||||
} else {
|
||||
echo '<textarea class="logoutput my-3"></textarea>';
|
||||
|
|
|
@ -1,58 +1,79 @@
|
|||
<!-- static leases tab -->
|
||||
<div class="tab-pane fade" id="static-leases">
|
||||
<h4 class="mt-3 mb-3"><?php echo _("Static leases") ?></h4>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h4 class="mt-3 mb-3"><?php echo _("Static leases") ?></h4>
|
||||
<p id="static-lease-description">
|
||||
<small><?php echo _("Clients with a particular hardware MAC address can always be allocated the same IP address.") ?></small>
|
||||
<small class="text-muted"><?php echo _("This option adds <code>dhcp-host</code> entries to the dnsmasq configuration.") ?></small>
|
||||
</p>
|
||||
<div class="dhcp-static-leases js-dhcp-static-lease-container">
|
||||
<?php foreach ($hosts as $host) : ?>
|
||||
<?php list($host, $comment) = array_map("trim", explode("#", $host)); ?>
|
||||
<?php list($mac, $ip) = array_map("trim", explode(",", $host)); ?>
|
||||
<div class="row dhcp-static-lease-row js-dhcp-static-lease-row">
|
||||
<div class="col-md-4 col-xs-3">
|
||||
<input type="text" name="static_leases[mac][]" value="<?php echo htmlspecialchars($mac, ENT_QUOTES) ?>" placeholder="<?php echo _("MAC address") ?>" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-3 col-xs-3">
|
||||
<input type="text" name="static_leases[ip][]" value="<?php echo htmlspecialchars($ip, ENT_QUOTES) ?>" placeholder="<?php echo _("IP address") ?>" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-3 col-xs-3">
|
||||
<input type="text" name="static_leases[comment][]" value="<?php echo htmlspecialchars($comment, ENT_QUOTES) ?>" placeholder="<?php echo _("Optional comment") ?>" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-2 col-xs-3">
|
||||
<button type="button" class="btn btn-outline-danger js-remove-dhcp-static-lease"><i class="far fa-trash-alt"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
|
||||
<div class="dhcp-static-leases js-dhcp-static-lease-container">
|
||||
<?php foreach ($hosts as $host) : ?>
|
||||
<?php list($host, $comment) = array_map("trim", explode("#", $host)); ?>
|
||||
<?php list($mac, $ip) = array_map("trim", explode(",", $host)); ?>
|
||||
<div class="row dhcp-static-lease-row js-dhcp-static-lease-row">
|
||||
<div class="row dhcp-static-lease-row js-new-dhcp-static-lease">
|
||||
<div class="col-md-4 col-xs-3">
|
||||
<input type="text" name="static_leases[mac][]" value="<?php echo htmlspecialchars($mac, ENT_QUOTES) ?>" placeholder="<?php echo _("MAC address") ?>" class="form-control">
|
||||
<input type="text" name="mac" value="" placeholder="<?php echo _("MAC address") ?>" class="form-control" autofocus="autofocus">
|
||||
</div>
|
||||
<div class="col-md-3 col-xs-3">
|
||||
<input type="text" name="static_leases[ip][]" value="<?php echo htmlspecialchars($ip, ENT_QUOTES) ?>" placeholder="<?php echo _("IP address") ?>" class="form-control">
|
||||
<input type="text" name="ip" value="" placeholder="<?php echo _("IP address") ?>" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-3 col-xs-3">
|
||||
<input type="text" name="static_leases[comment][]" value="<?php echo htmlspecialchars($comment, ENT_QUOTES) ?>" placeholder="<?php echo _("Optional comment") ?>" class="form-control">
|
||||
<input type="text" name="comment" value="" placeholder="<?php echo _("Optional comment") ?>" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-2 col-xs-3">
|
||||
<button type="button" class="btn btn-danger js-remove-dhcp-static-lease"><?php echo _("Remove") ?></button>
|
||||
<button type="button" class="btn btn-outline-success js-add-dhcp-static-lease"><i class="far fa-plus-square"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
|
||||
<h5 class="mt-3 mb-3"><?php echo _("Add static DHCP lease") ?></h5>
|
||||
<div class="row dhcp-static-lease-row js-new-dhcp-static-lease">
|
||||
<div class="col-md-4 col-xs-3">
|
||||
<input type="text" name="mac" value="" placeholder="<?php echo _("MAC address") ?>" class="form-control" autofocus="autofocus">
|
||||
</div>
|
||||
<div class="col-md-3 col-xs-3">
|
||||
<input type="text" name="ip" value="" placeholder="<?php echo _("IP address") ?>" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-3 col-xs-3">
|
||||
<input type="text" name="comment" value="" placeholder="<?php echo _("Optional comment") ?>" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-2 col-xs-3">
|
||||
<button type="button" class="btn btn-success js-add-dhcp-static-lease"><?php echo _("Add") ?></button>
|
||||
</div>
|
||||
</div>
|
||||
<h5 class="mt-3 mb-3"><?php echo _("Restrict access") ?></h5>
|
||||
<div class="input-group">
|
||||
<input type="hidden" name="dhcp-ignore" value="0">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" id="dhcp-ignore" type="checkbox" name="dhcp-ignore" value="1" <?php echo $conf['dhcp-ignore'] ? ' checked="checked"' : "" ?> aria-describedby="dhcp-ignore-description">
|
||||
<label class="custom-control-label" for="dhcp-ignore"><?php echo _("Limit network access to static clients") ?></label>
|
||||
</div>
|
||||
<p id="dhcp-ignore-description">
|
||||
<small><?php echo _("Enable this option if you want RaspAP to <b>ignore any clients</b> which are not specified in the static leases list.") ?></small>
|
||||
<small class="text-muted"><?php echo _("This option adds <code>dhcp-ignore</code> to the dnsmasq configuration.") ?></small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template id="js-dhcp-static-lease-row">
|
||||
<div class="row dhcp-static-lease-row js-dhcp-static-lease-row">
|
||||
<div class="col-md-4 col-xs-3">
|
||||
<input type="text" name="static_leases[mac][]" value="{{ mac }}" placeholder="<?php echo _("MAC address") ?>" class="form-control">
|
||||
<template id="js-dhcp-static-lease-row">
|
||||
<div class="row dhcp-static-lease-row js-dhcp-static-lease-row">
|
||||
<div class="col-md-4 col-xs-3">
|
||||
<input type="text" name="static_leases[mac][]" value="{{ mac }}" placeholder="<?php echo _("MAC address") ?>" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-3 col-xs-3">
|
||||
<input type="text" name="static_leases[ip][]" value="{{ ip }}" placeholder="<?php echo _("IP address") ?>" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-3 col-xs-3">
|
||||
<input type="text" name="static_leases[comment][]" value="{{ comment }}" placeholder="<?php echo _("Optional comment") ?>" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-2 col-xs-3">
|
||||
<button type="button" class="btn btn-outline-danger js-remove-dhcp-static-lease"><i class="far fa-trash-alt"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 col-xs-3">
|
||||
<input type="text" name="static_leases[ip][]" value="{{ ip }}" placeholder="<?php echo _("IP address") ?>" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-3 col-xs-3">
|
||||
<input type="text" name="static_leases[comment][]" value="{{ comment }}" placeholder="<?php echo _("Optional comment") ?>" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-2 col-xs-3">
|
||||
<button type="button" class="btn btn-warning js-remove-dhcp-static-lease"><?php echo _("Remove") ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
</div><!-- /.tab-pane -->
|
||||
|
||||
|
|
110
templates/firewall.php
Executable file
110
templates/firewall.php
Executable file
|
@ -0,0 +1,110 @@
|
|||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<i class="fas fa-shield-alt mr-2"></i><?php echo _("Firewall"); ?>
|
||||
</div>
|
||||
</div><!-- /.row -->
|
||||
</div><!-- /.card-header -->
|
||||
<div class="card-body">
|
||||
<?php $status->showMessages(); ?>
|
||||
<h4><?php echo _("Client Firewall"); ?></h4>
|
||||
<?php if ( $fw_conf["firewall-enable"]) : ?>
|
||||
<i class="fas fa-circle mr-2 service-status-up"></i><?php echo _("Firewall is ENABLED"); ?>
|
||||
<?php else : ?>
|
||||
<i class="fas fa-circle mr-2 service-status-down"></i><?php echo _("Firewall is OFF"); ?>
|
||||
<?php endif ?>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p class="mr-2">
|
||||
<small>
|
||||
<?php echo _("The default firewall will only allow outgoing and already established traffic."); ?><br />
|
||||
<?php echo _("No incoming UDP traffic is allowed."); ?><br />
|
||||
<?php printf(_("There are no restrictions for the access point <code>%s</code>."), $ap_device); ?>
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<form id="frm-firewall" action="firewall_conf" method="POST" >
|
||||
<?php echo CSRFTokenFieldTag(); ?>
|
||||
<h5><?php echo _("Exception: Service"); ?></h4>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" id="ssh-enable" type="checkbox" name="ssh-enable" value="1" aria-describedby="exception-description" <?php if ($fw_conf["ssh-enable"]) echo "checked"; ?> >
|
||||
<label class="custom-control-label" for="ssh-enable"><?php echo _("allow SSH access on port 22") ?></label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" id="http-enable" type="checkbox" name="http-enable" value="1" aria-describedby="exceptions-description" <?php if ($fw_conf["http-enable"]) echo "checked"; ?> >
|
||||
<label class="custom-control-label" for="http-enable"><?php echo _("allow access to the RaspAP GUI on port 80 or 443") ?></label>
|
||||
</div>
|
||||
<p class="mb-0" id="exceptions-description">
|
||||
<small><?php echo _("Allow incoming connections for some services from the internet side.") ?></small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<h5><?php echo _("Exception: network device"); ?></h4>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="excl-device"><?php echo _("Exclude device(s)") ?></label>
|
||||
<input class="form-control" id="excl-devices" type="text" name="excl-devices" value="<?php echo $fw_conf["excl-devices"] ?>" aria-describedby="exclusion-description" >
|
||||
<p class="mb-0" id="exclusion-description">
|
||||
<small>
|
||||
<?php echo _("Exclude the given network device(s) (separated by a blank or comma) from firewall rules."); ?><br />
|
||||
<?php printf(_("Current client devices: <code>%s</code>"), $str_clients); ?><br />
|
||||
<?php printf(_("The access point <code>%s</code> is per default excluded."), $ap_device); ?>
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<h5><?php echo _("Exception: IP-Address"); ?></h4>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="excluded-ips"><?php echo _("Allow incoming connections from") ?></label>
|
||||
<input class="form-control" id="excluded-ips" type="text" name="excluded-ips" value="<?php echo $fw_conf["excluded-ips"] ?>" aria-describedby="excl-ips-description" >
|
||||
<p class="mb-0" id="excl-ips-description">
|
||||
<small>
|
||||
<?php echo _("For the given IP-addresses (separated by a blank or comma) the incoming connection (via TCP and UDP) is accepted."); ?><br />
|
||||
<?php echo _("This is required for an OpenVPN via UDP or Wireguard connection."); ?><br />
|
||||
<?php if ( !empty($vpn_ips) ) printf (_("The list of configured VPN server IP addresses: <code><b>%s</b></code>"), $vpn_ips); ?>
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($fw_conf["firewall-enable"]) : ?>
|
||||
<input type="submit" class="btn btn-outline btn-primary" value="<?php echo _("Apply changes"); ?>" name="apply-firewall" />
|
||||
<input type="submit" class="btn btn-warning firewall-apply" value="<?php echo _("Disable Firewall") ?>" name="firewall-disable" data-toggle="modal" data-target="#firewallModal"/>
|
||||
<?php else : ?>
|
||||
<input type="submit" class="btn btn-outline btn-primary" value="<?php echo _("Save settings"); ?>" name="save-firewall" />
|
||||
<input type="submit" class="btn btn-success firewall-apply" value="<?php echo _("Enable Firewall") ?>" name="firewall-enable" data-toggle="modal" data-target="#firewallModal"/>
|
||||
<?php endif ?>
|
||||
</form>
|
||||
</div><!-- /.card-body -->
|
||||
<div class="card-footer"></div>
|
||||
</div><!-- /.card -->
|
||||
</div><!-- /.col-lg-12 -->
|
||||
</div><!-- /.row -->
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="firewallModal" 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="fas fa-sync-alt mr-2"></i><?php echo _("Executing firewall option") ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="col-md-12 mb-3 mt-1">
|
||||
<?php if($fw_conf["firewall-enable"]) echo _("Disabling firewall").'...'; else echo _("Enabling firewall").'...'; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline btn-primary" data-dismiss="modal"><?php echo _("Close"); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -52,11 +52,22 @@
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="cbxtxpower"><?php echo _("Transmit power (dBm)") ?></label>
|
||||
<i class="fas fa-question-circle text-muted" data-toggle="tooltip" data-placement="auto" title="<?php echo _("dBm is a unit of level used to indicate that a power ratio is expressed in decibels (dB) with reference to one milliwatt (mW). 30 dBm is equal to 1000 mW, while 0 dBm equals 1.25 mW."); ?>"></i>
|
||||
<?php
|
||||
SelectorOptions('txpower', $arrTxPower, $txpower, 'cbxtxpower');
|
||||
?>
|
||||
<small id="txpower_help" class="text-muted"><?php echo _("Sets the <code>txpower</code> option for the AP interface and the configured country."); ?></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="max_num_sta"><?php echo _("Maximum number of clients") ?></label>
|
||||
<input type="text" id="max_num_sta" class="form-control" name="max_num_sta" placeholder="2007" value="<?php echo $arrConfig["max_num_sta"] ?>" aria-describedby="max_num_sta_help">
|
||||
<small id="max_num_sta_help" class="text-muted"><?php echo _("Configures the max_num_sta option of hostapd. The default and maximum is 2007. If empty or 0, the default applies.") ?></small>
|
||||
<small id="max_num_sta_help" class="text-muted"><?php echo _("Configures the <code>max_num_sta</code> option of hostapd. The default and maximum is 2007. If empty or 0, the default applies.") ?></small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
|
|
@ -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,72 +33,58 @@
|
|||
<!-- 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 mb-2">
|
||||
<div class="col-lg-12 mt-2 mb-2">
|
||||
<div class="row ml-1">
|
||||
<div class="info-item col-xs-3"><?php echo _("IPv4 Address"); ?></div>
|
||||
<div class="info-value col-xs-3"><?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>
|
||||
<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/no-trace-200x200.png" class="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><!-- /.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>
|
||||
|
||||
|
|
35
templates/openvpn/configs.php
Normal file
35
templates/openvpn/configs.php
Normal 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 == $conf_default) {
|
||||
$btn_class = "active";
|
||||
} else {
|
||||
$btn_class = "disabled";
|
||||
}
|
||||
$label = preg_replace('/_client$/','',pathinfo($client, PATHINFO_FILENAME));
|
||||
$client = $label;
|
||||
?>
|
||||
<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>
|
70
templates/openvpn/general.php
Normal file
70
templates/openvpn/general.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<div class="tab-pane active" id="openvpnclient">
|
||||
<h4 class="mt-3"><?php echo _("Client settings"); ?></h4>
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<div class="row mb-2">
|
||||
<div class="col-lg-12 mt-2 mb-2">
|
||||
<div class="row ml-1">
|
||||
<div class="info-item col-xs-3"><?php echo _("IPv4 Address"); ?></div>
|
||||
<div class="info-value col-xs-3"><?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>
|
||||
<h5><?php echo _("Authentification Method"); ?></h5>
|
||||
<div class="col-sm-12 mt-2 mb-2 form-check">
|
||||
<input class="form-check-input" id="ovpn-userpw" name="sel1" value="userpw" data-toggle="" data-parent="#clientsettings" data-target="#UserPW" type="radio" checked>
|
||||
<label class="form-check-label"><?php echo _("Username and password"); ?></label>
|
||||
</div>
|
||||
<div class="col-sm-12 mt-2 mb-2 form-check">
|
||||
<input class="form-check-input" id="ovpn-certs" name="sel1" value="certs" data-toggle="" data-parent="#clientsettings" data-target="#Certs" type="radio">
|
||||
<label class="form-check-label"><?php echo _("Certificates"); ?></label>
|
||||
</div>
|
||||
<div class="col-sm-12 ml-2">
|
||||
<div class="panel-group" id="clientsettings">
|
||||
<div class="panel panel-default panel-collapse" id="PanelUserPW" >
|
||||
<div class="panel-heading">
|
||||
<h5 class="panel-title"><?php echo _("Enter username and password"); ?></h5>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<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 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><!-- panel -->
|
||||
<div class="panel panel-default panel-collapse collapse in" id="PanelCerts">
|
||||
<div class="panel-body">
|
||||
<div class="panel-heading">
|
||||
<h5 class="panel-title"><?php echo _("Certificates in the configuration file"); ?></h5>
|
||||
</div>
|
||||
<p><?php echo _("RaspAP supports certificates by including them in the configuration file."); ?>
|
||||
<ul>
|
||||
<small>
|
||||
<li><?php echo _("Signing certification authority (CA) certificate (e.g. <code>ca.crt</code>): enclosed in <code><ca> ... </ca></code> tags."); ?></li>
|
||||
<li><?php echo _("Client certificate (public key) (e.g. <code>client.crt</code>): enclosed in <code><cert> ... </cert></code> tags."); ?></li>
|
||||
<li><?php echo _("Private key of the client certificate (e.g. <code>client.key</code>): enclosed in <code><key> ... </key></code> tags."); ?></li>
|
||||
</small>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
</div> <!-- panel -->
|
||||
</div> <!-- panel-group -->
|
||||
</div> <!-- col -->
|
||||
<div class="col-sm-12 ">
|
||||
<div class="form-group">
|
||||
<h5 class="panel-title"><?php echo _("Configuration File"); ?></h4>
|
||||
<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> <!-- col -->
|
||||
</div><!-- col-8 -->
|
||||
<div class="col-sm-auto"></div>
|
||||
</div><!-- /.row -->
|
||||
</div><!-- /.tab-pane | general tab -->
|
||||
|
16
templates/openvpn/logging.php
Normal file
16
templates/openvpn/logging.php
Normal 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 -->
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
</div>
|
||||
<div class="col-xs-3 col-sm-3">
|
||||
<label for="code"><?php echo _("Color"); ?></label>
|
||||
<input class="form-control color-input" value="#d8224c" aria-label="color" />
|
||||
<input class="form-control color-input" value="#2b8080" aria-label="color" />
|
||||
</div>
|
||||
</div>
|
||||
<form action="system_info" method="POST">
|
||||
|
|
0
templates/torproxy.php
Normal file → Executable file
0
templates/torproxy.php
Normal file → Executable file
108
templates/wg/general.php
Normal file
108
templates/wg/general.php
Normal file
|
@ -0,0 +1,108 @@
|
|||
<!-- wireguard settings tab -->
|
||||
<div class="tab-pane active" id="wgsettings">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<h4 class="mt-3"><?php echo _("Tunnel settings"); ?></h4>
|
||||
<div class="col-lg-12 mt-2">
|
||||
<div class="row mt-3 mb-2">
|
||||
<div class="info-item col-xs-3"><?php echo _("IPv4 Address"); ?></div>
|
||||
<div class="info-value col-xs-3"><?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>
|
||||
<h5><?php echo _("Configuration Method"); ?></h5>
|
||||
<div class="col-sm-12 mt-2 mb-2 form-check">
|
||||
<input class="form-check-input" id="wg-upload" name="wgCnfOpt" value="upload" data-toggle="" data-parent="#serversettings" data-target="#wgUpload" type="radio" checked>
|
||||
<label class="form-check-label"><?php echo _("Upload file"); ?></label>
|
||||
</div>
|
||||
<div class="col-sm-12 mt-2 mb-2 form-check">
|
||||
<input class="form-check-input" id="wg-manual" name="wgCnfOpt" value="manual" data-toggle="" data-parent="#serversettings" data-target="#wgManual" type="radio">
|
||||
<label class="form-check-label"><?php echo _("Create manually"); ?></label>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 ml-2">
|
||||
<div class="panel-group" id="serversettings">
|
||||
|
||||
<div class="panel panel-default panel-collapse" id="PanelUpload">
|
||||
<div class="panel-heading">
|
||||
<h5 class="panel-title"><?php echo _("Upload a WireGuard config"); ?></h5>
|
||||
<p id="wg-description">
|
||||
<small><?php echo _("This option uploads and installs an existing WireGuard <code>.conf</code> file on this device.") ?></small>
|
||||
</p>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<?php $checked = $optRules == 1 ? 'checked="checked"' : '' ?>
|
||||
<input class="custom-control-input" id="chxwgrules" name="wgRules" type="checkbox" value="1" <?php echo $checked ?> />
|
||||
<label class="custom-control-label" for="chxwgrules"><?php echo _("Apply iptables rules for AP interface"); ?></label>
|
||||
<i class="fas fa-question-circle text-muted" data-toggle="tooltip" data-placement="auto" title="<?php echo _("Recommended if you wish to forward network traffic from the wg0 interface to clients connected on the AP interface."); ?>"></i>
|
||||
<p id="wg-description">
|
||||
<small><?php printf(_("This option adds <strong>iptables</strong> <code>Postup</code> and <code>PostDown</code> rules for the configured AP interface (%s)."), $_SESSION['ap_interface']) ?></small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<h5 class="panel-title"><?php echo _("Configuration File"); ?></h4>
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" name="wgFile" id="wgFile">
|
||||
<label class="custom-file-label" for="wgFile"><?php echo _("Select WireGuard configuration file (.conf)"); ?></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2"></div>
|
||||
|
||||
</div><!-- /.panel-body -->
|
||||
</div><!-- /.panel -->
|
||||
|
||||
<div class="panel panel-default panel-collapse" id="PanelManual">
|
||||
<div class="panel-heading">
|
||||
<h5 class="panel-title"><?php echo _("Create a local WireGuard config"); ?></h5>
|
||||
<div class="input-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" id="server_enabled" type="checkbox" name="wgSrvEnable" value="1" <?php echo $wg_senabled ? ' checked="checked"' : "" ?> aria-describedby="server-description">
|
||||
<label class="custom-control-label" for="server_enabled"><?php echo _("Enable server") ?></label>
|
||||
</div>
|
||||
<p id="wg-description">
|
||||
<small>
|
||||
<?php echo _("Enable this option to secure network traffic by creating an encrypted tunnel between RaspAP and configured peers.") ?>
|
||||
<?php echo _("This setting generates a new WireGuard <code>.conf</code> file on this device.") ?>
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<label for="code"><?php echo _("Local public key"); ?></label>
|
||||
<div class="input-group col-md-12 mb-3">
|
||||
<input type="text" class="form-control" name="wg-server" id="wg-srvpubkey" value="<?php echo htmlspecialchars($wg_srvpubkey, ENT_QUOTES); ?>" />
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary rounded-right wg-keygen" type="button"><i class="fas fa-magic"></i></button>
|
||||
<span id="wg-server-pubkey-status" class="input-group-addon check-hidden ml-2 mt-1"><i class="fas fa-check"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-xs-3 col-sm-3">
|
||||
<label for="code"><?php echo _("Local Port"); ?></label>
|
||||
<input type="text" class="form-control" name="wg_srvport" value="<?php echo htmlspecialchars($wg_srvport, ENT_QUOTES); ?>" />
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="code"><?php echo _("IP Address"); ?></label>
|
||||
<input type="text" class="form-control" name="wg_srvipaddress" value="<?php echo htmlspecialchars($wg_srvipaddress, ENT_QUOTES); ?>" />
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="code"><?php echo _("DNS"); ?></label>
|
||||
<input type="text" class="form-control" name="wg_srvdns" value="<?php echo htmlspecialchars($wg_srvdns, ENT_QUOTES); ?>" />
|
||||
</div>
|
||||
<div class="row mb-3"></div>
|
||||
|
||||
</div><!-- /.panel-body -->
|
||||
</div><!-- /.panel -->
|
||||
|
||||
</div><!-- /.panel-group -->
|
||||
</div><!-- /.col -->
|
||||
</div><!-- /.row -->
|
||||
|
||||
</div><!-- /.tab-pane | settings tab -->
|
||||
|
19
templates/wg/logging.php
Normal file
19
templates/wg/logging.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<!-- wireguard logging tab -->
|
||||
<div class="tab-pane fade" id="wglogging">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h4 class="mt-3"><?php echo _("Logging"); ?></h4>
|
||||
<p><?php echo _("Enable this option to display an updated <code>wg-quick</code> debug log.") ?></p>
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" id="wgLogEnable" type="checkbox" name="wgLogEnable" value="1" <?php echo $optLogEnable ? ' checked="checked"' : "" ?> aria-describedby="wgLogEnable">
|
||||
<label class="custom-control-label" for="wgLogEnable"><?php echo _("Logfile output") ?></label>
|
||||
</div>
|
||||
<?php
|
||||
exec('sudo chmod o+r /tmp/wireguard.log');
|
||||
$log = file_get_contents('/tmp/wireguard.log');
|
||||
echo '<textarea class="logoutput my-3">'.htmlspecialchars($log, ENT_QUOTES).'</textarea>';
|
||||
?>
|
||||
</div>
|
||||
</div><!-- /.row -->
|
||||
</div><!-- /.tab-pane | logging tab -->
|
||||
|
82
templates/wg/peers.php
Normal file
82
templates/wg/peers.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<!-- wireguard peers tab -->
|
||||
<div class="tab-pane fade" id="wgpeers">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h4 class="mt-3"><?php echo _("Peer"); ?></h4>
|
||||
<div class="input-group">
|
||||
<input type="hidden" name="peer_id" value="1">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" id="peer_enabled" type="checkbox" name="wg_penabled" value="1" <?php echo $wg_penabled ? ' checked="checked"' : "" ?> aria-describedby="endpoint-description">
|
||||
<label class="custom-control-label" for="peer_enabled"><?php echo _("Enable peer") ?></label>
|
||||
</div>
|
||||
<p id="wg-description">
|
||||
<small><?php echo _("Enable this option to encrypt traffic by creating a tunnel between RaspAP and this peer.") ?></small>
|
||||
<small><?php echo _("This option adds <code>client.conf</code> to the WireGuard configuration.") ?></small>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-sm-6 mt-3">
|
||||
<label for="code"><?php echo _("Peer public key"); ?></label>
|
||||
</div>
|
||||
<div class="input-group col-md-12">
|
||||
<input type="text" class="form-control" name="wg-peer" id="wg-peerpubkey" value="<?php echo htmlspecialchars($wg_peerpubkey, ENT_QUOTES); ?>" />
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary rounded-right wg-keygen" type="button"><i class="fas fa-magic"></i></button>
|
||||
<span id="wg-peer-pubkey-status" class="input-group-addon check-hidden ml-2 mt-1"><i class="fas fa-check"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-group col-xs-3 col-sm-3 mt-3">
|
||||
<label for="code"><?php echo _("Local Port"); ?></label>
|
||||
<input type="text" class="form-control" name="wg_plistenport" value="<?php echo htmlspecialchars($wg_plistenport, ENT_QUOTES); ?>" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-group col-xs-3 col-sm-6">
|
||||
<label for="code"><?php echo _("IP Address"); ?></label>
|
||||
<input type="text" class="form-control" name="wg_pipaddress" value="<?php echo htmlspecialchars($wg_pipaddress, ENT_QUOTES); ?>" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-group col-xs-3 col-sm-6">
|
||||
<label for="code"><?php echo _("Endpoint address"); ?></label>
|
||||
<input type="text" class="form-control" name="wg_pendpoint" value="<?php echo htmlspecialchars($wg_pendpoint, ENT_QUOTES); ?>" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-sm-6">
|
||||
<label for="code"><?php echo _("Allowed IPs"); ?></label>
|
||||
<input type="text" class="form-control mb-3" name="wg_pallowedips" value="<?php echo htmlspecialchars($wg_pallowedips, ENT_QUOTES); ?>" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-sm-6">
|
||||
<label for="code"><?php echo _("Persistent keepalive"); ?></label>
|
||||
<input type="text" class="form-control col-sm-3 mb-3" name="wg_pkeepalive" value="<?php echo htmlspecialchars($wg_pkeepalive, ENT_QUOTES); ?>" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 mt-5">
|
||||
<figure class="figure w-75 ml-3">
|
||||
<?php if ($wg_penabled == true ) : ?>
|
||||
<img src="app/img/wg-qr-code.php" class="figure-img img-fluid" alt="RaspAP Wifi QR code" style="width:100%;">
|
||||
<figcaption class="figure-caption">
|
||||
<?php echo _("Scan this QR code with your client to connect to this tunnel"); ?>
|
||||
<?php echo _("or download the <code>client.conf</code> file to your device."); ?>
|
||||
</figcaption>
|
||||
<button class="btn btn-outline-secondary rounded-right wg-client-dl mt-2" type="button"><?php echo _("Download"); ?> <i class="fas fa-download ml-1"></i></button>
|
||||
<?php endif; ?>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
</div><!-- /.row -->
|
||||
</div><!-- /.tab-pane | peers tab -->
|
||||
|
|
@ -14,12 +14,11 @@
|
|||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<?php $index = 0; ?>
|
||||
|
||||
<?php if (!empty($connected)): ?>
|
||||
<h4 class="h-underlined my-3"><?php echo _("Connected") ?></h4>
|
||||
<div class="card-grid">
|
||||
<?php foreach ($connected as $network) : ?>
|
||||
<?php $index = isset($network['index']) ? $network['index'] : -1; ?>
|
||||
<?php echo renderTemplate("wifi_stations/network", compact('network', 'index')) ?>
|
||||
<?php $index++; ?>
|
||||
<?php endforeach ?>
|
||||
|
@ -30,6 +29,7 @@
|
|||
<h4 class="h-underlined my-3"><?php echo _("Known") ?></h4>
|
||||
<div class="card-grid">
|
||||
<?php foreach ($known as $network) : ?>
|
||||
<?php $index = isset($network['index']) ? $network['index'] : -1; ?>
|
||||
<?php echo renderTemplate("wifi_stations/network", compact('network', 'index')) ?>
|
||||
<?php $index++; ?>
|
||||
<?php endforeach ?>
|
||||
|
@ -40,6 +40,7 @@
|
|||
<h4 class="h-underlined my-3"><?php echo _("Nearby") ?></h4>
|
||||
<div class="card-grid">
|
||||
<?php foreach ($nearby as $network) : ?>
|
||||
<?php $index = isset($network['index']) ? $network['index'] : -1; ?>
|
||||
<?php echo renderTemplate("wifi_stations/network", compact('network', 'index')) ?>
|
||||
<?php $index++; ?>
|
||||
<?php endforeach ?>
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
<?php if (strlen($network['ssid']) == 0) {
|
||||
$network['ssid'] = "(unknown)";
|
||||
} ?>
|
||||
<h5 class="card-title"><?php echo htmlspecialchars($network['ssid'], ENT_QUOTES); ?></h5>
|
||||
|
||||
<h5 class="card-title"><?php echo htmlspecialchars($network['ssidutf8'], ENT_QUOTES); ?></h5>
|
||||
<div class="info-item-wifi"><?php echo _("Status"); ?></div>
|
||||
<div>
|
||||
<?php if ($network['configured']) { ?>
|
||||
|
@ -62,7 +61,7 @@
|
|||
<?php if ($network['protocol'] === 'Open') { ?>
|
||||
<input type="password" disabled class="form-control" aria-describedby="passphrase" name="passphrase<?php echo $index ?>" value="" />
|
||||
<?php } else { ?>
|
||||
<input type="password" class="form-control js-validate-psk" aria-describedby="passphrase" name="passphrase<?php echo $index ?>" value="<?php echo $network['passphrase'] ?>" data-target="#update<?php echo $index ?>" data-colors="#ffd0d0,#d0ffd0">
|
||||
<input type="password" class="form-control" aria-describedby="passphrase" name="passphrase<?php echo $index ?>" value="<?php echo $network['passphrase'] ?>" data-target="#update<?php echo $index ?>" data-colors="#ffd0d0,#d0ffd0">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary js-toggle-password" type="button" data-target="[name=passphrase<?php echo $index ?>]" data-toggle-with="<?php echo _("Hide") ?>">Show</button>
|
||||
</div>
|
||||
|
@ -75,7 +74,7 @@
|
|||
<input type="submit" class="col-xs-4 col-md-4 btn btn-warning" value="<?php echo _("Update"); ?>" id="update<?php echo $index ?>" name="update<?php echo $index ?>"<?php echo ($network['protocol'] === 'Open' ? ' disabled' : '')?> data-toggle="modal" data-target="#configureClientModal" />
|
||||
<button type="submit" class="col-xs-4 col-md-4 btn btn-info" value="<?php echo $index?>" name="connect"><?php echo _("Connect"); ?></button>
|
||||
<?php } else { ?>
|
||||
<input type="submit" class="col-xs-4 col-md-4 btn btn-info" value="<?php echo _("Add"); ?>" id="update<?php echo $index ?>" name="update<?php echo $index ?>" <?php echo ($network['protocol'] === 'Open' ? '' : ' disabled')?> data-toggle="modal" data-target="#configureClientModal" />
|
||||
<input type="submit" class="col-xs-4 col-md-4 btn btn-info" value="<?php echo _("Add"); ?>" id="update<?php echo $index ?>" name="update<?php echo $index ?>" data-toggle="modal" data-target="#configureClientModal" />
|
||||
<?php } ?>
|
||||
<input type="submit" class="col-xs-4 col-md-4 btn btn-danger" value="<?php echo _("Delete"); ?>" name="delete<?php echo $index ?>"<?php echo ($network['configured'] ? '' : ' disabled')?> data-toggle="modal" data-target="#configureClientModal" />
|
||||
</div><!-- /.btn-group -->
|
||||
|
|
53
templates/wireguard.php
Executable file
53
templates/wireguard.php
Executable file
|
@ -0,0 +1,53 @@
|
|||
<?php ob_start() ?>
|
||||
<?php if (!RASPI_MONITOR_ENABLED) : ?>
|
||||
<input type="submit" class="btn btn-outline btn-primary" name="savewgsettings" value="<?php echo _("Save settings"); ?>">
|
||||
<?php if ($wg_state) : ?>
|
||||
<input type="submit" class="btn btn-warning" name="stopwg" value="<?php echo _("Stop WireGuard"); ?>">
|
||||
<?php else : ?>
|
||||
<input type="submit" class="btn btn-success" name="startwg" value="<?php echo _("Start WireGuard"); ?>">
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
<?php $buttons = ob_get_clean(); ob_end_clean() ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="ra-wireguard mr-2"></span><?php echo _("WireGuard"); ?>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button class="btn btn-light btn-icon-split btn-sm service-status float-right">
|
||||
<span class="icon text-gray-600"><i class="fas fa-circle service-status-<?php echo $serviceStatus ?>"></i></span>
|
||||
<span class="text service-status">wg <?php echo _($serviceStatus) ?></span>
|
||||
</button>
|
||||
</div>
|
||||
</div><!-- /.row -->
|
||||
</div><!-- /.card-header -->
|
||||
<div class="card-body">
|
||||
<?php $status->showMessages(); ?>
|
||||
<form role="form" action="/wg_conf" enctype="multipart/form-data" method="POST">
|
||||
<?php echo CSRFTokenFieldTag() ?>
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item"><a class="nav-link active" id="settingstab" href="#wgsettings" data-toggle="tab"><?php echo _("Settings"); ?></a></li>
|
||||
<li class="nav-item"><a class="nav-link" id="peertab" href="#wgpeers" data-toggle="tab"><?php echo _("Peer"); ?></a></li>
|
||||
<li class="nav-item"><a class="nav-link" id="loggingtab" href="#wglogging" data-toggle="tab"><?php echo _("Logging"); ?></a></li>
|
||||
</ul>
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<?php echo renderTemplate("wg/general", $__template_data) ?>
|
||||
<?php echo renderTemplate("wg/peers", $__template_data) ?>
|
||||
<?php echo renderTemplate("wg/logging", $__template_data) ?>
|
||||
</div><!-- /.tab-content -->
|
||||
|
||||
<?php echo $buttons ?>
|
||||
</form>
|
||||
</div><!-- /.card-body -->
|
||||
<div class="card-footer"><?php echo _("Information provided by wireguard"); ?></div>
|
||||
</div><!-- /.card -->
|
||||
</div><!-- /.col-lg-12 -->
|
||||
</div><!-- /.row -->
|
||||
|
25
yarn.lock
25
yarn.lock
|
@ -645,9 +645,9 @@ camelcase@^5.0.0:
|
|||
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
|
||||
|
||||
caniuse-lite@^1.0.30000998, caniuse-lite@^1.0.30001219:
|
||||
version "1.0.30001228"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa"
|
||||
integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==
|
||||
version "1.0.30001230"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71"
|
||||
integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
|
@ -1179,9 +1179,9 @@ ee-first@1.1.1:
|
|||
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
|
||||
|
||||
electron-to-chromium@^1.3.723:
|
||||
version "1.3.738"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.738.tgz#aec24b091c82acbfabbdcce08076a703941d17ca"
|
||||
integrity sha512-vCMf4gDOpEylPSLPLSwAEsz+R3ShP02Y3cAKMZvTqule3XcPp7tgc/0ESI7IS6ZeyBlGClE50N53fIOkcIVnpw==
|
||||
version "1.3.739"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.739.tgz#f07756aa92cabd5a6eec6f491525a64fe62f98b9"
|
||||
integrity sha512-+LPJVRsN7hGZ9EIUUiWCpO7l4E3qBYHNadazlucBfsXBbccDFNKUBAgzE68FnkWGJPwD/AfKhSzL+G+Iqb8A4A==
|
||||
|
||||
emoji-regex@^7.0.1:
|
||||
version "7.0.3"
|
||||
|
@ -2756,15 +2756,10 @@ minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2:
|
|||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@^1.1.3, minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
minimist@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
||||
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
|
||||
minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||
|
||||
minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
|
||||
version "2.9.0"
|
||||
|
|
Loading…
Reference in a new issue