diff --git a/README.md b/README.md index df6e45d9..c3c8f47e 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/config/dhcpcd.conf b/config/dhcpcd.conf index 5804655b..22a4ae18 100644 --- a/config/dhcpcd.conf +++ b/config/dhcpcd.conf @@ -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 diff --git a/config/hostapd.conf b/config/hostapd.conf index be164e30..856e4a1b 100644 --- a/config/hostapd.conf +++ b/config/hostapd.conf @@ -20,3 +20,5 @@ country_code= ## RaspAP wireless client AP mode #interface=uap0 +## RaspAP bridge AP mode (disabled by default) +#bridge=br0 diff --git a/config/raspap-br0-member-eth0.network b/config/raspap-br0-member-eth0.network new file mode 100644 index 00000000..1eddb017 --- /dev/null +++ b/config/raspap-br0-member-eth0.network @@ -0,0 +1,5 @@ +[Match] +Name=eth0 + +[Network] +Bridge=br0 diff --git a/config/raspap-bridge-br0.netdev b/config/raspap-bridge-br0.netdev new file mode 100644 index 00000000..6ec2b6dc --- /dev/null +++ b/config/raspap-bridge-br0.netdev @@ -0,0 +1,3 @@ +[NetDev] +Name=br0 +Kind=bridge diff --git a/includes/hostapd.php b/includes/hostapd.php index e33ca3c1..8a351fba 100755 --- a/includes/hostapd.php +++ b/includes/hostapd.php @@ -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']; diff --git a/includes/openvpn.php b/includes/openvpn.php index 5f6c2827..5fc11e63 100755 --- a/includes/openvpn.php +++ b/includes/openvpn.php @@ -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'); } diff --git a/index.php b/index.php index 4f3d8939..2bedcd9b 100755 --- a/index.php +++ b/index.php @@ -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']; + ?> @@ -124,7 +129,7 @@ if ($_COOKIE['sidebarToggled'] == 'true' ) { - + @@ -139,7 +144,7 @@ if ($_COOKIE['sidebarToggled'] == 'true' ) { - + diff --git a/installers/common.sh b/installers/common.sh index 8569f745..e73add3e 100755 --- a/installers/common.sh +++ b/installers/common.sh @@ -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" diff --git a/installers/configauth.sh b/installers/configauth.sh index 5fc6965a..1300f8c3 100755 --- a/installers/configauth.sh +++ b/installers/configauth.sh @@ -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 diff --git a/installers/servicestart.sh b/installers/servicestart.sh index fa4dd446..710d2b4b 100755 --- a/installers/servicestart.sh +++ b/installers/servicestart.sh @@ -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" diff --git a/installers/toggle-bridged-routed.sh b/installers/toggle-bridged-routed.sh new file mode 100755 index 00000000..5020bcfb --- /dev/null +++ b/installers/toggle-bridged-routed.sh @@ -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 diff --git a/locale/en_US/LC_MESSAGES/messages.po b/locale/en_US/LC_MESSAGES/messages.po index 7a513172..15e57c64 100644 --- a/locale/en_US/LC_MESSAGES/messages.po +++ b/locale/en_US/LC_MESSAGES/messages.po @@ -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" diff --git a/templates/hostapd.php b/templates/hostapd.php index cde019f7..d3d7786e 100755 --- a/templates/hostapd.php +++ b/templates/hostapd.php @@ -125,11 +125,20 @@

+
+
+
+ + /> + +
+
+
- + />
diff --git a/templates/networking.php b/templates/networking.php index acc8e793..7723733b 100755 --- a/templates/networking.php +++ b/templates/networking.php @@ -12,10 +12,18 @@