crusher79
Goto Top

OPNsense Captive Portal mit Registrierung + Vorgabe von Username und Password

Hallo,

habe OPNsense für 2x WLAN (paid, free) im Einsatz.

Voucher generiere ich über API. Name und Kennwort gebe ich vor. Habe also die API so erweitert, dass usernamedef und passworddef übermittelt werden. Den regulären Block zum erstellen auf Abruf habe ich via IF Bedingung ausgeklammert. Innerhalb der GUI funktioniert es wie gewohnt. Via curl geben ich dei 2 Pareameter (Name/ Kennwort) vor.

CP Ports sind also 8000 und 8001. Da ist auch das Problem.

Habe mir die index.html des Portals angeschaut. Dort wird auch einfach via API der Zugang abgefragt und entsprechend geschaltet.

Nehme ich die API für die Voucher Generierung wird die Seite nicht gefunden (Fehler 404).

In der light-zone.conf ist ein Proxy eingetragen. Für die Voucheranmeldung wird auf localhost umgeleitet.Denke das ist auch der Grund, warum die eine Variante geht, die andere nicht. Ich habe den Eintrag erweitert und auf die Voucher Create API umgeschrieben. Danach wollte das CP die Seite überhaupt nicht mehr laden.....

proxy.server = ( "/api/captiveportal/access/" => (  
		( "host" => "127.0.0.1",  
		  "port" => 8999 )  
	),
	"/api/captiveportal/voucher/generateVouchers/" => (  
	"host" => "127.0.0.1",  
    "port" => 80)  
)

nginx habe ich als Alterantive aktiviert. Wenn ich dort via PHP ganz Trivial ein Form absende und via curl die Daten an die OS sende werden die Tickets sofort erstellt. Ist ja uach klar, da ich die normale IP:80 anspreche.

Wäre also eine Alterantive. Leider bin ich in Sachen nginx ein noob. PHP wird sauber verarbeitet, aber Bilder und CSS sind futsch (MIME, etc.)

Hat schon mal jemand die Login HTML so umgebaut, dass auch ein Register möglich ist?

Alternative würde es mir reichen, wenn nginx die Seiten normal darstellt.

Für konsteloses WLAN soll der Empfang nicht belastet werden und nur Paid-Tickets ausstellen.

mfg Crusher

Content-Key: 399299

Url: https://administrator.de/contentid/399299

Printed on: June 21, 2024 at 20:06 o'clock

Member: aqui
aqui Jan 25, 2019 at 18:19:47 (UTC)
Goto Top
Warum machst du das dann nicht gleich automatisiert über SMS z.B.:
Voucher für pfSense online verwalten und optional Voucher per SMS verschicken
Wäre ja für den Empfang noch einfacher.
Was ein bischen unverständlich ist, ist warum du zusätzlich noch zum Voucher User und Pass vergibst. Eigentlich ist das doch doppelt gemoppelt wenn man mit Vouchern arbeitet.
Nur mal so zum Verständnis gefragt...
Member: Crusher79
Crusher79 Jan 26, 2019 updated at 15:15:16 (UTC)
Goto Top
Hi,

ich übergebe Voucher Name und Kennwort. Die interne Erstellung umgehe ich teils dafür!

ACHTUNG: Bezieht sich auf OPNsense 18.7.9-amd64! Vor Monaten gab es z.B. expirytime noch nicht! Die Unterschiede sind aber meist minimal. Bzw. bei der Erstellung hat sich länger nicht viel geändert!

Such einfach nach usernamedef. Dann siehst Du die 4 Stellen die man umschreiben muss. Der Block ist extra so aufgebaut, damit man bei Update nur IF ELSE einbauen muss, um es zu steuern.

Theoretisch braucht man es aber nur, wenn man wie bisher über WebGUI Tickets erstellen will. Ich nutz das nicht mehr.

Kennwörter werden vorher mit C# generiert und in PDF gedruckt.

1 und I sehen ähnlichz aus. Kann manim String entfernen um Misverständnisse zu vermeiden. Ist aber Geschmackssache.

Das Managemnt kann man aufbauen wie man will! PHP umd MS SQL oder MySQL. Meinetwegen auch Datenquellen wie XML. Ist egal. Hauptsache die entsprechenden Variablen kommen rüber.

api.key
ACHTUNG: Das ist mit der wichtigste Punkt. Ein spezieller User + api.key wird zum Steuern genutzt. Secret und Key authentifizieren das Progamm gegenüber der OPNsense. Sonst geht gar nix.

