mirror of
https://github.com/billz/raspap-webgui.git
synced 2025-12-27 07:31:09 +01:00
Compare commits
88 Commits
3.4.0
...
3.4.5-test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abd4c1e962 | ||
|
|
78d0b1a958 | ||
|
|
2aafe2b61c | ||
|
|
079191b660 | ||
|
|
ca8485d80b | ||
|
|
beb40ec7b9 | ||
|
|
939c5d164c | ||
|
|
1e6bd6f516 | ||
|
|
5cdd174e29 | ||
|
|
b84d26447f | ||
|
|
b2f7cad0d9 | ||
|
|
3f47043bbc | ||
|
|
90981a9f21 | ||
|
|
03c48a1c42 | ||
|
|
6433d83967 | ||
|
|
c6a738097a | ||
|
|
276f6585e1 | ||
|
|
53581c813f | ||
|
|
b4d5e9033c | ||
|
|
9cf65a29cb | ||
|
|
c74b410e8c | ||
|
|
593acb93bd | ||
|
|
5fa691bca1 | ||
|
|
bc2679ac68 | ||
|
|
d5ac2f6881 | ||
|
|
3691489194 | ||
|
|
74bd81a92c | ||
|
|
74194205ec | ||
|
|
fb4571a191 | ||
|
|
b98c1fb912 | ||
|
|
fdfbc62e9b | ||
|
|
cc6771ba07 | ||
|
|
b654e6bb33 | ||
|
|
6093b8107f | ||
|
|
1b708bc947 | ||
|
|
6a61320ea0 | ||
|
|
321c98de24 | ||
|
|
b9e78faf30 | ||
|
|
e3991a476b | ||
|
|
0f9583e366 | ||
|
|
34dd95f341 | ||
|
|
a33cb4ad57 | ||
|
|
6148d39e1b | ||
|
|
589126a83c | ||
|
|
a844328da3 | ||
|
|
4b67191823 | ||
|
|
ccd4db70bc | ||
|
|
895b880d69 | ||
|
|
e0d0ec05e3 | ||
|
|
29be30479e | ||
|
|
ae09dda000 | ||
|
|
e3e9adb63e | ||
|
|
8bf4116b42 | ||
|
|
2c896bbc12 | ||
|
|
66c04ec353 | ||
|
|
594ec2eec6 | ||
|
|
6772709141 | ||
|
|
23f32f9830 | ||
|
|
417f803411 | ||
|
|
f1dc6b3078 | ||
|
|
0114325a18 | ||
|
|
9e911847c5 | ||
|
|
4bc18f93e7 | ||
|
|
e514178b33 | ||
|
|
87d317db52 | ||
|
|
3b2396ec41 | ||
|
|
f7ac3d0b9d | ||
|
|
d4da4032b2 | ||
|
|
dc7122532f | ||
|
|
66b0a42576 | ||
|
|
08cc452e3d | ||
|
|
3eaa5b7801 | ||
|
|
bd53ef9ecc | ||
|
|
8bb18b43f8 | ||
|
|
23103c8c4b | ||
|
|
93b5dc4dac | ||
|
|
f7058b048a | ||
|
|
159e82dbd3 | ||
|
|
31303727a4 | ||
|
|
931086aecb | ||
|
|
a295dae059 | ||
|
|
a5a6747ced | ||
|
|
a36e3c7b57 | ||
|
|
f7e4b95ee2 | ||
|
|
a2c5eec53a | ||
|
|
66e2397ca0 | ||
|
|
6dd80575f4 | ||
|
|
73985333b0 |
16
.github/ISSUE_TEMPLATE/issue_form.yml
vendored
16
.github/ISSUE_TEMPLATE/issue_form.yml
vendored
@@ -52,13 +52,15 @@ body:
|
||||
attributes:
|
||||
label: Operating System
|
||||
options:
|
||||
- Raspberry Pi OS (64-bit) Lite Bookworm
|
||||
- Raspberry Pi OS (32-bit) Lite Bookworm
|
||||
- Raspberry Pi OS (64-bit) Desktop Bookwom
|
||||
- Raspberry Pi OS (64-bit) Lite Bullseye
|
||||
- Raspberry Pi OS (32-bit) Lite Bullseye
|
||||
- Armbian 23.05 (Suni)
|
||||
- Debian Bookworm
|
||||
- Raspberry Pi OS Lite 64-bit Debian 13 (trixie)
|
||||
- Raspberry Pi OS Lite 32-bit Debian 13 (trixie)
|
||||
- Raspberry Pi OS Lite 64-bit Debian 12 (bookworm)
|
||||
- Raspberry Pi OS Lite 32-bit Debian 12 (bookworm)
|
||||
- Raspberry Pi OS Desktop 64-bit Debian 12 (bookworm)
|
||||
- Raspberry Pi OS Lite 64-bit Debian 11 (bullseye)
|
||||
- Raspberry Pi OS Lite 32-bit Debian 11 (bullseye)
|
||||
- Armbian 23.11 (jammy)
|
||||
- Debian 12 (bookworm)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
|
||||
23
.github/workflows/release.yml
vendored
23
.github/workflows/release.yml
vendored
@@ -15,8 +15,10 @@ jobs:
|
||||
include:
|
||||
- arch: "32-bit"
|
||||
pi_gen_version: "master"
|
||||
release: "trixie"
|
||||
- arch: "64-bit"
|
||||
pi_gen_version: "arm64"
|
||||
release: "trixie"
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -27,20 +29,33 @@ jobs:
|
||||
|
||||
- name: Build RaspAP Image
|
||||
id: build
|
||||
uses: usimd/pi-gen-action@v1
|
||||
uses: usimd/pi-gen-action@v1.11.0
|
||||
with:
|
||||
image-name: "raspap-bookworm-${{ matrix.arch == '32-bit' && 'armhf' || 'arm64' }}-lite-${{ github.event.inputs.tag || github.ref_name }}"
|
||||
release: ${{ matrix.release }}
|
||||
image-name: "raspap-${{ matrix.release }}-${{ matrix.arch == '32-bit' && 'armhf' || 'arm64' }}-lite-${{ github.event.inputs.tag || github.ref_name }}"
|
||||
enable-ssh: 1
|
||||
stage-list: stage0 stage1 stage2 ./stage-raspap
|
||||
verbose-output: true
|
||||
pi-gen-version: ${{ matrix.pi_gen_version }}
|
||||
pi-gen-repository: RaspAP/pi-gen
|
||||
pi-gen-repository: billz/pi-gen
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
asset_name: "raspap-bookworm-${{ matrix.arch == '32-bit' && 'armhf' || 'arm64' }}-lite-${{ github.event.inputs.tag || github.ref_name }}.img.zip"
|
||||
asset_name: "raspap-${{ matrix.release }}-${{ matrix.arch == '32-bit' && 'armhf' || 'arm64' }}-lite-${{ github.event.inputs.tag || github.ref_name }}.img.zip"
|
||||
file: ${{ steps.build.outputs.image-path }}
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: ${{ github.event.inputs.tag || github.ref }}
|
||||
overwrite: true
|
||||
|
||||
torrent:
|
||||
needs: build-raspap-image
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Generate torrents for release
|
||||
uses: devopsx/action-torrent@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
local: false
|
||||
|
||||
39
README.md
39
README.md
@@ -1,5 +1,5 @@
|
||||

