From 4c9a86a6d00182cad8012cd356391d1ee53944cb Mon Sep 17 00:00:00 2001 From: io <> Date: Fri, 11 Feb 2005 00:06:43 +0000 Subject: [PATCH] die gute Einwahl- und Abrechnungsverwaltung fuer wg-netze --- wg-dialer/data/nutzer.liste | 9 + wg-dialer/homepage/.htaccess | 1 + wg-dialer/homepage/aktionen.php | 43 ++ wg-dialer/homepage/aktiveNutzer.php | 10 + wg-dialer/homepage/ausschalten.php | 22 + wg-dialer/homepage/definitionen.php | 144 ++++ wg-dialer/homepage/index.php | 35 + wg-dialer/homepage/not_aus.php | 9 + wg-dialer/homepage/nutzerStatus.php | 27 + wg-dialer/homepage/tarifWechsel.php | 13 + wg-dialer/homepage/trenneNutzer.php | 13 + wg-dialer/homepage/verbindeNutzer.php | 13 + wg-dialer/homepage/verbindungsStatus.php | 20 + wg-dialer/homepage/zeigeKosten.php | 31 + wg-dialer/homepage/zeigeKostenFormular.php | 111 +++ wg-dialer/homepage/zeigeKostenListe.php | 22 + wg-dialer/homepage/zeigeProtokoll.php | 42 ++ wg-dialer/scripts/WGDialer.neu.sh | 685 +++++++++++++++++ wg-dialer/scripts/WGDialer.sh | 818 +++++++++++++++++++++ wg-dialer/scripts/einwahl.sh | 170 +++++ wg-dialer/scripts/ip-down.local | 1 + wg-dialer/scripts/ip-up.local | 2 + wg-dialer/scripts/ueberwacheNutzung.sh | 34 + wg-dialer/scripts/waehleISDN-Tarif.sh | 75 ++ 24 files changed, 2350 insertions(+) create mode 100644 wg-dialer/data/nutzer.liste create mode 100644 wg-dialer/homepage/.htaccess create mode 100644 wg-dialer/homepage/aktionen.php create mode 100644 wg-dialer/homepage/aktiveNutzer.php create mode 100644 wg-dialer/homepage/ausschalten.php create mode 100644 wg-dialer/homepage/definitionen.php create mode 100644 wg-dialer/homepage/index.php create mode 100644 wg-dialer/homepage/not_aus.php create mode 100644 wg-dialer/homepage/nutzerStatus.php create mode 100644 wg-dialer/homepage/tarifWechsel.php create mode 100644 wg-dialer/homepage/trenneNutzer.php create mode 100644 wg-dialer/homepage/verbindeNutzer.php create mode 100644 wg-dialer/homepage/verbindungsStatus.php create mode 100644 wg-dialer/homepage/zeigeKosten.php create mode 100644 wg-dialer/homepage/zeigeKostenFormular.php create mode 100644 wg-dialer/homepage/zeigeKostenListe.php create mode 100644 wg-dialer/homepage/zeigeProtokoll.php create mode 100755 wg-dialer/scripts/WGDialer.neu.sh create mode 100755 wg-dialer/scripts/WGDialer.sh create mode 100755 wg-dialer/scripts/einwahl.sh create mode 100755 wg-dialer/scripts/ip-down.local create mode 100755 wg-dialer/scripts/ip-up.local create mode 100755 wg-dialer/scripts/ueberwacheNutzung.sh create mode 100755 wg-dialer/scripts/waehleISDN-Tarif.sh diff --git a/wg-dialer/data/nutzer.liste b/wg-dialer/data/nutzer.liste new file mode 100644 index 0000000..77706f3 --- /dev/null +++ b/wg-dialer/data/nutzer.liste @@ -0,0 +1,9 @@ +Kathrin 192.168.23.20 +Lars 192.168.23.21 +Christoph 192.168.23.22 +Aldo 192.168.23.23 +Anya 192.168.23.24 +Stefan 192.168.23.25 +Bakunin 192.168.23.26 +Carlos 192.168.23.27 +Eindringling 192.168.23.158 diff --git a/wg-dialer/homepage/.htaccess b/wg-dialer/homepage/.htaccess new file mode 100644 index 0000000..1d67776 --- /dev/null +++ b/wg-dialer/homepage/.htaccess @@ -0,0 +1 @@ +DirectoryIndex index.php diff --git a/wg-dialer/homepage/aktionen.php b/wg-dialer/homepage/aktionen.php new file mode 100644 index 0000000..ba16eb3 --- /dev/null +++ b/wg-dialer/homepage/aktionen.php @@ -0,0 +1,43 @@ +
+
+ + +
'; +$suffixFett='
'; +$prefixNormal='

'; +$suffixNormal='

'; +$linkVerbindung='verbinden'; +$linkTrennung='trenne Verbindung'; + +if ($status == "getrennt") +{ + print $prefixFett . $linkVerbindung . $suffixFett; + print $prefixNormal . $linkTrennung . $prefixNormal; +} +elseif (($status == "bei der Einwahl") || ($status == "verbunden")) +{ + print $prefixNormal . $linkVerbindung . $suffixNormal; + print $prefixFett . $linkTrennung . $prefixFett; +} +else print '

Zugriff verweigert

'; + +print ""; + +?> + +

+ +
+ + + + + + + +
+
+
diff --git a/wg-dialer/homepage/aktiveNutzer.php b/wg-dialer/homepage/aktiveNutzer.php new file mode 100644 index 0000000..bec0955 --- /dev/null +++ b/wg-dialer/homepage/aktiveNutzer.php @@ -0,0 +1,10 @@ +
"; +$namen = holeAktiveNutzer(); + +print "offene Verbindungen: $namen"; + +print "

"; + +?> \ No newline at end of file diff --git a/wg-dialer/homepage/ausschalten.php b/wg-dialer/homepage/ausschalten.php new file mode 100644 index 0000000..5aa6fd9 --- /dev/null +++ b/wg-dialer/homepage/ausschalten.php @@ -0,0 +1,22 @@ + + + + + io wird heruntergefahren + + + + + + +





+io wird heruntergefahren ... +

+ +
+(der Strom kann in etwa zwei Minuten abgeschaltet werden) +
+ + + + diff --git a/wg-dialer/homepage/definitionen.php b/wg-dialer/homepage/definitionen.php new file mode 100644 index 0000000..d46036e --- /dev/null +++ b/wg-dialer/homepage/definitionen.php @@ -0,0 +1,144 @@ +
Statusmeldung: '; + print $StatusText; + print '
'; + unset($StatusText); + } +} + + +function holeIPdesNutzers($name) +{ + global $DialSkript; + return exec("$DialSkript nutzer2ip $name"); +} + + +function holeNutzerDerIP($ip) +{ + global $DialSkript; + return exec("$DialSkript ip2nutzer $ip"); +} + + +function holeAktiveNutzer() +{ + global $DialSkript; + return exec("$DialSkript alle-aktiven-nutzer"); +} + + +function holeVerbindungsStatus() +{ + global $DialSkript; + return exec("$DialSkript status-verbindung"); +} + + +function holeNutzerStatus($nutzer) +{ + global $DialSkript; + return exec("$DialSkript status-nutzer $nutzer"); +} + + +function verbindeNutzer($nutzer) +{ + global $DialSkript; + return exec("$DialSkript verbinde $nutzer"); +} + + +function trenneNutzer($nutzer) +{ + global $DialSkript; + return exec("$DialSkript trenne $nutzer"); +} + + +function notTrennung() +{ + global $DialSkript; + return exec("$DialSkript not-aus"); +} + + +function holeKostenDesNutzers($nutzer, $von, $bis) +{ + global $DialSkript; + return exec("$DialSkript kosten $nutzer $von $bis"); +} + + +function zeigeNutzerLog($nutzer) +{ + global $DialSkript; + exec("$DialSkript nutzer-log $nutzer | cut -f 1,3-6 --output-delimiter=\"\"",$out); + if (count($out) > 1) + { + $kopf = str_replace("","",array_shift($out)); + $gesamt='
'; + foreach ($out as $z) + $gesamt.=''; + $gesamt.='
' . $kopf . '
' . $z . '
'; + } else $gesamt='
keine Einträge
'; + return $gesamt; +} + + +function zeigeProtokoll($protokoll) // meldungen, fehler, dialer, script +{ + global $DialSkript; + exec("$DialSkript protokoll $protokoll",$out); + $gesamt=""; + foreach ($out as $z) + $gesamt=$gesamt . $z . '
'; + if (count($out)<=1) $gesamt='
keine Einträge
'; + return $gesamt; +} + + +function holeTarif() +{ + global $TarifWahl; + return exec("$TarifWahl tarif"); +} + + +function setzeTarif($tarif) +{ + global $TarifWahl; + exec("$TarifWahl $tarif"); +} + + +function io_ausschalten() +{ + exec("/sbin/shutdown -h now"); +} + +?> diff --git a/wg-dialer/homepage/index.php b/wg-dialer/homepage/index.php new file mode 100644 index 0000000..367c9cb --- /dev/null +++ b/wg-dialer/homepage/index.php @@ -0,0 +1,35 @@ + + + + + + + + WG-Netzverwaltung + + + + +"; + +//include("nutzerStatus.php"); +//print "
"; + +include("aktiveNutzer.php"); +print "
"; + +include("aktionen.php"); +print "
"; + +zeigeStatusMeldung(); + +?> + + + + diff --git a/wg-dialer/homepage/not_aus.php b/wg-dialer/homepage/not_aus.php new file mode 100644 index 0000000..6861e58 --- /dev/null +++ b/wg-dialer/homepage/not_aus.php @@ -0,0 +1,9 @@ + diff --git a/wg-dialer/homepage/nutzerStatus.php b/wg-dialer/homepage/nutzerStatus.php new file mode 100644 index 0000000..880762b --- /dev/null +++ b/wg-dialer/homepage/nutzerStatus.php @@ -0,0 +1,27 @@ +
+ +
+ + + + + + + +"; + print ""; + print ""; +} + +?> + +
NameIPStatus
$nutzer$ip$status
+ +
+
diff --git a/wg-dialer/homepage/tarifWechsel.php b/wg-dialer/homepage/tarifWechsel.php new file mode 100644 index 0000000..39e91fa --- /dev/null +++ b/wg-dialer/homepage/tarifWechsel.php @@ -0,0 +1,13 @@ + 0) + setzeTarif("normal"); + else setzeTarif("xxl"); + +include("index.php"); + +?> diff --git a/wg-dialer/homepage/trenneNutzer.php b/wg-dialer/homepage/trenneNutzer.php new file mode 100644 index 0000000..e8085ed --- /dev/null +++ b/wg-dialer/homepage/trenneNutzer.php @@ -0,0 +1,13 @@ + diff --git a/wg-dialer/homepage/verbindeNutzer.php b/wg-dialer/homepage/verbindeNutzer.php new file mode 100644 index 0000000..2f36686 --- /dev/null +++ b/wg-dialer/homepage/verbindeNutzer.php @@ -0,0 +1,13 @@ + diff --git a/wg-dialer/homepage/verbindungsStatus.php b/wg-dialer/homepage/verbindungsStatus.php new file mode 100644 index 0000000..9e2e242 --- /dev/null +++ b/wg-dialer/homepage/verbindungsStatus.php @@ -0,0 +1,20 @@ +