BEISPIEL ZUR STEUERUNG - hier Command Line

Hier 3x CURL aus Windows - zum Testen! ACHTUNG: Unter Windows müssen Zeichen escaped werden. PHP sieht aber ählnlich aus!

1. Erstellt Voucher.
2. Setzt auf expired
3. Löscht expired.

curl -XPOST -d "{\"count\":\"1\",\"validity\":\"1814400\",\"usernamedef\":\"m.mustermann\",\"passworddef\":\"123456\",\"expirytime\":\"1814400\",\"vouchergroup\":\"WLAN01\"}" -H "Content-Type: application/json" -k -u <api.key>  http://192.168.1.1/api/captiveportal/voucher/generateVouchers/VoucherFree/  

curl -XPOST -d "{\"username\":\"m.mustermann\"}" -H "Content-Type: application/json" -k -u <api.key> http://192.168.1.1/api/captiveportal/voucher/expireVoucher/VoucherFree/  

curl -XPOST -d "{ }" -H "Content-Type: application/json" -k -u <api.key> http://192.168.1.1/api/captiveportal/voucher/dropExpiredVouchers/VoucherFree/WLAN01/  

BEISPIEL ZUR PASSWORTERSTELLUNG - hier C#
	public static System.String CreatePassword(System.Double length)
	{
			
        const string valid = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPRSTUVWXYZ23456789";  
        StringBuilder res = new StringBuilder();
        Random rnd = new Random();
        while (0 < length--)
        {
            res.Append(valid[rnd.Next(valid.Length)]);
        }
        return res.ToString();
		
	}

HINWEIS ZUM PASSWORT
Das Kennwort wird als Text übermittelt und dann über die PHP-Function verschlüsselt!

Wer die voucher.db direkt füttern möchte muss vorher Kennwort verschlüsseln! SQLite kann einfach direkt schreiben. So habe ich die User aus den alten System migriert. Ist einfacher SQL Query + INSERT in die SQLite DB.

Crypt zu $6$ ist das Geheimis! Dann sind die Kennwörter später für die Functionen der OPNsense lesbar!

$db = new SQLite3('<Pfad>\vouchers_5c2c6f64ad734.db');  

[...]crypt($obj->pass,'$6$')  

MODIFIZIERUNG DER PHP DATEIEN
/usr/local/opnsense/mvc/app/controllers/OPNsense/CaptivePortal/Api/VoucherController.php
    public function generateVouchersAction($provider)
    {
        $response = array("status" => "error");  
        if ($this->request->isPost()) {
            $authFactory = new AuthenticationFactory();
            $auth = $authFactory->get(urldecode($provider));
            if ($auth != null && method_exists($auth, 'generateVouchers')) {  
                $count = $this->request->getPost('count', 'int', 0);  
                $validity = $this->request->getPost('validity', 'int', 0);  
                $expirytime = $this->request->getPost('expirytime', 'int', 0);  
                $vouchergroup = $this->request->getPost('vouchergroup', 'striptags', '---');  
				$usernamedef = $this->request->getPost('usernamedef', 'striptags', '---');  
				$passworddef = $this->request->getPost('passworddef', 'striptags', '---');  
                // remove characters which are known to provide issues when using in the url
                foreach (array("&", "#") as $skip_chars) {  
                    $vouchergroup = str_replace($skip_chars, "", $vouchergroup);  
                }
                if ($count > 0 && $count <= 10000 && $validity > 0) {
					return $auth->generateVouchers($vouchergroup, $count, $validity, $usernamedef, $passworddef, $expirytime);
                }
            }
        }
        return $response;
    }