|
||||
[](https://github.com/raspap/raspap-webgui/releases) [](https://github.com/thibmaek/awesome-raspberry-pi) [](https://github.com/sponsors/RaspAP) [](https://app.travis-ci.com/RaspAP/raspap-webgui) [](https://crowdin.com/project/raspap) [](https://twitter.com/rasp_ap) [](https://reddit.com/r/RaspAP) [](https://discord.gg/KVAsaAR)
|
||||

|
||||
[](https://github.com/raspap/raspap-webgui/releases) [](https://github.com/thibmaek/awesome-raspberry-pi) [](https://github.com/sponsors/RaspAP) [](https://app.travis-ci.com/RaspAP/raspap-webgui) [](https://crowdin.com/project/raspap) [](https://twitter.com/rasp_ap) [](https://reddit.com/r/RaspAP) [](https://discord.gg/KVAsaAR)
|
||||
|
||||
RaspAP is feature-rich wireless router software that _just works_ on many popular [Debian-based devices](#supported-operating-systems), including the Raspberry Pi. Our [custom OS images](#pre-built-image), [Quick installer](#quick-installer) and [Docker container](#docker-support) create 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](https://docs.raspap.com/wireguard/), [Tailscale](https://docs.raspap.com/tailscale/) and [OpenVPN](https://docs.raspap.com/openvpn/) support, [SSL certificates](https://docs.raspap.com/ssl/), [ad blocking](#ad-blocking), security audits, [captive portal integration](https://docs.raspap.com/captive/), themes and [multilingual options](https://docs.raspap.com/translations/) are included.
|
||||
|
||||
@@ -41,10 +41,10 @@ RaspAP gives you two different ways to get up and running quickly. The simplest
|
||||
### Pre-built image
|
||||
Custom Raspberry Pi OS Lite images with the latest RaspAP are available for [direct download](https://github.com/RaspAP/raspap-webgui/releases/latest). This includes both 32- and 64-bit builds for ARM architectures.
|
||||
|
||||
| Operating system | Debian version | Kernel version | RaspAP version | Size |
|
||||
| ---------------------| ---------------|-----------------|----------------|-------|
|
||||
| Raspberry Pi OS (64-bit) Lite | 12 (bookworm) | 6.6 | Latest | 777 MB|
|
||||
| Raspberry Pi OS (32-bit) Lite | 12 (bookworm) | 6.6 | Latest | 805 MB|
|
||||
| Operating system | Debian version | Kernel version | RaspAP version | Size |
|
||||
| ------------ | -------------- | -------------- | -------------- | ---- |
|
||||
| Raspberry Pi OS (64-bit) Lite | 13 (trixie) | 6.12 | Latest | 826 MB |
|
||||
| Raspberry Pi OS (32-bit) Lite | 13 (trixie) | 6.12 | Latest | 799 MB |
|
||||
|
||||
These images are automatically generated with each release of RaspAP. You may choose between an `arm64` or `armhf` (32-bit) based build. Refer to [this resource](https://www.raspberrypi.com/software/operating-systems/) to ensure compatibility with your hardware.
|
||||
|
||||
@@ -84,7 +84,8 @@ It's _strongly recommended_ that your first post-install action is to change the
|
||||
Please [read this](https://docs.raspap.com/issues/) before reporting an issue.
|
||||
|
||||
## Join Insiders
|
||||
[](https://github.com/sponsors/RaspAP/)
|
||||
|
||||
[<img src="https://github.com/user-attachments/assets/832f1f0d-517a-4d73-8b62-068cf1a2041d" width="320">](https://github.com/sponsors/RaspAP/)
|
||||
|
||||
RaspAP is free software, but powered by _your_ support. If you find RaspAP useful for your personal or commercial projects, [become an Insider](https://github.com/sponsors/RaspAP/) and get early access to [exclusive features](https://docs.raspap.com/insiders/#exclusive-features) in the [Insiders Edition](https://docs.raspap.com/insiders/).
|
||||
|
||||
@@ -92,8 +93,6 @@ A tangible side benefit of sponsorship is that **Insiders** are able to help _st
|
||||
|
||||
## WireGuard support
|
||||
|
||||

|
||||
|
||||
WireGuard® is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be considerably more performant than OpenVPN, and is generally regarded as the most secure, easiest to use, and simplest VPN solution for modern Linux distributions.
|
||||
|
||||
WireGuard may be optionally installed by the [Quick Installer](https://docs.raspap.com/quick/). Once this is done, you can manage local (server) settings, create a peer configuration and control the `wg-quick` service with RaspAP.
|
||||
@@ -102,8 +101,6 @@ Details are [provided here](https://docs.raspap.com/wireguard/).
|
||||
|
||||
## OpenVPN support
|
||||
|
||||

|
||||
|
||||
OpenVPN may be optionally installed by the Quick Installer. Once this is done, you can [manage client configurations](https://docs.raspap.com/openvpn/) and the `openvpn-client` service with RaspAP.
|
||||
|
||||
To configure an OpenVPN client, upload a valid .ovpn file and, optionally, specify your login credentials. RaspAP will store your client configuration and add firewall rules to forward traffic from OpenVPN's `tun0` interface to your configured wireless interface.
|
||||
@@ -137,15 +134,17 @@ RaspAP provides an 802.11ac wireless mode option for supported hardware (current
|
||||
## Supported operating systems
|
||||
RaspAP was originally made for Raspbian, but now also installs on the following Debian-based distros.
|
||||
|
||||
| Distribution | Release | Architecture | Support |
|
||||
|---|:---:|:---:|:---:|
|
||||
| Raspberry Pi OS | (64-bit) Lite Bookworm | ARM | Official |
|
||||
| Raspberry Pi OS | (32-bit) Lite Bookworm | ARM | Official |
|
||||
| Raspberry Pi OS | (64-bit) Desktop Bookworm | ARM | Official |
|
||||
| Raspberry Pi OS | (64-bit) Lite Bullseye | ARM | Official |
|
||||
| Raspberry Pi OS | (32-bit) Lite Bullseye | ARM | Official |
|
||||
| Armbian | 23.11 (Jammy) | [ARM](https://docs.armbian.com/#supported-socs) | Beta |
|
||||
| Debian | Bookworm | ARM / x86_64 | Beta |
|
||||
| Distribution | Release | Architecture | Support |
|
||||
| ------------ | ------- | ------------ | ------- |
|
||||
| Raspberry Pi OS Lite | 64-bit Debian 13 (trixie) | ARM | Official |
|
||||
| Raspberry Pi OS Lite | 32-bit Debian 13 (trixie) | ARM | Official |
|
||||
| Raspberry Pi OS Lite | 64-bit Debian 12 (bookworm) | ARM | Official |
|
||||
| Raspberry Pi OS Lite | 32-bit Debian 12 (bookworm) | ARM | Official |
|
||||
| Raspberry Pi OS Desktop | 64-bit Debian 12 (bookworm) | ARM | Official |
|
||||
| Raspberry Pi OS Lite | 64-bit Debian 11 (bullseye) | ARM | Official |
|
||||
| Raspberry Pi OS Lite | 32-bit Debian 11 (bullseye) | ARM | Official |
|
||||
| Armbian | 23.11 (jammy) | ARM | Beta |
|
||||
| Debian | 12 (bookworm) | ARM / x86_64 | Beta |
|
||||
|
||||
<img src="https://i.imgur.com/XiAJNKb.png" style="width:480px;" />
|
||||
|
||||
|
||||
@@ -48,8 +48,15 @@ th {
|
||||
}
|
||||
|
||||
.navbar-logo {
|
||||
margin-top: 0.5em;
|
||||
margin-left: 0.5em;
|
||||
margin-top: 0.2em;
|
||||
margin-left: 0.7em;
|
||||
}
|
||||
|
||||
.login-logo {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
margin-left: 1.2rem;
|
||||
margin-bottom: -0.5rem;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<?php
|
||||
require_once '../../includes/functions.php';
|
||||
$color = getColorOpt();
|
||||
$allCss = 'all.css';
|
||||
?>
|
||||
/*
|
||||
Theme Name: RaspAP default
|
||||
@@ -11,7 +12,7 @@ Description: Default theme for RaspAP
|
||||
License: GNU General Public License v3.0
|
||||
*/
|
||||
|
||||
@import url('all.css');
|
||||
@import url('<?= $allCss ?>?v=<?= filemtime($allCss); ?>');
|
||||
|
||||
:root {
|
||||
--raspap-theme-color: <?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<?php header("Content-Type: image/svg+xml; charset=utf-8"); ?>
|
||||
<?php
|
||||
require_once '../../includes/config.php';
|
||||
require_once '../../includes/functions.php';
|
||||
$color = getColorOpt();
|
||||
$static = (isset($_GET['static']) && $_GET['static'] == '1') ||
|
||||
(defined('RASPI_UI_STATIC_LOGO') && RASPI_UI_STATIC_LOGO === true);
|
||||
?>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
@@ -10,42 +13,41 @@ $color = getColorOpt();
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 490.66666 487.11066"
|
||||
height="487.11066"
|
||||
width="490.66666"
|
||||
viewBox="0 180 352 290"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
version="1.1"><metadata
|
||||
id="metadata8"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs6"><clipPath
|
||||
id="clipPath18"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path16"
|
||||
d="M 0,365.333 H 368 V 0 H 0 Z" /></clipPath></defs><g
|
||||
transform="matrix(1.3333333,0,0,-1.3333333,0,487.11067)"
|
||||
id="g10"><g
|
||||
id="g12"><g
|
||||
clip-path="url(#clipPath18)"
|
||||
id="g14"><g
|
||||
transform="translate(192.6768,123.4365)"
|
||||
id="g20"><path
|
||||
id="path22"
|
||||
style="fill:<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 0,-37.169 -30.128,-67.3 -67.296,-67.3 -37.167,0 -67.294,30.131 -67.294,67.3 0,37.165 30.127,67.296 67.294,67.296 C -30.128,67.296 0,37.165 0,0" /></g><g
|
||||
transform="translate(125.3823,219.0791)"
|
||||
id="g24"><path
|
||||
id="path26"
|
||||
style="fill:<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -52.737,0 -95.641,-42.905 -95.641,-95.643 0,-52.74 42.904,-95.647 95.641,-95.647 52.737,0 95.642,42.907 95.642,95.647 C 95.642,-42.905 52.737,0 0,0 m 0,-217.29 c -67.073,0 -121.641,54.571 -121.641,121.647 C -121.641,-28.569 -67.073,26 0,26 67.074,26 121.642,-28.569 121.642,-95.643 121.642,-162.719 67.074,-217.29 0,-217.29" /></g><g
|
||||
transform="translate(144.4277,271.9385)"
|
||||
id="g28"><path
|
||||
id="path30"
|
||||
style="fill:<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 66.188,0 121.118,-49.055 130.392,-112.714 l 28.259,-1.874 C 150.044,-34.655 82.181,27.791 0,27.791 c -3.892,0 -7.75,-0.147 -11.571,-0.423 L -9.73,-0.397 C -6.513,-0.161 -3.275,0 0,0" /></g><g
|
||||
transform="translate(144.4883,334.7588)"
|
||||
id="g32"><path
|
||||
id="path34"
|
||||
style="fill:<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 101.94,0 185.667,-79.438 192.56,-179.664 l 27.962,-1.857 C 214.513,-65.087 117.899,27.791 0,27.791 c -5.31,0 -10.576,-0.2 -15.792,-0.571 l 1.84,-27.728 C -9.343,-0.177 -4.691,0 0,0" /></g></g></g></g></svg>
|
||||
version="1.1">
|
||||
<style>
|
||||
<?php if (!$static): ?>
|
||||
.wave {
|
||||
opacity: 0.4;
|
||||
animation: pulse 1.8s infinite;
|
||||
}
|
||||
.wave1 { animation-delay: 0.3s; }
|
||||
.wave2 { animation-delay: 0.6s; }
|
||||
|
||||
@keyframes pulse {
|
||||
0% { opacity: 0.4; }
|
||||
20% { opacity: 1; }
|
||||
60% { opacity: 0.4; }
|
||||
100% { opacity: 0.4; }
|
||||
}
|
||||
<?php else: ?>
|
||||
.wave {
|
||||
opacity: 1.0;
|
||||
}
|
||||
<?php endif; ?>
|
||||
</style>
|
||||
|
||||
<!-- inner solid circle -->
|
||||
<circle cx="128" cy="384" r="60" fill="<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>"/>
|
||||
|
||||
<!-- outer ring -->
|
||||
<circle cx="128" cy="384" r="100" fill="none" stroke="<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>" stroke-width="25"/>
|
||||
|
||||
<!-- arcs -->
|
||||
<path class="wave wave1" d="M128 234 A 150 150 0 0 1 278 384" fill="none" stroke="<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>" stroke-width="25"/>
|
||||
<path class="wave wave2" d="M128 184 A 200 200 0 0 1 328 384" fill="none" stroke="<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>" stroke-width="25"/>
|
||||
|
||||
</svg>
|
||||
|
||||
|
||||
@@ -78,6 +78,38 @@ $(document).on("submit", ".js-dhcp-settings-form", function(e) {
|
||||
$(".js-add-dhcp-upstream-server").trigger("click");
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const bridgeCheckbox = document.getElementById('chxbridgedenable');
|
||||
const bridgeSection = document.getElementById('bridgeStaticIpSection');
|
||||
const staticIpInput = document.getElementById('bridgeStaticIp');
|
||||
const netmaskInput = document.getElementById('bridgeNetmask');
|
||||
const gatewayInput = document.getElementById('bridgeGateway');
|
||||
const dnsInput = document.getElementById('bridgeDNS');
|
||||
const previewIp = document.getElementById('previewStaticIp');
|
||||
|
||||
const bridgeInputs = [staticIpInput, netmaskInput, gatewayInput, dnsInput];
|
||||
|
||||
// toggle visibility and required fields
|
||||
bridgeCheckbox.addEventListener('change', function() {
|
||||
if (this.checked) {
|
||||
bridgeSection.style.display = 'block';
|
||||
bridgeInputs.forEach(input => input.setAttribute('required', 'required'));
|
||||
} else {
|
||||
bridgeSection.style.display = 'none';
|
||||
bridgeInputs.forEach(input => input.removeAttribute('required'));
|
||||
}
|
||||
});
|
||||
|
||||
// auto-populate DNS when gateway loses focus
|
||||
gatewayInput.addEventListener('blur', function() {
|
||||
const gatewayVal = this.value.trim();
|
||||
if (gatewayVal !== '' && dnsInput.value.trim() === '') {
|
||||
dnsInput.value = gatewayVal;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* mark a form field, e.g. a select box, with the class `.js-field-preset`
|
||||
* and give it an attribute `data-field-preset-target` with a text field's
|
||||
@@ -542,7 +574,7 @@ function disableValidation(form) {
|
||||
|
||||
function updateActivityLED() {
|
||||
const threshold_bytes = 300;
|
||||
fetch('/app/net_activity')
|
||||
fetch('app/net_activity')
|
||||
.then(res => res.text())
|
||||
.then(data => {
|
||||
const activity = parseInt(data.trim());
|
||||
|
||||
@@ -2,7 +2,7 @@ server.modules += (
|
||||
"mod_rewrite",
|
||||
)
|
||||
|
||||
$HTTP["url"] =~ "^/REPLACE_ME/(?!(dist|app|ajax|config)).*" {
|
||||
$HTTP["url"] =~ "^/REPLACE_ME/(?!(dist|app|ajax|config|rootCA\.pem)).*" {
|
||||
url.rewrite-once = ( "^/REPLACE_ME/(.*?)(\?.+)?$"=>"/REPLACE_ME/index.php/$1$2" )
|
||||
server.error-handler-404 = "/REPLACE_ME/index.php"
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ define('RASPI_SYSTEM_ENABLED', true);
|
||||
define('RASPI_MONITOR_ENABLED', false);
|
||||
define('RASPI_RESTAPI_ENABLED', false);
|
||||
define('RASPI_PLUGINS_ENABLED', true);
|
||||
define('RASPI_UI_STATIC_LOGO', false);
|
||||
|
||||
// Locale settings
|
||||
define('LOCALE_ROOT', 'locale');
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"hostapd":{
|
||||
"modes":{
|
||||
"n":{
|
||||
"settings":[
|
||||
"hostapd": {
|
||||
"modes": {
|
||||
"n": {
|
||||
"settings": [
|
||||
"hw_mode=g",
|
||||
"ieee80211n=1",
|
||||
"wmm_enabled=1"
|
||||
]
|
||||
},
|
||||
"ac":{
|
||||
"settings":[
|
||||
"ac": {
|
||||
"settings": [
|
||||
"hw_mode=a",
|
||||
"# N",
|
||||
"ieee80211n=1",
|
||||
@@ -25,90 +25,117 @@
|
||||
"vht_oper_centr_freq_seg0_idx={VHT_FREQ_IDX}"
|
||||
]
|
||||
},
|
||||
"g":{
|
||||
"settings":[
|
||||
"g": {
|
||||
"settings": [
|
||||
"hw_mode=g",
|
||||
"ieee80211n=0"
|
||||
]
|
||||
},
|
||||
"a":{
|
||||
"settings":[
|
||||
"a": {
|
||||
"settings": [
|
||||
"hw_mode=a",
|
||||
"ieee80211n=0"
|
||||
]
|
||||
},
|
||||
"b":{
|
||||
"settings":[
|
||||
"b": {
|
||||
"settings": [
|
||||
"hw_mode=b",
|
||||
"ieee80211n=0"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"dhcp": {
|
||||
"wlan0": {
|
||||
"static ip_address": [ "10.3.141.1" ],
|
||||
"static routers": [ "10.3.141.1" ],
|
||||
"static domain_name_server": [ "1.1.1.1 8.8.8.8" ],
|
||||
"subnetmask": [ "255.255.255.0" ]
|
||||
},
|
||||
"dhcp":{
|
||||
"wlan0":{
|
||||
"static ip_address":[ "10.3.141.1/24" ],
|
||||
"static routers":[ "10.3.141.1" ],
|
||||
"static domain_name_server":[ "1.1.1.1 8.8.8.8" ],
|
||||
"subnetmask":[ "255.255.255.0" ]
|
||||
},
|
||||
"wlan1":{
|
||||
"static ip_address":[ "10.9.141.1/24" ],
|
||||
"static routers":[ "10.9.141.1" ],
|
||||
"static domain_name_server":[ "1.1.1.1 8.8.8.8" ],
|
||||
"subnetmask":[ "255.255.255.0" ]
|
||||
},
|
||||
"uap0":{
|
||||
"static ip_address":[ "192.168.50.1/24" ],
|
||||
"static routers":[ "192.168.50.1" ],
|
||||
"static domain_name_server":[ "1.1.1.1 8.8.8.8" ],
|
||||
"subnetmask":[ "255.255.255.0" ]
|
||||
},
|
||||
"options":{
|
||||
"# RaspAP default configuration":null,
|
||||
"hostname":null,
|
||||
"clientid":null,
|
||||
"persistent":null,
|
||||
"option rapid_commit":null,
|
||||
"option domain_name_servers, domain_name, domain_search, host_name":null,
|
||||
"option classless_static_routes":null,
|
||||
"option ntp_servers":null,
|
||||
"require dhcp_server_identifier":null,
|
||||
"slaac private":null,
|
||||
"nohook lookup-hostname":null
|
||||
}
|
||||
"wlan1": {
|
||||
"static ip_address": [ "10.9.141.1" ],
|
||||
"static routers": [ "10.9.141.1" ],
|
||||
"static domain_name_server": [ "1.1.1.1 8.8.8.8" ],
|
||||
"subnetmask": [ "255.255.255.0" ]
|
||||
},
|
||||
"dnsmasq":{
|
||||
"wlan0":{
|
||||
"dhcp-range":[ "10.3.141.50,10.3.141.254,255.255.255.0,12h" ]
|
||||
},
|
||||
"wlan1":{
|
||||
"dhcp-range":[ "10.9.141.50,10.9.141.254,255.255.255.0,12h" ]
|
||||
},
|
||||
"uap0":{
|
||||
"dhcp-range":[ "192.168.50.50,192.168.50.150,12h" ]
|
||||
}
|
||||
"wlan2": {
|
||||
"static ip_address": [ "10.6.141.1" ],
|
||||
"static routers": [ "10.6.141.1" ],
|
||||
"static domain_name_server": [ "1.1.1.1 8.8.8.8" ],
|
||||
"subnetmask": [ "255.255.255.0" ]
|
||||
},
|
||||
"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" ],
|
||||
"PostUpEx":[ "iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL ! -d %s -j REJECT" ],
|
||||
"PreDown":[ "iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL ! -d %s -j REJECT" ]
|
||||
},
|
||||
"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" ]
|
||||
}
|
||||
"uap0": {
|
||||
"static ip_address": ["192.168.50.1" ],
|
||||
"static routers": [ "192.168.50.1" ],
|
||||
"static domain_name_server": [ "1.1.1.1 8.8.8.8" ],
|
||||
"subnetmask": [ "255.255.255.0" ]
|
||||
},
|
||||
"eth0": {
|
||||
"static ip_address": [ "192.168.55.1" ],
|
||||
"static routers": [ "192.168.55.1" ],
|
||||
"static domain_name_server": [ "1.1.1.1 8.8.8.8" ],
|
||||
"subnetmask": [ "255.255.255.0" ]
|
||||
},
|
||||
"enx": {
|
||||
"static ip_address": [ "192.168.60.1" ],
|
||||
"static routers": [ "192.168.60.1" ],
|
||||
"static domain_name_server": [ "1.1.1.1 8.8.8.8" ],
|
||||
"subnetmask": [ "255.255.255.0" ]
|
||||
},
|
||||
"options": {
|
||||
"# RaspAP default configuration": null,
|
||||
"hostname": null,
|
||||
"clientid": null,
|
||||
"persistent": null,
|
||||
"option rapid_commit": null,
|
||||
"option domain_name_servers, domain_name, domain_search, host_name": null,
|
||||
"option classless_static_routes": null,
|
||||
"option ntp_servers": null,
|
||||
"require dhcp_server_identifier": null,
|
||||
"slaac private": null,
|
||||
"nohook lookup-hostname": null
|
||||
}
|
||||
},
|
||||
"dnsmasq": {
|
||||
"wlan0": {
|
||||
"dhcp-range": [ "10.3.141.50,10.3.141.254,255.255.255.0,12h" ]
|
||||
},
|
||||
"wlan1": {
|
||||
"dhcp-range": [ "10.9.141.50,10.9.141.254,255.255.255.0,12h" ]
|
||||
},
|
||||
"wlan2": {
|
||||
"dhcp-range": [ "10.6.141.50,10.6.141.254,255.255.255.0,12h" ]
|
||||
},
|
||||
"uap0": {
|
||||
"dhcp-range": [ "192.168.50.50,192.168.50.150,12h" ]
|
||||
},
|
||||
"eth0": {
|
||||
"dhcp-range": [ "192.168.55.50,192.168.55.150,12h" ]
|
||||
},
|
||||
"enx": {
|
||||
"dhcp-range": [ "192.168.60.50,192.168.60.150,12h" ]
|
||||
}
|
||||
},
|
||||
"wireguard": {
|
||||
"server": {
|
||||
"Address": [ "10.8.2.1/24" ],
|
||||
"ListenPort": [ "51820" ],
|
||||
"DNS": [ "9.9.9.9" ],
|
||||
"PostUp": [ "iptables -A FORWARD -i wlan0 -o %i -j ACCEPT; iptables -A FORWARD -i %i -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -A POSTROUTING -o %i -j MASQUERADE" ],
|
||||
"PostDown": [ "iptables -D FORWARD -i wlan0 -o %i -j ACCEPT; iptables -D FORWARD -i %i -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -D POSTROUTING -o %i -j MASQUERADE" ],
|
||||
"PostUpEx": [ "iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL ! -d %s -j REJECT" ],
|
||||
"PreDown": [ "iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL ! -d %s -j REJECT" ]
|
||||
},
|
||||
"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" ]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
dist/raspap/css/fonts/RaspAP.eot
vendored
BIN
dist/raspap/css/fonts/RaspAP.eot
vendored
Binary file not shown.
1
dist/raspap/css/fonts/RaspAP.svg
vendored
1
dist/raspap/css/fonts/RaspAP.svg
vendored
@@ -11,4 +11,5 @@
|
||||
<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" />
|
||||
<glyph unicode="" glyph-name="tailscale" d="M131.2 323.8c70.6 0 127.8 57.2 127.8 127.8s-57.2 127.8-127.8 127.8-127.6-57.4-127.6-127.8 57.2-127.8 127.6-127.8zM514.4 323.8c70.6 0 127.8 57.2 127.8 127.8s-57.2 127.8-127.8 127.8c-70.6 0-127.8-57.2-127.8-127.8s57.2-127.8 127.8-127.8zM514.4-64c70.6 0 127.8 57.2 127.8 127.8s-57.2 127.8-127.8 127.8c-70.6 0-127.8-57.2-127.8-127.8s57.2-127.8 127.8-127.8zM892.8 323.8c70.6 0 127.8 57.2 127.8 127.8s-57.2 127.8-127.8 127.8c-70.6 0-127.8-57.2-127.8-127.8s57.2-127.8 127.8-127.8z" />
|
||||
<glyph unicode="" glyph-name="torproxy" d="M750.016 439.488c-32.512 29.504-73.504 53.344-115.328 77.152-19.008 10.496-77.344 56.16-57.152 120.992l-36.32 15.328c57.152 88.672 131.68 176.32 223.008 258.336-73.344-24.672-138.176-62.848-186.848-130.496 28.672 60 75.328 119.168 126.848 179.168-70.496-50.496-131.488-107.68-169.664-184l26.656 106.848c-38.176-68.672-64.832-138.336-75.328-207.84l-56.16 22.848-9.504-7.68c49.504-88.672 23.84-135.328-0.992-151.68-49.504-33.344-120.992-76.16-157.344-113.344-68.672-70.656-88.672-137.344-82.016-226.016 6.656-113.504 89.664-207.84 199.328-244.992 48.672-16.32 93.344-18.176 143.008-18.176 80 0 162.016 20.992 222.176 71.488 63.84 52.992 100.832 131.488 100.992 214.496 0.32 82.656-34.336 161.664-95.328 217.504zM598.336 60.832c-3.84-17.152-16.16-38.176-31.328-57.152 5.664 10.496 10.496 20.992 13.344 32.512 23.84 84.832 34.336 123.84 22.848 217.344-1.824 9.504-5.664 40-20 73.344-20 50.656-50.496 98.336-54.336 108.832-6.656 16.16-16.16 84.832-17.152 131.488 0.992-40 3.84-113.344 14.336-142.016 2.848-9.664 30.496-52.512 50.496-104.832 13.344-36.32 16.16-69.664 19.008-79.168 9.664-43.008-1.824-115.488-16.992-184-4.832-24.832-18.176-53.504-35.328-75.328 9.504 13.344 17.152 30.496 22.848 50.496 11.488 40 16.16 91.488 15.168 124-0.832 19.008-9.504 60-23.84 97.152-8.512 20-20.992 40.992-29.504 55.328-9.504 14.336-9.504 45.664-13.344 82.016 0.832-39.168-2.848-59.168 6.656-86.848 5.664-16.16 26.656-39.008 32.32-60.992 8.672-29.504 17.152-62.016 16.32-82.016 0-22.848-0.992-64.832-11.488-110.656-6.656-34.176-22.016-63.84-46.656-82.848 10.496 13.344 16.16 26.656 19.008 40 3.84 20 4.832 39.168 6.656 63.008 2.016 24.512 0.32 49.344-4.672 73.344-7.68 34.336-20 68.672-25.824 92.512 0.992-26.656 11.488-60 16.32-95.328 3.68-25.824 1.824-51.488 0.832-74.336-0.832-26.656-9.504-73.504-20.992-96.32-11.488 4.832-15.168 11.488-22.848 20.992-9.664 12.32-15.328 25.664-20.992 40.992-5.344 12.672-9.504 25.664-12.512 39.008-4.512 33.504 4.16 67.168 23.84 94.496 20 28.672 24 30.496 30.496 63.84-9.504-29.504-16.16-32.32-37.152-57.152-23.84-27.68-27.488-67.68-27.488-100.16 0-13.344 5.664-28.672 10.496-43.008 5.664-15.168 11.328-30.336 19.008-41.824 5.664-9.504 13.344-16.16 20-20.992-24.832 6.656-50.496 16.16-66.656 29.504-40 34.496-75.328 92.512-80.16 144-3.84 42.016 34.336 103.008 88.672 133.504 45.824 26.656 56.32 56.32 65.824 104.992-13.344-42.016-26.656-78.336-70.656-100.16-62.848-34.336-95.328-89.664-92.32-143.008 4.672-67.68 31.328-114.496 85.824-151.68 12.32-8.672 29.504-17.152 47.68-23.84-67.84 16.16-76.32 25.664-99.168 52.32 0 2.016-5.824 5.824-5.824 6.656-30.496 34.336-68.512 93.504-82.016 147.84-4.672 19.008-9.504 39.008-3.68 58.176 24.672 89.664 79.008 124 133.344 160.992 13.504 9.664 26.848 18.176 39.168 27.68 30.496 24 38.176 85.824 44.832 121.152-12.32-43.008-25.824-96.32-49.664-113.504-12.32-9.504-27.68-17.152-40-25.664-56.16-38.176-112.512-74.496-138.176-166.848-5.824-24-2.016-41.152 3.68-64 14.336-56.16 52.512-117.152 84.992-153.504l5.664-5.664c14.336-16.32 32.512-28.672 54.336-37.152-19.168 4.512-37.664 11.168-55.328 20-88.672 42.848-147.68 135.328-151.488 210.656-7.68 153.504 65.824 198.336 134.336 254.656 38.176 31.328 91.68 46.656 122.176 102.848 5.664 12.512 9.504 39.168 1.824 67.84-2.848 9.504-17.152 43.84-22.848 51.488l84.832-37.344c-1.824-40-2.848-72.32 4.672-102.016 8.672-32.32 50.656-79.008 67.84-133.504 33.344-102.848 24.832-237.152 0.832-342.176z" />
|
||||
<glyph unicode="" glyph-name="wireshark" d="M729.968 781.328c-214.016-3.36-335.76-129.28-399.568-251.616-55.952-106.816-67.744-198.88-70.688-224.032l-259.712-2.576v-42.208l277.376 2.56c10.861 0.224 19.694 8.612 20.618 19.265l0.006 0.079s10.8 113.6 69.696 227.36c54.976 106.24 151.2 209.504 324.8 225.696-107.008-213.44 10.8-460.832 10.8-460.832 3.38-7.112 10.427-11.983 18.631-12.176h0.025l302.048-2.528v42.208l-287.168 2.56c-13.76 32.208-105.040 261.040 10.8 443.84 2.048 3.197 3.265 7.097 3.265 11.281 0 11.597-9.347 21.011-20.919 21.119h-0.010z" />
|
||||
</font></defs></svg>
|
||||
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 9.4 KiB |
BIN
dist/raspap/css/fonts/RaspAP.ttf
vendored
BIN
dist/raspap/css/fonts/RaspAP.ttf
vendored
Binary file not shown.
BIN
dist/raspap/css/fonts/RaspAP.woff
vendored
BIN
dist/raspap/css/fonts/RaspAP.woff
vendored
Binary file not shown.
34
dist/raspap/css/style.css
vendored
34
dist/raspap/css/style.css
vendored
@@ -1,16 +1,15 @@
|
||||
@font-face {
|
||||
font-family: 'RaspAP';
|
||||
src: url('fonts/RaspAP.eot?3vjloy');
|
||||
src: url('fonts/RaspAP.eot?3vjloy#iefix') format('embedded-opentype'),
|
||||
url('fonts/RaspAP.ttf?3vjloy') format('truetype'),
|
||||
url('fonts/RaspAP.woff?3vjloy') format('woff'),
|
||||
url('fonts/RaspAP.svg?3vjloy#RaspAP') format('svg');
|
||||
src: url('fonts/RaspAP.eot?8h3d6d');
|
||||
src: url('fonts/RaspAP.eot?8h3d6d#iefix') format('embedded-opentype'),
|
||||
url('fonts/RaspAP.ttf?8h3d6d') format('truetype'),
|
||||
url('fonts/RaspAP.woff?8h3d6d') format('woff'),
|
||||
url('fonts/RaspAP.svg?8h3d6d#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 fonts */
|
||||
font-family: 'RaspAP' !important;
|
||||
@@ -26,10 +25,15 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.ra-wireshark:before {
|
||||
font-size: 1.3rem;
|
||||
font-weight: bold;
|
||||
content: "\e904";
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.ra-wireguard:before {
|
||||
font-size: 1.1rem;
|
||||
content: "\e900";
|
||||
vertical-align: middle;
|
||||
}
|
||||
.ra-raspap:before {
|
||||
content: "\e901";
|
||||
@@ -46,19 +50,3 @@
|
||||
content: "\e903";
|
||||
vertical-align: top;
|
||||
}
|
||||
.card-header .ra-wireguard:before,
|
||||
.card-header .ra-tailscale:before,
|
||||
.card-header .ra-torproxy:before {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.sidebar .nav-item.active .nav-link span.ra-wireguard:before,
|
||||
.sidebar .nav-item.active .nav-link span.ra-tailscale:before,
|
||||
.sidebar .nav-item.active .nav-link span.ra-torproxy:before {
|
||||
color: #6e707e;
|
||||
}
|
||||
|
||||
.sb-nav-link-icon .ra-tailscale {
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,12 +82,15 @@ function DisplayDashboard(&$extraFooterScripts): void
|
||||
$vpnStatus = $vpn ? "active" : "inactive";
|
||||
$vpnManaged = $vpn ? $dashboard->getVpnManaged($vpn) : null;
|
||||
$firewallManaged = $firewallStatus = "";
|
||||
$firewallInstalled = array_filter($plugins, fn($p) => str_ends_with($p, 'Firewall')) ? true : false;
|
||||
$firewallInstalled = (bool) array_filter($plugins, function($p) {
|
||||
return substr($p, -strlen('Firewall')) === 'Firewall';
|
||||
});
|
||||
if (!$firewallInstalled) {
|
||||
$firewallUnavailable = '<i class="fas fa-slash fa-stack-1x"></i>';
|
||||
} else {
|
||||
$firewallManaged = '<a href="/plugin__Firewall">';
|
||||
$firewallStatus = ($dashboard->firewallEnabled() == true) ? "active" : "";
|
||||
$firewallUnavailable = null;
|
||||
}
|
||||
|
||||
echo renderTemplate(
|
||||
|
||||
@@ -7,7 +7,7 @@ if (!defined('RASPI_CONFIG')) {
|
||||
$defaults = [
|
||||
'RASPI_BRAND_TEXT' => 'RaspAP',
|
||||
'RASPI_BRAND_TITLE' => RASPI_BRAND_TEXT.' Admin Panel',
|
||||
'RASPI_VERSION' => '3.4.0',
|
||||
'RASPI_VERSION' => '3.4.5',
|
||||
'RASPI_CONFIG_NETWORK' => RASPI_CONFIG.'/networking/defaults.json',
|
||||
'RASPI_CONFIG_PROVIDERS' => 'config/vpn-providers.json',
|
||||
'RASPI_CONFIG_API' => RASPI_CONFIG.'/api',
|
||||
|
||||
@@ -915,7 +915,7 @@ function renderStatus($hostapd_led, $hostapd_status, $memused_led, $memused, $cp
|
||||
?>
|
||||
<div class="row g-0">
|
||||
<div class="col-4 ms-2 sidebar-brand-icon">
|
||||
<img src="app/img/raspAP-logo.php" class="navbar-logo" width="60" height="60">
|
||||
<img src="app/img/raspAP-logo.php?static=1" class="navbar-logo" width="70" height="70">
|
||||
</div>
|
||||
<div class="col ml-2">
|
||||
<div class="ml-1 sb-status">Status</div>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
use RaspAP\Networking\Hotspot\HostapdManager;
|
||||
use RaspAP\Networking\Hotspot\HotspotService;
|
||||
use RaspAP\Networking\Hotspot\WiFiManager;
|
||||
use RaspAP\Networking\Hotspot\DhcpcdManager;
|
||||
use RaspAP\Messages\StatusMessage;
|
||||
use RaspAP\System\Sysinfo;
|
||||
|
||||
@@ -18,6 +19,7 @@ function DisplayHostAPDConfig()
|
||||
$hostapd = new HostapdManager();
|
||||
$hotspot = new HotspotService();
|
||||
$status = new StatusMessage();
|
||||
$dhcpcd = new DhcpcdManager();
|
||||
$system = new Sysinfo();
|
||||
$operatingSystem = $system->operatingSystem();
|
||||
|
||||
@@ -61,7 +63,15 @@ function DisplayHostAPDConfig()
|
||||
$status->addMessage($line, 'info');
|
||||
}
|
||||
} elseif (isset($_POST['SaveHostAPDSettings'])) {
|
||||
$hotspot->saveSettings($_POST, $arrSecurity, $arrEncType, $arr80211Standard, $interfaces, $reg_domain, $status);
|
||||
$result = $hotspot->saveSettings(
|
||||
$_POST,
|
||||
$arrSecurity,
|
||||
$arrEncType,
|
||||
$arr80211Standard,
|
||||
$interfaces,
|
||||
$reg_domain,
|
||||
$status
|
||||
);
|
||||
} elseif (isset($_POST['StopHotspot'])) {
|
||||
$status->addMessage('Attempting to stop hotspot', 'info');
|
||||
exec('sudo /bin/systemctl stop hostapd.service', $return);
|
||||
@@ -96,6 +106,30 @@ function DisplayHostAPDConfig()
|
||||
error_log('Error: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// bridge configuration
|
||||
if (!empty($arrHostapdConf['BridgedEnable']) && (int)$arrHostapdConf['BridgedEnable'] === 1) {
|
||||
$iface = 'br0';
|
||||
$bridgeConfig = $dhcpcd->getInterfaceConfig($iface);
|
||||
|
||||
if (is_array($bridgeConfig) && !empty($bridgeConfig)) {
|
||||
$arrConfig['bridgeStaticIP'] = !empty($bridgeConfig['StaticIP'])
|
||||
? $bridgeConfig['StaticIP']
|
||||
: '192.168.1.10';
|
||||
|
||||
$arrConfig['bridgeNetmask'] = !empty($bridgeConfig['SubnetMask'])
|
||||
? mask2cidr($bridgeConfig['SubnetMask'])
|
||||
: '24';
|
||||
|
||||
$arrConfig['bridgeGateway'] = !empty($bridgeConfig['StaticRouters'])
|
||||
? $bridgeConfig['StaticRouters']
|
||||
: '192.168.1.1';
|
||||
|
||||
$arrConfig['bridgeDNS'] = !empty($bridgeConfig['StaticDNS'])
|
||||
? $bridgeConfig['StaticDNS']
|
||||
: '192.168.1.1';
|
||||
}
|
||||
}
|
||||
|
||||
// assign disassoc_low_ack boolean if value is set
|
||||
$arrConfig['disassoc_low_ack_bool'] = isset($arrConfig['disassoc_low_ack']) ? 1 : 0;
|
||||
$hostapdstatus = $system->hostapdStatus();
|
||||
|
||||
@@ -16,16 +16,24 @@
|
||||
$validLocales = array_keys(getLocales());
|
||||
if (!empty($_POST['locale']) && in_array($_POST['locale'], $validLocales, true)) {
|
||||
$_SESSION['locale'] = $_POST['locale'];
|
||||
setcookie('locale', $_POST['locale'], time() + (86400 * 30), '/', '', false, true);
|
||||
}
|
||||
|
||||
// Set locale from browser detection, if not already set
|
||||
// Set locale from cookie or browser detection, if not already set in session
|
||||
if (empty($_SESSION['locale'])) {
|
||||
$_SESSION['locale'] = detectBrowserLocale();
|
||||
if (isset($_COOKIE['locale']) && in_array($_COOKIE['locale'], $validLocales, true)) {
|
||||
$_SESSION['locale'] = $_COOKIE['locale'];
|
||||
} else {
|
||||
$_SESSION['locale'] = detectBrowserLocale();
|
||||
setcookie('locale', $_SESSION['locale'], time() + (86400 * 30), '/', '', false, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce only valid locale values in session
|
||||
if (!in_array($_SESSION['locale'], $validLocales, true)) {
|
||||
$_SESSION['locale'] = 'en_GB.UTF-8';
|
||||
// Update cookie with default locale
|
||||
setcookie('locale', $_SESSION['locale'], time() + (86400 * 30), '/', '', false, true);
|
||||
}
|
||||
|
||||
// Apply locale settings
|
||||
|
||||
@@ -49,7 +49,9 @@ function DisplayWireGuardConfig()
|
||||
exec('sudo cat '. RASPI_WIREGUARD_CONFIG, $return);
|
||||
$conf = ParseConfig($return, $parseFlag);
|
||||
$wg_srvpubkey = exec('sudo cat '. RASPI_WIREGUARD_PATH .'wg-server-public.key', $return);
|
||||
$wg_srvport = ($conf['ListenPort'] == '') ? getDefaultNetValue('wireguard','server','ListenPort') : $conf['ListenPort'];
|
||||
$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'];
|
||||
if (is_array($wg_srvdns)) {
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
* 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 (64-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.69 installed via apt)
|
||||
* php-cgi (version 8.2.28 installed via apt)
|
||||
* lighttpd (version 1.4.79 installed via apt)
|
||||
* php-fpm (version 8.4.11 installed via apt)
|
||||
* along with their supporting packages, php8.2 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 3.4.0
|
||||
* @version 3.4.5
|
||||
* @link https://github.com/RaspAP/raspap-webgui/
|
||||
* @link https://raspap.com/
|
||||
* @see http://sirlagz.net/2013/02/08/raspap-webgui/
|
||||
|
||||
@@ -34,7 +34,16 @@ if [ "$insiders" == 1 ]; then
|
||||
repo="RaspAP/raspap-insiders"
|
||||
branch=${RASPAP_INSIDERS_LATEST}
|
||||
fi
|
||||
git_source_url="https://github.com/$repo"
|
||||
|
||||
#Use ssh IF $ssh is set AND $username and $acctoken IS NOT set
|
||||
if [ -n "$username" ] && [ -n "$acctoken" ]; then
|
||||
git_source_url="https://${username}:${acctoken}@github.com/$repo"
|
||||
ssh=0
|
||||
elif [ "$ssh" == 1 ]; then
|
||||
git_source_url="git@github.com:$repo"
|
||||
else
|
||||
git_source_url="https://github.com/$repo"
|
||||
fi
|
||||
webroot_dir="/var/www/html"
|
||||
|
||||
# NOTE: all the below functions are overloadable for system-specific installs
|
||||
@@ -149,21 +158,24 @@ function _get_linux_distro() {
|
||||
# Sets php package option based on Linux version, abort if unsupported distro
|
||||
function _set_php_package() {
|
||||
case $RELEASE in
|
||||
13) # Debian 13 trixie
|
||||
php_package="php8.4-fpm"
|
||||
phpiniconf="/etc/php/8.4/fpm/php.ini" ;;
|
||||
23.05|12*) # Debian 12 & Armbian 23.05
|
||||
php_package="php8.2-cgi"
|
||||
phpcgiconf="/etc/php/8.2/cgi/php.ini" ;;
|
||||
phpiniconf="/etc/php/8.2/cgi/php.ini" ;;
|
||||
23.04) # Ubuntu Server 23.04
|
||||
php_package="php8.1-cgi"
|
||||
phpcgiconf="/etc/php/8.1/cgi/php.ini" ;;
|
||||
phpiniconf="/etc/php/8.1/cgi/php.ini" ;;
|
||||
22.04|20.04|18.04|19.10|11*) # Previous Ubuntu Server, Debian & Armbian distros
|
||||
php_package="php7.4-cgi"
|
||||
phpcgiconf="/etc/php/7.4/cgi/php.ini" ;;
|
||||
phpiniconf="/etc/php/7.4/cgi/php.ini" ;;
|
||||
10*|11*)
|
||||
php_package="php7.3-cgi"
|
||||
phpcgiconf="/etc/php/7.3/cgi/php.ini" ;;
|
||||
phpiniconf="/etc/php/7.3/cgi/php.ini" ;;
|
||||
9*)
|
||||
php_package="php7.0-cgi"
|
||||
phpcgiconf="/etc/php/7.0/cgi/php.ini" ;;
|
||||
phpiniconf="/etc/php/7.0/cgi/php.ini" ;;
|
||||
8)
|
||||
_install_status 1 "${DESC} and php5 are not supported. Please upgrade."
|
||||
exit 1 ;;
|
||||
@@ -272,6 +284,12 @@ function _install_dependencies() {
|
||||
echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections
|
||||
echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections
|
||||
sudo apt-get install -y lighttpd git hostapd dnsmasq iptables-persistent $php_package $dhcpcd_package $iw_package $rsync_package $network_tools $ifconfig_package vnstat qrencode jq isoquery || _install_status 1 "Unable to install dependencies"
|
||||
|
||||
if [[ "$php_package" == *"-fpm" ]]; then
|
||||
_install_log "Enabling lighttpd fastcgi-php-fpm module for $php_package"
|
||||
sudo lighty-enable-mod fastcgi-php-fpm || _install_status 1 "Unable to enable fastcgi-php-fpm module"
|
||||
fi
|
||||
|
||||
_install_status 0
|
||||
}
|
||||
|
||||
@@ -489,6 +507,7 @@ function _install_provider() {
|
||||
|
||||
if [ "$answer" != "${answer#[0]}" ]; then
|
||||
_install_status 0 "(Skipped)"
|
||||
skip=true
|
||||
break
|
||||
elif [[ "$answer" =~ ^[0-9]+$ ]] && [[ -n ${options[$answer]+abc} ]]; then
|
||||
break
|
||||
@@ -497,25 +516,25 @@ function _install_provider() {
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if ! [ "$skip" ]; then
|
||||
selected="${options[$answer]}"
|
||||
echo "Configuring support for ${selected%%|*}"
|
||||
bin_path=${selected#*|}
|
||||
if ! grep -q "$bin_path" "$webroot_dir/installers/raspap.sudoers"; then
|
||||
echo "Adding $bin_path to raspap.sudoers"
|
||||
echo "www-data ALL=(ALL) NOPASSWD:$bin_path *" | sudo tee -a "$webroot_dir/installers/raspap.sudoers" > /dev/null || _install_status 1 "Unable to modify raspap.sudoers"
|
||||
fi
|
||||
echo "Enabling administration option for ${selected%%|*}"
|
||||
sudo sed -i "s/\('RASPI_VPN_PROVIDER_ENABLED', \)false/\1true/g" "$webroot_dir/includes/config.php" || _install_status 1 "Unable to modify config.php"
|
||||
|
||||
selected="${options[$answer]}"
|
||||
echo "Configuring support for ${selected%%|*}"
|
||||
bin_path=${selected#*|}
|
||||
if ! grep -q "$bin_path" "$webroot_dir/installers/raspap.sudoers"; then
|
||||
echo "Adding $bin_path to raspap.sudoers"
|
||||
echo "www-data ALL=(ALL) NOPASSWD:$bin_path *" | sudo tee -a "$webroot_dir/installers/raspap.sudoers" > /dev/null || _install_status 1 "Unable to modify raspap.sudoers"
|
||||
fi
|
||||
echo "Enabling administration option for ${selected%%|*}"
|
||||
sudo sed -i "s/\('RASPI_VPN_PROVIDER_ENABLED', \)false/\1true/g" "$webroot_dir/includes/config.php" || _install_status 1 "Unable to modify config.php"
|
||||
|
||||
echo "Adding VPN provider to $raspap_dir/provider.ini"
|
||||
if [ ! -f "$raspap_dir/provider.ini" ]; then
|
||||
sudo touch "$raspap_dir/provider.ini"
|
||||
echo "providerID = $answer" | sudo tee "$raspap_dir/provider.ini" > /dev/null || _install_status 1 "Unable to create $raspap_dir/provider.ini"
|
||||
elif ! grep -q "providerID = $answer" "$raspap_dir/provider.ini"; then
|
||||
echo "providerID = $answer" | sudo tee "$raspap_dir/provider.ini" > /dev/null || _install_status 1 "Unable to write to $raspap_dir/provider.ini"
|
||||
fi
|
||||
|
||||
echo "Adding VPN provider to $raspap_dir/provider.ini"
|
||||
if [ ! -f "$raspap_dir/provider.ini" ]; then
|
||||
sudo touch "$raspap_dir/provider.ini"
|
||||
echo "providerID = $answer" | sudo tee "$raspap_dir/provider.ini" > /dev/null || _install_status 1 "Unable to create $raspap_dir/provider.ini"
|
||||
elif ! grep -q "providerID = $answer" "$raspap_dir/provider.ini"; then
|
||||
echo "providerID = $answer" | sudo tee "$raspap_dir/provider.ini" > /dev/null || _install_status 1 "Unable to write to $raspap_dir/provider.ini"
|
||||
fi
|
||||
fi
|
||||
_install_status 0
|
||||
}
|
||||
|
||||
@@ -528,6 +547,13 @@ function _install_wireguard() {
|
||||
fi
|
||||
echo "Installing wireguard from apt"
|
||||
sudo apt-get install -y wireguard $wg_dep || _install_status 1 "Unable to install wireguard"
|
||||
|
||||
# create shim for resolvconf under debian 13
|
||||
if { ! command -v resolvconf >/dev/null || [ "$RELEASE" == 13 ]; } then
|
||||
echo "Applying resolvconf shim to prevent DNS conflicts"
|
||||
sudo ln -sf /usr/bin/true /usr/local/bin/resolvconf || _install_status 1 "Failed to apply resolvconf shim"
|
||||
fi
|
||||
|
||||
echo "Enabling wg-quick@wg0"
|
||||
sudo systemctl enable wg-quick@wg0 || _install_status 1 "Failed to enable wg-quick service"
|
||||
echo "Enabling WireGuard management option"
|
||||
@@ -596,22 +622,16 @@ function _download_latest_files() {
|
||||
source_dir="/tmp/raspap-webgui"
|
||||
if [ -d "$source_dir" ]; then
|
||||
echo "Temporary download destination $source_dir exists. Removing..."
|
||||
rm -r "$source_dir"
|
||||
rm -rf "$source_dir"
|
||||
fi
|
||||
if [ "$repo" == "RaspAP/raspap-insiders" ]; then
|
||||
if [ -n "$username" ] && [ -n "$acctoken" ]; then
|
||||
insiders_source_url="https://${username}:${acctoken}@github.com/$repo"
|
||||
git clone --branch $branch --depth 1 --recurse-submodules -c advice.detachedHead=false $insiders_source_url $source_dir || clone=false
|
||||
git -C $source_dir submodule update --remote plugins || clone=false
|
||||
else
|
||||
_install_status 3
|
||||
echo "Insiders please read this: https://docs.raspap.com/insiders/#authentication"
|
||||
fi
|
||||
fi
|
||||
if [ -z "$insiders_source_url" ]; then
|
||||
git clone --branch $branch --depth 1 --recurse-submodules -c advice.detachedHead=false $git_source_url $source_dir || clone=false
|
||||
git -C $source_dir submodule update --remote plugins || clone=false
|
||||
if [ "$insiders" == 1 ] && [ "$ssh" != 1 ] && [[ -z "$username" || -z "$acctoken" ]]; then
|
||||
_install_status 3
|
||||
_install_status 0 "Insiders please read this: https://docs.raspap.com/insiders/#authentication"
|
||||
fi
|
||||
|
||||
git clone --branch $branch --depth 1 --recurse-submodules -c advice.detachedHead=false $git_source_url $source_dir || clone=false
|
||||
git -C $source_dir submodule update --remote plugins || clone=false
|
||||
|
||||
if [ "$clone" = false ]; then
|
||||
_install_status 1 "Unable to download files from GitHub"
|
||||
echo "The installer cannot continue." >&2
|
||||
@@ -956,14 +976,14 @@ function _patch_system_files() {
|
||||
function _optimize_php() {
|
||||
if [ "$upgrade" == 0 ]; then
|
||||
_install_log "Optimize PHP configuration"
|
||||
if [ ! -f "$phpcgiconf" ]; then
|
||||
if [ ! -f "$phpiniconf" ]; then
|
||||
_install_status 2 "PHP configuration could not be found."
|
||||
return
|
||||
fi
|
||||
|
||||
# Backup php.ini and create symlink for restoring.
|
||||
datetimephpconf=$(date +%F-%R)
|
||||
sudo cp "$phpcgiconf" "$raspap_dir/backups/php.ini.$datetimephpconf"
|
||||
sudo cp "$phpiniconf" "$raspap_dir/backups/php.ini.$datetimephpconf"
|
||||
sudo ln -sf "$raspap_dir/backups/php.ini.$datetimephpconf" "$raspap_dir/backups/php.ini"
|
||||
|
||||
echo -n "Enable HttpOnly for session cookies (Recommended)? [Y/n]: "
|
||||
@@ -978,7 +998,7 @@ function _optimize_php() {
|
||||
|
||||
if [ "$assume_yes" == 1 ] || [ "$php_session_cookie" == 1 ]; then
|
||||
echo "Php-cgi enabling session.cookie_httponly."
|
||||
sudo sed -i -E 's/^session\.cookie_httponly\s*=\s*(0|([O|o]ff)|([F|f]alse)|([N|n]o))\s*$/session.cookie_httponly = 1/' "$phpcgiconf"
|
||||
sudo sed -i -E 's/^session\.cookie_httponly\s*=\s*(0|([O|o]ff)|([F|f]alse)|([N|n]o))\s*$/session.cookie_httponly = 1/' "$phpiniconf"
|
||||
fi
|
||||
|
||||
if [ "$php_package" = "php7.1-cgi" ]; then
|
||||
@@ -994,7 +1014,7 @@ function _optimize_php() {
|
||||
|
||||
if [ "$assume_yes" == 1 ] || [ "$phpopcache" == 1 ]; then
|
||||
echo -e "Php-cgi enabling opcache.enable."
|
||||
sudo sed -i -E 's/^;?opcache\.enable\s*=\s*(0|([O|o]ff)|([F|f]alse)|([N|n]o))\s*$/opcache.enable = 1/' "$phpcgiconf"
|
||||
sudo sed -i -E 's/^;?opcache\.enable\s*=\s*(0|([O|o]ff)|([F|f]alse)|([N|n]o))\s*$/opcache.enable = 1/' "$phpiniconf"
|
||||
# Make sure opcache extension is turned on.
|
||||
if [ -f "/usr/sbin/phpenmod" ]; then
|
||||
sudo phpenmod opcache
|
||||
|
||||
@@ -41,6 +41,21 @@ case "$action" in
|
||||
echo "OK"
|
||||
;;
|
||||
|
||||
"deb")
|
||||
[ $# -lt 1 ] && { echo "Usage: $0 deb <deb_file>"; exit 1; }
|
||||
deb_file="$1"
|
||||
|
||||
if [ ! -f "$deb_file" ]; then
|
||||
echo "Error: File not found: $deb_file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing .deb package: $deb_file"
|
||||
dpkg -i "$deb_file"
|
||||
|
||||
echo "OK"
|
||||
;;
|
||||
|
||||
"user")
|
||||
[ $# -lt 2 ] && { echo "Usage: $0 user <username> <password>."; exit 1; }
|
||||
|
||||
|
||||
@@ -87,5 +87,6 @@ www-data ALL=(ALL) NOPASSWD:/usr/bin/nmap --script=broadcast-dhcp-discover -e [a
|
||||
www-data ALL=(ALL) NOPASSWD:/usr/bin/vnstat *
|
||||
www-data ALL=(ALL) NOPASSWD:/usr/sbin/visudo -cf *
|
||||
www-data ALL=(ALL) NOPASSWD:/etc/raspap/plugins/plugin_helper.sh
|
||||
www-data ALL=(ALL) NOPASSWD: /bin/systemctl start raspap-network-activity@*.service
|
||||
www-data ALL=(ALL) NOPASSWD: /bin/systemctl stop raspap-network-activity@*.service
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/systemctl start raspap-network-activity@*.service
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/systemctl stop raspap-network-activity@*.service
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/wpa_conf_* /etc/wpa_supplicant/wpa_supplicant.conf
|
||||
|
||||
@@ -49,6 +49,7 @@ OPTIONS:
|
||||
-b, --branch <name> Overrides the default git branch (latest release)
|
||||
-t, --token <accesstoken> Specify a GitHub token to access a private repository
|
||||
-n, --name <username> Specify a GitHub username to access a private repository
|
||||
-x, --use-ssh Use ssh instead of https for git
|
||||
-u, --upgrade Upgrades an existing installation to the latest release version
|
||||
-d, --update Updates an existing installation to the latest release version
|
||||
-p, --path <path> Used with -d, --update, sets the existing install path
|
||||
@@ -56,7 +57,7 @@ OPTIONS:
|
||||
-m, --minwrite Configures a microSD card for minimum write operation
|
||||
-k, --check <flag> Sets the connectivity check flag (default is 1=perform check)
|
||||
-v, --version Outputs release info and exits
|
||||
-n, --uninstall Loads and executes the uninstaller
|
||||
-z, --uninstall Loads and executes the uninstaller
|
||||
-h, --help Outputs usage notes and exits
|
||||
|
||||
Examples:
|
||||
@@ -106,6 +107,7 @@ function _parse_params() {
|
||||
adblock_option=1
|
||||
wg_option=1
|
||||
insiders=0
|
||||
ssh=0
|
||||
minwrite=0
|
||||
acctoken=""
|
||||
path=""
|
||||
@@ -165,6 +167,9 @@ function _parse_params() {
|
||||
-m|--minwrite)
|
||||
minwrite=1
|
||||
;;
|
||||
-x|--use-ssh)
|
||||
ssh=1
|
||||
;;
|
||||
-t|--token)
|
||||
acctoken="$2"
|
||||
shift
|
||||
@@ -187,7 +192,7 @@ function _parse_params() {
|
||||
-v|--version)
|
||||
_version
|
||||
;;
|
||||
-n|--uninstall)
|
||||
-z|--uninstall)
|
||||
uninstall=1
|
||||
;;
|
||||
-*|--*)
|
||||
@@ -308,7 +313,10 @@ function _check_internet() {
|
||||
tput civis # hide cursor
|
||||
|
||||
# run check in background
|
||||
( curl -Is --connect-timeout 3 --max-time 15 https://github.com | head -n 1 | grep "HTTP/2 200" >/dev/null ) &
|
||||
(
|
||||
curl -Is --connect-timeout 3 --max-time 15 https://github.com \
|
||||
| grep -q "^HTTP/2 200"
|
||||
) &
|
||||
local pid=$!
|
||||
|
||||
# display spinner while curl runs
|
||||
@@ -318,8 +326,9 @@ function _check_internet() {
|
||||
done
|
||||
printf "\r"
|
||||
|
||||
# check exit status of curl
|
||||
wait $pid || exit_code=$?
|
||||
# capture exit status
|
||||
wait "$pid"
|
||||
exit_code=$?
|
||||
|
||||
tput cnorm # restore cursor
|
||||
|
||||
|
||||
@@ -48,21 +48,24 @@ function _get_linux_distro() {
|
||||
# Sets php package option based on Linux version, abort if unsupported distro
|
||||
function _set_php_package() {
|
||||
case $RELEASE in
|
||||
13) # Debian 13 trixie
|
||||
php_package="php8.4-fpm"
|
||||
phpiniconf="/etc/php/8.4/fpm/php.ini" ;;
|
||||
23.05|12*) # Debian 12 & Armbian 23.05
|
||||
php_package="php8.2-cgi"
|
||||
phpcgiconf="/etc/php/8.2/cgi/php.ini" ;;
|
||||
phpiniconf="/etc/php/8.2/cgi/php.ini" ;;
|
||||
23.04) # Ubuntu Server 23.04
|
||||
php_package="php8.1-cgi"
|
||||
phpcgiconf="/etc/php/8.1/cgi/php.ini" ;;
|
||||
phpiniconf="/etc/php/8.1/cgi/php.ini" ;;
|
||||
22.04|20.04|18.04|19.10|11*) # Previous Ubuntu Server, Debian & Armbian distros
|
||||
php_package="php7.4-cgi"
|
||||
phpcgiconf="/etc/php/7.4/cgi/php.ini" ;;
|
||||
phpiniconf="/etc/php/7.4/cgi/php.ini" ;;
|
||||
10*|11*)
|
||||
php_package="php7.3-cgi"
|
||||
phpcgiconf="/etc/php/7.3/cgi/php.ini" ;;
|
||||
phpiniconf="/etc/php/7.3/cgi/php.ini" ;;
|
||||
9*)
|
||||
php_package="php7.0-cgi"
|
||||
phpcgiconf="/etc/php/7.0/cgi/php.ini" ;;
|
||||
phpiniconf="/etc/php/7.0/cgi/php.ini" ;;
|
||||
8)
|
||||
_install_error "${DESC} and php5 are unsupported."
|
||||
exit 1 ;;
|
||||
@@ -127,11 +130,11 @@ function _check_for_backups() {
|
||||
sudo cp "$raspap_dir/backups/dhcpcd.conf" /etc/dhcpcd.conf
|
||||
fi
|
||||
fi
|
||||
if [ -f "$raspap_dir/backups/php.ini" ] && [ -f "$phpcgiconf" ]; then
|
||||
if [ -f "$raspap_dir/backups/php.ini" ] && [ -f "$phpiniconf" ]; then
|
||||
echo -n "Restore the last php.ini file? [y/N]: "
|
||||
read answer
|
||||
if [[ $answer -eq 'y' ]]; then
|
||||
sudo cp "$raspap_dir/backups/php.ini" "$phpcgiconf"
|
||||
sudo cp "$raspap_dir/backups/php.ini" "$phpiniconf"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -10,7 +10,7 @@ msgstr ""
|
||||
"Project-Id-Version: 1.2.1\n"
|
||||
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
||||
"PO-Revision-Date: 2022-01-05 20:35+0000\n"
|
||||
"PO-Revision-Date: 2025-10-20 08:35+0000\n"
|
||||
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: en_US\n"
|
||||
@@ -414,9 +414,6 @@ msgstr "Signal quality"
|
||||
msgid "WAN IP"
|
||||
msgstr "WAN IP"
|
||||
|
||||
msgid "Web-GUI"
|
||||
msgstr "Web-GUI"
|
||||
|
||||
msgid "Signal strength"
|
||||
msgstr "Signal strength"
|
||||
|
||||
@@ -581,11 +578,8 @@ msgstr "This option adds <code>dhcp-host</code> entries to the dnsmasq configura
|
||||
msgid "This toggles the <code>gateway</code>/<code>nogateway</code> option for this interface in the dhcpcd.conf file."
|
||||
msgstr "This toggles the <code>gateway</code>/<code>nogateway</code> option for this interface in the dhcpcd.conf file."
|
||||
|
||||
msgid "This toggles the <code>nohook wpa_supplicant</code> option for this interface in the DHCPCD configuration."
|
||||
msgstr "This toggles the <code>nohook wpa_supplicant</code> option for this interface in the DHCPCD configuration."
|
||||
|
||||
msgid "Enable this only if you want your device to use this interface as its primary route to the internet."
|
||||
msgstr "Enable this only if you want your device to use this interface as its primary route to the internet."
|
||||
msgid "This toggles the <code>nohook wpa_supplicant</code> option for this interface in the dhcpcd.conf file."
|
||||
msgstr "This toggles the <code>nohook wpa_supplicant</code> option for this interface in the dhcpcd.conf file."
|
||||
|
||||
msgid "Disable wpa_supplicant dhcp hook for this interface"
|
||||
msgstr "Disable wpa_supplicant dhcp hook for this interface"
|
||||
@@ -735,6 +729,9 @@ msgstr "Bridged AP mode"
|
||||
msgid "WiFi repeater mode"
|
||||
msgstr "WiFi repeater mode"
|
||||
|
||||
msgid "Dual band AP mode"
|
||||
msgstr "Dual band AP mode"
|
||||
|
||||
msgid "Hide SSID in broadcast"
|
||||
msgstr "Hide SSID in broadcast"
|
||||
|
||||
@@ -837,6 +834,75 @@ msgstr "Parameter hiddenSSID contains invalid configuration value."
|
||||
msgid "Parameter hiddenSSID is not a number."
|
||||
msgstr "Parameter hiddenSSID is not a number."
|
||||
|
||||
msgid "Bridge interface configuration"
|
||||
msgstr "Bridge interface configuration"
|
||||
|
||||
msgid "Configure a static IP address for the <code>br0</code> interface to maintain connectivity during bridge mode activation."
|
||||
msgstr "Configure a static IP address for the <code>br0</code> interface to maintain connectivity during bridge mode activation."
|
||||
|
||||
msgid "Static IP Address"
|
||||
msgstr "Static IP Address"
|
||||
|
||||
msgid "Netmask / CIDR"
|
||||
msgstr "Netmask / CIDR"
|
||||
|
||||
msgid "Example: 192.168.1.100"
|
||||
msgstr "Example: 192.168.1.100"
|
||||
|
||||
msgid "CIDR notation (e.g., 24 for 255.255.255.0)"
|
||||
msgstr "CIDR notation (e.g., 24 for 255.255.255.0)"
|
||||
|
||||
msgid "Gateway"
|
||||
msgstr "Gateway"
|
||||
|
||||
msgid "Your router's IP address"
|
||||
msgstr "Your router's IP address"
|
||||
|
||||
msgid "Usually same as gateway"
|
||||
msgstr "Usually same as gateway"
|
||||
|
||||
msgid "Bridge static IP address must be a valid IPv4 address"
|
||||
msgstr "Bridge static IP address must be a valid IPv4 address"
|
||||
|
||||
msgid "Bridge netmask must be a number between 1 and 32"
|
||||
msgstr "Bridge netmask must be a number between 1 and 32"
|
||||
|
||||
msgid "Bridge netmask is required when using static IP"
|
||||
msgstr "Bridge netmask is required when using static IP"
|
||||
|
||||
msgid "Bridge gateway must be a valid IPv4 address"
|
||||
msgstr "Bridge gateway must be a valid IPv4 address"
|
||||
|
||||
msgid "Bridge gateway is required when using static IP"
|
||||
msgstr "Bridge gateway is required when using static IP"
|
||||
|
||||
msgid "Bridge DNS server must be a valid IPv4 address"
|
||||
msgstr "Bridge DNS server must be a valid IPv4 address"
|
||||
|
||||
msgid "Bridge DNS server is required when using static IP"
|
||||
msgstr "Bridge DNS server is required when using static IP"
|
||||
|
||||
msgid "Bridge static IP and gateway must be in the same subnet"
|
||||
msgstr "Bridge static IP and gateway must be in the same subnet"
|
||||
|
||||
msgid "Please enter a valid IPv4 address"
|
||||
msgstr "Please enter a valid IPv4 address"
|
||||
|
||||
msgid "Please enter a valid netmask"
|
||||
msgstr "Please enter a valid netmask"
|
||||
|
||||
msgid "DHCP configuration for br0 enabled"
|
||||
msgstr "DHCP configuration for br0 enabled"
|
||||
|
||||
msgid "Unable to save WiFi hotspot settings due to validation errors"
|
||||
msgstr "Unable to save WiFi hotspot settings due to validation errors"
|
||||
|
||||
msgid "Enable AP isolation"
|
||||
msgstr "Enable AP isolation"
|
||||
|
||||
msgid "Blocks wireless clients from seeing or connecting to each other. Recommended for guest networks and public access points."
|
||||
msgstr "Blocks wireless clients from seeing or connecting to each other. Recommended for guest networks and public access points."
|
||||
|
||||
#: includes/networking.php
|
||||
msgid "Summary"
|
||||
msgstr "Summary"
|
||||
@@ -886,14 +952,14 @@ msgstr "Devices"
|
||||
msgid "Diagnostics"
|
||||
msgstr "Diagnostics"
|
||||
|
||||
msgid "Properties of network devices"
|
||||
msgstr "Properties of network devices"
|
||||
msgid "Network devices"
|
||||
msgstr "Network devices"
|
||||
|
||||
msgid "Device"
|
||||
msgstr "Device"
|
||||
|
||||
msgid "MAC"
|
||||
msgstr "MAC"
|
||||
msgid "MAC address"
|
||||
msgstr "MAC address"
|
||||
|
||||
msgid "USB vid/pid"
|
||||
msgstr "USB vid/pid"
|
||||
@@ -907,11 +973,11 @@ msgstr "Fixed name"
|
||||
msgid "Change"
|
||||
msgstr "Change"
|
||||
|
||||
msgid "Settings for Mobile Data Devices"
|
||||
msgstr "Settings for Mobile Data Devices"
|
||||
msgid "Mobile data settings"
|
||||
msgstr "Mobile data settings"
|
||||
|
||||
msgid "PIN of SIM card"
|
||||
msgstr "PIN of SIM card"
|
||||
msgid "SIM card PIN number"
|
||||
msgstr "SIM card PIN number"
|
||||
|
||||
msgid "APN Settings (Modem device ppp0)"
|
||||
msgstr "APN Settings (Modem device ppp0)"
|
||||
@@ -1256,11 +1322,29 @@ msgstr "Installed"
|
||||
msgid "Alert messages"
|
||||
msgstr "Alert messages"
|
||||
|
||||
msgid "Alert close timeout (milliseconds)"
|
||||
msgstr "Alert close timeout (milliseconds)"
|
||||
|
||||
msgid "Automatically close alerts after a specified timeout"
|
||||
msgstr "Automatically close alerts after a specified timeout"
|
||||
|
||||
msgid "Alert close timeout (milliseconds)"
|
||||
msgstr "Alert close timeout (milliseconds)"
|
||||
msgid "To <a href=\"%s\" target=\"_blank\">inspect adapters</a> attached to this device, click or tap the button below."
|
||||
msgstr "To <a href=\"%s\" target=\"_blank\">inspect adapters</a> attached to this device, click or tap the button below."
|
||||
|
||||
msgid "The adapter inspection tool returns details about external WLAN devices including drivers, supported modes and so on."
|
||||
msgstr "The adapter inspection tool returns details about external WLAN devices including drivers, supported modes and so on."
|
||||
|
||||
msgid "Choose a network interface to inspect"
|
||||
msgstr "Choose a network interface to inspect"
|
||||
|
||||
msgid "Select an interface..."
|
||||
msgstr "Select an interface..."
|
||||
|
||||
msgid "Adapter health check"
|
||||
msgstr "Adapter health check"
|
||||
|
||||
msgid "Inspect adapters"
|
||||
msgstr "Inspect adapters"
|
||||
|
||||
#: includes/data_usage.php
|
||||
msgid "Data usage"
|
||||
@@ -2198,12 +2282,30 @@ msgstr "Configure exit node"
|
||||
msgid "The device <code>%s</code> is connected to your tailnet with the address <code>%s</code>."
|
||||
msgstr "The device <code>%s</code> is connected to your tailnet with the address <code>%s</code>."
|
||||
|
||||
msgid "By default, Tailscale only routes traffic between the devices on which it's been installed. By configuring <code>%s</code> as an <strong>exit node</strong>, your public internet traffic will be routed through this device"
|
||||
msgstr "By default, Tailscale only routes traffic between the devices on which it's been installed. By configuring <code>%s</code> as an <strong>exit node</strong>, your public internet traffic will be routed through this device"
|
||||
msgid "By default, Tailscale only routes traffic between the devices on which it's been installed. You can also route all your public internet traffic by configuring a device on your network as a <strong>exit node</strong>"
|
||||
msgstr "By default, Tailscale only routes traffic between the devices on which it's been installed. You can also route all your public internet traffic by configuring a device on your network as a <strong>exit node</strong>"
|
||||
|
||||
msgid "When you route all traffic through an exit node, you're effectively using default routes (0.0.0.0/0, ::/0), similar to how you would if you were using a typical VPN."
|
||||
msgstr "When you route all traffic through an exit node, you're effectively using default routes (0.0.0.0/0, ::/0), similar to how you would if you were using a typical VPN."
|
||||
|
||||
msgid "You have the option of configuring this device as an exit node, or using another exit node in your tailnet."
|
||||
msgstr "You have the option of configuring this device as an exit node, or using another exit node in your tailnet."
|
||||
|
||||
msgid "Select an existing exit node on your tailnet"
|
||||
msgstr "Select an existing exit node on your tailnet"
|
||||
|
||||
msgid "This is a typical configuration if you're using this device as a VPN travel router, for example."
|
||||
msgstr "This is a typical configuration if you're using this device as a VPN travel router, for example."
|
||||
|
||||
msgid "Configure this device as a new exit node"
|
||||
msgstr "Configure this device as a new exit node"
|
||||
|
||||
msgid "By configuring this device as an exit node, public internet traffic from devices connected in your tailnet will be routed through it."
|
||||
msgstr "By configuring this device as an exit node, public internet traffic from devices connected in your tailnet will be routed through it."
|
||||
|
||||
msgid "For security reasons, you must opt in to enable exit node functionality. The first step is to advertise <code>%s</code> as an exit node in your tailnet. In the next step, you'll allow this device to be an exit node."
|
||||
msgstr "For security reasons, you must opt in to enable exit node functionality. The first step is to advertise <code>%s</code> as an exit node in your tailnet. In the next step, you'll allow this device to be an exit node."
|
||||
|
||||
msgid "Advertise <code>%s</code> as an exit node"
|
||||
msgstr "Advertise <code>%s</code> as an exit node"
|
||||
|
||||
@@ -2219,12 +2321,370 @@ msgstr "Recommended for Tailscale exit nodes with Linux 6.2 or later kernels, th
|
||||
msgid "This option enables transport layer offloads for better performance."
|
||||
msgstr "This option enables transport layer offloads for better performance."
|
||||
|
||||
msgid "Select an exit node"
|
||||
msgstr "Select an exit node"
|
||||
|
||||
msgid "To use <code>%s</code> as a VPN gateway, configure Tailscale to use an exit node. Tailscale's suggested node is indicated with a star."
|
||||
msgstr "To use <code>%s</code> as a VPN gateway, configure Tailscale to use an exit node. Tailscale's suggested node is indicated with a star."
|
||||
|
||||
msgid "Advertise a <strong>subnet route</strong> for the active <code>%s</code> AP interface"
|
||||
msgstr "Advertise a <strong>subnet route</strong> for the active <code>%s</code> AP interface"
|
||||
|
||||
msgid "Subnet routes let you extend your Tailscale network (known as a tailnet) to include devices that don't or can't run the Tailscale client."
|
||||
msgstr "Subnet routes let you extend your Tailscale network (known as a tailnet) to include devices that don't or can't run the Tailscale client."
|
||||
|
||||
msgid "A subnet route acts as a gateway between your tailnet and a physical subnet. The subnet of the active AP interface is preconfigured below; edit if necessary."
|
||||
msgstr "A subnet route acts as a gateway between your tailnet and a physical subnet. The subnet of the active AP interface is preconfigured below; edit if necessary."
|
||||
|
||||
msgid "Route LAN traffic through the exit node."
|
||||
msgstr "Route LAN traffic through the exit node."
|
||||
|
||||
msgid "This will direct all LAN traffic to go through your exit node only."
|
||||
msgstr "This will direct all LAN traffic to go through your exit node only."
|
||||
|
||||
msgid "Choose <strong>Next</strong> to configure <code>%s</code> to use the selected exit node with these options."
|
||||
msgstr "Choose <strong>Next</strong> to configure <code>%s</code> to use the selected exit node with these options."
|
||||
|
||||
msgid "No exit nodes found on your tailnet. Choose <strong>Back</strong> to continue."
|
||||
msgstr "No exit nodes found on your tailnet. Choose <strong>Back</strong> to continue."
|
||||
|
||||
msgid "Using exit node"
|
||||
msgstr "Using exit node"
|
||||
|
||||
msgid "The device <code>%s</code> is configured to use exit node <code>%s</code>. It has the Tailscale MagicDNS address <code>%s</code>."
|
||||
msgstr "The device <code>%s</code> is configured to use exit node <code>%s</code>. It has the Tailscale MagicDNS address <code>%s</code>."
|
||||
|
||||
msgid "Choose <strong>Save settings</strong> to continue."
|
||||
msgstr "Choose <strong>Save settings</strong> to continue."
|
||||
|
||||
msgid "Choose <strong>Next</strong> to continue."
|
||||
msgstr "Choose <strong>Next</strong> to continue."
|
||||
|
||||
msgid "Tailnet status"
|
||||
msgstr "Tailnet status"
|
||||
|
||||
msgid "Current <code>tailnet</code> status is displayed below."
|
||||
msgstr "Current <code>tailnet</code> status is displayed below."
|
||||
|
||||
msgid "Use Tailscale DNS settings (default)."
|
||||
msgstr "Use Tailscale DNS settings (default)."
|
||||
|
||||
msgid "Uncheck to use local DNS. This sets <code>--accept-dns=false</code>."
|
||||
msgstr "Uncheck to use local DNS. This sets <code>--accept-dns=false</code>."
|
||||
|
||||
msgid "Do not use Tailscale subnets (default on Linux)."
|
||||
msgstr "Do not use Tailscale subnets (default on Linux)."
|
||||
|
||||
msgid "If subnet routes exist for your tailnet, you can route your device's traffic to a subnet router. Enabling this sets <code>--accept-routes=true</code>."
|
||||
msgstr "If subnet routes exist for your tailnet, you can route your device's traffic to a subnet router. Enabling this sets <code>--accept-routes=true</code>."
|
||||
|
||||
msgid "If keys expire for a device, connections to/from the given endpoint will stop working."
|
||||
msgstr "If keys expire for a device, connections to/from the given endpoint will stop working."
|
||||
|
||||
msgid "This option uses <code>--force-reauth</code> to renew the keys for this device."
|
||||
msgstr "This option uses <code>--force-reauth</code> to renew the keys for this device."
|
||||
|
||||
#: wireshark plugin
|
||||
|
||||
msgid "Start capture"
|
||||
msgstr "Start capture"
|
||||
|
||||
msgid "Stop capture"
|
||||
msgstr "Stop capture"
|
||||
|
||||
msgid "Capture files"
|
||||
msgstr "Capture files"
|
||||
|
||||
msgid "Capture interface"
|
||||
msgstr "Capture interface"
|
||||
|
||||
msgid "Output file"
|
||||
msgstr "Output file"
|
||||
|
||||
msgid "Path where capture file will be saved (.pcap format)"
|
||||
msgstr "Path where capture file will be saved (.pcap format)"
|
||||
|
||||
msgid "File will be saved with .pcap extension"
|
||||
msgstr "File will be saved with .pcap extension"
|
||||
|
||||
msgid "Capture filter (BPF syntax)"
|
||||
msgstr "Capture filter (BPF syntax)"
|
||||
|
||||
msgid "Berkeley Packet Filter syntax. Leave empty to capture all traffic."
|
||||
msgstr "Berkeley Packet Filter syntax. Leave empty to capture all traffic."
|
||||
|
||||
msgid "Examples: <code>port 80</code>, <code>host 192.168.1.1</code>, <code>tcp and not port 22</code>"
|
||||
msgstr "Examples: <code>port 80</code>, <code>host 192.168.1.1</code>, <code>tcp and not port 22</code>"
|
||||
|
||||
msgid "Capture limits"
|
||||
msgstr "Capture limits"
|
||||
|
||||
msgid "Packet count limit"
|
||||
msgstr "Packet count limit"
|
||||
|
||||
msgid "Stop capture after this many packets. Leave empty for unlimited."
|
||||
msgstr "Stop capture after this many packets. Leave empty for unlimited."
|
||||
|
||||
msgid "Duration limit (seconds)"
|
||||
msgstr "Duration limit (seconds)"
|
||||
|
||||
msgid "Stop capture after this many seconds. Leave empty for unlimited."
|
||||
msgstr "Stop capture after this many seconds. Leave empty for unlimited."
|
||||
|
||||
msgid "Ring buffer settings"
|
||||
msgstr "Ring buffer settings"
|
||||
|
||||
msgid "File size (KB)"
|
||||
msgstr "File size (KB)"
|
||||
|
||||
msgid "Create new file when this size is reached. Leave empty to disable."
|
||||
msgstr "Create new file when this size is reached. Leave empty to disable."
|
||||
|
||||
msgid "10000 = 10 MB per file"
|
||||
msgstr "10000 = 10 MB per file"
|
||||
|
||||
msgid "Number of files"
|
||||
msgstr "Number of files"
|
||||
|
||||
msgid "Maximum number of ring buffer files to keep. Oldest files are deleted."
|
||||
msgstr "Maximum number of ring buffer files to keep. Oldest files are deleted."
|
||||
|
||||
msgid "Advanced options"
|
||||
msgstr "Advanced options"
|
||||
|
||||
msgid "Snapshot length (bytes)"
|
||||
msgstr "Snapshot length (bytes)"
|
||||
|
||||
msgid "Limit the amount of data captured per packet. Leave empty for full packets."
|
||||
msgstr "Limit the amount of data captured per packet. Leave empty for full packets."
|
||||
|
||||
msgid "96 bytes captures headers only, reduces file size"
|
||||
msgstr "96 bytes captures headers only, reduces file size"
|
||||
|
||||
msgid "Promiscuous mode"
|
||||
msgstr "Promiscuous mode"
|
||||
|
||||
msgid "Capture all packets on the network segment, not just those destined for this interface"
|
||||
msgstr "Capture all packets on the network segment, not just those destined for this interface"
|
||||
|
||||
msgid "Quick filter presets"
|
||||
msgstr "Quick filter presets"
|
||||
|
||||
msgid "Capture files generated by <code>tshark</code> are displayed below."
|
||||
msgstr "Capture files generated by <code>tshark</code> are displayed below."
|
||||
|
||||
msgid "No capture files found in /tmp directory"
|
||||
msgstr "No capture files found in /tmp directory"
|
||||
|
||||
msgid "Filename"
|
||||
msgstr "Filename"
|
||||
|
||||
msgid "Size"
|
||||
msgstr "Size"
|
||||
|
||||
msgid "Modified"
|
||||
msgstr "Modified"
|
||||
|
||||
msgid "Actions"
|
||||
msgstr "Actions"
|
||||
|
||||
msgid "Download file"
|
||||
msgstr "Download file"
|
||||
|
||||
msgid "Delete file"
|
||||
msgstr "Delete file"
|
||||
|
||||
msgid "Confirm deletion"
|
||||
msgstr "Confirm deletion"
|
||||
|
||||
msgid "Are you sure you want to delete this file?"
|
||||
msgstr "Are you sure you want to delete this file?"
|
||||
|
||||
msgid "All Traffic"
|
||||
msgstr "All Traffic"
|
||||
|
||||
msgid "HTTP/HTTPS"
|
||||
msgstr "HTTP/HTTPS"
|
||||
|
||||
msgid "ICMP (Ping)"
|
||||
msgstr "ICMP (Ping)"
|
||||
|
||||
msgid "SSH"
|
||||
msgstr "SSH"
|
||||
|
||||
msgid "Exclude SSH"
|
||||
msgstr "Exclude SSH"
|
||||
|
||||
msgid "A Wireshark (TShark) CLI packet capture for RaspAP"
|
||||
msgstr "A Wireshark (TShark) CLI packet capture for RaspAP"
|
||||
|
||||
msgid "Information provided by tshark"
|
||||
msgstr "Information provided by tshark"
|
||||
|
||||
msgid "Total: %d file(s), %s"
|
||||
msgstr "Total: %d file(s), %s"
|
||||
|
||||
#: captive portal plugin
|
||||
|
||||
msgid "Captive portal"
|
||||
msgstr "Captive portal"
|
||||
|
||||
msgid "Gateway interface"
|
||||
msgstr "Gateway interface"
|
||||
|
||||
msgid "Gateway name"
|
||||
msgstr "Gateway name"
|
||||
|
||||
msgid "Gateway address"
|
||||
msgstr "Gateway address"
|
||||
|
||||
msgid "Gateway port"
|
||||
msgstr "Gateway port"
|
||||
|
||||
msgid "Defaults to the active AP interface, typically <code>wlan0</code>"
|
||||
msgstr "Defaults to the active AP interface, typically <code>wlan0</code>"
|
||||
|
||||
msgid "Auto-detected from gateway interface if not specified"
|
||||
msgstr "Auto-detected from gateway interface if not specified"
|
||||
|
||||
msgid "Start portal"
|
||||
msgstr "Start portal"
|
||||
|
||||
msgid "Stop portal"
|
||||
msgstr "Stop portal"
|
||||
|
||||
msgid "Information provided by nodogsplash"
|
||||
msgstr "Information provided by nodogsplash"
|
||||
|
||||
msgid "Stop portal service"
|
||||
msgstr "Stop portal service"
|
||||
|
||||
msgid "Start portal service"
|
||||
msgstr "Start portal service"
|
||||
|
||||
msgid "Changing the portal service will momentarily disrupt client traffic. Choose <strong>Proceed</strong> to continue."
|
||||
msgstr "Changing the portal service will momentarily disrupt client traffic. Choose <strong>Proceed</strong> to continue."
|
||||
|
||||
msgid "Interface to be managed by the portal"
|
||||
msgstr "Interface to be managed by the portal"
|
||||
|
||||
msgid "Name of your gateway (available as \\$gatewayname variable)"
|
||||
msgstr "Name of your gateway (available as \\$gatewayname variable)"
|
||||
|
||||
msgid "IP address of the router. Leave empty for auto-detection"
|
||||
msgstr "IP address of the router. Leave empty for auto-detection"
|
||||
|
||||
msgid "Port for Nodogsplash HTTP server"
|
||||
msgstr "Port for Nodogsplash HTTP server"
|
||||
|
||||
msgid "Maximum clients"
|
||||
msgstr "Maximum clients"
|
||||
|
||||
msgid "Session timeout (minutes)"
|
||||
msgstr "Session timeout (minutes)"
|
||||
|
||||
msgid "Pre-auth idle timeout (minutes)"
|
||||
msgstr "Pre-auth idle timeout (minutes)"
|
||||
|
||||
msgid "Does not include users on the trusted MAC list"
|
||||
msgstr "Does not include users on the trusted MAC list"
|
||||
|
||||
msgid "Auth idle timeout (minutes)"
|
||||
msgstr "Auth idle timeout (minutes)"
|
||||
|
||||
msgid "Check interval (seconds)"
|
||||
msgstr "Check interval (seconds)"
|
||||
|
||||
msgid "MAC address control"
|
||||
msgstr "MAC address control"
|
||||
|
||||
msgid "MAC mechanism"
|
||||
msgstr "MAC mechanism"
|
||||
|
||||
msgid "Blocked MAC list"
|
||||
msgstr "Blocked MAC list"
|
||||
|
||||
msgid "Trusted MAC list"
|
||||
msgstr "Trusted MAC list"
|
||||
|
||||
msgid "These devices are not subject to authentication or firewall rules"
|
||||
msgstr "These devices are not subject to authentication or firewall rules"
|
||||
|
||||
msgid "Maximum number of concurrent authenticated users"
|
||||
msgstr "Maximum number of concurrent authenticated users"
|
||||
|
||||
msgid "Default session length in minutes. 0 = unlimited"
|
||||
msgstr "Default session length in minutes. 0 = unlimited"
|
||||
|
||||
msgid "Time before unauthenticated idle users are removed"
|
||||
msgstr "Time before unauthenticated idle users are removed"
|
||||
|
||||
msgid "Time before authenticated idle users are deauthenticated"
|
||||
msgstr "Time before authenticated idle users are deauthenticated"
|
||||
|
||||
msgid "How often to check client timeouts"
|
||||
msgstr "How often to check client timeouts"
|
||||
|
||||
msgid "Block: blocklisted MACs are blocked. Allow: only allowlisted MACs are allowed"
|
||||
msgstr "Block: blocklisted MACs are blocked. Allow: only allowlisted MACs are allowed"
|
||||
|
||||
msgid "Example: <code>00:11:22:33:44:55,AA:BB:CC:DD:EE:FF</code>"
|
||||
msgstr "Example: <code>00:11:22:33:44:55,AA:BB:CC:DD:EE:FF</code>"
|
||||
|
||||
msgid "Comma-separated MAC addresses that bypass authentication entirely"
|
||||
msgstr "Comma-separated MAC addresses that bypass authentication entirely"
|
||||
|
||||
msgid "Block (blocklist mode)"
|
||||
msgstr "Block (blocklist mode)"
|
||||
|
||||
msgid "Allow (allowlist mode)"
|
||||
msgstr "Allow (allowlist mode)"
|
||||
|
||||
msgid "Gateway IP range"
|
||||
msgstr "Gateway IP range"
|
||||
|
||||
msgid "Default: 0.0.0.0/0 (all addresses)"
|
||||
msgstr "Default: 0.0.0.0/0 (all addresses)"
|
||||
|
||||
msgid "Debug level"
|
||||
msgstr "Debug level"
|
||||
|
||||
msgid "Firewall settings"
|
||||
msgstr "Firewall settings"
|
||||
|
||||
msgid "Allow all traffic for authenticated users"
|
||||
msgstr "Allow all traffic for authenticated users"
|
||||
|
||||
msgid "Allow DNS for pre-authenticated users"
|
||||
msgstr "Allow DNS for pre-authenticated users"
|
||||
|
||||
msgid "IP range to manage in CIDR notation. Leave empty for all addresses"
|
||||
msgstr "IP range to manage in CIDR notation. Leave empty for all addresses"
|
||||
|
||||
msgid "Amount of logging detail reported by the nodogsplash.service"
|
||||
msgstr "Amount of logging detail reported by the nodogsplash.service"
|
||||
|
||||
msgid "0 - Errors only"
|
||||
msgstr "0 - Errors only"
|
||||
|
||||
msgid "1 - Errors, warnings, infos"
|
||||
msgstr "1 - Errors, warnings, infos"
|
||||
|
||||
msgid "2 - Errors, warnings, infos, verbose"
|
||||
msgstr "2 - Errors, warnings, infos, verbose"
|
||||
|
||||
msgid "3 - Errors, warnings, infos, verbose, debug"
|
||||
msgstr "3 - Errors, warnings, infos, verbose, debug"
|
||||
|
||||
msgid "When enabled, authenticated users have unrestricted access"
|
||||
msgstr "When enabled, authenticated users have unrestricted access"
|
||||
|
||||
msgid "Required for clients to resolve domain names before authentication"
|
||||
msgstr "Required for clients to resolve domain names before authentication"
|
||||
|
||||
msgid "Portal status"
|
||||
msgstr "Portal status"
|
||||
|
||||
msgid "Current <code>nodogsplash</code> status is displayed below."
|
||||
msgstr "Current <code>nodogsplash</code> status is displayed below."
|
||||
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
2
plugins
2
plugins
Submodule plugins updated: 054f6bc0ab...deb689143e
@@ -79,12 +79,17 @@ class HTTPAuth
|
||||
*/
|
||||
public function logout(): void
|
||||
{
|
||||
$locale = $_SESSION['locale'] ?? 'en_GB.UTF-8'; // save locale
|
||||
session_regenerate_id(true); // generate a new session id
|
||||
session_unset(); // unset all session variables
|
||||
session_destroy(); // destroy the session
|
||||
session_start();
|
||||
$_SESSION['locale'] = $locale;
|
||||
setcookie('locale', $locale, time() + (86400 * 30), '/', '', false, true);
|
||||
$basePath = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/');
|
||||
$redirectUrl = $_SERVER['REQUEST_URI'];
|
||||
if (strpos($redirectUrl, '/login') === false) {
|
||||
header('Location: /login?action=' . urlencode($redirectUrl));
|
||||
header('Location: ' . $basePath . '/login?action=' . urlencode(basename($redirectUrl)));
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class HtmlErrorRenderer
|
||||
public function __construct()
|
||||
{
|
||||
$this->charset = 'UTF-8';
|
||||
$this->projectDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
$this->projectDir = dirname(__DIR__, 3);
|
||||
$this->template = '/templates/exception.php';
|
||||
$this->debug = true;
|
||||
}
|
||||
|
||||
@@ -36,12 +36,13 @@ class DhcpcdManager
|
||||
bool $repeaterEnable,
|
||||
bool $wifiAPEnable,
|
||||
bool $dualAPEnable,
|
||||
?array $bridgeConfig = null,
|
||||
StatusMessage $status
|
||||
): bool
|
||||
{
|
||||
// determine static IP, routers, DNS
|
||||
$jsonData = $this->getInterfaceConfig($ap_iface);
|
||||
//error_log("DhcpcdManager::buildConfig() jsonData =" . print_r($jsonData, true));
|
||||
|
||||
$ip_address = empty($jsonData['StaticIP'])
|
||||
? getDefaultNetValue('dhcp', $ap_iface, 'static ip_address')
|
||||
: $jsonData['StaticIP'];
|
||||
@@ -61,9 +62,14 @@ class DhcpcdManager
|
||||
|
||||
if ($bridgedEnable) {
|
||||
$config = array_keys(getDefaultNetOpts('dhcp', 'options'));
|
||||
$config[] = '';
|
||||
$config[] = '# RaspAP br0 configuration';
|
||||
$config[] = 'denyinterfaces eth0 wlan0';
|
||||
$config[] = 'interface br0';
|
||||
$config[] = 'static ip_address='.$bridgeConfig['staticIp'] . '/'. $bridgeConfig['netmask'];
|
||||
$config[] = 'static routers='.$bridgeConfig['gateway'];
|
||||
$config[] = 'static domain_name_server='.$bridgeConfig['dns'];
|
||||
$config[] = PHP_EOL;
|
||||
} elseif ($repeaterEnable) {
|
||||
$config = [
|
||||
'# RaspAP ' . $ap_iface . ' configuration',
|
||||
@@ -110,7 +116,10 @@ class DhcpcdManager
|
||||
|
||||
if (preg_match('/wlan[3-9]\d*|wlan[1-9]\d+/', $ap_iface)) {
|
||||
$skip_dhcp = true;
|
||||
} elseif ($bridgedEnable == 1 || $wifiAPEnable == 1) {
|
||||
} elseif ($bridgedEnable == 1) {
|
||||
$dhcp_cfg = join(PHP_EOL, $config);
|
||||
$status->addMessage('DHCP configuration for br0 enabled', 'success');
|
||||
} elseif ($wifiAPEnable == 1) {
|
||||
$dhcp_cfg = join(PHP_EOL, $config);
|
||||
$status->addMessage(sprintf(_('DHCP configuration for %s enabled.'), $ap_iface), 'success');
|
||||
} elseif (!preg_match('/^interface\s'.$ap_iface.'$/m', $dhcp_cfg)) {
|
||||
@@ -485,6 +494,21 @@ class DhcpcdManager
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// fallback to defaults
|
||||
$rangeRaw = getDefaultNetValue('dnsmasq', $iface, 'dhcp-range');
|
||||
if ($rangeRaw) {
|
||||
$result['DHCPEnabled'] = true;
|
||||
$rangeParts = explode(',', $rangeRaw);
|
||||
$result['RangeStart'] = $rangeParts[0] ?? null;
|
||||
$result['RangeEnd'] = $rangeParts[1] ?? null;
|
||||
$result['RangeMask'] = $rangeParts[2] ?? null;
|
||||
$leaseSpec = $rangeParts[3] ?? null;
|
||||
if ($leaseSpec && preg_match('/^(\d+)([smhd])?$/i', $leaseSpec, $m)) {
|
||||
$result['leaseTime'] = $m[1];
|
||||
$result['leaseTimeInterval'] = $m[2] ?? 'h';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dhcpcd
|
||||
@@ -513,6 +537,11 @@ class DhcpcdManager
|
||||
$result['FallbackEnabled'] = (bool) preg_match('/fallback\s+static_' . preg_quote($iface, '/') . '/i', $block);
|
||||
$result['DefaultRoute'] = (bool) preg_match('/\bgateway\b/', $block);
|
||||
$result['NoHookWPASupplicant'] = (bool) preg_match('/nohook\s+wpa_supplicant/i', $block);
|
||||
} else {
|
||||
$result['StaticIP'] = getDefaultNetValue('dhcp', $iface, 'static ip_address');
|
||||
$result['SubnetMask'] = getDefaultNetValue('dhcp', $iface, 'subnetmask');
|
||||
$result['StaticRouters'] = getDefaultNetValue('dhcp', $iface, 'static routers');
|
||||
$result['StaticDNS'] = getDefaultNetValue('dhcp', $iface, 'static domain_name_server');
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
|
||||
@@ -61,8 +61,17 @@ class DnsmasqManager
|
||||
* @return array $config
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function buildConfig(array $syscfg, string $iface, bool $wifiAPEnable, bool $bridgedEnable): array
|
||||
public function buildConfig(?array $syscfg, string $iface, bool $wifiAPEnable, bool $bridgedEnable): array
|
||||
{
|
||||
// fallback: if no syscfg for interface seed with defaults
|
||||
if ($syscfg === null) {
|
||||
$syscfg = [];
|
||||
$dhcp_range = getDefaultNetValue('dnsmasq', $iface, 'dhcp-range');
|
||||
if ($dhcp_range !== false) {
|
||||
$syscfg['dhcp-range'] = $dhcp_range;
|
||||
}
|
||||
}
|
||||
|
||||
if ($wifiAPEnable == 1) {
|
||||
// Enable uap0 configuration for ap-sta mode
|
||||
// Set dhcp-range from system config, fallback to default if undefined
|
||||
@@ -159,7 +168,7 @@ class DnsmasqManager
|
||||
if ($post_data['no-resolv'] == "1") {
|
||||
$config[] = "no-resolv";
|
||||
}
|
||||
foreach ($post_data['server'] as $server) {
|
||||
foreach (($post_data['server'] ?? []) as $server) {
|
||||
$config[] = "server=$server";
|
||||
}
|
||||
if (!empty($post_data['DNS1'])) {
|
||||
|
||||
@@ -136,65 +136,84 @@ class HotspotService
|
||||
// validate config from post data
|
||||
$validated = $this->hostapd->validate($post_data, $wpa_array, $enc_types, $modes, $interfaces, $reg_domain, $status);
|
||||
|
||||
if ($validated !== false) {
|
||||
if ($validated === false) {
|
||||
$status->addMessage('Unable to save WiFi hotspot settings due to validation errors', 'danger');
|
||||
error_log("HotspotService::validate() -> validated = false");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// normalize state flags
|
||||
$validated['interface'] = $apIface;
|
||||
$validated['bridge'] = !empty($states['BridgedEnable']);
|
||||
$validated['apsta'] = !empty($states['WifiAPEnable']);
|
||||
$validated['repeater'] = !empty($states['RepeaterEnable']);
|
||||
$validated['dualmode'] = !empty($states['DualAPEnable']);
|
||||
$validated['txpower'] = $post_data['txpower'];
|
||||
|
||||
// hostapd
|
||||
$config = $this->hostapd->buildConfig($validated, $status);
|
||||
$this->hostapd->saveConfig($config, $dualAPEnable, $validated['interface']);
|
||||
$this->maybeSetRegDomain($post_data['country_code'], $status);
|
||||
|
||||
$status->addMessage('WiFi hotspot settings saved.', 'success');
|
||||
|
||||
// dnsmasq
|
||||
try {
|
||||
// normalize state flags
|
||||
$validated['interface'] = $apIface;
|
||||
$validated['bridge'] = !empty($states['BridgedEnable']);
|
||||
$validated['apsta'] = !empty($states['WifiAPEnable']);
|
||||
$validated['repeater'] = !empty($states['RepeaterEnable']);
|
||||
$validated['dualmode'] = !empty($states['DualAPEnable']);
|
||||
$validated['txpower'] = $post_data['txpower'];
|
||||
|
||||
// hostapd
|
||||
$config = $this->hostapd->buildConfig($validated, $status);
|
||||
$this->hostapd->saveConfig($config, $dualAPEnable, $validated['interface']);
|
||||
$this->maybeSetRegDomain($post_data['country_code'], $status);
|
||||
|
||||
$status->addMessage('WiFi hotspot settings saved.', 'success');
|
||||
|
||||
// dnsmasq
|
||||
try {
|
||||
$syscfg = $this->dnsmasq->getConfig($validated['interface'] ?? RASPI_WIFI_AP_INTERFACE);
|
||||
} catch (\RuntimeException $e) {
|
||||
error_log('Error: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
$dnsmasqConfig = $this->dnsmasq->buildConfig(
|
||||
$syscfg,
|
||||
$validated['interface'],
|
||||
$validated['apsta'],
|
||||
$validated['bridge']
|
||||
);
|
||||
$this->dnsmasq->saveConfig($dnsmasqConfig, $validated['interface'], $status);
|
||||
} catch (\RuntimeException $e) {
|
||||
error_log('Error: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// dhcpcd
|
||||
try {
|
||||
$return = $this->dhcpcd->buildConfig(
|
||||
$validated['interface'],
|
||||
$validated['bridge'],
|
||||
$validated['repeater'],
|
||||
$validated['apsta'],
|
||||
$validated['dualmode'],
|
||||
$status,
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
error_log('Error: ' . $e->getMessage());
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
error_log(sprintf(
|
||||
"Error: %s in %s on line %d\nStack trace:\n%s",
|
||||
$e->getMessage(),
|
||||
$e->getFile(),
|
||||
$e->getLine(),
|
||||
$e->getTraceAsString()
|
||||
));
|
||||
$status->addMessage('Unable to save WiFi hotspot settings', 'danger');
|
||||
$syscfg = $this->dnsmasq->getConfig($validated['interface'] ?? RASPI_WIFI_AP_INTERFACE);
|
||||
} catch (\RuntimeException $e) {
|
||||
error_log('Error: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
$dnsmasqConfig = $this->dnsmasq->buildConfig(
|
||||
$syscfg,
|
||||
$validated['interface'],
|
||||
$validated['apsta'],
|
||||
$validated['bridge']
|
||||
);
|
||||
$this->dnsmasq->saveConfig($dnsmasqConfig, $validated['interface'], $status);
|
||||
} catch (\RuntimeException $e) {
|
||||
error_log('Error: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// dhcpcd
|
||||
// pass bridge configuration if available
|
||||
try {
|
||||
$bridgeConfig = null;
|
||||
if ($validated['bridge'] && !empty($validated['bridgeStaticIp'])) {
|
||||
$bridgeConfig = [
|
||||
'staticIp' => $validated['bridgeStaticIp'],
|
||||
'netmask' => $validated['bridgeNetmask'],
|
||||
'gateway' => $validated['bridgeGateway'],
|
||||
'dns' => $validated['bridgeDNS']
|
||||
];
|
||||
}
|
||||
|
||||
$return = $this->dhcpcd->buildConfig(
|
||||
$validated['interface'],
|
||||
$validated['bridge'],
|
||||
$validated['repeater'],
|
||||
$validated['apsta'],
|
||||
$validated['dualmode'],
|
||||
$bridgeConfig,
|
||||
$status,
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
error_log('Error: ' . $e->getMessage());
|
||||
$status->addMessage('Error configuring DHCP: ' . $e->getMessage(), 'danger');
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
error_log(sprintf(
|
||||
"Error: %s in %s on line %d\nStack trace:\n%s",
|
||||
$e->getMessage(),
|
||||
$e->getFile(),
|
||||
$e->getLine(),
|
||||
$e->getTraceAsString()
|
||||
));
|
||||
$status->addMessage('Unable to save WiFi hotspot settings', 'danger');
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -117,6 +117,66 @@ class HostapdValidator
|
||||
$post['max_num_sta'] = $post['max_num_sta'] > 2007 ? 2007 : $post['max_num_sta'];
|
||||
$post['max_num_sta'] = $post['max_num_sta'] < 1 ? null : $post['max_num_sta'];
|
||||
|
||||
// validate bridged mode static IP configuration
|
||||
$bridgedEnable = !empty($post['bridgedEnable']);
|
||||
$bridgeStaticIp = trim($post['bridgeStaticIp'] ?? '');
|
||||
$bridgeNetmask = trim($post['bridgeNetmask'] ?? '');
|
||||
$bridgeGateway = trim($post['bridgeGateway'] ?? '');
|
||||
$bridgeDNS = trim($post['bridgeDNS'] ?? '');
|
||||
|
||||
if ($bridgedEnable) {
|
||||
// validate static IP address
|
||||
if (!filter_var($bridgeStaticIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
$status->addMessage('Bridge static IP address must be a valid IPv4 address', 'danger');
|
||||
$goodInput = false;
|
||||
}
|
||||
|
||||
// validate netmask (CIDR notation)
|
||||
if (!empty($bridgeNetmask)) {
|
||||
if (!ctype_digit($bridgeNetmask) || (int)$bridgeNetmask < 1 || (int)$bridgeNetmask > 32) {
|
||||
$status->addMessage('Bridge netmask must be a number between 1 and 32', 'danger');
|
||||
$goodInput = false;
|
||||
}
|
||||
} else {
|
||||
$status->addMessage('Bridge netmask is required when using static IP', 'danger');
|
||||
$goodInput = false;
|
||||
}
|
||||
|
||||
// validate gateway
|
||||
if (!empty($bridgeGateway)) {
|
||||
if (!filter_var($bridgeGateway, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
$status->addMessage('Bridge gateway must be a valid IPv4 address', 'danger');
|
||||
$goodInput = false;
|
||||
}
|
||||
} else {
|
||||
$status->addMessage('Bridge gateway is required when using static IP', 'danger');
|
||||
$goodInput = false;
|
||||
}
|
||||
|
||||
// validate DNS server
|
||||
if (!empty($bridgeDNS)) {
|
||||
if (!filter_var($bridgeDNS, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
$status->addMessage('Bridge DNS server must be a valid IPv4 address', 'danger');
|
||||
$goodInput = false;
|
||||
}
|
||||
} else {
|
||||
$status->addMessage('Bridge DNS server is required when using static IP', 'danger');
|
||||
$goodInput = false;
|
||||
}
|
||||
|
||||
// validate that static IP and gateway are in the same subnet
|
||||
if ($goodInput && !empty($bridgeStaticIp) && !empty($bridgeGateway) && !empty($bridgeNetmask)) {
|
||||
$ipLong = ip2long($bridgeStaticIp);
|
||||
$gatewayLong = ip2long($bridgeGateway);
|
||||
$mask = -1 << (32 - (int)$bridgeNetmask);
|
||||
|
||||
if (($ipLong & $mask) !== ($gatewayLong & $mask)) {
|
||||
$status->addMessage('Bridge static IP and gateway must be in the same subnet', 'danger');
|
||||
$goodInput = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$goodInput) {
|
||||
return false;
|
||||
}
|
||||
@@ -136,7 +196,11 @@ class HostapdValidator
|
||||
'max_num_sta' => $post['max_num_sta'],
|
||||
'beacon_interval' => $post['beacon_interval'] ?? null,
|
||||
'disassoc_low_ack' => $post['disassoc_low_ackEnable'] ?? null,
|
||||
'bridge' => ($post['bridgedEnable'] ?? false) ? 'br0' : null
|
||||
'bridge' => ($post['bridgedEnable'] ?? false) ? 'br0' : null,
|
||||
'bridgeStaticIp' => ($post['bridgeStaticIp']),
|
||||
'bridgeNetmask' => ($post['bridgeNetmask']),
|
||||
'bridgeGateway' => ($post['bridgeGateway']),
|
||||
'bridgeDNS' => ($post['bridgeDNS'])
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -313,6 +313,8 @@ class WiFiManager
|
||||
*/
|
||||
public function setKnownStationsWPA($networks)
|
||||
{
|
||||
$this->ensureWpaSupplicant();
|
||||
|
||||
$iface = escapeshellarg($_SESSION['wifi_client_interface']);
|
||||
$output = shell_exec("sudo wpa_cli -i $iface list_networks 2>&1");
|
||||
|
||||
@@ -475,5 +477,41 @@ class WiFiManager
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures /etc/wpa_supplicant/wpa_supplicant.conf exists with minimal safe contents
|
||||
* Does not overwrite an existing file
|
||||
*
|
||||
* @throws \RuntimeException on permission or write failure
|
||||
*/
|
||||
public function ensureWpaSupplicant(): void
|
||||
{
|
||||
$confPath = '/etc/wpa_supplicant/wpa_supplicant.conf';
|
||||
|
||||
if (file_exists($confPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$contents = <<<CONF
|
||||
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
|
||||
update_config=1
|
||||
CONF;
|
||||
|
||||
$tmpFile = tempnam(sys_get_temp_dir(), 'wpa_conf_');
|
||||
if ($tmpFile === false) {
|
||||
throw new \RuntimeException("Failed to create temporary file for wpa_supplicant.conf");
|
||||
}
|
||||
|
||||
file_put_contents($tmpFile, $contents);
|
||||
chmod($tmpFile, 0600);
|
||||
|
||||
$cmd = escapeshellcmd("sudo cp $tmpFile $confPath");
|
||||
exec($cmd, $output, $exitCode);
|
||||
unlink($tmpFile);
|
||||
|
||||
if ($exitCode !== 0) {
|
||||
throw new \RuntimeException("Failed to initialize wpa_supplicant.conf: " . implode("\n", $output));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class PluginInstaller
|
||||
$this->tempSudoers = '/tmp/090_';
|
||||
$this->destSudoers = '/etc/sudoers.d/';
|
||||
$this->refModules = '/refs/heads/master/.gitmodules';
|
||||
$this->rootPath = $_SERVER['DOCUMENT_ROOT'];
|
||||
$this->rootPath = dirname(__DIR__, 3);
|
||||
$this->pluginsManifest = '/plugins/manifest.json';
|
||||
$this->repoPublic = $this->getRepository();
|
||||
$this->helperScriptPath = RASPI_CONFIG.'/plugins/plugin_helper.sh';
|
||||
@@ -197,6 +197,10 @@ class PluginInstaller
|
||||
$this->installDependencies($manifest['dependencies']);
|
||||
$rollbackStack[] = 'uninstallDependencies';
|
||||
}
|
||||
if (!empty($manifest['dpkgs'])) {
|
||||
$this->installDebianPackages($manifest['dpkgs'], $pluginDir);
|
||||
$rollbackStack[] = 'uninstallDebianPackages';
|
||||
}
|
||||
if (!empty($manifest['user_nonprivileged'])) {
|
||||
$this->createUser($manifest['user_nonprivileged']);
|
||||
$rollbackStack[] = 'deleteUser';
|
||||
@@ -285,6 +289,54 @@ class PluginInstaller
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs a Debian package (.deb) for the current architecture
|
||||
*
|
||||
* @param array $dpkgs
|
||||
* @param string $pluginDir
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function installDebianPackages(array $dpkgs, string $pluginDir): void
|
||||
{
|
||||
$arch = trim(shell_exec('dpkg --print-architecture'));
|
||||
if (empty($arch)) {
|
||||
throw new \Exception('Unable to detect system architecture');
|
||||
}
|
||||
|
||||
// match .deb file for current arch
|
||||
$debFile = null;
|
||||
foreach ($dpkgs as $pkg) {
|
||||
if (strpos($pkg, $arch) !== false) {
|
||||
$debFile = $pkg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$debFile) {
|
||||
throw new \Exception("No matching .deb package found for architecture: $arch");
|
||||
}
|
||||
|
||||
$debPath = realpath(rtrim($pluginDir, '/') . '/dpkgs/' . $debFile);
|
||||
if ($debPath === false || !is_file($debPath)) {
|
||||
throw new \Exception("Debian package not found: $debFile");
|
||||
}
|
||||
|
||||
// invoke the plugin-helper
|
||||
$cmd = sprintf(
|
||||
'sudo %s deb %s 2>&1',
|
||||
escapeshellcmd($this->helperScriptPath), escapeshellarg($debPath)
|
||||
);
|
||||
$return = shell_exec($cmd);
|
||||
|
||||
// check for success
|
||||
if (stripos($return, 'ok') === false) {
|
||||
throw new \Exception("Plugin helper failed to install .deb package: $debFile\nOutput: $return");
|
||||
}
|
||||
|
||||
error_log("Installed Debian package: $debFile for arch $arch");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a non-priviledged Linux user
|
||||
*
|
||||
@@ -317,7 +369,7 @@ class PluginInstaller
|
||||
$source = escapeshellarg($pluginDir . DIRECTORY_SEPARATOR . $config['source']);
|
||||
$destination = $config['destination'];
|
||||
|
||||
if (!str_starts_with($destination, '/')) {
|
||||
if (strncmp($destination, '/', 1) !== 0) {
|
||||
$destination = $this->rootPath . '/' . ltrim($destination, '/');
|
||||
}
|
||||
$destination = escapeshellarg($destination);
|
||||
|
||||
@@ -173,12 +173,14 @@ class Sysinfo
|
||||
{
|
||||
exec('cat '. RASPI_ADBLOCK_CONFIG, $return);
|
||||
$arrConf = ParseConfig($return);
|
||||
$enabled = false;
|
||||
if (sizeof($arrConf) > 0) {
|
||||
$enabled = true;
|
||||
}
|
||||
exec('pidof dnsmasq | wc -l', $dnsmasq);
|
||||
$dnsmasq_state = ($dnsmasq[0] > 0);
|
||||
$status = $dnsmasq_state && $enabled ? true : false;
|
||||
|
||||
$status = $dnsmasq_state && $enabled;
|
||||
return $status;
|
||||
}
|
||||
|
||||
|
||||
@@ -301,14 +301,12 @@ class Dashboard {
|
||||
*/
|
||||
public function firewallEnabled(): bool
|
||||
{
|
||||
$conf = array();
|
||||
if (file_exists($this->firewallConfig) ) {
|
||||
$conf = parse_ini_file($this->firewallConfig);
|
||||
if (!file_exists($this->firewallConfig)) {
|
||||
return false;
|
||||
}
|
||||
if ($conf["firewall-enable"] == 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
$conf = parse_ini_file($this->firewallConfig) ?: [];
|
||||
return !empty($conf['firewall-enable']) && (int)$conf['firewall-enable'] === 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -10,6 +10,76 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- static IP settings -->
|
||||
<div class="row" id="bridgeStaticIpSection" style="display: <?php echo $arrHostapdConf['BridgedEnable'] == 1 ? 'block' : 'none' ?>;">
|
||||
<div class="col-md-12 mb-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title"><?php echo _("Bridge interface configuration"); ?></h6>
|
||||
<p class="text-muted small mb-3">
|
||||
<?php echo _("Configure a static IP address for the <code>br0</code> interface to maintain connectivity during bridge mode activation."); ?>
|
||||
</p>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label for="bridgeStaticIp" class="form-label"><?php echo _("Static IP Address"); ?></label>
|
||||
<div class="input-group has-validation">
|
||||
<input type="text" class="form-control ip_address" id="bridgeStaticIp" name="bridgeStaticIp"
|
||||
value="<?php echo htmlspecialchars($arrConfig['bridgeStaticIP'] ?? '', ENT_QUOTES); ?>"
|
||||
placeholder="192.168.1.100" />
|
||||
<div class="invalid-feedback">
|
||||
<?php echo _("Please enter a valid IPv4 address"); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-text"><?php echo _("Example: 192.168.1.100"); ?></div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label for="bridgeNetmask" class="form-label"><?php echo _("Netmask / CIDR"); ?></label>
|
||||
<div class="input-group has-validation">
|
||||
<input type="text" class="form-control" id="bridgeNetmask" name="bridgeNetmask"
|
||||
value="<?php echo htmlspecialchars($arrConfig['bridgeNetmask'] ?? '24', ENT_QUOTES); ?>"
|
||||
placeholder="24" />
|
||||
<div class="invalid-feedback">
|
||||
<?php echo _("Please enter a valid netmask"); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-text"><?php echo _("CIDR notation (e.g., 24 for 255.255.255.0)"); ?></div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label for="bridgeGateway" class="form-label"><?php echo _("Gateway"); ?></label>
|
||||
<div class="input-group has-validation">
|
||||
<input type="text" class="form-control ip_address" id="bridgeGateway" name="bridgeGateway"
|
||||
value="<?php echo htmlspecialchars($arrConfig['bridgeGateway'] ?? '', ENT_QUOTES); ?>"
|
||||
placeholder="192.168.1.1" />
|
||||
<div class="invalid-feedback">
|
||||
<?php echo _("Please enter a valid IPv4 address"); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-text"><?php echo _("Your router's IP address"); ?></div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label for="bridgeDNS" class="form-label"><?php echo _("DNS Server"); ?></label>
|
||||
<div class="input-group has-validation">
|
||||
<input type="text" class="form-control ip_address" id="bridgeDNS" name="bridgeDNS"
|
||||
value="<?php echo htmlspecialchars($arrConfig['bridgeDNS'] ?? '', ENT_QUOTES); ?>"
|
||||
placeholder="192.168.1.1" />
|
||||
<div class="invalid-feedback">
|
||||
<?php echo _("Please enter a valid IPv4 address"); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-text"><?php echo _("Usually same as gateway"); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-2">
|
||||
<div class="form-check form-switch">
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="col-12">
|
||||
<!-- branding -->
|
||||
<div class="text-center mb-3">
|
||||
<img src="app/img/raspAP-logo.php" class="navbar-logo" alt="RaspAP logo" class="img-fluid" style="max-width: 100px;">
|
||||
<img src="app/img/raspAP-logo.php" class="login-logo" alt="RaspAP logo" class="img-fluid" style="max-width: 100px;">
|
||||
<h2 class="login-brand"><?php echo htmlspecialchars(RASPI_BRAND_TEXT); ?></h2>
|
||||
<div class="mt-2 admin-login"><?php echo _("Administrator login") ?></div>
|
||||
<div class="text-center text-danger mt-1 mb-3"><?php echo $status ?></div>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<input class="form-check-input" id="wgLogEnable" type="checkbox" name="wgLogEnable" value="1" <?php echo $optLogEnable ? ' checked="checked"' : "" ?> aria-describedby="wgLogEnable">
|
||||
<label class="form-check-label" for="wgLogEnable"><?php echo _("Logfile output") ?></label>
|
||||
</div>
|
||||
<?php echo '<textarea class="logoutput text-secondary my-3">'.htmlspecialchars($wg_log, ENT_QUOTES).'</textarea>';
|
||||
<?php echo '<textarea class="logoutput text-secondary my-3">'.htmlspecialchars($log, ENT_QUOTES).'</textarea>';
|
||||
?>
|
||||
</div>
|
||||
</div><!-- /.row -->
|
||||
|
||||
Reference in New Issue
Block a user