Toon posts:

[PHP] SSH interactive shell

Pagina: 1
Acties:

Onderwerpen


  • webfreakz.nl
  • Registratie: November 2003
  • Laatst online: 28-08-2022

webfreakz.nl

el-nul-zet-é-er

Topicstarter
Beste,

Op het werk ben ik bezig met het maken van een simpele webportaal om wat configuratie bestanden van Cisco / Juniper routers te managen. Hierbij wil ik inloggen op een router en configuraties ophalen en opslaan binnen een project, of een configuratie bestand installeren op een router. Echter, ophalen van de huidige configuraties lukt wel, het uploaden van een configuratie is lastiger.

Het probleem zit hem in de omgang met interactive shells. Dit is de volgorde van de commando's hoe ze moeten worden uitgevoerd voor een Juniper router:
  1. edit
  2. load override ftp://<<URL>>
  3. commit check
  4. commit
Hier zitten wat haken en ogen aan omdat commando #2 pas uitgevoerd kan worden als commando #1 is uitgevoerd. Commando #4 wil ik pas laten uitvoeren als de output van commando #3 mij bevalt.

De code die ik vooral vind op internet over shell scripting die gaat er niet vanuit dat de commando's nested zijn (gebruik ik hiervoor de goede term?).

Ook ben ik tegen gekomen op engelstalige forums dat Expect aangeraden wordt, echter dit vooral in combinatie met Perl. Zelf ben ik niet zo'n fan van het forken van processen binnen PHP, die processen moeten ook weer gemanaged worden en introduceert dus meer (mogelijke) bugs dan me leuk lijkt. Ook Telnet wordt genoemd om te gebruiken binnen PHP. Security is niet het hoogste goed binnen het project, aangezien het volledig intern gebruikt zal worden.

Is er iemand die hier wat zinnigs over kan zeggen en mij kan vertellen hoe dit kan met PHP + SSH of is het beste dat ik inderdaad overstap op Perl + Expect? Ben zelf meer bekend met PHP in Web Development, dus vandaar dat ik in die hoek wil blijven.

[Voor 9% gewijzigd door webfreakz.nl op 22-08-2011 11:41]

"You smell that, son? What sir? Napalm, I love the smell of napalm in the mornin!" || Children of Bodom fan!


  • jeroenr
  • Registratie: Juni 2001
  • Niet online
Kan je die commando's niet met SNMP inschieten? Op Cisco kan dat in ieder geval wel.

  • webfreakz.nl
  • Registratie: November 2003
  • Laatst online: 28-08-2022

webfreakz.nl

el-nul-zet-é-er

Topicstarter
Dat is niet wat ik wil gebruiken. De netwerk engineers hier willen snel configuratie files kunnen lezen / bewerken. Ik wil geen custom SNMP libraries gaan schrijven, als de command line commando's straight-forward zijn. Ook wil ik het script eventueel kunnen uitbreiden zodat er ook gebruik gemaakt kan worden van Brocade, Force10 of Juniper ScreenOS.

edit:
Ik zie nu inderdaad dat je met SNMP op een Cisco router de configs kan setten. Maar bij Juniper zie ik dat niet. Dus in het kader van uitbreidbaarheid is dat niet de weg die ik op wil gaan :)

Met http://phpseclib.sourcefo...ion/net.html#net_ssh_ssh2 kan ik heel makkelijk de configuratie ophalen van een Juniper router:

PHP:
1
2
3
4
5
6
7
8
9
10
<?php
include('Net/SSH2.php');

$ssh = new Net_SSH2($ipadres);
if (!$ssh->login($user, $pass)) {
    exit('Login Failed');
}

echo $ssh->exec('show configuration');
?>


http://phpseclib.sourcefo...ion/net.html#net_ssh_exec legt ook het probleem uit:
exec() works by creating a channel, issuing a command, and then subsequently destroying that channel. Since SSH-1 only allows one channel, exec() can only be called once. SSH-2, in contrast, allows an unlimited number of channels, and as such, you can perform as many exec()'s as you see fit.
Maar die SSH2 is dus niet nested, in mijn ervaring met:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
<?php
include('Net/SSH2.php');

$ssh = new Net_SSH2($ip);
if (!$ssh->login($user, $pass)) {
    exit('Login Failed');
}