/usr/local/opnsense/mvc/app/library/OPNsense/Auth/Voucher.php
   	public function generateVouchers($vouchergroup, $count, $validity, $usernamedef, $passworddef, $expirytime, $starttime = null)
    {
        $response = array();
        if ($this->dbHandle != null) {
            if ($this->simplePasswords) {
                // create a map of easy to read characters
                $characterMap = '';  
                while (strlen($characterMap) < 256) {
                    $random_bytes = openssl_random_pseudo_bytes(10000);
                    for ($i = 0; $i < strlen($random_bytes); $i++) {
                        $chr_ord = ord($random_bytes[$i]);
                        if (($chr_ord >= 50 && $chr_ord <= 57) || // 2..9
                            ($chr_ord >= 65 && $chr_ord <= 72) || // A..H
                            ($chr_ord >= 74 && $chr_ord <= 78) || // J..N
                            ($chr_ord >= 80 && $chr_ord <= 90) || // P..Z
                            ($chr_ord >= 97 && $chr_ord <= 107) || // a..k
                            ($chr_ord >= 109 && $chr_ord <= 110) || // m..n
                            ($chr_ord >= 112 && $chr_ord <= 122)  // p..z
                        ) {
                            $characterMap .= $random_bytes[$i];
                        }
                    }
                }
            } else {
                // list of characters to skip for random generator
                $doNotUseChr = array('<', '>', '{', '}', '&', 'l' , 'O' ,'`', '\'', '|' ,'^', '"');  

                // create map of random readable characters
                $characterMap = '';  
                while (strlen($characterMap) < 256) {
                    $random_bytes = openssl_random_pseudo_bytes(10000);
                    for ($i = 0; $i < strlen($random_bytes); $i++) {
                        $chr_ord = ord($random_bytes[$i]);
                        if ($chr_ord >= 33 && $chr_ord <= 125 && !in_array($random_bytes[$i], $doNotUseChr)) {
                            $characterMap .= $random_bytes[$i];
                        }
                    }
                }
            }

            // generate new vouchers
            $vouchersGenerated = 0;
            $expirytime = $expirytime == 0 ? 0 : $expirytime + time();
            while ($vouchersGenerated < $count) {
                $generatedUsername = '';  
                $random_bytes = openssl_random_pseudo_bytes($this->usernameLength);
                for ($j=0; $j < strlen($random_bytes); $j++) {
                    $generatedUsername .= $characterMap[ord($random_bytes[$j])];
                }
                $generatedPassword = '';  
                $random_bytes = openssl_random_pseudo_bytes($this->passwordLength);
                for ($j=0; $j < strlen($random_bytes); $j++) {
                    $generatedPassword .= $characterMap[ord($random_bytes[$j])];
                }

				#### BLOCK BEGIN ###
				if ($usernamedef != '---')  {  
                if (!$this->userNameExists($generatedUsername)) {
                    $vouchersGenerated++;
                    // save user, hash password first
                    $generatedPasswordHash = crypt($passworddef, '$6$');  
                    $stmt = $this->dbHandle->prepare('  
                                insert into vouchers(username, password, vouchergroup, validity, expirytime, starttime)
                                values (:username, :password, :vouchergroup, :validity, :expirytime, :starttime)
                                ');  
                    $stmt->bindParam(':username', $usernamedef);  
                    $stmt->bindParam(':password', $generatedPasswordHash);  
                    $stmt->bindParam(':vouchergroup', $vouchergroup);  
                    $stmt->bindParam(':validity', $validity);  
                    $stmt->bindParam(':expirytime', $expirytime);  
                    $stmt->bindParam(':starttime', $starttime);  
                    $stmt->execute();

                    $row = array('username' => $usernamedef,  
                        'password' => $passworddef,  
                        'vouchergroup' => $vouchergroup,  
                        'validity' => $validity,  
                        'expirytime' => $expirytime,  
                        'starttime' => $starttime  
                    );
                    $response = $row;
                }
				}
				ELSE 
				{
                if (!$this->userNameExists($generatedUsername)) {
                    $vouchersGenerated++;
                    // save user, hash password first
                    $generatedPasswordHash = crypt($generatedPassword, '$6$');  
                    $stmt = $this->dbHandle->prepare('  
                                insert into vouchers(username, password, vouchergroup, validity, expirytime, starttime)
                                values (:username, :password, :vouchergroup, :validity, :expirytime, :starttime)
                                ');  
                    $stmt->bindParam(':username', $generatedUsername);  
                    $stmt->bindParam(':password', $generatedPasswordHash);  
                    $stmt->bindParam(':vouchergroup', $vouchergroup);  
                    $stmt->bindParam(':validity', $validity);  
                    $stmt->bindParam(':expirytime', $expirytime);  
                    $stmt->bindParam(':starttime', $starttime);  
                    $stmt->execute();

                    $row = array('username' => $generatedUsername,  
                        'password' => $generatedPassword,  
                        'vouchergroup' => $vouchergroup,  
                        'validity' => $validity,  
                        'expirytime' => $expirytime,  
                        'starttime' => $starttime  
                    );
                    $response = $row;
                }
				}
				### BLOCK END ###
            }
        }
        return $response;
    }

mfg Crusher