Merge pull request #523 from Taikuh/bridge-mode

Bridged AP Mode
This commit is contained in:
Bill Zimmerman 2020-03-16 10:04:26 +01:00 committed by GitHub
commit 6d893e4a3f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 188 additions and 21 deletions

View file

@ -16,6 +16,7 @@ We hope you enjoy using RaspAP as much as we do creating it. Tell us how you use
- [Prerequisites](#prerequisites)
- [Quick installer](#quick-installer)
- [Bridged AP](#bridged-ap)
- [Simultaneous AP and Wifi client](#simultaneous-ap-and-wifi-client)
- [Support us](#support-us)
- [Manual installation](#manual-installation)
@ -60,6 +61,11 @@ configured as an access point as follows:
**Note:** As the name suggests, the Quick Installer is a great way to quickly setup a new AP. However, it does not automagically detect the unique configuration of your RPi. Best results are obtained by connecting an RPi to ethernet (`eth0`) or as a WiFi client, also known as managed mode, with `wlan0`. For the latter, refer to [this FAQ](https://github.com/billz/raspap-webgui/wiki/FAQs#how-do-i-prepare-the-sd-card-to-connect-to-wifi-in-headless-mode). Please [read this](https://github.com/billz/raspap-webgui/wiki/Reporting-issues) before reporting an issue.
## Bridged AP
By default RaspAP configures a routed AP for your clients to connect to. A bridged AP configuration is also possible. Slide the **Bridged AP mode** toggle under the **Advanced** tab of **Configure hotspot**, then save and restart the hotspot.
**Note:** In bridged mode, all routing capabilities are handled by your upstream router. Because your router assigns IP addresses to your RPi's hotspot and its clients, you might not be able to reach the RaspAP web interface from the default `10.3.141.1` address. Instead use your RPi's hostname followed by `.local` to access the RaspAP web interface. With Raspbian default settings, this should look like `raspberrypi.local`.
## Simultaneous AP and Wifi client
RaspAP lets you easily create an AP with a Wifi client configuration. With your RPi configured in managed mode, enable the AP from the **Advanced** tab of **Configure hotspot** by sliding the **Wifi client AP mode** toggle. Save settings and start the hotspot. The managed mode AP is functional without restart.

View file

@ -10,6 +10,11 @@ require dhcp_server_identifier
slaac private
nohook lookup-hostname
#denyinterfaces eth0 wlan0 #BRIDGED
# RaspAP br0 configuration
interface br0
# RaspAP wlan0 configuration
interface wlan0
static ip_address=10.3.141.1/24

View file

@ -20,3 +20,5 @@ country_code=
## RaspAP wireless client AP mode
#interface=uap0
## RaspAP bridge AP mode (disabled by default)
#bridge=br0

View file

@ -0,0 +1,5 @@
[Match]
Name=eth0
[Network]
Bridge=br0

View file

@ -0,0 +1,3 @@
[NetDev]
Name=br0
Kind=bridge

View file

@ -31,7 +31,9 @@ function DisplayHostAPDConfig()
SaveHostAPDConfig($arrSecurity, $arrEncType, $arr80211Standard, $interfaces, $status);
} elseif (isset($_POST['StartHotspot']) || isset($_POST['RestartHotspot'])) {
$status->addMessage('Attempting to start hotspot', 'info');
if ($arrHostapdConf['WifiAPEnable'] == 1) {
if ($arrHostapdConf['BridgedEnable'] == 1) {
exec('sudo /etc/raspap/hostapd/servicestart.sh --interface br0 --seconds 3', $return);
} elseif ($arrHostapdConf['WifiAPEnable'] == 1) {
exec('sudo /etc/raspap/hostapd/servicestart.sh --interface uap0 --seconds 3', $return);
} else {
exec('sudo /etc/raspap/hostapd/servicestart.sh --seconds 3', $return);
@ -108,15 +110,29 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
$good_input = true;
// Check for WiFi client AP mode checkbox
$wifiAPEnable = 0;
if ($arrHostapdConf['WifiAPEnable'] == 0) {
if (isset($_POST['wifiAPEnable'])) {
$wifiAPEnable = 1;
// Check for Bridged AP mode checkbox
$bridgedEnable = 0;
if ($arrHostapdConf['BridgedEnable'] == 0) {
if (isset($_POST['bridgedEnable'])) {
$bridgedEnable = 1;
}
} else {
if (isset($_POST['wifiAPEnable'])) {
$wifiAPEnable = 1;
if (isset($_POST['bridgedEnable'])) {
$bridgedEnable = 1;
}
}
// Check for WiFi client AP mode checkbox
$wifiAPEnable = 0;
if ($bridgedEnable == 0) { // enable client mode actions when not bridged
if ($arrHostapdConf['WifiAPEnable'] == 0) {
if (isset($_POST['wifiAPEnable'])) {
$wifiAPEnable = 1;
}
} else {
if (isset($_POST['wifiAPEnable'])) {
$wifiAPEnable = 1;
}
}
}
@ -137,9 +153,13 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
exec('sudo /etc/raspap/hostapd/disablelog.sh');
}
}
$cfg = [];
$cfg['LogEnable'] = $logEnable;
$cfg['WifiAPEnable'] = $wifiAPEnable;
// Save previous Client mode status when Bridged
$cfg['WifiAPEnable'] = ($bridgedEnable == 1 ?
$arrHostapdConf['WifiAPEnable'] : $wifiAPEnable);
$cfg['BridgedEnable'] = $bridgedEnable;
$cfg['WifiManaged'] = RASPI_WIFI_CLIENT_INTERFACE;
write_php_ini($cfg, '/etc/raspap/hostapd.ini');
@ -226,6 +246,9 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
}
if ($wifiAPEnable == 1) {
$config.= 'interface=uap0'.PHP_EOL;
} elseif ($bridgedEnable == 1) {
$config.='interface='.RASPI_WIFI_CLIENT_INTERFACE.PHP_EOL;
$config.= 'bridge=br0'.PHP_EOL;
} else {
$config.= 'interface='.$_POST['interface'].PHP_EOL;
}
@ -288,7 +311,10 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
$config[] = 'slaac private';
$config[] = 'nohook lookup-hostname';
if ($wifiAPEnable == 1) {
if ($bridgedEnable == 1) {
$config[] = 'denyinterfaces eth0 wlan0';
$config[] = 'interface br0';
} elseif ($wifiAPEnable == 1) {
// Enable uap0 configuration in dhcpcd for Wifi client AP mode
$intConfig = parse_ini_file(RASPI_CONFIG_NETWORKING.'/uap0.ini', false, INI_SCANNER_RAW);
$ip_address = ($intConfig['ip_address'] == '') ? '192.168.50.1/24' : $intConfig['ip_address'];

View file

@ -21,12 +21,14 @@ function DisplayOpenVPNConfig()
} elseif (isset($_POST['StartOpenVPN'])) {
$status->addMessage('Attempting to start OpenVPN', 'info');
exec('sudo /bin/systemctl start openvpn-client@client', $return);
exec('sudo /bin/systemctl enable openvpn-client@client', $return);
foreach ($return as $line) {
$status->addMessage($line, 'info');
}
} elseif (isset($_POST['StopOpenVPN'])) {
$status->addMessage('Attempting to stop OpenVPN', 'info');
exec('sudo /bin/systemctl stop openvpn-client@client', $return);
exec('sudo /bin/systemctl disable openvpn-client@client', $return);
foreach ($return as $line) {
$status->addMessage($line, 'info');
}

View file

@ -55,6 +55,11 @@ if ($_COOKIE['sidebarToggled'] == 'true' ) {
$toggleState = "toggled";
}
// Get Bridged AP mode status
$arrHostapdConf = parse_ini_file('/etc/raspap/hostapd.ini');
// defaults to false
$bridgedEnabled = $arrHostapdConf['BridgedEnable'];
?><!DOCTYPE html>
<html lang="en">
<head>
@ -124,7 +129,7 @@ if ($_COOKIE['sidebarToggled'] == 'true' ) {
<li class="nav-item">
<a class="nav-link" href="index.php?page=wlan0_info"><i class="fas fa-tachometer-alt fa-fw mr-2"></i><span class="nav-label"><?php echo _("Dashboard"); ?></span></a>
</li>
<?php if (RASPI_WIFICLIENT_ENABLED) : ?>
<?php if (RASPI_WIFICLIENT_ENABLED && !$bridgedEnabled) : ?>
<li class="nav-item">
<a class="nav-link" href="index.php?page=wpa_conf"><i class="fas fa-wifi fa-fw mr-2"></i><span class="nav-label"><?php echo _("WiFi client"); ?></span></a>
</li>
@ -139,7 +144,7 @@ if ($_COOKIE['sidebarToggled'] == 'true' ) {
<a class="nav-link" href="index.php?page=network_conf"><i class="fas fa-network-wired fa-fw mr-2"></i><span class="nav-label"><?php echo _("Networking"); ?></a>
</li>
<?php endif; ?>
<?php if (RASPI_DHCP_ENABLED) : ?>
<?php if (RASPI_DHCP_ENABLED && !$bridgedEnabled) : ?>
<li class="nav-item">
<a class="nav-link" href="index.php?page=dhcpd_conf"><i class="fas fa-exchange-alt fa-fw mr-2"></i><span class="nav-label"><?php echo _("DHCP Server"); ?></a>
</li>

View file

@ -171,6 +171,7 @@ function download_latest_files() {
install_log "Cloning latest files from github"
git clone --branch $branch --depth 1 $git_source_url /tmp/raspap-webgui || install_error "Unable to download files from github"
sudo mv /tmp/raspap-webgui $webroot_dir || install_error "Unable to move raspap-webgui to web root"
}
@ -210,6 +211,14 @@ function check_for_old_configs() {
sudo cp /etc/rc.local "$raspap_dir/backups/rc.local.`date +%F-%R`"
sudo ln -sf "$raspap_dir/backups/rc.local.`date +%F-%R`" "$raspap_dir/backups/rc.local"
fi
for file in /etc/systemd/network/raspap-*.net*; do
if [-f "${file}" ]; then
filename = $(basename $file)
sudo cp "$file" "${raspap_dir}/backups/${filename}.`date +%F-%R`"
sudo ln -sf "${raspap_dir}/backups/${filename}.`date +%F-%R`" "${raspap_dir}/backups/${filename}"
fi
done
}
# Move configuration file to the correct location
@ -236,6 +245,11 @@ function default_configuration() {
[ -d /etc/dnsmasq.d ] || sudo mkdir /etc/dnsmasq.d
sudo systemctl stop systemd-networkd
sudo systemctl disable systemd-networkd
sudo cp $webroot_dir/config/raspap-bridge-br0.netdev /etc/systemd/network/raspap-bridge-br0.netdev || install_error "Unable to move br0 netdev file"
sudo cp $webroot_dir/config/raspap-br0-member-eth0.network /etc/systemd/network/raspap-br0-member-eth0.network || install_error "Unable to move br0 member file"
if [ ! -f "$webroot_dir/includes/config.php" ]; then
sudo cp "$webroot_dir/config/config.php" "$webroot_dir/includes/config.php"
fi
@ -311,7 +325,9 @@ function patch_system_files() {
"/bin/systemctl start dnsmasq.service"
"/bin/systemctl stop dnsmasq.service"
"/bin/systemctl start openvpn-client@client"
"/bin/systemctl enable openvpn-client@client"
"/bin/systemctl stop openvpn-client@client"
"/bin/systemctl disable openvpn-client@client"
"/bin/cp /tmp/ovpnclient.ovpn /etc/openvpn/client/client.conf"
"/bin/cp /tmp/authdata /etc/openvpn/client/login.conf"
"/bin/cp /tmp/dnsmasqdata /etc/dnsmasq.conf"

View file

@ -34,7 +34,8 @@ lines=(
for line in "${lines[@]}"; do
if grep "$line" /etc/rc.local > /dev/null; then
else
echo "$line: Line already added"
else
sudo sed -i "s/^exit 0$/$line\nexit 0/" /etc/rc.local
echo "Adding rule: $line"
fi

View file

@ -6,6 +6,8 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NAME=raspap
DESC="Service control for RaspAP"
CONFIGFILE="/etc/raspap/hostapd.ini"
DAEMONPATH="/lib/systemd/system/raspap.service"
OPENVPNENABLED=$(pidof openvpn | wc -l)
positional=()
while [[ $# -gt 0 ]]
@ -28,25 +30,54 @@ done
set -- "${positional[@]}"
echo "Stopping network services..."
systemctl stop openvpn-client@client
systemctl stop systemd-networkd
systemctl stop hostapd.service
systemctl stop dnsmasq.service
systemctl stop dhcpcd.service
if [ -f "$DAEMONPATH" ]; then
echo "Changing RaspAP Daemon --interface to $interface"
sed -i "s/\(--interface \)[[:alnum:]]*/\1$interface/" "$DAEMONPATH"
fi
if [ -r "$CONFIGFILE" ]; then
declare -A config
while IFS=" = " read -r key value; do
config["$key"]="$value"
done < "$CONFIGFILE"
if [ "${config[WifiAPEnable]}" = 1 ]; then
if [ "${interface}" = "uap0" ]; then
if [ "${config[BridgedEnable]}" = 1 ]; then
if [ "${interface}" = "br0" ]; then
echo "Restarting eth0 interface..."
ip link set down eth0
ip link set up eth0
echo "Removing uap0 interface..."
iw dev uap0 del
echo "Adding uap0 interface to ${config[WifiManaged]}"
iw dev ${config[WifiManaged]} interface add uap0 type __ap
# Bring up uap0 interface
ifconfig uap0 up
echo "Enabling systemd-networkd"
systemctl start systemd-networkd
systemctl enable systemd-networkd
fi
else
echo "Disabling systemd-networkd"
systemctl disable systemd-networkd
echo "Removing br0 interface..."
ip link set down br0
ip link del dev br0
if [ "${config[WifiAPEnable]}" = 1 ]; then
if [ "${interface}" = "uap0" ]; then
echo "Removing uap0 interface..."
iw dev uap0 del
echo "Adding uap0 interface to ${config[WifiManaged]}"
iw dev ${config[WifiManaged]} interface add uap0 type __ap
# Bring up uap0 interface
ifconfig uap0 up
fi
fi
fi
fi
@ -61,5 +92,9 @@ sleep "${seconds}"
systemctl start dnsmasq.service
if [ $OPENVPNENABLED -eq 1 ]; then
systemctl start openvpn-client@client
fi
echo "RaspAP service start DONE"

View file

@ -0,0 +1,41 @@
#!/bin/bash
function do_routed_mode() {
sudo systemctl disable systemd-networkd
sudo sed -i "s/^.*#BRIDGED$/#&/" /etc/dhcpcd.conf
sudo sed -i "s/^bridge/#&/" /etc/hostapd/hostapd.conf
sudo ip link set down br0
sudo ip link del dev br0
}
function do_bridged_mode() {
sudo sed -i "s/^#\(.*#BRIDGED\)$/\1/" /etc/dhcpcd.conf
sudo sed -i "s/^#\(bridge\)/\1/" /etc/hostapd/hostapd.conf
sudo ip link set down eth0
sudo ip link set up eth0
sudo systemctl start systemd-networkd
sudo systemctl enable systemd-networkd
}
sudo systemctl stop systemd-networkd
sudo systemctl stop hostapd
sudo systemctl stop dhcpcd
sudo systemctl stop dnsmasq
if [ "$1" = "force-routed" ]
then do_routed_mode
elif [ "$1" = "force-bridged" ]
then do_bridged_mode
elif ip addr show br0 | grep 'inet ' > /dev/null
then do_routed_mode
elif ! ip addr show br0 | grep 'inet ' > /dev/null
then do_bridged_mode
fi
sudo systemctl start hostapd
sudo systemctl start dhcpcd
sudo systemctl start dnsmasq

View file

@ -429,6 +429,9 @@ msgstr "Logfile output"
msgid "WiFi client AP mode"
msgstr "WiFi client AP mode"
msgid "Bridged AP mode"
msgstr "Bridged AP mode"
msgid "Hide SSID in broadcast"
msgstr "Hide SSID in broadcast"

View file

@ -125,11 +125,20 @@
</div>
<div class="tab-pane fade" id="advanced">
<h4 class="mt-3"><?php echo _("Advanced settings"); ?></h4>
<div class="row">
<div class="col-md-6 mb-2">
<div class="custom-control custom-switch">
<?php $checked = $arrHostapdConf['BridgedEnable'] == 1 ? 'checked="checked"' : '' ?>
<input class="custom-control-input" id="chxbridgedenable" name="bridgedEnable" type="checkbox" value="1" <?php echo $checked ?> />
<label class="custom-control-label" for="chxbridgedenable"><?php echo _("Bridged AP mode"); ?></label>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-2">
<div class="custom-control custom-switch">
<?php $checked = $arrHostapdConf['WifiAPEnable'] == 1 ? 'checked="checked"' : '' ?>
<?php $disabled = $managedModeEnabled == false && $arrHostapdConf['WifiAPEnable'] != 1 ? 'disabled="disabled"' : '' ?>
<?php $disabled = $managedModeEnabled == false && $arrHostapdConf['WifiAPEnable'] != 1 || $arrHostapdConf['BridgedEnable'] == 1 ? 'disabled="disabled"' : '' ?>
<input class="custom-control-input" id="chxwificlientap" name="wifiAPEnable" type="checkbox" value="1" <?php echo $checked ?> <?php echo $disabled ?> />
<label class="custom-control-label" for="chxwificlientap"><?php echo _("WiFi client AP mode"); ?></label>
</div>

View file

@ -12,10 +12,18 @@
<div id="msgNetworking"></div>
<ul class="nav nav-tabs">
<li role="presentation" class="nav-item"><a class="nav-link active" href="#summary" aria-controls="summary" role="tab" data-toggle="tab"><?php echo _("Summary"); ?></a></li>
<?php
// Get Bridged AP mode status
$arrHostapdConf = parse_ini_file('/etc/raspap/hostapd.ini');
// defaults to false
$bridgedEnabled = $arrHostapdConf['BridgedEnable'];
?>
<?php if (!$bridgedEnabled): // no interface details when bridged ?>
<?php foreach ($interfaces as $if): ?>
<?php $if_quoted = htmlspecialchars($if, ENT_QUOTES) ?>
<li role="presentation" class="nav-item"><a class="nav-link" href="#<?php echo $if_quoted ?>" aria-controls="<?php echo $if_quoted ?>" role="tab" data-toggle="tab"><?php echo $if_quoted ?></a></li>
<?php endforeach ?>
<?php endif ?>
</ul>
<div class="tab-content">