echo $ssh->exec('edit');
echo $ssh->exec('load override ftp://<<URL>> ');
echo $ssh->exec('commit');
?>


Geeft de output:
Entering configuration mode

error: syntax error, expecting <command>: override

error: unknown command: commit
Hij zeurt hier dus over het woord "override". Dat komt omdat hij niet in Edit-modus blijft zitten.

Zie ook:

http://phpseclib.sourcefo...t.html#net_ssh_successive en dan de tekst onder het code blok. Zelfde situatie als bij mij.

[Voor 108% gewijzigd door webfreakz.nl op 22-08-2011 12:22]

"You smell that, son? What sir? Napalm, I love the smell of napalm in the mornin!" || Children of Bodom fan!


  • Tiemez
  • Registratie: December 2003
  • Laatst online: 24-10-2022

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 03-06 13:04
En eventueel ook naar php.net ssh2_exec. In de comments zie ik daar namelijk staan dat je een stream als blocking kunt flaggen. Wat volgens mij inhoud dat eerst die stream klaar moet zijn voordat je een nieuwe stream/commanda issued.

  • webfreakz.nl
  • Registratie: November 2003
  • Laatst online: 28-08-2022

webfreakz.nl

el-nul-zet-é-er

Topicstarter
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
$conn = ssh2_connect($host, 22);
if(!$conn)
        exit("Connecting failed.\n");
if(!ssh2_auth_password($conn, $user, $pass))
        exit("Login failed.\n");

$shell = ssh2_shell($conn, 'xterm');

function sshexec($cmd, $shell)
{
        fwrite($shell, $cmd."\r");
        sleep(1);
        $result = "";
        while ($buf = fgets($shell,4096))
                $result .= $buf;
        return $result;
}

echo sshexec("edit", $shell);
echo sshexec("load override <<URL>>", $shell);
echo sshexec("commit", $shell);
echo sshexec(" ", $shell);

?>


Dit is wat ik nu heb, en hij voert in ieder geval het "load override <<URL>>" uit dus hij zit in de Edit-modus. Dat is alvast goed! :) Alleen daarna stuurt hij "commit" en logt direct weer uit. Echter dat uitloggen mag pas na het uitvoeren van commit. Heb dus niet het idee dat hij netjes wacht met het uitvoerend van het volgend commando als de huidige nog bezig is. Commit duurt namelijk 15+ seconden. Hoe krijg ik dat voor elkaar? Heb ik daarvoor stream_set_blocking($shell, true) nodig? Waar moet ik die dan plaatsen?

[Voor 6% gewijzigd door webfreakz.nl op 22-08-2011 16:34]

"You smell that, son? What sir? Napalm, I love the smell of napalm in the mornin!" || Children of Bodom fan!


  • Cartman!
  • Registratie: April 2000
  • Niet online
webfreakz.nl schreef op maandag 22 augustus 2011 @ 16:23:
[Hoe krijg ik dat voor elkaar? Heb ik daarvoor stream_set_blocking($shell, true) nodig? Waar moet ik die dan plaatsen?
- Heb je t al geprobeerd? :)
- Waar is die sleep() voor?
- Waarom gebruik je geen ssh2_exec zoals alex3305 al aanwees?

  • webfreakz.nl
  • Registratie: November 2003
  • Laatst online: 28-08-2022

webfreakz.nl

el-nul-zet-é-er

Topicstarter
Heb hem tussen sleep() en $result gezet, maar daar werkt het niet.
- Waar is die sleep() voor?
Stond in een forum post dat PHP soms te snel gaat, en zo kan je het afremmen.
- Waarom gebruik je geen ssh2_exec zoals alex3305 al aanwees?
Die blijft niet in de edit-modus zitten, omdat die ssh2 channel weer destroyed wordt. Anders had ik dat graag gebruikt :)

[Voor 5% gewijzigd door webfreakz.nl op 22-08-2011 16:44]

"You smell that, son? What sir? Napalm, I love the smell of napalm in the mornin!" || Children of Bodom fan!


  • dusty
  • Registratie: Mei 2000
  • Laatst online: 13:27

dusty

Y! Celebrate Life!

Persoonlijk zou ik nested oplossen met zoiets als:
PHP:
1
   sshexec("edit;load override <<URL>>", $shell);

En dan als het correct is:
PHP:
1
   sshexec("edit;load override <<URL>>;commit", $shell);

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


  • webfreakz.nl
  • Registratie: November 2003
  • Laatst online: 28-08-2022

webfreakz.nl

el-nul-zet-é-er

Topicstarter
Dat gaat dus helemaal niet werken :)

"load override" is pas beschikbaar nadat "edit" is uitgevoerd. Zie het alsof je "sudo bash" doet op een Linux machine en je bepaalde root-only commando's wil doen :)

"You smell that, son? What sir? Napalm, I love the smell of napalm in the mornin!" || Children of Bodom fan!


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 03-06 13:04
Als je connect lijkt het - aan de hand van documentatie in ieder geval - alsof de SSH verbinding gewoon openblijft. Op php.net ssh2_connect heeft iemand overigens een complete klasse gemaakt voor het verbinden naar SSH die zo te zien wel open blijft.

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 14:01

Matis

Rubber Rocket

Ik kan het niet testen, maar als je de return-value van ssh2_exec inleest, wordt dan het commando niet automagisch blocking?

If money talks then I'm a mime
If time is money then I'm out of time


  • dusty
  • Registratie: Mei 2000
  • Laatst online: 13:27

dusty

Y! Celebrate Life!

webfreakz.nl schreef op maandag 22 augustus 2011 @ 16:57:
Dat gaat dus helemaal niet werken :)

"load override" is pas beschikbaar nadat "edit" is uitgevoerd. Zie het alsof je "sudo bash" doet op een Linux machine en je bepaalde root-only commando's wil doen :)
Als het goed is wordt de tweede commando pas uitgevoerd zodra de eerste klaar is; aangezien ze op dezelfde thread worden uitgevoerd.

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


  • Cartman!
  • Registratie: April 2000
  • Niet online
webfreakz.nl schreef op maandag 22 augustus 2011 @ 16:44:
[...]
Stond in een forum post dat PHP soms te snel gaat, en zo kan je het afremmen.
Dat is enkel een workaround lijkt me, niet betrouwbaar.
Die blijft niet in de edit-modus zitten, omdat die ssh2 channel weer destroyed wordt. Anders had ik dat graag gebruikt :)
Ik begrijp uit de documentatie juist dat als die je blocking instelt het gewoon werkt. Dit kom ik in diverse voorbeelden (zoals de class op ssh2_connect) ook weer tegen.

  • webfreakz.nl
  • Registratie: November 2003
  • Laatst online: 28-08-2022

webfreakz.nl

el-nul-zet-é-er

Topicstarter
dusty schreef op dinsdag 23 augustus 2011 @ 00:12:
[...]

Als het goed is wordt de tweede commando pas uitgevoerd zodra de eerste klaar is; aangezien ze op dezelfde thread worden uitgevoerd.
Als het hier om een Bash shell ging, dan had je gelijk. Op een router werkt het anders.

Als ik inlog kom ik eerst in een modus waar ik alleen gegevens kan opvragen met "show" commando's. Als ik naar de Edit modus ga, kan ik met "set" commando's van alles editten. Eenmaal klaar doe ik "commit" en kan ik met "exit" terug naar de modus waar alleen de "show" commando's werken.

Er zit dus een verschil met beschikbare commando's in de operationele modus (show) en de configuration modus (edit).

Trust me on this :P
Cartman! schreef op dinsdag 23 augustus 2011 @ 09:08:
Dat is enkel een workaround lijkt me, niet betrouwbaar.
Dat idee had ik inderdaad ook :)
Ik begrijp uit de documentatie juist dat als die je blocking instelt het gewoon werkt. Dit kom ik in diverse voorbeelden (zoals de class op ssh2_connect) ook weer tegen.
Ben die class aan het ombouwen, u hoort van me :)

[Voor 60% gewijzigd door webfreakz.nl op 23-08-2011 09:45]

"You smell that, son? What sir? Napalm, I love the smell of napalm in the mornin!" || Children of Bodom fan!


  • webfreakz.nl
  • Registratie: November 2003
  • Laatst online: 28-08-2022

webfreakz.nl

el-nul-zet-é-er

Topicstarter
Ik heb van die NiceSSH class van ssh2_connect het volgende gebruikt:
PHP:
1
2
3
4
5
6
7
8
9
10
        if (!($stream = ssh2_exec($this->connection, $cmd))) {
            throw new Exception('SSH command failed');
        }
        stream_set_blocking($stream, true);
        $data = "";
        while ($buf = fread($stream, 4096)) {
            $data .= $buf;
        }
        fclose($stream);
        return $data;


Dit gaat niet werken, omdat ssh2_exec roet in het eten gooit, die blijft niet in die edit-modus hangen. Ik moet dus ssh2_shell gebruiken. Maar krijg dus problemen met die stream_set_blocking()....

Het volgende werkt ook niet:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
$conn = ssh2_connect($host, 22);
if(!$conn)
        exit("Connecting failed.\n");
if(!ssh2_auth_password($conn, $user, $pass))
        exit("Login failed.\n");

$shell = ssh2_shell($conn, 'xterm');

function sshexec($cmd, $shell)
{
        fwrite($shell, $cmd."\r");
#       sleep(1);
        stream_set_blocking($shell, true);
        $result = "";
        while ($buf = fgets($shell,4096))
                $result .= $buf;
        return $result;
}

echo sshexec("edit", $shell);
#stream_set_blocking($shell, true);
echo sshexec("load override <<URL>>", $shell);
#stream_set_blocking($shell, true);
echo sshexec("commit", $shell);
#stream_set_blocking($shell, true);
echo sshexec(" ", $shell);
?>


Uit de log file van de juniper router:
Aug 23 08:44:47 ex3200-2 mgd[28452]: UI_AUTH_EVENT: Authenticated user 'admin' at permission level 'j-superuser-local'
Aug 23 08:44:47 ex3200-2 mgd[28452]: UI_LOGIN_EVENT: User 'admin' login, class 'j-superuser-local' [28452], ssh-connection '192.168.168.20 41612 10.0.0.81 22', client-mode 'cli'
Aug 23 08:44:47 ex3200-2 mgd[28452]: UI_CMDLINE_READ_LINE: User 'admin', command 'edit '
Aug 23 08:44:47 ex3200-2 mgd[28452]: UI_DBASE_LOGIN_EVENT: User 'admin' entering configuration mode
Hij gaat naar de edit modus, maar daarna doet het script meer. Hij stopt dus bij de eerste keer dat die stream_set_blocking() aanroept en gaat daarna niet meer verder.

[Voor 54% gewijzigd door webfreakz.nl op 23-08-2011 10:48]

"You smell that, son? What sir? Napalm, I love the smell of napalm in the mornin!" || Children of Bodom fan!


  • Cartman!
  • Registratie: April 2000
  • Niet online
Die "edit", wat doe je normaal om daaruit te komen? Dan kun je toch dat command ook uitvoeren door in die stream te schrijven?

  • webfreakz.nl
  • Registratie: November 2003
  • Laatst online: 28-08-2022

webfreakz.nl

el-nul-zet-é-er

Topicstarter
Ik schets het gedrag als ik zelf met SSH een shell open:

Ik log in en zit in operationele modus.

Ik typ "edit" en zit in configuratie modus.
Hier kan ik nu eventueel die "load override <<URL>>" en "commit" doen. We gaan er vanuit dat het slaagt.

Ik type "exit" en zit weer in operationele modus.
Ik type nogmaals "exit" en mijn shell sluit.

Het PHP script mag die 2x "edit" vergeten, gewoon de socket killen is genoeg en is ook netjes genoeg volgens de router log :)
ronald@server:~$ ssh admin@juniper_host
admin@juniper_host's password:
--- JUNOS 10.4R4.5 built 2011-05-06 05:43:08 UTC
admin@juniper> edit
Entering configuration mode
Users currently editting the configuration:
admin terminal p1 (pid 28452) on since 2011-08-23 08:44:47 UTC, idle 00:19:41
[editt]

[editt]
admin@juniper# load override ?
Possible completions:
<filename> Filename (URL, local, remote, or floppy)
terminal Use login terminal
[editt]
admin@juniper# exit
Exiting configuration mode

admin@juniper> exit

Connection to juniper_host closed.
ronald@server:~$
Het woord "editt" is fout, maar anders gaat de parser van het forum stuiteren hier :P

[Voor 48% gewijzigd door webfreakz.nl op 23-08-2011 11:09]

"You smell that, son? What sir? Napalm, I love the smell of napalm in the mornin!" || Children of Bodom fan!

Pagina: 1


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee