NotrufSim (5) LAN-Funktion umschaltbar

Fortsetzung von (4) Optimierung Netzwerk

Wie bekommt man nun den Pi wieder ins heimische Netz?

Für dieses Problem habe ich eine Steuerung über den Webserver vorgesehen. Dazu benötigen wir ein paar kleine Shellskripte und ein PHP-Skript.

Shell: getip

Dieses Skript liefert uns beim Aufrufer per /var/local/getip <if> [dbg] die IP des jeweiligen <if> (= eth0, wlan0 oder br0). Mit dem optionalem Parameter dbg wird zusätzlich zur IP auch die abgefragte Schnittstelle ausgegeben.

sudo nano /var/local/getip

#!/bin/bash
IFACE=$1
IPFUND=`ifconfig $IFACE | grep -c "inet "`
IP=`ifconfig $IFACE | grep -o -P "\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b" | head -1`
if [ $IPFUND = 1 ]
then
  if [ "$2" = "dbg" ]
  then
    echo "$IFACE IPv4: $IP"
  else
    echo "$IP"
  fi
else
  if [ "$2" = "dbg" ]
  then
    echo "$IFACE IPv4: nicht zugewiesen"
  else
    echo "0.0.0.0"
  fi
fi

sudo chmod +x /var/local/getip

Shell: admin

Dieses Skript nimmt die LAN-Schnittstelle aus der Bridge und startet sie als DHCP-Client neu, damit sie sich in einem bestehenden LAN verbinden kann.

sudo nano /var/local/admin

#!/bin/bash
sudo brctl delif br0 eth0
sudo ifdown eth0
sudo ifup eth0=lan
/var/local/getip eth0

sudo chmod +x /var/local/admin

Shell: bridge

Hier wird die LAN-Schnittstelle getrennt und wieder in die Bridge aufgenommen, danach der DNS-DHCP-Server neu gestartet.

sudo nano /var/local/bridge

#!/bin/bash
sudo ifdown eth0
sudo ifup eth0=off
sudo brctl addif br0 eth0
sudo service dnsmasq restart
/var/local/getip br0

sudo chmod +x /var/local/bridge

Shell-Skripte für Webserver freigeben

Damit der Webserver unsere Shell-Skripte ausführen kann, müssen wir ihm erlauben diese per sudo ausführen zu können. Dazu müssen wir den Webserver-Benutzer (unter Raspbian www-data) mit den Skripten in die /etc/sudoers eintragen.

Achtung … Durch Eingabefehler in dieser Datei kann man sich aus dem System komplett aussperren !

sudo nano /etc/sudoers

Folgendes an das Ende der Datei anfügen …

www-data ALL=(ALL) NOPASSWD: /var/local/admin
www-data ALL=(ALL) NOPASSWD: /var/local/bridge
www-data ALL=(ALL) NOPASSWD: /var/local/getip
Webserver: netzwerk.php

Jetzt müssen wir uns noch das Bedienskript auf dem Webserver anlegen. Dazu erstellen wir einen Unterordner und legen das Skript an.

sudo mkdir /var/www/admin

sudo nano /var/www/admin/netzwerk.php

<?php
if (isset($_POST['setadmin'])) {
  $HTML = "<h5>DHCP-Client auf LAN-Schnittstelle (ADMIN)</h5>
  <div>Alle Netzverbindungen werden unterbrochen und danach neu gestartet.</div>";
  exec('sudo /var/local/admin',$dhcp);
  $HTML .= "<div><code>$dhcp</code></div>";
  $HTML .= "<div><a href=\"netzwerk.php\">zurück</a></div>";
} elseif (isset($_POST['bridge'])) {
  $HTML = "<h5>DHCP-Server und BRIDGE aktivieren (NORMAL)</h5>
  <div>Alle Netzverbindungen werden unterbrochen und danach neu gestartet.</div>";
  exec('sudo /var/local/bridge',$bridge);
  $HTML .= "<div><code>$bridge</code></div>";
  $HTML .= "<div><a href=\"netzwerk.php\">zurück</a></div>";
} elseif (isset($_POST['getip'])) {
  $HMTL = "<h5>IP-Adressen aller Schnittstellen<h5>";
  exec('sudo /var/local/getip eth0',$eth0);
  exec('sudo /var/local/getip wlan0',$wlan0);
  exec('sudo /var/local/getip br0',$br0);
  $eth = $eth0[0];
  $wlan = $wlan0[0];
  $br = $br0[0];
  if ($eth0[0] == "0.0.0.0") {
    $eth = "inaktiv" ;
  }
  if ($wlan0[0] == "0.0.0.0") {
    $wlan = "inaktiv" ;
  }
  if ($br0[0] == "0.0.0.0") {
    $br = "inaktiv";
  }
  if ($eth0[0] == "0.0.0.0" && $wlan0[0] == "0.0.0.0" && $br0[0] != "0.0.0.0") {
    $eth = "verbunden" ;
    $wlan = "verbunden" ;
    $br = $br0[0];
  }
  $HTML .= "<div><code>
    LAN-Schnittstelle: <b>".$eth."</b><br>
    WLAN-Schnittstelle: <b>".$wlan."</b><br>
    BRIDGE: <b>".$br."</b><br>
    </code></div>";
  $HTML .= "<div><a href=\"netzwerk.php\">zurück</a></div>";
} else {
  $HTML = "<form action=\"\" method=\"POST\">
  <h5>DHCP-Client auf LAN-Schnittstelle (ADMIN)</h5>
  <p>Alle Netzwerkverbindungen werden unterbrochen und die LAN-Schnittstelle wird auf DHCP-Client konfiguriert.</p>
  <input type=\"submit\" name=\"setadmin\" value=\"ADMIN-Modus\">
  <hr>
  <h5>DHCP-Server und BRIDGE aktivieren (NORMAL)</h5>
  <p>Alle Netzwerkverbindungen werden unterbrochen und es wird auf BRIDGE-Modus mit DHCP-Server konfiguriert.</p>
  <input type=\"submit\" name=\"bridge\" value=\"NORMAL-Modus\">
  <hr>
  <h5>IP-Adressen aller Schnittstellen</h5>
  <p>Anzeige der aktuellen IPs</p>
  <input type=\"submit\" name=\"getip\" value=\"zeige IPs\">
  </form>";
}
echo "<html><h4>Admin-Funktionen</h4><div>$HTML</div></html>";
?>

Das Skript nun noch ausführbar machen und den Ordner für den Webserver-Benutzer freigeben.

sudo chmod +x /var/www/admin/netzwerk.php

sudo chown -R 33:33 /var/www/admin

Jetzt ist das Skript über http://notrufsim/admin/netzwerk.php aufrufbar und mit einem klick auf „zeige IPs“ sollte das Skript nun die IPs der Schnittstellen liefern.

Automatische Erkennung beim Start des Pi

Wenn wir nun möchten, dass der Pi beim Neustart automatisch erkennt, ob er auf der LAN-Seite eine Verbindung bekommt, müssen wir unsere interfaces abändern …

iface eth0 inet manualdhcp
...
bridge_ports eth0 wlan0

Jetzt wird beim Neustart die LAN-Schnittstelle nicht mit in die Netzwerkbrücke aufgenommen und als DHCP-Client gestartet.

Im Startskript rc.local können wir nun prüfen, ob die Schnittstelle eine IP bekommen hat.

sudo nano /etc/rc.local

Dort fügen wir am Ende vor dem exit 0 Folgendes ein

...
sleep 5
IP=`/var/local/getip eth0`
if [ "$IP" = "0.0.0.0" ]
then
  /var/local/bridge
fi
exit 0

Der Skriptteil wartet nun nach dem Start 5 Sekunden und prüft dann, ob die LAN-Schnittstelle eine gültige IP bekommen hat. Unser Skript getip liefert 0.0.0.0, wenn es keine IP findet. In diesem Fall wird mit unserem Skript bridge die LAN-Schnittstelle wieder in die Netzwerkbrücke aufgenommen.

Fortsetzung folgt