Articles

Awk Script for automatic ssh config file configuration.

In awk, script, ssh, ubuntu on September 18, 2010 by e1saman Tagged: , , , , , , ,

Awk is very powerful, I usually use it in order to parse and modify files. The example that I present here is a script to automatically modify the .ssh/ssh_config file, using only awk;

Here is a script that I build in order to make my life easier by automatically creating the .ssh_config file and configuring jump boxes and tunnels. The logic behind it is very simple, at the BEGIN section it reads the file (.ssh/ssh_config) line by line and stores the keywords (Host,Hostname,HostKeyAlias,Port,ForwardAgent,ForwardX11,ForwardX11Trusted,LocalForward,CheckHostIP,User) in associative arrays. Then is creates another entry with the options that are given with the command line (check the output without arguments) ans then it prints the whole file.

—————————————————————————————————————————————————————————————-

#!/usr/bin/gawk -f

#Status: it adds the host and works
#probelms:
#               1. It does not check if the host already exists.
#          2. the comments are corresponding to the incorrect host
#        … and more more others 🙂

BEGIN  {
parent[“”]=””;
Hostname[“”]=””;
HostKeyalias[“”]=””;
Port[“”]=””;
ForwardAgent[“”]=””;
ForwardX11Trusted[“”]=””;
LocalForward[“”]=””;
Host[“”]=””;
Gateway[“”]=””;
line=0;
maxPort=10024;
“date” | getline  current_time
close (“date”);
“echo ~/.ssh/config” | getline sshfile_d
close(“echo ~/.ssh/config”);
#printf(“%d-%d-1%d-%d”, OptionAddHost,  OptionFindMaxPort ,OptionPrintParents,OptionOutput );
#OptionOutput=-1;
#OptionPrintParents=1;
#OptionPrintGateways=1;
if( OptionAddHost==0 &&  OptionFindMaxPort ==0 && OptionPrintParents ==0 && OptionOutput ==0 && OptionPrintGateways==0 && OptionAddParent==0 && sshfile==0)
{
print “”
print “This script can be used to create hosts in ~/.ssh/config in an easy way:”
print “”
print “-v sshfile : the path to your ssh config file that you want to change. Defalut ~/.ssh/config”
print “”
print “”
print “”
print “-v OptionAddParent :  Add a parent host that will be used to create tunnels to hosts behind a jumb box.”
print ”         this host will be an alias of tha jumb box, that whenever you ssh to it, it creates tunnels”
print ”         to all the child hosts that you can set with the -v OptionAddHost option.”
print ”         for example a parent for the LIT hosts host1.lit host2.lit  that are behind 85.1.1.2 ”
print ”        jumbbox can be the following declaration in ~.ssh/config:”
print “”
print ”        Host a-lit-tunnels”
print ”         HostKeyAlias a-lit”
print ”          HostName 85.1.1.2″
print ”          Port 22″
print ”          ForwardAgent yes”
print ”          ForwardX11 yes”
print ”          ForwardX11Trusted yes”
print ”          LocalForward 33049 host1.lit:22″
print ”          LocalForward 33050 host2.lit:22″
print “”
print ”    example : -v OptionAddHost=parentHost@jumbboxip    ”
print “”
print “”
print “”
print “-v OptionAddHost:  Add a new host on the config file that is based on a parent host”
print ”    example Usage : -v OptionAddHost=newhost1,newhost2@parentHost.   ”
print “”
exit;
}

#main process
#print “reading ” sshfile
if (sshfile==0) sshfile=sshfile_d;
if ( sshfile!=sshfile_d) {
print “Using a different file than the default” > “/dev/stderr”
}

while ( (getline < sshfile ) > 0)
{
#print $0
IGNORECASE=1;
if($1~/#.*/) #ignore comments
{
comments[host]=$0;
}
else
{
if(debug==1) print $0
if($1~/Host$/) {host=$2; Host[host]=line; if(debug==1) print “Host: “$2;}
if($1~/Hostname$/) {Hostname[host]=$2; };
if($1~/HostKeyAlias$/) {HostKeyAlias[host]=$2};
if($1~/Port$/) {Port[host]=$2};
if($1~/ForwardAgent$/) {ForwardAgent[host]=$2};
if($1~/ForwardX11$/) {ForwardX11[host]=$2};
if($1~/ForwardX11Trusted$/) {ForwardX11Trusted[host]=$2};
if($1~/LocalForward$/) {LocalForwardPortHost[$2]=host;LocalForwardPortRemoteHost[$2]=$3;}
if($1~/CheckHostIP$/)  {CheckHostIP[host]=$2};
if($1~/User$/)  {User[host]=$2};
}
line++;

}
#print “End reading    ”
exit

}

END {

IGNORECASE=0;
if(OptionFindMaxPort)
{

for ( hport in     LocalForwardPortHost ) {
if(maxPort<hport) {maxPort=hport}
}
print “max port = ” maxPort;
}

if(OptionAddParent>0)
{

if(split(OptionAddParent,a,”@”)!=2) {print “Wrong input! It shoud be -v OptionAddParent parentHost@Gateway” > “/dev/stderr”; exit; }
#Add a host on a known parent
#Get the max port
#maxPort=1024;
#for ( hport in     LocalForwardPortHost ) {
#if(maxPort<hport) {maxPort=hport}
#}

phostgiven=a[1];
jumbbox=a[2];
Host[phostgiven]=phostgiven;
Hostname[phostgiven]=jumbbox;
HostKeyAlias[phostgiven]=phostgiven”_”jumbbox;
Port[phostgiven]=22;
ForwardAgent[phostgiven]=”yes”;
ForwardX11[phostgiven]=”yes”;
ForwardX11Trusted[phostgiven]=”yes”;

OptionOutput=1;

}

if(OptionAddHost)
{
#The format of the info is like that: Hostname;parentname

if(split(OptionAddHost,a,”@”)!=2) {print “Wrong input! It shoud be -v OptionAddHost host1@parentHost” > “/dev/stderr”; exit; }

#Add a host on a known parent
#Get the max port
#maxPort=1024;
for ( hport in     LocalForwardPortHost ) {
if(maxPort<hport) {maxPort=hport}
}

#Add the host
#print a[1],a[2],maxPort;

phostgiven=a[2];
n=split(a[1],b,”,”);

if(n<1) {print “Wrong input! It shoud be -v OptionAddHost host1,host2@parentHost” > “/dev/stderr” ; exit; }

for (i=1;i<=n;++i)
hostgivenArray[b[i]]=b[i];

print “#Config File that created automatically by ssh-config.nawk on: ”  current_time
#check if the parent exists
found=0;
for (hostgiven in hostgivenArray)
{
for ( phost in Hostname ) {
if(phost==phostgiven)
{
#print “Found the parent host: “phost;
maxPort++; #using the next port
split(hostgiven,c,”.”);
hostgivenNodots=c[1]c[2]; #remove the dots from the host that we add, that will be its new local Alias
#print “Host “hostn.com – Verlockende Angebote. One-way Flüge bei airberlin ab 29 €
Host[hostgivenNodots]=hostgivenNodots;
Hostname[hostgivenNodots]=”localhost”;
HostKeyAlias[hostgivenNodots]=”localhost_”maxPort;
Port[hostgivenNodots]=maxPort;
ForwardAgent[hostgivenNodots]=”yes”;
ForwardX11[hostgivenNodots]=”yes”;
ForwardX11Trusted[hostgivenNodots]=”yes”;
LocalForwardPortHost[maxPort]=phostgiven;
LocalForwardPortRemoteHost[maxPort]=hostgiven”:22″;
found=1
OptionOutput=1
}

}
}
#print “Ended”
#
if (found==0)
{
#
print “#Parent host: ” phostgiven ” is not found in the config file  ” > “/dev/stderr”
}

}

#try to find the parent (it can be usefull to find orphan hosts)
if(OptionPrintParents>0)
{
print “Parent hosts:”
for (host in Hostname)
{
if(Hostname[host]~/localhost$/) { parent[host]=LocalForwardPortHost[Port[host]];
#print “parent [“host”]=”parent[host]”,”Port[host]”,”LocalForwardPortHost[Port[host]];
}
if(parent[host]==””) print host;
}
}

if(OptionPrintGateways>0)
{
print “\n\n\nGateways hosts:”
for (host in Hostname)
{

if(Hostname[host]~/localhost$/) {}
else
{ Gateway[Hostname[host]]=host }
}
for (gtw in Gateway)
{
print gtw
}
}

if(OptionOutput>0)
{

#insert the comments at the start
#for (cmt in comments)    print “#”cmt;

n=asorti(Host,host_s);
#for ( host in Hostname )
for (i=1;i<=n;++i)
{
if(host_s[i]!=”” )
{
#finally check the comments also
if(comments[host_s[i]]) print “#”comments[host_s[i]];
print “Host “host_s[i]
if(Hostname[host_s[i]]) print “Hostname “Hostname[host_s[i]]
if(HostKeyAlias[host_s[i]]) print “HostKeyAlias “HostKeyAlias[host_s[i]]
if(Port[host_s[i]]) print “Port “Port[host_s[i]]
if(CheckHostIP[host_s[i]]) print “CheckHostIP “CheckHostIP[host_s[i]]
if(ForwardAgent[host_s[i]]) print “ForwardAgent “ForwardAgent[host_s[i]]
if(ForwardX11[host_s[i]]) print “ForwardX11 “ForwardX11[host_s[i]]
if(ForwardX11Trusted[host_s[i]]) print “ForwardX11Trusted “ForwardX11Trusted[host_s[i]]
for  ( port in LocalForwardPortHost)
{
if(LocalForwardPortHost[port]==host_s[i]) print “LocalForward “port” “LocalForwardPortRemoteHost[port] ;
}
if(User[host_s[i]]) print “User ” User[host_s[i]];
print “”
print “”
}
}
}

}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: