<= back to main index

SSH automation tools

Last modified: Aug 26 12:49


An assortment of useful scripts for working with ssh(1).

sshto - bang-style ssh to do multihop ssh

Sometimes it is necessary to ssh to one host and then ssh again to another to do your intended work. A typical example is sshing into a firewalled environment where ssh delivers you to some terminus machine for outsiders, and thus an extra hop is needed to deliver you to your required machine within the LAN. sshto performs this for you for an arbitrary number of hops, utilising the venerable UUCPlike bang syntax, eg:

        sshto somewhere!host2!host3 command

which would run command on host3, reached by sshing to somewhere, then to host2, then to host3. Shells with bang style command history substitution may need to escape the bangs:

        sshto somewhere\!host2\!host3 command

As with ssh, command is a piece of shell. It is suitably escaped by sshto to run unscathed on the final host.

This lets you do nifty things like:

        rsync -e sshto somewhere!host2:/blah/. /blah/.

In addition to accepting the usual ssh options sshto also accepts arguments of the form confgi=value and creates -o 'config value' options because it has long narked me that ssh itself does not do this.

bgssh - background ssh with tagged output

bgssh runs an ssh command in the background and prefixes the output with a tag. This is especially useful when I'm doing things to many hosts in parallel:

        for h in list-of-hosts...
        do  bgssh "$h" command...

That way if something interesting happens (or blows up) you know which host had the problem.

An alternative approach is:

        for h in list-of-hosts...
        do  pfx "$h" ssh -f "$h" command...

See also ngssh below and pfx.

ngssh - netgroup-wide bgssh

ngssh does a bgssh to the members of a netgroup. Example:

        ngssh unix /opt/script/syncopt -x

to run syncopt on all unix hosts after an install on the central server.

no-ssh-agent - run command without prevailing ssh-agent settings

no-ssh-agent runs a command or a shell without an ssh-agent. I find this necessary when doing passphraseless VPN stuff with ssh because ssh happily ignores the -i flag on the command line if you have an active ssh-agent, which is most undesirable. See also nphssh, below.

nphssh - no-passphrase ssh invocation

nphssh runs an agentless ssh with a passphraseless key file, typically for making a VPN or other special purpose connection. See also vpnssh, below.

rig-ssh-agent - rig up a permanent ssh-agent

rig-ssh-agent and get-ssh-agent set up a daemonised ssh-agent process to keep ssh keys across login sessions. rig-ssh-agent establishes an ssh-agent for this purpose if one is not already present. rig-ssh-agent emits shell commands to attach to this agent, and is thus used:

        eval `get-ssh-agent`

Note well: this is a weakening of security because the agent is there and accessible even when you are away from your machine. However, I can live with this because I am normally logged in with an agent most of the time anyway, and that agent is no more secure than the daemonised one. You must make your own evaluation on this score.

hotfwd - on-demand remote netcat via ssh tunnel

I have a system in use on my laptop for location independent VPN-like access to remote TCP services that is based on ssh port forwards.

My scheme is to bring up logical interfaces on lo:1, lo:2 etc numbered, etc at boot. For mnemonic purposes I have matching entiries in my /etc/hosts file mapping these numbers to zip.local and so forth, naming the various locations to which I desire tunnels.

For each remote site there is an ssh invocation ready to hand to bring up an ssh connection to that site, with port forwards bound to the appproriate logical interface. In this way the same port/service can be offered for various remote locations without juggling conflicting port numbers and inventing tedious numering schemes.

Previous incarnations of this scheme used rnc (below), and ran a tcpio listening on the appropriate port on the lo:X interface associated with that location, that invoked an ssh connection that ran netcat to connection to the service. This upside to that was that setup was simple and a persistent connection (that could then die during coinnection dificulties or changes) was not made. The downside of this was that service connection required a fresh ssh connection. That is unduly burdensome to the remote host (especially if multiple connections were in use at once) and also introduced annoying latency (no big deal for, say, outgoing SMTP traffic but very irritating for something like a web proxy connection).

The hotfwd scheme uses only one ssh connection for a given remote site.

rnc - remote netcat

[Superceded by hotfwd.] rnc runs a netcat on a remote host using ssh to get there if necessary.

I usually use it in conjunction with tcpio to set up local access to remote services as described under hotfwd, above.

Using this scheme I have things like this:

        ! tcpio -a zip.local:smtp rnc -u vpn -i /home/vpn/.ssh/2smtp zip smtp smtp &
        ! tcpio -a zip.local:pop3 rnc -u vpn -i /home/vpn/.ssh/2pop zip pop pop3 &

in my the rc.mobile manpage configuration. Those two lines set up tcpios listening on the SMTP and POP3 ports on the zip.local interface. Connectioning to one of these spawns an rnc command that connects to zip and thence via nc to the desired service, and so the same service appears transparently on my local machine, securely tunnels from zip. I can then, for example, collect my email by pointing fetchmail directly at the pop3 port on the zip.local interface.

vpnssh and portfwd - crude VPN-like facilities

[Superceded by rnc, in turn superceded by hotfwd.] vpnssh and portfwd are what I used to use for setting up VPNs between home and work and my ISP. Well, actually long running background ssh sessions with port forwards, not true VPNs. Portfwd just knows what sshes and port forwardings to do based on my locale, and calls vpnssh suitably to set things up.

I now mostly use tcpio and rnc above.