Analyse probleem remote execution Karel Nijs 2005-09-28
1.1 Beschrijving van het project De bedoeling van de GUI is een gemakkelijke uitvoering van verschillende checks van ICs. De GUI moet in Tcl/Tk ontworpen worden op het *nix platform. Er moet zo weinig mogelijk gebruik gemaakt worden van andere software omdat alle software centraal genstalleerd wordt en dit dus een upgrade zou betekenen voor heel IMEC. Net zoals de software, worden de home directories centraal beheerd: de directory ~ /work/drc/ is op elke server waarop je inlogt hetzelfde. 1.2 Probleemstelling De checks zijn zwaar om uit te voeren (haast volledig CPU gebruik) en kunnen tot 2 dagen duren. We willen checks op verschillende servers en op verschillende tijdstippen (eigenlijk vertragingen) uitvoeren. Omdat we de GUI vanaf de lokale host kunnen opstarten en de checks op de servers uitgevoerd worden, moet de GUI via het netwerk contact maken met de verschillende servers tegelijk. Vervolgens worden de checks op de server uitgevoerd (in de GUI moet er de mogelijkheid zijn dit proces visueel te volgen). Na voltooien van de check wordt er in de GUI aan de gebruiker duidelijk gemaakt dat de check voltooid is (failed - completed with(out) errors - waiting -...) (zie Figuur 1.1). De GUI wordt pas afgesloten als alle checks voltooid zijn. Verder zullen we ook nog het CPU gebruik en het aantal ingelogde gebruikers van de servers moeten opvragen, maar dit is eigenlijk een vereenvoudigde versie van het remote execution probleem en zal niet meer vermeld worden in deze analyse. 1.3 Analyse Voor dit probleem zijn er meerdere oplossingen mogelijk: uitvoeren via ssh uitvoeren via een C service 1 uitvoeren via een C module met rexec() Deze kunnen dan nog eens opgedeeld worden in: 1 Bij Tcl bestaat er de mogelijkheid om zelf uitbreidingen te schrijven in ANSI C 1
Figuur 1.1: Executie check de commandos een per een doorsturen een bash script maken en dit uitvoeren een Tcl script maken en dit uitvoeren 1.3.1 Uitvoeren via ssh Voor de scripts op de server uit te voeren kan men in Tcl makkelijk gebruik maken van ssh: deze functie kan via een bepaald Tcl commando uitgevoerd worden en (waardes van) Tcl variabelen kunnen zo meegegeven worden: set res [exec $::env(shell) -c "ssh \$path \$source \$command"]} 2 Het meegegeven commando wordt door Tcl in een virtuele shell uitgevoerd en het resultaat ervan opgeslagen in de variabele res. 2 De backslashes moeten hier staan voor het dollar teken (Tcl afspraak) 2
Het programma stopt met uitvoeren totdat het commando voltooid is en de res variabele gezet is. Enkele problemen hiermee: Voor het kunnen uitvoeren van zo'n commando, moeten telkens het PATH en de source gezet worden zodat de juiste scripts uitgevoerd worden. Het uitvoeren van een check vereist meerdere commandos 3 en het path en source moeten dus telkens opnieuw ingesteld worden. Tcl heeft geen threads zodat we niet meerdere commando's tegelijk kunnen uitvoeren. Dit is een probleem want we moeten namelijk ssh'en naar verschillende servers tegelijk voor echt distributief de checks uit te voeren. Dit probleem is eventueel op te lossen door een ingewikkelde datastructur aan een klokfunctie te hangen en uitvoerende functies te markeren, maar daar gaat dit document niet over. Als we ssh gebruiken, moeten we remote inloggen op de server. Hiervoor zijn login en paswoord vereist en owv. de virtuele shell zullen we deze prompt nooit te zien krijgen. De gebruikers van het programma wllen ook niet nog eens het paswoord invoeren: dit doen ze al wanneer ze inloggen op hun PC. Oplossingen voor interactief inloggen met ssh expect installeren expect is een script dat je bepaalde antwoorden aan een interactieve applicatie kan geven op basis van regular expressions. Enkele nadelen van expect: Het is een apart programma en moet dus ook centraal genstalleerd worden (belangrijkste reden). expect is zeer syntax gevoelig en de applicatie kan, bij wijzigen van de output van een afhankelijke applicatie, niet meer werken. Het programmeren en opvangen van expect in Tcl lijkt me wanordelijk. 3 Bv: Een check door de Dracula EDA uitgevoerd vereist eerst compilatie, vervolgens uitvoering en als laatste wordt met Perl de werk directory uitgekuist 3
Een sleutelpaar genereren Met een sleutelpaar kunnen we het inloggen automatiseren: er moet een ssh sleutelpaar aangemaakt worden en de client sleutel moet in de home directory van elke mogelijke gebruiker van het programma (die rechten heeft) geplaatst worden. Als we ssh gaan gebruiken om de checks uit te voeren, kiezen we best deze methode. 1.3.2 Uitvoeren via C service Zoals eerder vermeldt, biedt Tcl de mogelijkheid om zelf uitbreidingen te schrijven in ANSI C. Met deze uitbreidingen kan er dan gecommuniceerd worden met de rest van het Tcl programma. Tijdens mijn stage heb ik al een deel van deze service uitgewerkt (zie Figuur 1.2): 1. De Tcl GUI voert de module uit en geeft inline alle commando's mee die uitgevoerd moeten worden: ::nw_service::my_socket sent <host>:<port> $path $cmd1 [$cmd2...] 2. De extensie contacteert de server en stuurt de commando's een voor een door naar de server. Hierbij wordt er telkens gewacht op de output die de server terugstuurt. 3. Bij een (ontvangen) EOF na het sturen van het laatste commando sluit de client de verbinding. Omdat het uit te voeren commando in C met het system() ook virtueel gebeurt, krijgen we hier de output niet onmiddelijk van. Mogelijke manieren om de output door te sturen van de server naar de client: We redirecten de output naar een bestand. Voordeel: met een Tcl equivalent voor tail -f kan zo het aanvullen van de le live worden getoond in de GUI. Opmerking: deze methode kan ook gebruikt worden met ssh We maken een fo aan en hiernaar redirecten we de output van de commando's. Voordeel: op deze manier is het helemaal niet nodig om de output door te sturen van de client naar de server want op de client kunnen we met C deze fo ook gewoon lezen. 4 4 Herinnering: we hebben een centraal beheerd systeem 4
Beveiliging Een probleem van deze methode is de beveiliging: als er op de server een service draait waar iedereen commando's kan naar sturen en deze uitgevoerd worden, is er een zeer groot beveiligings probleem. Ook hiervoor zijn er weer meerdere oplossingen: Op de server met PAM 5 de gebruiker authenticeren. Probleem: hoe weet de server welke gebruiker de service wil gebruiken? namelijk ook over het netwerk verstuurd worden. Dit moet Met de server een bepaald sleutelwoord naar de nieuwe client sturen. De client gebruikt dit sleutelwoord voor encodering en stuurt de server het antwoord terug (of alle commando's geencodeerd met dit sleutelwoord (of variant van het sleutelwoord)). Probleem: op deze manier ben ik eigenlijk mijn eigen ssh aan het schrijven in C; het is goed iets nieuws te (leren) gebruiken, maar je moet het wiel niet opnieuw uitvinden. 1.3.3 Uitvoeren via een C module met rexec() Deze mogelijkheid, beschreven in http://www.die.net/doc/linux/man/man1/rexec.1.html, kan een commando of script uitvoeren op een server door de lokale gebruiker en paswoord op te vragen. Via C functies kan je makkelijk aan de echte gebruiker en zijn paswoord komen (ook na su gebruik), vervolgens met de server contact maken en het script/command uitvoeren. Nadeel: Het paswoord wordt als gewone tekst doorgestuurd en uiteindelijk komen we dan in dezelfde situatie als de C service. 1.3.4 Uitvoeren via aangemaakt script Deze methode kan door alle methodes gebruikt worden. Het komt er gewoon op neer dat we met Tcl een Bash of ander Tcl script genereren met de uit te voeren commando's en dit dan uitvoeren op de server. Nadelen: 5 Pluggable Authentication Modules for Linux 5
Als er een commando mislukt heeft een (simpel) Bash script de neiging om verder te gaan met de uitvoer van de andere commando's. Dit kan eventueel wel opgelost worden door een geavanceerder Bash script te maken. Het output probleem blijft: hoe we deze moeten opvangen heb ik op pagina 4 uitvoerig besproken. 1.4 Nog te bestuderen Volgende technologieen moet ik nog onderzoeken of ze tot de mogelijkheden gerekend mogen worden: pipes in Tcl 1.5 Voorlopig besluit Ondanks het werk dat ik al verricht heb voor de C service, lijkt me de methode van ssh in combinatie met het ge-time-de tail -f commando het beste. 6
start 1 command Client Server Tcl GUI User Auth Execute commands feedback result end Figuur 1.2: Remote excution met C service 7