EXPECT via PHP automate switch config
2010/10/26 | 13:49This is how it will look like:
This script is highly dangerous and should only be run by those who knows what they are doing. The purpose of the script is to make easier configurations on several switches a breeze.
In this example the IP of the server is 192.168.1.254, a hostname works aswell.
OBS! Sofar the script can just handle CISCO/HP and Allied switches.
I dare to say this is the coolest I’ve done sofar 🙂
[bash]
sudo -s
apt-get install expect php5-cli
mkdir /home/user/specialare
mkdir /home/user/specialare/lists
touch /home/user/allowedCMDs.txt
touch /home/user/CMDs.txt
touch /home/user/IPs.txt
touch /home/user/lastCMDs.txt
touch /home/user/lastUserCMDs.txt
touch /home/user/lists.txt
touch /home/user/message.txt
touch /home/user/output.txt
echo "0" > /home/user/pidfile.txt
touch /home/user/pwd.txt
touch /home/user/userCMDs.txt
touch /home/user/userIPs.txt
touch /home/user/useroutput.txt
touch /home/user/userpwd.txt
[/bash]
index.php 1680×1050 optimized, W3C compliant
[php]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Expect script</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
body {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
color: white;
background-color: black;
}
input {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
color: white;
background-color: black;
}
a:link { color: #FF0000; text-decoration: none; }
a:visited { color: #FF0000; text-decoration: none; }
a:active { color: #FF0000; text-decoration: none; }
a:hover { color: #FFFFF0; text-decoration: none; }
#menu { position:absolute; width:340px; height:500px; z-index:1; left:30px; top:0px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
#ip_cmd { position:absolute; width:250px; height:500px; z-index:1; left:400px; top:0px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
#lastcmd { position:absolute; width:250px; height:500px; z-index:1; left:680px; top:0px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
#output { position:absolute; width:700px; height:810px; z-index:1; left:960px; top:0px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
#manual { position:absolute; width:900px; height:310px; z-index:1; left:30px; top:500px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
#message { position:absolute; width:800px; height:100px; z-index:1; left:225px; top:470px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
fieldset {
background:black;
position:relative;
}
legend {
background:black;
color:white;
padding:1px 2px;
}
</style>
</head>
<body>
<div id="menu">
<h2>
Switch Expect Script
</h2>
<form action="addIPs.php" method="post">
<fieldset>
<legend>1.Add IP to list</legend>
<input type="text" name="search" id="search">
<input type="submit" value="Ok" name="Ok" id="addIPs"> <input type="reset" value="Reset" name="Reset" id="resetAddIP">
</fieldset>
</form>
<?php
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
echo "<form action=’runCommand.php’ method=’post’>\n";
echo "<fieldset>\n";
echo "<legend>2.Input the command to be run</legend>\n";
echo "<input type=’text’ name=’search’ id=’search2′>\n";
echo "<input type=’submit’ value=’Ok’ name=’Ok’ id=’runCommand’> <input type=’reset’ value=’Reset’ name=’Reset’ id=’resetRunCmd’>\n";
echo "</fieldset>\n";
echo "</form>\n";
}
else
{
$lines4 = file(‘allowedCMDs.txt’);
echo "<form action=’runCommand.php’ method=’post’>\n";
echo "<fieldset>\n";
echo "<legend>2.Choose command from list</legend>\n";
echo "<select name=’search’ id=’runCommand’ style=’color: white; background-color: black;’>\n";
echo "<option value=” style=’color: white; font-family: Verdana; font-size: 13px; background-color: black;’></option>\n";
foreach ($lines4 as $line_num => $line)
{
echo "<option value=’$line’ style=’color: white; font-family: Verdana; font-size: 13px; background-color: black;’>$line</option>\n";
}
echo "</select>\n";
echo "<input type=’submit’ name=’send’ id=’send’ value=’Add’ style=’color: white; font-family: Verdana; font-size: 13px; background-color: black;’>\n";
echo "</fieldset>\n";
echo "</form>\n";
}
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
$lines3 = file(‘IPs.txt’);
}
else
{
$lines3 = file(‘userIPs.txt’);
}
echo "<form action=’removeIPfromList.php’ method=’post’ name=’search’ id=’removeIP’>\n";
echo "<fieldset>\n";
echo "<legend>3.Remove IP from list</legend>\n";
echo "<select name=’select’ id=’removeIPfromList’ style=’color: white; background-color: black;’>\n";
echo "<option value=” style=’color: white; font-family: Verdana; font-size: 13px; background-color: black;’></option>\n";
foreach ($lines3 as $line_num => $line)
{
echo "<option value=’$line’ style=’color: white; font-family: Verdana; font-size: 13px; background-color: black;’>$line</option>\n";
}
echo "</select>\n";
echo "<input type=’submit’ name=’send’ id=’send’ value=’Remove’ style=’color: white; font-family: Verdana; font-size: 13px; background-color: black;’>\n";
echo "</fieldset>\n";
echo "</form>\n";
?>
<form action="insertPWD.php" method="post">
<fieldset>
<legend>4.Input the password (hidden)</legend>
<input type="text" name="search" id="search3">
<input type="submit" value="Ok" name="Ok" id="insertPWD"> <input type="reset" value="Reset" name="Reset" id="resetInsertPWD">
</fieldset>
</form>
<form action="saveIPs.php" method="post">
<fieldset>
<legend>5.Save the IPlist as (filename)</legend>
<input type="text" name="search" id="search4">
<input type="submit" value="Ok" name="Ok" id="saveIPs"> <input type="reset" value="Reset" name="Reset" id="resetSaveIPs">
</fieldset>
</form>
<?php
$lines2 = file(‘lists.txt’);
echo "<form action=’loadIPs.php’ method=’post’ name=’search’ id=’loadIPsForm’>\n";
echo "<fieldset>\n";
echo "<legend>6.Load IPlist (filename)</legend>\n";
echo "<select name=’select’ id=’loadIPs’ style=’color: white; background-color: black;’>\n";
echo "<option value=” style=’color: white; font-family: Verdana; font-size: 13px; background-color: black;’></option>\n";
foreach ($lines2 as $line_num => $line)
{
echo "<option value=’$line’ style=’color: white; font-family: Verdana; font-size: 13px; background-color: black;’>$line</option>\n";
}
echo "</select>\n";
echo "<input name=’send’ type=’submit’ value=’Load’ style=’color: white; font-family: Verdana; font-size: 13px; background-color: black;’>\n";
echo "</fieldset>\n";
echo "</form>\n";
?>
<?php
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
$lines = file(‘lists.txt’);
echo "<form action=’deleteIPList.php’ method=’post’ name=’search’>\n";
echo "<fieldset>\n";
echo "<legend>7.Delete IPlist (filename)</legend>\n";
echo "<select name=’select’ id=’deleteIPList’ style=’color: white; background-color: black;’>\n";
echo "<option value=” style=’color: white; font-family: Verdana; font-size: 13px; background-color: black;’></option>\n";
foreach ($lines as $line_num => $line)
{
echo "<option value=’$line’ style=’color: white; font-family: Verdana; font-size: 13px; background-color: black;’>$line</option>\n";
}
echo "</select>\n";
echo "<input name=’send’ type=’submit’ value=’Delete’ style=’color: white; font-family: Verdana; font-size: 13px; background-color: black;’>\n";
echo "</fieldset>\n";
echo "</form>\n";
}
else
{
echo "<form action=’runCustomSHCommand.php’ method=’post’>\n";
echo "<fieldset>\n";
echo "<legend>7.Custom show command to be run</legend>\n";
echo "<input type=’text’ name=’search’ id=’search2′>\n";
echo "<input type=’submit’ value=’Ok’ name=’Ok’ id=’runCommand’> <input type=’reset’ value=’Reset’ name=’Reset’ id=’resetRunCmd’>\n";
echo "</fieldset>\n";
echo "</form>\n";
}
?><br>
8.Click this link to <a href="clearIPList.php">clear the IP list</a>.
<br>
9.Click this link to <a href="clearCMDList.php">clear the CMD list</a>.
<br>
<?php
$messageArray = file(‘message.txt’);
$allowReset = file(‘pidfile.txt’);
if (empty($messageArray))
{
echo "10.<b><a href=\"runScript.php\">((((Execute the script))))</a></b>\n";
echo "<br>";
}
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
if($allowReset[0] == 1)
{
echo "11.<a href=\"reset.php\">Reset</a>\n";
}
}
?>
</div>
<div id="ip_cmd">
<h2>
IP list
</h2>
<pre>
<?PHP
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
include("IPs.txt");
}
else
{
include("userIPs.txt");
}
?>
</pre>
<h2>
Command to be run
</h2>
<pre>
<?PHP
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
include("CMDs.txt");
}
else
{
include("userCMDs.txt");
}
?>
</pre>
</div>
<div id="manual">
<h2>
Manual
</h2>
This page will invoke an Expect script which runs the commands you specify and outputs the values on selected switchIPs. The script can handle CISCO/HP and (hopefully) Allied Telesyn switches. When running on HP you get alot of weird characters, these are control codes (VT100).
<br><br>
!!OBS!! <b>Be careful what you run, the script will run precisely what you enter!</b> !!OBS!!
!!OBS!! <b>This PHP page won’t work on Google Chrome as it sends weird characters with $_POST</b>
<br><br>
<b>1.</b> Enter the ip’s of the switches you want to run the script on (one-by-one or separated by :,; or space). You can also cut’n’paste from example Excell, Word or the Wiki. The script will automagically parse and detect if any viable IPnumers exist in the string of text. <b>OBS! Cut’n’Paste doesn’t work in IE, the browser only sends 1 row!</b>
<br>
<b>2.</b> Input the commands you want to run (one-by-one). To write your changes you need to specifically use <b>wr mem</b> or similiar commands.
<br>
<b>3.</b> Input the password (this won’t be showed anywhere on the page and the file is protected).
<br>
<b>4.</b> Execute the script and cross your fingers! 😀
<br><br>
//Coded by Viktor Å
</div>
<div id="lastcmd">
<h2>
Last executed CMDs:
</h2>
<pre>
<?PHP
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
include("lastCMDs.txt");
}
else
{
include("lastUserCMDs.txt");
}
?>
</pre>
</div>
<div id="output">
<h2>
Output (last change
<?PHP
//where thefile.php is the current file
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
$last_modified = filemtime("output.txt");
}
else
{
$last_modified = filemtime("useroutput.txt");
}
//print it all out
print(date("m/j/y H:i", $last_modified));
?>
):
</h2>
<pre>
<?PHP
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
include("output.txt");
}
else
{
include("useroutput.txt");
}
?>
</pre>
</div>
<div id="message">
<h2>
<pre>
<?PHP
include("message.txt");
?>
</pre>
</h2>
</div>
</body>
</html>
[/php]
addIPs.php
[php]
<?php
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
$array = file(‘IPs.txt’);
}
else
{
$array = file(‘userIPs.txt’);
}
$addItem = $_POST[‘search’];
if(!valid_ip($addItem))
{
if(stristr($addItem, ‘;’) OR stristr($addItem, ‘,’) OR stristr($addItem, ‘:’) OR stristr($addItem, ‘ ‘) OR stristr($addItem, ‘ ‘)) {
$newArray = preg_split("/[;,: ]+/", $addItem);
foreach ($newArray as $item){
$exists = 0;
if(valid_ip($item))
{
foreach ($array as $line_num => $line)
{
$lineWoCR = str_replace("\n", "", $line);
$item = str_replace("\n", "", $item);
if(strcmp($lineWoCR,$item) == 0)
{
$exists = 1;
}
}
if ($exists == 0)
{
$item = "$item\n";
array_push ($array,$item);
natsort($array);
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
file_put_contents(‘IPs.txt’, $array);
}
else
{
file_put_contents(‘userIPs.txt’, $array);
}
}
}
}
}
}
else
{
foreach ($array as $line_num => $line)
{
$exists = 0;
$lineWoCR = str_replace("\n", "", $line);
$addItem = str_replace("\n", "", $addItem);
if(strcmp($lineWoCR,$addItem) == 0)
{
$exists = 1;
}
}
if ($exists == 0)
{
$addItem = "$addItem\n";
array_push ($array,$addItem);
natsort($array);
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
file_put_contents(‘IPs.txt’, $array);
}
else
{
file_put_contents(‘userIPs.txt’, $array);
}
}
}
header( ‘Location: http://192.168.1.254/specialare’ ) ;
function valid_ip($ip) {
return preg_match("/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])" .
"(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/", $ip);
}
?>
[/php]
clearCMDList.php
[php]
<?php
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
$myFile = "CMDs.txt";
}
else
{
$myFile = "userCMDs.txt";
}
unlink($myFile);
$myFileHandle = fopen($myFile, ‘w’) or die("can’t open file");
fclose($myFileHandle);
header( ‘Location: http://192.168.1.254/specialare’ ) ;
?>
[/php]
clearIPList.php
[php]
<?php
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
$myFile = "IPs.txt";
unlink($myFile);
$myFileHandle = fopen($myFile, ‘w’) or die("can’t open file");
fclose($myFileHandle);
}
else
{
$myFile = "userIPs.txt";
unlink($myFile);
$myFileHandle = fopen($myFile, ‘w’) or die("can’t open file");
fclose($myFileHandle);
}
header( ‘Location: http://192.168.1.254/specialare’ ) ;
?>
[/php]
deleteIPList.php
[php]
<?php
$lines = file(‘lists.txt’);
$searchedFor = $_POST[‘select’];
$searchedFor = str_replace("\n", "", $searchedFor);
$searchedFor = str_replace("\r", "", $searchedFor);
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
foreach ($lines as $line_num => $line)
{
$lineWoCR = str_replace("\n", "", $line);
if(strcmp($lineWoCR,$searchedFor) == 0)
{
$myFile = $lines[$line_num];
$folder="/home/user/specialare/lists/";
$delFile = "$folder$searchedFor";
unlink($delFile);
unset($lines[$line_num]);
file_put_contents(‘lists.txt’, implode("", $lines));
}
}
}
header( ‘Location: http://192.168.1.254/specialare’ ) ;
?>
[/php]
insertPWD.php
[php]
<?php
$searchedFor = $_POST[‘search’];
$searchedFor = str_replace("\n", "", $searchedFor);
$searchedFor = str_replace("\r", "", $searchedFor);
if (!$searchedFor == "")
{
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
$test = fopen("pwd.txt","rw") or exit("Unable to open file!");
file_put_contents(‘pwd.txt’, $searchedFor);
fclose($test);
}
else
{
$test = fopen("userpwd.txt","rw") or exit("Unable to open file!");
file_put_contents(‘userpwd.txt’, $searchedFor);
fclose($test);
}
}
header( ‘Location: http://192.168.1.254/specialare’ ) ;
?>
[/php]
loadIPs.php
[php]
<?php
$loadItem = $_POST[‘select’];
$loadItem = str_replace("\n", "", $loadItem);
$loadItem = str_replace("\r", "", $loadItem);
if (!$loadItem == "")
{
$folder="/home/user/specialare/lists/";
$loadFile = "$folder$loadItem";
$array = file($loadFile);
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
file_put_contents(‘IPs.txt’, $array);
}
else
{
file_put_contents(‘userIPs.txt’, $array);
}
}
header( ‘Location: http://192.168.1.254/specialare’ ) ;
?>
[/php]
removeIPfromList.php
[php]
<?php
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
$lines = file(‘IPs.txt’);
}
else
{
$lines = file(‘userIPs.txt’);
}
$searchedFor = $_POST[‘select’];
$searchedFor = str_replace("\n", "", $searchedFor);
$searchedFor = str_replace("\r", "", $searchedFor);
if(valid_ip($searchedFor))
{
foreach ($lines as $line_num => $line)
{
$lineWoCR = str_replace("\n", "", $line);
if(strcmp($lineWoCR,$searchedFor) == 0)
{
unset($lines[$line_num]);
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
file_put_contents(‘IPs.txt’, implode("", $lines));
}
else
{
file_put_contents(‘userIPs.txt’, implode("", $lines));
}
}
}
}
header( ‘Location: http://192.168.1.254/specialare’ ) ;
function valid_ip($ip) {
return preg_match("/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])" .
"(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/", $ip);
}
?>
[/php]
reset.php
[php]
<?php
file_put_contents(‘pidfile.txt’, ‘0’);
file_put_contents(‘message.txt’, ”);
header( ‘Location: http://192.168.1.254/specialare’ ) ;
?>
[/php]
runCommand.php
[php]
<?php
$addItem2 = $_POST[‘search’];
$addItem2 = str_replace("\n", "", $addItem2);
$addItem2 = str_replace("\r", "", $addItem2);
if (!$addItem2 == "")
{
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
$array2 = file(‘CMDs.txt’);
$addItem2 = "$addItem2\n";
array_push ($array2,$addItem2);
file_put_contents(‘CMDs.txt’, $array2);
}
else
{
$array2 = file(‘userCMDs.txt’);
$addItem2 = "$addItem2\n";
array_push ($array2,$addItem2);
file_put_contents(‘userCMDs.txt’, $array2);
}
}
header( ‘Location: http://192.168.1.254/specialare’ ) ;
?>
[/php]
runCustomSHCommand.php
[php]
<?php
$addItem2 = $_POST[‘search’];
$addItem2 = str_replace("\n", "", $addItem2);
$addItem2 = str_replace("\r", "", $addItem2);
if (!$addItem2 == "")
{
if (string_begins_with($addItem2,"sh") OR string_begins_with($addItem2,"show"))
{
$array2 = file(‘userCMDs.txt’);
$addItem2 = "$addItem2\n";
array_push ($array2,$addItem2);
file_put_contents(‘userCMDs.txt’, $array2);
}
}
header( ‘Location: http://192.168.1.254/specialare’ ) ;
function string_begins_with($string, $search)
{
return (strncmp($string, $search, strlen($search)) == 0);
}
?>
[/php]
runScript.php
[php]
<?php
$pidFile = file(‘pidfile.txt’);
if ($pidFile[0] == 0)
{
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
$array = file(‘lastCMDs.txt’);
$array2 = file(‘CMDs.txt’);
$CMDfilename = "CMDs.txt";
$IPfilename = "IPs.txt";
$PWDfilename = "pwd.txt";
$OUTPUTfilename = "output.txt";
$lastUserCMDfilename = "lastCMDs.txt";
}
else
{
$array = file(‘lastUserCMDs.txt’);
$array2 = file(‘userCMDs.txt’);
$CMDfilename = "userCMDs.txt";
$IPfilename = "userIPs.txt";
$PWDfilename = "userpwd.txt";
$OUTPUTfilename = "useroutput.txt";
$lastUserCMDfilename = "lastUserCMDs.txt";
}
if (!empty($array2))
{
$messageFile[0] = "Script is running, please wait. Refresh page after a few minutes.";
file_put_contents(‘message.txt’, $messageFile);
$result = array_merge ($array,$array2);
$arraySize = sizeof($result);
if($arraySize > 25)
{
$test5 = $arraySize – 25;
for ($i = 0; $i < $test5; $i++)
{
unset($result[$i]);
$result=array_values($result);
}
file_put_contents($lastUserCMDfilename, $result);
}
else
{
file_put_contents($lastUserCMDfilename, $result);
}
$command="expect specialare.tcl $IPfilename $PWDfilename $CMDfilename";
$output=shell_exec($command." 2>&1");
file_put_contents($OUTPUTfilename, $output);
}
}
header( ‘Location: http://192.168.1.254/specialare’ ) ;
?>
[/php]
saveIPs.php
[php]
<?php
$newFileName=$_POST[‘search’];
$newFileName = str_replace("\n", "", $newFileName);
$newFileName = str_replace("\r", "", $newFileName);
$exists = 0;
$folder="/home/user/specialare/lists/";
if (!$newFileName == "")
{
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
$array = file(‘IPs.txt’);
}
else
{
$array = file(‘userIPs.txt’);
}
$array2 = file(‘lists.txt’);
foreach ($array2 as $line_num => $line)
{
$lineWoCR = str_replace("\n", "", $line);
if(strcmp($lineWoCR,$newFileName) == 0)
{
$exists = 1;
$putFile = "$folder$array2[$line_num]";
$putFile = str_replace("\n", "", $putFile);
file_put_contents($putFile, $array);
}
}
if ($exists == 0)
{
$putFile = "$folder$newFileName";
$newListName = "$newFileName\n";
array_push ($array2,$newListName);
file_put_contents($putFile, $array);
natsort($array2);
file_put_contents(‘lists.txt’, $array2);
}
}
header( ‘Location: http://192.168.1.254/specialare’ ) ;
?>
[/php]
And now to the actual worker, this one is hard to code. There doesn’t exist much code examples nor help for Expect. What I can say for people struggling is that try read help for TCL. Most TCL commands works in Expect.
specialare.tcl
[bash]
[/bash]
Now we want to protect this site:
[html]
vim /etc/apache2/conf.d/specialare.conf
Alias /specialare /home/user/specialare
<Directory /home/user/specialare>
Options FollowSymLinks Indexes
AllowOverride All
AuthUserFile /home/user/specialare/.htpasswd
AuthType Basic
AuthName "Secret Place"
<Limit GET POST>
order deny,allow
deny from all
allow from 192.168.1.254
require valid-user
</Limit>
DirectoryIndex index.php
<Files *.txt>
Order allow,deny
Deny from all
</Files>
</Directory>
#close and restart apache
[/html]
And set the permissions
[bash]
chown -R www-data:www-data /home/user/specialare
chown root:root /home/user/specialare/*.php
htpasswd -c /home/user/specialare/.htpasswd admin
[/bash]