'; +print ''; +print 'Status aktualisieren: '; +print ''; +print holeVerbindungsStatus(); +print '

'; +print '
'; +$tarif=holeTarif(); +print "Aktueller Tarif: $tarif"; +print '
'; +print 'Vorsicht:
achte unbedingt darauf, dass der angezeigte Tarif
'; +print 'zum heutigen Wochentag passt - ansonsten klicke '; +print 'hier um den anderen Tarif zu aktivieren!
'; + +print '
'; + + +?> diff --git a/wg-dialer/homepage/zeigeKosten.php b/wg-dialer/homepage/zeigeKosten.php new file mode 100644 index 0000000..a5be6cb --- /dev/null +++ b/wg-dialer/homepage/zeigeKosten.php @@ -0,0 +1,31 @@ + + + + + Kostenübersicht + + + + +

zurück zur Startseite


+

+
+ +

'; + include("zeigeKostenListe.php"); +} + +?> + +
+ + + + \ No newline at end of file diff --git a/wg-dialer/homepage/zeigeKostenFormular.php b/wg-dialer/homepage/zeigeKostenFormular.php new file mode 100644 index 0000000..1f3a2c9 --- /dev/null +++ b/wg-dialer/homepage/zeigeKostenFormular.php @@ -0,0 +1,111 @@ +
+von + + + bis + + + +
diff --git a/wg-dialer/homepage/zeigeKostenListe.php b/wg-dialer/homepage/zeigeKostenListe.php new file mode 100644 index 0000000..f1ad8b3 --- /dev/null +++ b/wg-dialer/homepage/zeigeKostenListe.php @@ -0,0 +1,22 @@ + + + + + +"; +} + +?> + +
wer?wieviel?
' . $nutzer . '
'; + $erg = holeKostenDesNutzers($nutzer, $von, $bis); + $cent = $erg % 100; + if ($cent<10) $cent="0$cent"; + $euro = $erg/100; + settype($euro,"integer"); + print $euro . ',' . $cent; + print "
diff --git a/wg-dialer/homepage/zeigeProtokoll.php b/wg-dialer/homepage/zeigeProtokoll.php new file mode 100644 index 0000000..4c6da95 --- /dev/null +++ b/wg-dialer/homepage/zeigeProtokoll.php @@ -0,0 +1,42 @@ + + + + + WG-Netzverwaltung - Protokolle + + + + + + +

zurück zur Startseite


+

+
+ + + + + + + + +
+
+ +

'; + if ($prot=="nutzer") print zeigeNutzerLog($NUTZER); + else print zeigeProtokoll($prot); +} + +?> + + + + + + diff --git a/wg-dialer/scripts/WGDialer.neu.sh b/wg-dialer/scripts/WGDialer.neu.sh new file mode 100755 index 0000000..3a83e52 --- /dev/null +++ b/wg-dialer/scripts/WGDialer.neu.sh @@ -0,0 +1,685 @@ +#!/bin/sh + + +# Beginn des Scripts +HOMEDIR="/home/WGDialer/" +PIDDatei=${HOMEDIR}data/WGDialer.pid +WarteSekunden=2 +WarteSchleifen=10 +ScriptLog=${HOMEDIR}data/WGDialer.log +WGET="/usr/bin/wget --spider http://www.freenet.de &>${HOMEDIR}data/wget.log &" +IPTABLES="/usr/sbin/iptables" +SitzungsPrefix=${HOMEDIR}data/sitzung/ +NutzerLogPrefix=${HOMEDIR}data/nutzer/ +AdminFehlerLog=${HOMEDIR}data/fehler.log +AdminLog=${HOMEDIR}data/meldungen.log +NutzerListenDatei=${HOMEDIR}data/nutzer.liste +VerbindungsWunschDatei=${HOMEDIR}data/verbindungs.anforderung +EinwahlSkript=${HOMEDIR}scripts/einwahl.sh + +# Format der Nutzerdateien: +# "Datum (lesbar)" "Datum (auswertbar)" "Kostensatz" "Anzahl der Teilnehmer" "Kosten der Teilverbindung" "Dauer" +# Format der Sitzungsdateien: +# "Beginn der/s Verbindung(-sabschnitts) in Sek. seit 1970" / +# "lesbares Datum" + + +# Format der Nutzerlistendatei: +# "Nutzername" "IP" + + +############ Protokollierung ################## + +function aktiviereSkriptLog() +{ + exec 2>>$ScriptLog + echo -e "\n\nSitzungsbeginn:" `date` >> ${HOMEDIR}data/WGDialer.log + + set -xu + #set -u +} + +function AdminNachricht() # Para: Text +{ + echo -e "`date` - $1" >>$AdminLog +} + + +function AdminFehler() # Para: Text +{ + AdminNachricht "Fehler: $1" + echo -e "`date` - $1" >>$AdminFehlerLog +} + + +################ Konsistenz ################ + +function pruefeStatus() +{ + holeAktiveNutzer + local nutzer=$ERG + holeAnzahlNutzer + local AnzahlNutzer=$ERG + local t= + test -e $VerbindungsWunschDatei && (istDialerGestartet || (t="? Verbindungswuensche ohne gestarteten Dialer" && rm $VerbindungsWunschDatei)) + if test 0 -lt $AnzahlNutzer; then + istDialerGestartet || (t="? Nutzer ($nutzer) ohne Verbindung -> Trennung" && trenneAlleVerbindungen) + fi + test 0 -eq $AnzahlNutzer -a ! -e $VerbindungsWunschDatei && istDialerGestartet && (beendeDialer; t="? Verbindung ohne Nutzer") + test -e $NutzerListenDatei || t="? keine Nutzerlistendatei vorhanden!" + test -n "$t" && AdminFehler "$t" + test -z "$t" +} + + +# pruefe, ob Skript bereits aktiv, falls ja, dann bis zu sechs Sekunden auf +# Ende des Parallelprozesses warten, sonst Abbruch +function pruefeWeitereInstanz() +{ + local count=0 + local PID + local COMMAND + while test "$1" != "reset" -a -e $PIDDatei -a $WarteSchleifen -gt $count; do + PID=`cat $PIDDatei` + if test -z "$PID"; then + rm $PIDDatei + else + COMMAND=`ps -p $PID -o comm |tail -1` + if test `echo $0 | grep $COMMAND | wc -l` -eq 0; then + test -e $PIDDatei && rm $PIDDatei + else + let count=count+1 + sleep $WarteSekunden + fi + fi + done + + test -e $PIDDatei && AdminFehler "p-w-I: Wartezeit ueberschritten" && exit 1 + trap "rm $PIDDatei" 0 + echo $$ > $PIDDatei +} + + +################### Sitzungsverwaltung #################### + +# sollte nur von "aktualisiereAlleSitzungen" aufgerufen werden +function verarbeiteSitzungsDatei() # Para: Nutzername +{ + function holeSitzungsDauer() # Para: Nutzername + { + local jetzt=`date +%s` + local beginn=`tail -1 $SitzungsPrefix$1 | cut -f 1` + let ERG=jetzt-beginn + } + # liefert die Pro-Minute-Kosten der atuell gewaehlten Verbindung + function holeAktuellenKostenSatz() + { + ERG="`$EinwahlSkript hole-kosten-satz`" + test -n "X" + } + + + function holeSitzungsKosten() # Para: Nutzername + { + holeAktuellenKostenSatz + local pro=$ERG + holeSitzungsDauer $1 + local dauer + local gesamtKosten + let dauer=ERG+45 + # "45" als Korrektur wegen der Minutenabrechnung + let gesamtKosten=pro*dauer/60 + holeAnzahlNutzer + local anz=$ERG + let ERG=gesamtKosten/anz + test 0 -eq $ERG && AdminFehler "hSK: kostenfrei ($pro/$dauer/$anz)?" + test -n "X" + } + + holeSitzungsKosten $1 + local kosten=$ERG + holeSitzungsDauer $1 + local dauer=$ERG + holeAnzahlNutzer + local anz=$ERG + holeAktuellenKostenSatz + local kostenSatz + let kostenSatz=ERG/anz + echo -e "`date`\t`date +%Y%m%d`\t$kostenSatz\t$anz\t$kosten\t$dauer" >>$NutzerLogPrefix$1 +} + + + + +function aktualisiereAlleSitzungen() +{ + local SITZUNG + holeAktiveNutzer + local aktiveNutzer="$ERG" + if test -n "$aktiveNutzer"; then + for SITZUNG in $aktiveNutzer; do + verarbeiteSitzungsDatei $SITZUNG + erstelleSitzungsDatei $SITZUNG + done + fi + test -n "X" +} + + +function loescheSitzungsDatei() # Para: Nutzername +{ + rm $SitzungsPrefix$1 +} + + +function erstelleSitzungsDatei() # Para: Nutzername +{ + echo -e "`date +%s`" >$SitzungsPrefix$1 +} + + +################# Nutzerverwaltung #################### + +function holeAktiveNutzer() +{ + ERG=`ls $SitzungsPrefix` +} + + +function holeAnzahlNutzer() +{ + ERG=`ls $SitzungsPrefix|wc -l` + local aN=`ls $SitzungsPrefix` + test -z "$aN" && ERG=0 + test -n "X" +} + + +function verbindeNutzer() # Parameter: Nutzername +{ + holeAnzahlNutzer + local anz=$ERG + if test 0 -eq $anz; then + meldeVerbindungsWunschAn $1 + istDialerGestartet || starteDialer + elif istNutzerAktiv $1; then + AdminFehler "$1 versucht sich mehrfach anzumelden" + else + test 0 -lt $anz && NutzerVerbindungenHergestellt $1 + fi +} + + +function NutzerVerbindungenHergestellt() # Para: Nutzernamen +{ + holeAnzahlNutzer + test 0 -lt $ERG && aktualisiereAlleSitzungen + local nutzer + for nutzer in $1; do + if istNutzerOK "$nutzer"; then + AdminNachricht "$nutzer oeffnet die Verbindung" + erstelleSitzungsDatei $nutzer + else + AdminFehler "ungueltiger Nutzer: $nutzer" + fi + done + aktualisiereWeiterleitungen +} + + +function holeVerbindungsStatus() +{ + local zustand="unzulaessiger Status" + holeAnzahlNutzer + local anz=$ERG + test 0 -lt $anz && zustand="verbunden" + istDialerGestartet || zustand="getrennt" + test -e $VerbindungsWunschDatei && zustand="Waehlvorgang" + ERG=$zustand +} + + +function holeNutzerStatus() # Para: Nutzername +{ + local status="unbekannter Nutzer" + istNutzerOK $1 && status="getrennt" + istNutzerAktiv $1 && status="verbunden" + istNutzerBeiEinwahl $1 && status="bei der Einwahl" + ERG=$status +} + + +function holeIPdesNutzers() # Para: Nutzername +{ + local aNutzer="`cat $NutzerListenDatei`" + local ip="unbekannt" + local nutzer + local tName + local tIP + for nutzer in $aNutzer; do + if test -z "$tName"; then + tName="`echo $nutzer|cut -f 1`" + else + tIP="`echo $nutzer|cut -f 1`" + test "$1" = "$tName" && ip=$tIP + tName= + fi + done + ERG=$ip + test "$ip" != "unbekannt" +} + + +function holeNutzerDerIP() # Para: IP +{ + local a5Nutzer="`cat $NutzerListenDatei`" + local name="unbekannt" + local nutzer + local tName + local tIP + for nutzer in $a5Nutzer; do + if test -z "$tName"; then + tName="`echo $nutzer|cut -f 1`" + else + tIP="`echo $nutzer|cut -f 1`" + test "$1" = "$tIP" && name=$tName + tName= + fi + done + ERG=$name +} + + +function istNutzerAktiv() # Para: Nutzername +{ + local gefunden=nein + holeAktiveNutzer + local a2Nutzer="$ERG" + local nutzer + for nutzer in $a2Nutzer; do + test "$nutzer" = "$1" && gefunden=ja + done + test "$gefunden" = "ja" +} + + +function istNutzerOK() # Para: Nutzername +{ + local a3Nutzer="`cat $NutzerListenDatei|cut -f 1`" + local gefunden="nein" + local name + for name in $a3Nutzer; do + test "$name" = "$1" && gefunden="ja" + done + test "$gefunden" = "ja" +} + + +function istNutzerBeiEinwahl() # Para: Nutzername +{ + local gefunden=nein + if test -e "$VerbindungsWunschDatei"; then + local nutzer + for nutzer in `cat $VerbindungsWunschDatei`; do + test "$nutzer" = "$1" && gefunden=ja + done + fi + test "$gefunden" = "ja" +} + + +function meldeVerbindungsWunschAn() # Para: Nutzername +{ + echo $1 >>$VerbindungsWunschDatei + AdminNachricht "$1 meldet Verbindungswunsch an" +} + + +function holeAnzahlVerbindungsWuensche() +{ + local anz=0 + test -s "$VerbindungsWunschDatei" && anz=`cat $VerbindungsWunschDatei|wc -l` + # "test -s" -> pruefe ob Datei groesser Null ist + test $anz -le 0 && AdminFehler "hAVW: ungueltige Anzahl von Verbindungswuenschen ($anz)!" + test -s "$VerbindungsWunschDatei" || AdminFehler "hAVW: fehlende (oder leere) Verbindungswunschdatei!" + ERG=$anz + +} + + +function erfuelleVerbindungsWuensche() +{ + if test -f "$VerbindungsWunschDatei"; then + local wuensche="`cat $VerbindungsWunschDatei`" + NutzerVerbindungenHergestellt "$wuensche" + rm "$VerbindungsWunschDatei" + else + AdminFehler "keine Verbindungswuensche vorhanden!" + fi +} + + +function entferneNutzerAusWunschDatei() # Para: Nutzername +{ + local alle="`cat $VerbindungsWunschDatei`" + rm $VerbindungsWunschDatei + local einer + for einer in $alle; do + test "$einer" != "$1" && echo $einer >>$VerbindungsWunschDatei + done + test -e "$VerbindungsWunschDatei" || beendeDialer && AdminNachricht "Nutzer $1 trennt vor Verbindungsaufbau" +} + + +function trenneNutzer() # Para: Nutzername +{ + if istNutzerBeiEinwahl $1; then + entferneNutzerAusWunschDatei $1 + if istNutzerBeiEinwahl $1; then + AdminFehler "Nutzer konnte nicht aus Wunschdatei entfernt werden: $1" + test -z "X" + else AdminNachricht "Nutzer widerruft Verbindungswunsch: $1" + test -n "X" + fi + elif istNutzerAktiv $1; then + aktualisiereAlleSitzungen + loescheSitzungsDatei $1 + aktualisiereWeiterleitungen + istNutzerAktiv $1 || AdminNachricht "$1 trennt die Verbindung" + holeAnzahlNutzer + test $ERG -eq 0 && beendeDialer && AdminNachricht "keine weiteren Nutzer nach $1 - Trennung" + if istNutzerAktiv $1; then + test -z "X" + else test -n "X" + fi + else + AdminFehler "trenneNutzer: Nutzer $1 nicht verbunden" + test -z "X" + fi +} + + +function trenneAlleVerbindungen() +{ + local nutzer + holeAktiveNutzer + local a4Nutzer=$ERG + if test -n "$a4Nutzer"; then + aktualisiereAlleSitzungen + for nutzer in "$a4Nutzer"; do + loescheSitzungsDatei $nutzer + done + fi + verbieteAlleWeiterleitungen + holeAnzahlNutzer + local anz=$ERG + holeAktiveNutzer + local namen=$ERG + test $anz -gt 0 && AdminFehler "Verbindungstrennung: offene Verbindungen entdeckt ($namen)" + holeAnzahlNutzer + test $ERG -eq 0 +} + + +############### Kostenermittlung ###################### + +function ermittleKosten() # Para: Nutzer, von, bis (jeweils in Form von "20041231") +{ + local datumKosten + test -e $NutzerLogPrefix$1 && datumKosten=`cat $NutzerLogPrefix$1 | cut -f 2,5` + if test -n "$datumKosten"; then + local t + local was="datum" + local gesamt=0 + local neuGesamt + local datum + local preis + for t in $datumKosten; do + if test "$was" = "datum"; then + datum=$t + was="preis" + else + preis=$t + test "$datum" -ge "$2" -a "$datum" -le "$3" && let neuGesamt=gesamt+preis + gesamt=$neuGesamt + was="datum" + fi + done + let ERG=gesamt/100 + # Ergebnis in Cent + else + ERG=0; + fi +} + + +############### Weiterleitungskontrolle ############### + +function aktualisiereWeiterleitungen() +{ + holeAktiveNutzer + local alle=$ERG + local n + $IPTABLES -F FORWARD # die Forward-Regeln loeschen + if test -n "$alle"; then + for n in $alle; do + holeIPdesNutzers $n && $IPTABLES -A FORWARD -i $OUTDEV -o eth0 -d $ERG -m state --state ESTABLISHED,RELATED -j ACCEPT && $IPTABLES -A FORWARD -i eth0 -o $OUTDEV -s $ERG -j ACCEPT + done + fi +} + + +function erlaubeAlleWeiterleitungen() +{ + $IPTABLES -A FORWARD -i $OUTDEV -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT + $IPTABLES -A FORWARD -i eth0 -o $OUTDEV -j ACCEPT +} + + +function verbieteAlleWeiterleitungen() +{ + $IPTABLES -F FORWARD +} + + +function entschaerfeProvider() +{ + $IPTABLES -A OUTPUT -o $OUTDEV --protocol tcp --dport 80 -j ACCEPT + $IPTABLES -A INPUT -i $OUTDEV --protocol tcp --sport 80 -m state --state ESTABLISHED,RELATED -j ACCEPT + $WGET + sleep 2 + kill $! + # beende WGET, damit keine Firewall-Logs auftauchen + $IPTABLES -D OUTPUT -o $OUTDEV --protocol tcp --dport 80 -j ACCEPT + $IPTABLES -D INPUT -i $OUTDEV --protocol tcp --sport 80 -m state --state ESTABLISHED,RELATED -j ACCEPT +} + +################## main ############################ + + +pruefeWeitereInstanz # sorgt dafuer, dass nur eine Instanz laeuft + +aktiviereSkriptLog # aktiviert die Log-Datei + + +set +u # wegen "unbound"-Warnungen notwendig + +case "$1" in + verbinde ) # ein Nutzer moechte die Verbindung nutzen + pruefeStatus + if istNutzerOK $2; then + if verbindeNutzer $2; then + echo "Verbindungsaufbau gestartet" + else echo "Verbindungsaufbau fehlgeschlagen" + fi + else AdminFehler "$2 - versuchte Anmeldung" + echo "unzulaessiger Nutzer" + fi + ;; + ip-up ) # der Dialer hat die Verbindung hergestellt + # wird von "if-up" aufgerufen + pruefeStatus + erfuelleVerbindungsWuensche + entschaerfeProvider + ;; + ip-down ) # Verbindung beendet (regulaer? / Wuensche zurueckziehen?) + pruefeStatus + holeAktiveNutzer + dieANutzer=$ERG + if test -n "$dieANutzer"; then + AdminNachricht "Zeitueberschreitung der Verbindung fuer: $dieANutzer" + trenneAlleVerbindungen + fi + # der Dialer sollte sich gerade selbst beenden + $EinwahlSkript einwahl-ist-beendet + ;; + trenne ) # Nutzer moechte Verbindung fuer sich beenden + pruefeStatus + if istNutzerOK $2;then + if trenneNutzer $2; then echo "Nutzer getrennt" + else echo "Trennung fehlerhaft" + fi + else echo "unzulaessiger Nutzer" + fi + ;; + status-verbindung ) # offen/waehlen/getrennt + pruefeStatus + holeVerbindungsStatus + echo -e "$ERG" + ;; + status-nutzer ) # Verbindungsstatus fuer einen Nutzer + pruefeStatus + istNutzerOK $2 || AdminFehler "s-n: unbekannter Nutzer: $2" + holeNutzerStatus $2 + echo -e "$ERG" + ;; + alle-nutzer ) # Namen der Nutzer + pruefeStatus + cat $NutzerListenDatei | cut -f 1 + ;; + alle-aktiven-nutzer ) # Namen aller aktiven Nutzer + holeAktiveNutzer + if test -z "$ERG"; + then echo "kein aktiver Nutzer" + else echo $ERG + fi + ;; + status ) # Gesamtuebersicht + pruefeStatus + holeVerbindungsStatus + echo -e "Verbindungsstatus:\t$ERG" + for n in `cat $NutzerListenDatei | cut -f 1`; do + holeIPdesNutzers $n + echo -en "$ERG\t\t" + holeNutzerStatus $n + echo -e "$ERG\t$n" + done + ;; + kosten ) # Kosten fuer einen Nutzer in bestimmtem Zeitraum + t="" + istNutzerOK $2 || t1="kosten: ungueltiger Nutzer ($2)" + test -n "$3" -a -n "$4" -a $3 -le $4 || t2="ungueltiger Datumsbereich ($3/$4)" + test -z "$t1" && t=$t2; + test -z "$t2" && t=$t1; + test -n "$t1" -a -n "$t2" && t="$t1 / $t2"; + if test -z "$t"; then + ermittleKosten $2 $3 $4 + echo $ERG + else + AdminFehler $t + echo $t + fi + ;; + nutzer2ip ) # + if istNutzerOK $2; then + holeIPdesNutzers $2 + echo $ERG + else + AdminFehler "n2i: unbekannter Nutzer: $2" + fi + ;; + ip2nutzer ) # ermittle Nutzernamen fuer IP + holeNutzerDerIP $2 + echo $ERG + ;; + nutzer-log ) # zeigt das Verbindungsprotokoll des Nutzers + if istNutzerOK $2; then + if test -s $NutzerLogPrefix$2; then + echo -e "Datum\tDatum (Comp)\tPreis je min\tAnzahl der Nutzer\tVerbindungskosten\tDauer (in Sek.)" + cat $NutzerLogPrefix$2 + else + echo "keine Eintraege" + fi + else + AdminFehler "n-l: unbekannter Nutzer: $2" + echo "ungueltiger Nutzername" + fi + ;; + protokoll ) # zeigt eine Log-Datei an + datei= + case $2 in + fehler ) + datei=$AdminFehlerLog + prog="cat" + ;; + meldungen ) + datei=$AdminLog + prog="tail -200" + ;; + script ) + datei=$ScriptLog + prog="tail -300" + ;; + dialer ) + datei=$DialerLog + prog="tail -70" + ;; + * ) + echo "ungueltige Auswahl der Protokoll-Datei" + ;; + esac + if test -n "$datei"; then + if test -s $datei; then + $prog $datei + else + echo "keine Eintraege" + fi + fi + ;; + reset ) + trenneAlleVerbindungen + # beenden geht leider nicht, wegen PID + if test -e $DialPIDDatei; then + ERG1=`cat $DialPIDDatei` + ERG2=`ps --pid $ERG1 -o comm | tail -1` + ERG3=`echo $0 | grep $ERG2` + test -n "$ERG3" && kill $ERG1 + # beim Beenden sollte die PID-Datei geloescht werden, aber: + test -e "$DialPIDDatei" && rm $DialPIDDatei + fi + test -n "`ls $SitzungsPrefix`" && rm $SitzungsPrefix* + test -e $DialerStatus && rm $DialerStatus + test -e $VerbindungsWunschDatei && rm $VerbindungsWunschDatei + # unnoetig die PIDDatei zu loeschen, da trap dies tut + verbieteAlleWeiterleitungen + AdminNachricht "Reset ausgeloest" + ;; + * ) # Hilfe + echo -e "Parameter:" + echo -e "\t verbinde X\t\t- oeffne Verbindung fuer X" + echo -e "\t trenne X\t\t- trenne die Verbindung fuer X" + echo -e "\t status\t\t\t- allgemeine Informationen" + echo -e "\t status-verbindung\t- Ausgabe der Info" + echo -e "\t status-nutzer X\t- Ausgabe der Info" + echo -e "\t alle-nutzer\t\t- Ausgabe aller Nutzernamen" + echo -e "\t alle-aktiven-nutzer\t- Ausgabe der derzeit verbundenen Nutzer" + echo -e "\t ip2nutzer X\t\t- liefert den Nutzernamen fuer eine IP" + echo -e "\t nutzer2ip X\t\t- liefert die IP des Nutzers" + echo -e "\t kosten X Y Z\t\t- Kosten fuer X von Y bis Z (z.B.: 20041231)" + echo -e "\t nutzer-log X\t\t- Verbindungsprotokoll des Nutzers X" + echo -e "\t protokoll X\t\t- Log-Datei (fehler,meldungen,script,dialer)" + ;; + esac + + + diff --git a/wg-dialer/scripts/WGDialer.sh b/wg-dialer/scripts/WGDialer.sh new file mode 100755 index 0000000..87e91c7 --- /dev/null +++ b/wg-dialer/scripts/WGDialer.sh @@ -0,0 +1,818 @@ +#!/bin/sh + + +# Beginn des Scripts +HOMEDIR="/home/WGDialer/" +PIDDatei=${HOMEDIR}data/WGDialer.pid +WarteSekunden=2 +WarteSchleifen=10 +OUTDEV="ippp0" +ScriptLog=${HOMEDIR}data/WGDialer.log +WGET="/usr/bin/wget --spider http://www.freenet.de &>${HOMEDIR}data/wget.log &" +IPTABLES="/usr/sbin/iptables" +DialerModem="/usr/bin/wvdial" +DialerISDN="/usr/sbin/isdnctrl" +DialPIDDatei=${HOMEDIR}data/dialer.pid +SitzungsPrefix=${HOMEDIR}data/sitzung/ +NutzerLogPrefix=${HOMEDIR}data/nutzer/ +AdminFehlerLog=${HOMEDIR}data/fehler.log +AdminLog=${HOMEDIR}data/meldungen.log +DialerStatus=${HOMEDIR}data/dialer.info +# enthaelt Namen des Verbindungsaufbauenden / Einwahltarif +DialerLog=${HOMEDIR}data/dialer.log +NutzerListenDatei=${HOMEDIR}data/nutzer.liste +VerbindungsWunschDatei=${HOMEDIR}data/verbindungs.anforderung + +# Format der Nutzerdateien: +# "Datum (lesbar)" "Datum (auswertbar)" "Kostensatz" "Anzahl der Teilnehmer" "Kosten der Teilverbindung" "Dauer" +# Format der Sitzungsdateien: +# "Beginn der/s Verbindung(-sabschnitts) in Sek. seit 1970" / +# "lesbares Datum" + + +# Format der Nutzerlistendatei: +# "Nutzername" "IP" + +# Format der Dialer-Status-Datei: +# "Kosten" folgende Zeilen: "Name der/s Einwaehlenden" + +################## der Dialer ############################ + +function istDialerGestartet() +{ + local istGestartet + istGestartet="falsch" + if test $OUTDEV = "ppp0"; then + if test -e "$DialPIDDatei"; then + local dialPID=`cat $DialPIDDatei` + local t=`ps -p $dialPID -h -o cmd|cut -f 1 -d " "` + if test "$DialerModem" != "$t"; then + AdminFehler "Dial-PID-Datei enthaelt fehlerhaften Verweis" + rm $DialPIDDatei + fi + fi + test -e "$DialPIDDatei" && istGestartet="wahr" + else + test -n `${DialerISDN} status $OUTDEV | grep "not connected"` && istGestartet="wahr" + fi + test $istGestartet = "wahr" +} + + +function beendeDialer() +{ + if istDialerGestartet; then + AdminNachricht "Der Dialer wird beendet ..." + if test "$OUTDEV" = "ppp0"; then + kill `cat $DialPIDDatei` + else + $DialerISDN hangup $OUTDEV + fi + # jetzt sollte die Aufraeumaktion gestartet werden + test -e $DialPIDDatei && rm $DialerStatus + DialerIstBeendet + test -n "X" + else + AdminFehler "beendeDialer: nicht gestartet" + test -z "X" + fi +} + + +function starteDialer() +{ + if istDialerGestartet; then + AdminFehler "Dialer lief bereits ohne aktive Nutzer!" + test -n "X" + fi + holeProviderInfo Preis + local preis=$ERG + test 0 -gt $preis && AdminFehler "sD: Kostenlose Verbindung?" + holeProviderInfo Name + local name=$ERG + AdminNachricht "Aufbau der Verbindung" + echo -e "$preis\t$name" >$DialerStatus + if test -e $VerbindungsWunschDatei; then + cat $VerbindungsWunschDatei >>$DialerStatus + test -n "X" + else + AdminFehler "sD: keine Verb.-Anforderungen!" + test -z "X" + fi + echo -e "\n`date` - ######## Start des Waehlprogramms #########" >>$DialerLog + if test $OUTDEV = "ppp0"; then + $DialerModem $name >>$DialerLog 2>>$DialerLog & + local pid=$! + echo $pid >$DialPIDDatei + else + # die Auswahl des Tarifs erfolgt extern per cron + $DialerISDN dial $OUTDEV + fi + istDialerGestartet + # damit der Rueckgabestatus stimmt +} + + +# Aufraeumarbeiten +function DialerIstBeendet() +{ + holeAnzahlNutzer + local anz=$ERG + test $anz -gt 0 && AdminFehler "Dialer beendet trotz aktiver Nutzer" + trenneAlleVerbindungen + test $OUTDEV = "ppp0" -a -e "$DialPIDDatei" && rm $DialPIDDatei + test -e "$DialerStatus" && rm $DialerStatus + test -e "$VerbindungsWunschDatei" && rm $VerbindungsWunschDatei + test $anz -eq 0 +} + + +############ Protokollierung ################## + +function aktiviereSkriptLog() +{ + exec 2>>$ScriptLog + echo -e "\n\nSitzungsbeginn:" `date` >> ${HOMEDIR}data/WGDialer.log + + set -xu + #set -u +} + +function AdminNachricht() # Para: Text +{ + echo -e "`date` - $1" >>$AdminLog +} + + +function AdminFehler() # Para: Text +{ + AdminNachricht "Fehler: $1" + echo -e "`date` - $1" >>$AdminFehlerLog +} + + +################ Konsistenz ################ + +function pruefeStatus() +{ + holeAktiveNutzer + local nutzer=$ERG + holeAnzahlNutzer + local AnzahlNutzer=$ERG + local t= + test -e $VerbindungsWunschDatei && (istDialerGestartet || (t="? Verbindungswuensche ohne gestarteten Dialer" && rm $VerbindungsWunschDatei)) + if test 0 -lt $AnzahlNutzer; then + istDialerGestartet || (t="? Nutzer ($nutzer) ohne Verbindung -> Trennung" && trenneAlleVerbindungen) + fi + test 0 -eq $AnzahlNutzer -a ! -e $VerbindungsWunschDatei && istDialerGestartet && (beendeDialer; t="? Verbindung ohne Nutzer") + test -e $NutzerListenDatei || t="? keine Nutzerlistendatei vorhanden!" + test -n "$t" && AdminFehler "$t" + test -z "$t" +} + + +# pruefe, ob Skript bereits aktiv, falls ja, dann bis zu sechs Sekunden auf +# Ende des Parallelprozesses warten, sonst Abbruch +function pruefeWeitereInstanz() +{ + local count=0 + local PID + local COMMAND + while test "$1" != "reset" -a -e $PIDDatei -a $WarteSchleifen -gt $count; do + PID=`cat $PIDDatei` + if test -z "$PID"; then + rm $PIDDatei + else + COMMAND=`ps -p $PID -o comm |tail -1` + if test `echo $0 | grep $COMMAND | wc -l` -eq 0; then + test -e $PIDDatei && rm $PIDDatei + else + let count=count+1 + sleep $WarteSekunden + fi + fi + done + + test -e $PIDDatei && AdminFehler "p-w-I: Wartezeit ueberschritten" && exit 1 + trap "rm $PIDDatei" 0 + echo $$ > $PIDDatei +} + + +################### Sitzungsverwaltung #################### + +# sollte nur von "aktualisiereAlleSitzungen" aufgerufen werden +function verarbeiteSitzungsDatei() # Para: Nutzername +{ + function holeSitzungsDauer() # Para: Nutzername + { + local jetzt=`date +%s` + local beginn=`tail -1 $SitzungsPrefix$1 | cut -f 1` + let ERG=jetzt-beginn + } + # liefert die Pro-Minute-Kosten der atuell gewaehlten Verbindung + function holeAktuellenKostenSatz() + { + ERG="`head -1 $DialerStatus|cut -f 1`" + test -n "X" + } + + + function holeSitzungsKosten() # Para: Nutzername + { + holeAktuellenKostenSatz + local pro=$ERG + holeSitzungsDauer $1 + local dauer + local gesamtKosten + let dauer=ERG+45 + # "45" als Korrektur wegen der Minutenabrechnung + let gesamtKosten=pro*dauer/60 + holeAnzahlNutzer + local anz=$ERG + let ERG=gesamtKosten/anz + #test 0 -eq $ERG && AdminFehler "hSK: kostenfrei ($pro/$dauer/$anz)?" + test -n "X" + } + + holeSitzungsKosten $1 + local kosten=$ERG + holeSitzungsDauer $1 + local dauer=$ERG + holeAnzahlNutzer + local anz=$ERG + holeAktuellenKostenSatz + local kostenSatz + let kostenSatz=ERG/anz + echo -e "`date`\t`date +%Y%m%d`\t$kostenSatz\t$anz\t$kosten\t$dauer" >>$NutzerLogPrefix$1 +} + + +# liefert "Preis" oder "Name (Dialer-Parameter)" +function holeProviderInfo() # gewuenschte Information +# WICHTIG: Aenderung, damit angewaehlter Tarif bezahlt wird +{ + # Provider: 0 - Freenet-Super (Nebenzeit) + # 1 - Freenet-Super (Hauptzeit) + # 2 - Freenet-XXL (Sonntags) + local prov + local jetzt="`date +%H%M`" # liefert die aktuelle Stunde + if test $jetzt -lt 730; then + prov=0 + elif test $jetzt -lt 1730; then + prov=1 + elif test $jetzt -lt 2130; then + prov=0 + else + prov=0 + fi + local tag="`date +%w`" + test $tag -eq 0 -o $tag -eq 6 && prov=0 + test $tag -eq 0 && prov=2 + local preis + local name + case $prov in + 0 ) preis=99; name="FreeNet-Super";; + 1 ) preis=145; name="FreeNet-Super";; + 2 ) preis=0; name="FreeNet-XXL";; + esac + if test "$1" = "Preis"; then ERG=$preis + elif test "$1" = "Name"; then ERG="$name" + else AdminFehler "ProviderInfo: fehlerhafte Anfrage" + fi + test -n "X" +} + + +function aktualisiereAlleSitzungen() +{ + local SITZUNG + holeAktiveNutzer + local aktiveNutzer="$ERG" + if test -n "$aktiveNutzer"; then + for SITZUNG in $aktiveNutzer; do + verarbeiteSitzungsDatei $SITZUNG + erstelleSitzungsDatei $SITZUNG + done + fi + test -n "X" +} + + +function loescheSitzungsDatei() # Para: Nutzername +{ + rm $SitzungsPrefix$1 +} + + +function erstelleSitzungsDatei() # Para: Nutzername +{ + echo -e "`date +%s`" >$SitzungsPrefix$1 +} + + +################# Nutzerverwaltung #################### + +function holeAktiveNutzer() +{ + ERG=`ls $SitzungsPrefix` +} + + +function holeAnzahlNutzer() +{ + ERG=`ls $SitzungsPrefix|wc -l` + local aN=`ls $SitzungsPrefix` + test -z "$aN" && ERG=0 + test -n "X" +} + + +function verbindeNutzer() # Parameter: Nutzername +{ + holeAnzahlNutzer + local anz=$ERG + if test 0 -eq $anz; then + meldeVerbindungsWunschAn $1 + istDialerGestartet || starteDialer + elif istNutzerAktiv $1; then + AdminFehler "$1 versucht sich mehrfach anzumelden" + else + test 0 -lt $anz && NutzerVerbindungenHergestellt $1 + fi +} + + +function NutzerVerbindungenHergestellt() # Para: Nutzernamen +{ + holeAnzahlNutzer + test 0 -lt $ERG && aktualisiereAlleSitzungen + local nutzer + for nutzer in $1; do + if istNutzerOK "$nutzer"; then + AdminNachricht "$nutzer oeffnet die Verbindung" + erstelleSitzungsDatei $nutzer + else + AdminFehler "ungueltiger Nutzer: $nutzer" + fi + done + aktualisiereWeiterleitungen +} + + +function holeVerbindungsStatus() +{ + local zustand="unzulaessiger Status" + holeAnzahlNutzer + local anz=$ERG + test 0 -lt $anz && zustand="verbunden" + istDialerGestartet || zustand="getrennt" + test -e $VerbindungsWunschDatei && zustand="Waehlvorgang" + ERG=$zustand +} + + +function holeNutzerStatus() # Para: Nutzername +{ + local status="unbekannter Nutzer" + istNutzerOK $1 && status="getrennt" + istNutzerAktiv $1 && status="verbunden" + istNutzerBeiEinwahl $1 && status="bei der Einwahl" + ERG=$status +} + + +function holeIPdesNutzers() # Para: Nutzername +{ + local aNutzer="`cat $NutzerListenDatei`" + local ip="unbekannt" + local nutzer + local tName + local tIP + for nutzer in $aNutzer; do + if test -z "$tName"; then + tName="`echo $nutzer|cut -f 1`" + else + tIP="`echo $nutzer|cut -f 1`" + test "$1" = "$tName" && ip=$tIP + tName= + fi + done + ERG=$ip + test "$ip" != "unbekannt" +} + + +function holeNutzerDerIP() # Para: IP +{ + local a5Nutzer="`cat $NutzerListenDatei`" + local name="unbekannt" + local nutzer + local tName + local tIP + for nutzer in $a5Nutzer; do + if test -z "$tName"; then + tName="`echo $nutzer|cut -f 1`" + else + tIP="`echo $nutzer|cut -f 1`" + test "$1" = "$tIP" && name=$tName + tName= + fi + done + ERG=$name +} + + +function istNutzerAktiv() # Para: Nutzername +{ + local gefunden=nein + holeAktiveNutzer + local a2Nutzer="$ERG" + local nutzer + for nutzer in $a2Nutzer; do + test "$nutzer" = "$1" && gefunden=ja + done + test "$gefunden" = "ja" +} + + +function istNutzerOK() # Para: Nutzername +{ + local a3Nutzer="`cat $NutzerListenDatei|cut -f 1`" + local gefunden="nein" + local name + for name in $a3Nutzer; do + test "$name" = "$1" && gefunden="ja" + done + test "$gefunden" = "ja" +} + + +function istNutzerBeiEinwahl() # Para: Nutzername +{ + local gefunden=nein + if test -e "$VerbindungsWunschDatei"; then + local nutzer + for nutzer in `cat $VerbindungsWunschDatei`; do + test "$nutzer" = "$1" && gefunden=ja + done + fi + test "$gefunden" = "ja" +} + + +function meldeVerbindungsWunschAn() # Para: Nutzername +{ + echo $1 >>$VerbindungsWunschDatei + AdminNachricht "$1 meldet Verbindungswunsch an" +} + + +function holeAnzahlVerbindungsWuensche() +{ + local anz=0 + test -s "$VerbindungsWunschDatei" && anz=`cat $VerbindungsWunschDatei|wc -l` + # "test -s" -> pruefe ob Datei groesser Null ist + test $anz -le 0 && AdminFehler "hAVW: ungueltige Anzahl von Verbindungswuenschen ($anz)!" + test -s "$VerbindungsWunschDatei" || AdminFehler "hAVW: fehlende (oder leere) Verbindungswunschdatei!" + ERG=$anz + +} + + +function erfuelleVerbindungsWuensche() +{ + if test -f "$VerbindungsWunschDatei"; then + local wuensche="`cat $VerbindungsWunschDatei`" + NutzerVerbindungenHergestellt "$wuensche" + rm "$VerbindungsWunschDatei" + else + AdminFehler "keine Verbindungswuensche vorhanden!" + fi +} + + +function entferneNutzerAusWunschDatei() # Para: Nutzername +{ + local alle="`cat $VerbindungsWunschDatei`" + rm $VerbindungsWunschDatei + local einer + for einer in $alle; do + test "$einer" != "$1" && echo $einer >>$VerbindungsWunschDatei + done + test -e "$VerbindungsWunschDatei" || beendeDialer && AdminNachricht "Nutzer $1 trennt vor Verbindungsaufbau" +} + + +function trenneNutzer() # Para: Nutzername +{ + if istNutzerBeiEinwahl $1; then + entferneNutzerAusWunschDatei $1 + if istNutzerBeiEinwahl $1; then + AdminFehler "Nutzer konnte nicht aus Wunschdatei entfernt werden: $1" + test -z "X" + else AdminNachricht "Nutzer widerruft Verbindungswunsch: $1" + test -n "X" + fi + elif istNutzerAktiv $1; then + aktualisiereAlleSitzungen + loescheSitzungsDatei $1 + aktualisiereWeiterleitungen + istNutzerAktiv $1 || AdminNachricht "$1 trennt die Verbindung" + holeAnzahlNutzer + test $ERG -eq 0 && beendeDialer && AdminNachricht "keine weiteren Nutzer nach $1 - Trennung" + if istNutzerAktiv $1; then + test -z "X" + else test -n "X" + fi + else + AdminFehler "trenneNutzer: Nutzer $1 nicht verbunden" + test -z "X" + fi +} + + +function trenneAlleVerbindungen() +{ + local nutzer + holeAktiveNutzer + local a4Nutzer=$ERG + if test -n "$a4Nutzer"; then + aktualisiereAlleSitzungen + for nutzer in "$a4Nutzer"; do + loescheSitzungsDatei $nutzer + done + fi + verbieteAlleWeiterleitungen + holeAnzahlNutzer + local anz=$ERG + holeAktiveNutzer + local namen=$ERG + test $anz -gt 0 && AdminFehler "Verbindungstrennung: offene Verbindungen entdeckt ($namen)" + holeAnzahlNutzer + test $ERG -eq 0 +} + + +############### Kostenermittlung ###################### + +function ermittleKosten() # Para: Nutzer, von, bis (jeweils in Form von "20041231") +{ + local datumKosten + test -e $NutzerLogPrefix$1 && datumKosten=`cat $NutzerLogPrefix$1 | cut -f 2,5` + if test -n "$datumKosten"; then + local t + local was="datum" + local gesamt=0 + local neuGesamt + local datum + local preis + for t in $datumKosten; do + if test "$was" = "datum"; then + datum=$t + was="preis" + else + preis=$t + test "$datum" -ge "$2" -a "$datum" -le "$3" && let neuGesamt=gesamt+preis + gesamt=$neuGesamt + was="datum" + fi + done + let ERG=gesamt/100 + # Ergebnis in Cent + else + ERG=0; + fi +} + + +############### Weiterleitungskontrolle ############### + +function aktualisiereWeiterleitungen() +{ + holeAktiveNutzer + local alle=$ERG + local n + $IPTABLES -F FORWARD # die Forward-Regeln loeschen + if test -n "$alle"; then + for n in $alle; do + holeIPdesNutzers $n && $IPTABLES -A FORWARD -i $OUTDEV -o eth0 -d $ERG -m state --state ESTABLISHED,RELATED -j ACCEPT && $IPTABLES -A FORWARD -i eth0 -o $OUTDEV -s $ERG -j ACCEPT + done + fi +} + + +function erlaubeAlleWeiterleitungen() +{ + $IPTABLES -A FORWARD -i $OUTDEV -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT + $IPTABLES -A FORWARD -i eth0 -o $OUTDEV -j ACCEPT +} + + +function verbieteAlleWeiterleitungen() +{ + $IPTABLES -F FORWARD +} + + +function entschaerfeProvider() +{ + $IPTABLES -A OUTPUT -o $OUTDEV --protocol tcp --dport 80 -j ACCEPT + $IPTABLES -A INPUT -i $OUTDEV --protocol tcp --sport 80 -m state --state ESTABLISHED,RELATED -j ACCEPT + $WGET + sleep 3 + kill $! + # beende WGET, damit keine Firewall-Logs auftauchen + $IPTABLES -D INPUT -i $OUTDEV --protocol tcp --sport 80 -m state --state ESTABLISHED,RELATED -j ACCEPT + $IPTABLES -D OUTPUT -o $OUTDEV --protocol tcp --dport 80 -j ACCEPT +} + +################## main ############################ + + +pruefeWeitereInstanz # sorgt dafuer, dass nur eine Instanz laeuft + +aktiviereSkriptLog # aktiviert die Log-Datei + + +set +u # wegen "unbound"-Warnungen notwendig + +case "$1" in + verbinde ) # ein Nutzer moechte die Verbindung nutzen + pruefeStatus + if istNutzerOK $2; then + if verbindeNutzer $2; then + echo "Verbindungsaufbau gestartet" + else echo "Verbindungsaufbau fehlgeschlagen" + fi + else AdminFehler "$2 - versuchte Anmeldung" + echo "unzulaessiger Nutzer" + fi + ;; + ip-up ) # der Dialer hat die Verbindung hergestellt + # wird von "if-up" aufgerufen + pruefeStatus + erfuelleVerbindungsWuensche + entschaerfeProvider + ;; + ip-down ) # Verbindung beendet (regulaer? / Wuensche zurueckziehen?) + pruefeStatus + holeAktiveNutzer + dieANutzer=$ERG + if test -n "$dieANutzer"; then + AdminNachricht "Zeitueberschreitung der Verbindung fuer: $dieANutzer" + trenneAlleVerbindungen + fi + # der Dialer sollte sich gerade selbst beenden + DialerIstBeendet + ;; + trenne ) # Nutzer moechte Verbindung fuer sich beenden + pruefeStatus + if istNutzerOK $2;then + if trenneNutzer $2; then echo "Nutzer getrennt" + else echo "Trennung fehlerhaft" + fi + else echo "unzulaessiger Nutzer" + fi + ;; + status-verbindung ) # offen/waehlen/getrennt + pruefeStatus + holeVerbindungsStatus + echo -e "$ERG" + ;; + status-nutzer ) # Verbindungsstatus fuer einen Nutzer + pruefeStatus + istNutzerOK $2 || AdminFehler "s-n: unbekannter Nutzer: $2" + holeNutzerStatus $2 + echo -e "$ERG" + ;; + alle-nutzer ) # Namen der Nutzer + pruefeStatus + cat $NutzerListenDatei | cut -f 1 + ;; + alle-aktiven-nutzer ) # Namen aller aktiven Nutzer + holeAktiveNutzer + if test -z "$ERG"; + then echo "kein aktiver Nutzer" + else echo $ERG + fi + ;; + status ) # Gesamtuebersicht + pruefeStatus + holeVerbindungsStatus + echo -e "Verbindungsstatus:\t$ERG" + for n in `cat $NutzerListenDatei | cut -f 1`; do + holeIPdesNutzers $n + echo -en "$ERG\t\t" + holeNutzerStatus $n + echo -e "$ERG\t$n" + done + ;; + kosten ) # Kosten fuer einen Nutzer in bestimmtem Zeitraum + t="" + istNutzerOK $2 || t1="kosten: ungueltiger Nutzer ($2)" + test -n "$3" -a -n "$4" -a $3 -le $4 || t2="ungueltiger Datumsbereich ($3/$4)" + test -z "$t1" && t=$t2; + test -z "$t2" && t=$t1; + test -n "$t1" -a -n "$t2" && t="$t1 / $t2"; + if test -z "$t"; then + ermittleKosten $2 $3 $4 + echo $ERG + else + AdminFehler $t + echo $t + fi + ;; + nutzer2ip ) # + if istNutzerOK $2; then + holeIPdesNutzers $2 + echo $ERG + else + AdminFehler "n2i: unbekannter Nutzer: $2" + fi + ;; + ip2nutzer ) # ermittle Nutzernamen fuer IP + holeNutzerDerIP $2 + echo $ERG + ;; + nutzer-log ) # zeigt das Verbindungsprotokoll des Nutzers + if istNutzerOK $2; then + if test -s $NutzerLogPrefix$2; then + echo -e "Datum\tDatum (Comp)\tPreis je min\tAnzahl der Nutzer\tVerbindungskosten\tDauer (in Sek.)" + cat $NutzerLogPrefix$2 + else + echo "keine Eintraege" + fi + else + AdminFehler "n-l: unbekannter Nutzer: $2" + echo "ungueltiger Nutzername" + fi + ;; + protokoll ) # zeigt eine Log-Datei an + datei= + case $2 in + fehler ) + datei=$AdminFehlerLog + prog="cat" + ;; + meldungen ) + datei=$AdminLog + prog="tail -200" + ;; + script ) + datei=$ScriptLog + prog="tail -300" + ;; + dialer ) + datei=$DialerLog + prog="tail -70" + ;; + * ) + echo "ungueltige Auswahl der Protokoll-Datei" + ;; + esac + if test -n "$datei"; then + if test -s $datei; then + $prog $datei + else + echo "keine Eintraege" + fi + fi + ;; + reset ) + trenneAlleVerbindungen + # beenden geht leider nicht, wegen PID + if test -e $DialPIDDatei; then + ERG1=`cat $DialPIDDatei` + ERG2=`ps --pid $ERG1 -o comm | tail -1` + ERG3=`echo $0 | grep $ERG2` + test -n "$ERG3" && kill $ERG1 + # beim Beenden sollte die PID-Datei geloescht werden, aber: + test -e "$DialPIDDatei" && rm $DialPIDDatei + fi + test -n "`ls $SitzungsPrefix`" && rm $SitzungsPrefix* + test -e $DialerStatus && rm $DialerStatus + test -e $VerbindungsWunschDatei && rm $VerbindungsWunschDatei + # unnoetig die PIDDatei zu loeschen, da trap dies tut + verbieteAlleWeiterleitungen + AdminNachricht "Reset ausgeloest" + ;; + * ) # Hilfe + echo -e "Parameter:" + echo -e "\t verbinde X\t\t- oeffne Verbindung fuer X" + echo -e "\t trenne X\t\t- trenne die Verbindung fuer X" + echo -e "\t status\t\t\t- allgemeine Informationen" + echo -e "\t status-verbindung\t- Ausgabe der Info" + echo -e "\t status-nutzer X\t- Ausgabe der Info" + echo -e "\t alle-nutzer\t\t- Ausgabe aller Nutzernamen" + echo -e "\t alle-aktiven-nutzer\t- Ausgabe der derzeit verbundenen Nutzer" + echo -e "\t ip2nutzer X\t\t- liefert den Nutzernamen fuer eine IP" + echo -e "\t nutzer2ip X\t\t- liefert die IP des Nutzers" + echo -e "\t kosten X Y Z\t\t- Kosten fuer X von Y bis Z (z.B.: 20041231)" + echo -e "\t nutzer-log X\t\t- Verbindungsprotokoll des Nutzers X" + echo -e "\t protokoll X\t\t- Log-Datei (fehler,meldungen,script,dialer)" + ;; + esac + + + diff --git a/wg-dialer/scripts/einwahl.sh b/wg-dialer/scripts/einwahl.sh new file mode 100755 index 0000000..eca93fd --- /dev/null +++ b/wg-dialer/scripts/einwahl.sh @@ -0,0 +1,170 @@ +#!/bin/sh + +OUTDEV="ippp0" +HOMEDIR="/home/WGDialer/" +DialerModem="/usr/bin/wvdial" +DialerISDN="/usr/sbin/isdnctrl" +DialerISDNWahlHilfe=${HOMEDIR}scripts/waehleISDN.sh +DialPIDDatei=${HOMEDIR}data/dialer.pid +DialerLog=${HOMEDIR}data/dialer.log +DialerStatus=${HOMEDIR}data/dialer.info +# enthaelt Namen des Verbindungsaufbauenden / Einwahltarif +# Format der Dialer-Status-Datei: +# "Kosten" folgende Zeilen: "Name der/s Einwaehlenden" + +if test 0 -lt `echo $OUTDEV | grep ippp | wc -l`; + then Anschkuss=isdn + else Anschluss=analog + fi + + +function istDialerGestartet() +{ +} + + + +function beendeDialer() +{ + if istDialerGestartet; then + AdminNachricht "Der Dialer wird beendet ..." + if test "$Geraet" = "analog"; then + kill `cat $DialPIDDatei` + else + $DialerISDN hangup $OUTDEV + fi + # jetzt sollte die Aufraeumaktion gestartet werden + test -e $DialPIDDatei && rm $DialerStatus + DialerIstBeendet + test -n "X" + else + AdminFehler "beendeDialer: nicht gestartet" + test -z "X" + fi +} + + +function starteDialer() +{ + if istDialerGestartet; then + AdminFehler "Dialer lief bereits ohne aktive Nutzer!" + test -n "X" + fi + holeProviderInfo Preis + local preis=$ERG + holeProviderInfo Name + local name=$ERG + AdminNachricht "Aufbau der Verbindung" + echo -e "$preis\t$name" >$DialerStatus + if test -e $VerbindungsWunschDatei; then + cat $VerbindungsWunschDatei >>$DialerStatus + test -n "X" + else + AdminFehler "sD: keine Verb.-Anforderungen!" + test -z "X" + fi + echo -e "\n`date` - ######## Start des Waehlprogramms #########" >>$DialerLog + $0 rufe-dialer-raw & + local pid=$! + echo $pid >$DialPIDDatei + istDialerGestartet + # damit der Rueckgabestatus stimmt +} + +function rufeDialerRaw() +{ + if test $Geraet = "analog"; then + $DialerModem $name >>$DialerLog 2>>$DialerLog & + local pid=$! + trap "kill $pid" 0 + wait $pid + else + holeProviderInfo Name + $DialerISDNWahlHilfe $ERG $OUTDEV 2>>$DialerLog >>$DialerLog + $DialerISDN dial $OUTDEV + sleep 60 + + fi +} + + +# Aufraeumarbeiten +function DialerIstBeendet() +{ + holeAnzahlNutzer + local anz=$ERG + test $anz -gt 0 && AdminFehler "Dialer beendet trotz aktiver Nutzer" + trenneAlleVerbindungen + test $Geraet = "analog" -a -e "$DialPIDDatei" && rm $DialPIDDatei + test -e "$DialerStatus" && rm $DialerStatus + test -e "$VerbindungsWunschDatei" && rm $VerbindungsWunschDatei + test $anz -eq 0 +} + + + +# liefert "Preis" oder "Name (Dialer-Parameter)" +function holeProviderInfo() # gewuenschte Information +# WICHTIG: Aenderung, damit angewaehlter Tarif bezahlt wird +{ + # Provider: 0 - Freenet-Super (Nebenzeit) + # 1 - Freenet-Super (Hauptzeit) + # 2 - Freenet-XXL (Sonntags) + local prov + local jetzt="`date +%H%M`" # liefert die aktuelle Stunde + if test $jetzt -lt 730; then + prov=0 + elif test $jetzt -lt 1730; then + prov=1 + elif test $jetzt -lt 2130; then + prov=0 + else + prov=0 + fi + local tag="`date +%w`" + test $tag -eq 0 -o $tag -eq 6 && prov=0 + test $tag -eq 0 && prov=2 + local preis + local name + case $prov in + 0 ) preis=99; name="FreeNet-Super";; + 1 ) preis=145; name="FreeNet-Super";; + 2 ) preis=0; name="FreeNet-XXL";; + esac + if test "$1" = "Preis"; then ERG=$preis + elif test "$1" = "Name"; then ERG="$name" + else AdminFehler "ProviderInfo: fehlerhafte Anfrage" + fi + test -n "X" +} + + +case "$1" in + starte-einwahl ) + starteDialer + einwahl-ist-beendet ) + DialerIstBeendet + ;; + hole-kosten-satz ) + holeProviderInfo Preis + echo $ERG + ;; + hole-tarif-name ) + holeProviderInfo Name + echo $ERG + ;; + * ) + echo "einwahl.sh { einwahl-ist-beendet | hole-kosten-satz } + ;; + esac + + + + + + + + + + + diff --git a/wg-dialer/scripts/ip-down.local b/wg-dialer/scripts/ip-down.local new file mode 100755 index 0000000..f529265 --- /dev/null +++ b/wg-dialer/scripts/ip-down.local @@ -0,0 +1 @@ +sudo -u wgdialer /home/WGDialer/scripts/WGDialer.sh ip-down diff --git a/wg-dialer/scripts/ip-up.local b/wg-dialer/scripts/ip-up.local new file mode 100755 index 0000000..1a29fd3 --- /dev/null +++ b/wg-dialer/scripts/ip-up.local @@ -0,0 +1,2 @@ +sudo -u wgdialer /home/WGDialer/scripts/WGDialer.sh ip-up +/home/scripts/dnsQ.sh & diff --git a/wg-dialer/scripts/ueberwacheNutzung.sh b/wg-dialer/scripts/ueberwacheNutzung.sh new file mode 100755 index 0000000..5950318 --- /dev/null +++ b/wg-dialer/scripts/ueberwacheNutzung.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +warteZeit=200 +nutzer=`ls /home/WGDialer/data/nutzer` +alteDatei=/home/WGDialer/data/letzterVerkehr +neueDatei=/home/WGDialer/data/aktuellerVerkehr +holeName="/home/WGDialer/scripts/WGDialer.sh ip2nutzer " +trenneVerbindung="/home/WGDialer/scripts/WGDialer.sh trenne " +logDatei=/home/WGDialer/data/verkehr.log + + +exec >>$logDatei +exec 2>>$logDatei +echo -e "\n`date` - Ueberwachung wurde gestartet ..." >>$logDatei + +while true +do +iptables --numeric -vL FORWARD | grep "\-\-" >$neueDatei +nutzerWahl=`cat $neueDatei | cut -c 69-87 | grep 192` + +test -n "$nutzerWahl" -a -s "$alteDatei" && for n in "$nutzerWahl" + do alt=`cat $alteDatei | grep $n` + neu=`cat $neueDatei | grep $n` + if test -n "$alt" -a "$alt" = "$neu"; + then name=`$holeName $n` + $trenneVerbindung $name + echo "`date` - Nutzer $name wurde abgemeldet wegen Untaetigkeit" >> $logDatei + fi + done + +iptables --numeric -vL FORWARD | grep "\-\-" >$alteDatei +rm $neueDatei +sleep $warteZeit +done diff --git a/wg-dialer/scripts/waehleISDN-Tarif.sh b/wg-dialer/scripts/waehleISDN-Tarif.sh new file mode 100755 index 0000000..ae15219 --- /dev/null +++ b/wg-dialer/scripts/waehleISDN-Tarif.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +DEV="ippp0" + +test -n "$2" && DEV=$2 + + + +function setzeNormaleParameter() +{ + isdnctrl hangup $DEV + sleep 1 + # ifconfig $DEV down + isdnctrl delif $DEV + isdnctrl addif $DEV + isdnctrl dialmode $DEV manual + isdnctrl eaz $DEV 4007523 + isdnctrl huptimeout $DEV 300 + isdnctrl dialmax $DEV 50 + isdnctrl secure $DEV on + isdnctrl callback $DEV off + isdnctrl encap $DEV syncppp + isdnctrl l2_prot $DEV hdlc + isdnctrl l3_prot $DEV trans + isdnctrl pppbind $DEV + nums=`isdnctrl list $DEV | grep Outgoing: | cut -d " " -f 16-` + for num in $nums; + do isdnctrl delphone $DEV out $num + done +} + +case "$1" in + FreeNet-Super | normal ) + setzeNormaleParameter + isdnctrl addphone $DEV out 01019019231760 + #isdnctrl addphone $DEV out 0101901929 + ;; + FreeNet-XXL | xxl ) + setzeNormaleParameter + isdnctrl addphone $DEV out 030221600707 + isdnctrl addphone $DEV out 089890900707 + isdnctrl addphone $DEV out 022126090707 + isdnctrl addphone $DEV out 023122620707 + isdnctrl addphone $DEV out 069698600707 + isdnctrl addphone $DEV out 071122670707 + # korrekt? isdnctrl addphone $DEV out 04035070707 + isdnctrl addphone $DEV out 034123890707 + isdnctrl addphone $DEV out 091121000707 + isdnctrl huptimeout $DEV 1200 + ;; + status ) + isdnctrl list $DEV + ;; + tarif ) + telNormal=`isdnctrl list $DEV | grep 01019019231760` + telXXL=`isdnctrl list $DEV | grep 030221600707` + if test -n "$telNormal" -a -n "$telXXL"; then + echo "Warnung: ungueltige Einstellungen!" + elif test -n "$telNormal"; then + echo "FreeNet-Super: 0,99/1,45c (Mo-Sa)" + elif test -n "$telXXL"; then + echo "XXL-kostenloser Sonntag" + else + echo "unbekannter Tarif!" + fi + ;; + * ) + echo "Syntax: { normal | xxl | status | tarif }" + ;; + esac + +exit 0 + + +