> XHTML 1.0 Transitional Invalid_ 

c u t u p @ c u t u p . o r g

 xml 

[ssh scp bash location] last modified: 03/25/2007 02:06 pm

Making ssh/scp aware of location on laptops.

~/.ssh/config is nice - I have a bunch of hosts and options aliased there. The problem is that depending on which network I'm on I might need to connect to a given host externally with one configuration, or internally. It would be nice to have the computer figure out which configuration it should use instead of making me do the work.

I futzed around with scripting a wrapper for ssh/scp that would be smart about how it connected based on my wlan location, but finally figured out a way to do it transparently - without using other commands, having multiple aliases for the same machine, or changing usage in any way.

First, for each network I want custom settings for, I make a copy of ~/.ssh/config as ~/.ssh/<name of network> and edit the entries for the machines that are different on that network.

Next, I have a shell script that figures out where I am, and if there is a config file for that network in ~.ssh/. If there is, it spits out the name of the network/filename, else it simply prints "config". I called that script lan. The script looks something like this on my mac with airport:

/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | awk '
 / SSID/{for( i=2;i<=NF;i++ )ssid=ssid $i " ";sub(/ *$/,"",ssid)}
 END{if( ssid ){print ssid} else {print "config"}}
'

On Linux, something like this should work:

/sbin/iwconfig | awk '
 /ESSID/{if( $NF ~ /ESSID:/ ){split($NF,a,"\"");if( a[2] )ssid=a[2]}}
 END{if( ssid ){print ssid} else {print "config"}}
'

Finally, I have a couple of functions in my .bashrc, that look like this:

function ssh {
 /usr/bin/ssh -F ~/.ssh/"$(lan)" $*
}

function scp {
 /usr/bin/scp -F ~/.ssh/"$(lan)" $*
}

The full path to the ssh/scp executable is necessary so the functions don't just call themselves over and over again, and $(lan) returns the output of the lan script. Now, ssh/scp will transparently use the correct config file for all commands.

The nice thing is you can tweak the lan script for ethernet connections or whatever, because all it has to do is spit out a filename, and you can insert other functionality into the base commands. For example, I have mine set up so that calling ssh -ls will return a nicely formatted list of my defined hosts and aliases.




[bash ssh bashrc] last modified: 03/25/2007 02:01 pm

If you have a server at home or on a wireless network you frequent, you'd connect to it with an internal IP. But off the LAN, you connect with its domain name or external IP. Here's a simple and obvious function for your .bashrc that figures out where you are and connects accordingly. If defaults to your username but allows you to specify another.

Pick the function for your OS, substitute the stuff in brackets, add a port if you need to, and you'll probably rename the function to something better than sssh, like the server name or something.

# smart ssh for linux
function sssh() {
 WLAN=$(/sbin/iwconfig 2>/dev/null | awk '/ESSID/{split($4,a,"\"");print a[2]}')
 [ $1 ] && local AT='@'
 [ "$WLAN" == "<wireless_ssid>" ] && ssh $1$AT$<internal_ip> || ssh $1$AT<domain_name>
}

# smart ssh for mac
function sssh() {
 WLAN=$(/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | awk '/ SSID/ {print $2}')
 [ $1 ] && local AT='@'
 [ "$WLAN" == "<wireless_ssid>" ] && ssh $1$AT<internal_ip> || ssh $1$AT<domain_name>
}

Then you connect with sssh [username] wherever you are and it figures itself out.

Yeah, it's obvious but it's not like I can claim I thunk of it on my own.




[All Posts] [top]

tags:

bash
bashrc
location
scp
ssh