Links

Content Skeleton

This Page

Previous topic

Base Tools

Next topic

MACPORTS

ssh– Bash Functions

Passwordless SSH setup

Warning

the permissions setting is crucial, without this the passwordless connection fails, with no error message the keys are just silently ignored

Create keys on source machine

Remember to kill the agent if a prior one is running:

source> ssh--keygen

A passphrase will be promted for twice, and key pairs created at:

~/.ssh/id_rsa
~/.ssh/id_dsa
~/.ssh/id_rsa.pub
~/.ssh/id_dsa.pub

Copy public keys to target

If you have password access to the target:

source> ssh--putkey target

Otherwise copy/paste or attach the public .pub keys to an email and send to administrator of target machine.

Start the SSH agent on source machine

Start the agent and give it the keys on the source machine, the passphrase used at key creation will be prompted for

source>  ssh--agent-start

SSH Key Juggling

As direct ssh connection from D to N is blocked (by network gnomes) are making such connections via C, using a forced ssh command that only kicks in when an alternative key is used:

61 # belle7 via forced command on C
62 host CN
63     user blyth
64     hostname 140.112.101.190
65     IdentityFile ~/.ssh/alt_dsa
66     protocol 2

Problem is that when the normal ssh agent is running providing passwordless access to all non-blocked nodes this uses the normal key and thus doesnt run the forced command to get to N, ending up at C:

delta:~ blyth$ ssh CN
Scientific Linux CERN SLC release 4.8 (Beryllium)
Last login: Thu Dec 11 12:04:14 2014 from simon.phys.ntu.edu.tw
[blyth@cms01 ~]$

Workaround (not solution as need to manually enter password) is to prevent interference from the agent when connecting to CN:

delta:env blyth$ SSH_AUTH_SOCK= ssh CN
Scientific Linux CERN SLC release 4.8 (Beryllium)
Enter passphrase for key '/Users/blyth/.ssh/alt_dsa':
Last login: Thu Dec 11 12:04:27 2014 from cms01.phys.ntu.edu.tw
[blyth@belle7 ~]$

Or equivalently with function:

delta:env blyth$ CN(){ SSH_AUTH_SOCK= ssh CN ; }
delta:env blyth$ CN
Scientific Linux CERN SLC release 4.8 (Beryllium)
Enter passphrase for key '/Users/blyth/.ssh/alt_dsa':
Last login: Thu Dec 11 12:12:00 2014 from cms01.phys.ntu.edu.tw
[blyth@belle7 ~]$

Debugging Tips

Connect without the keys

For debugging or to avoid running a “forced” command (eg from gateway to internal node) it is sometimes useful to revert to password authentication. Do so with:

source> ssh -o PubkeyAuthentication=no VT

This setting can be persisted in the config file under a new host name (add to ~/.ssh-local-config then sshconf-gen if using sshconf-)

host VTN
     hostname gateway.domain
     protocol 2
     PubkeyAuthentication no

SSH from cron issues

Passwordless ssh requires the ssh-agent to be running and authenticates and some envvars to identify the agent.

[blyth@belle7 ~]$ env -i SSH_AUTH_SOCK=/tmp/ssh-pXBvj24135/agent.24135 SSH_AGENT_PID=24136 ssh N1 hostname
belle1.nuu.edu.tw
[blyth@belle7 ~]$ env -i SSH_AUTH_SOCK=/tmp/ssh-pXBvj24135/agent.24135 ssh N1 hostname
belle1.nuu.edu.tw
[blyth@belle7 ~]$ env -i ssh N1 hostname
Enter passphrase for key '/home/blyth/.ssh/id_dsa':

[blyth@belle7 ~]$ cat .ssh-agent-info-N
SSH_AUTH_SOCK=/tmp/ssh-pXBvj24135/agent.24135; export SSH_AUTH_SOCK;
SSH_AGENT_PID=24136; export SSH_AGENT_PID;
#echo Agent pid 24136;

Troubleshoot Passwordless access not working

ssh works via client-daemon with config files for both client (man ssh_config) and daemon (man sshd_config) on both the nodes you are connecting

All 4 config files need to be reviewed and have:

  • client settings should use “Protocol 2” or “2,1” (NOT with 1 first)
  • daemon settings should use AuthorizedKeysFile .ssh/authorized_keys2

Recover from a forgotten passphrase

  1. create a new key pair
  2. transfer public keys to target and append to authorized_keys2
scp ~/Downloads/id_dsa.pub C:.ssh/dybdb1.id_dsa.pub
scp ~/Downloads/id_rsa.pub C:.ssh/dybdb1.id_rsa.pub
C >  cd .ssh ; cat dybdb1.id_dsa.pub dybdb1.id_rsa.pub >> authorized_keys2

NB this can be automated with ssh–putkey when you have control of both ends

Appending keys for restricted no-login shell identity

sudo vi  ~dayabayscp/.ssh/authorized_keys2
sudo bash -c "cat dybdb1.* >>  ~dayabayscp/.ssh/authorized_keys2"

Access remote node via gateway

The problem: network gnomes have blocked directed access D -> N but access D -> C and C -> N remains operational.

To avoid an extra manual ssh step and prevent direct running of commands over ssh : need to setup a forced command on the gateway.

On originating node D, generate an alternative key:

delta:.ssh blyth$ ssh-keygen -t rsa -f alt_rsa -C "alt $USER@$NODE_TAG"
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in alt_rsa.
Your public key has been saved in alt_rsa.pub.

delta:.ssh blyth$ ssh-keygen -t dsa -f alt_dsa -C "alt $USER@$NODE_TAG"
Generating public/private dsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in alt_dsa.
Your public key has been saved in alt_dsa.pub.
...

Add the key to the agent:

delta:.ssh blyth$ ssh-add -l
1024 4d:f7:32:71:1e:09:6a:2b:02:1b:91:5c:49:fd:1c:04 /Users/blyth/.ssh/id_dsa (DSA)
2048 2c:3a:e2:f7:e4:04:7e:62:08:fd:dc:7b:19:ec:24:10 /Users/blyth/.ssh/id_rsa (RSA)

delta:.ssh blyth$ ssh-add alt_rsa
Enter passphrase for alt_rsa:
Identity added: alt_rsa (alt_rsa)

delta:.ssh blyth$ ssh-add -l
1024 4d:f7:32:71:1e:09:6a:2b:02:1b:91:5c:49:fd:1c:04 /Users/blyth/.ssh/id_dsa (DSA)
2048 2c:3a:e2:f7:e4:04:7e:62:08:fd:dc:7b:19:ec:24:10 /Users/blyth/.ssh/id_rsa (RSA)
2048 b0:9c:a6:c9:f5:80:97:65:48:a3:76:fb:04:62:2b:37 alt_rsa (RSA)

Copy public key to gateway:

delta:.ssh blyth$ scp alt_rsa.pub C:.ssh/
delta:.ssh blyth$ scp alt_dsa.pub C:.ssh/

On the gateway machine:

[blyth@cms01 .ssh]$ cat alt_rsa.pub >> authorized_keys2
[blyth@cms01 .ssh]$ cat alt_dsa.pub >> authorized_keys2

Edit the authorized_keys2 adding a forced command infront of the public key just added:

[blyth@cms01 .ssh]$ vi authorized_keys2

command="sh -c 'ssh N ${SSH_ORIGINAL_COMMAND:-}'" ssh-rsa AAAAB3NzaC1y
    ## this works, but promts for password for the key of gateway machine

command="sh -c 'source ~/.ssh-agent-info ; ssh N ${SSH_ORIGINAL_COMMAND:-}'" ssh-dss AAAAB
    ## sourcing the agent info in the forced command, allows to make the two hops passwordless-ly

Back on original machine add .ssh/config entry that uses the alternative key, and ssh-add that to the agent:

host CN
    user blyth
    hostname 140.112.101.190
    IdentityFile ~/.ssh/alt_rsa
    protocol 2

On gateway, copy the alt key forward to target and append to authorized_keys2 on target:

[blyth@cms01 .ssh]$ scp alt_dsa.pub N:.ssh/
[blyth@belle7 .ssh]$ cat alt_dsa.pub >> authorized_keys2

Success : tis fiddly to get working due to too many moving parts, but can now hop around network blockages and run remote commands:

delta:~ blyth$ ssh CN
Scientific Linux CERN SLC release 4.8 (Beryllium)
Last login: Thu Oct 23 14:38:13 2014 from cms01.phys.ntu.edu.tw
[blyth@belle7 ~]$

delta:~ blyth$ ssh CN hostname
Scientific Linux CERN SLC release 4.8 (Beryllium)
belle7.nuu.edu.tw

Private web server access over SSH

The problem: a remote node K is running a web server that you wish to test from your laptop but the remote node is not web accessible. How can you conveniently check webserver responses from browsers or commandlines on your laptop ?

Fork a tunnel

Start the tunnel on laptop. The process goes to background so the terminal session can be closed without stopping the tunnel process:

simon:~ blyth$ ssh--
simon:~ blyth$ ssh--tunnel K 9090

     -D Specifies a local dynamic'' application-level port forwarding.  This works by allocating a socket to listen to port on the local side, optionally bound to the specified bind_address.
     -N no remote command, just forward
     -f go to background

   kill the process to stop the tunnel

opening tunnel with command ...  ssh -fND localhost:9090 K

Alternatively without the ssh–tunnel bash function can just directly do:

ssh -fND localhost:9090 K

Check the tunnel process:

simon:e blyth$ ps aux | grep localhost:9090
blyth    20464   0.0  0.0    77864    488   ??  Ss   12:43pm   0:00.01 ssh -fND localhost:9090 K

Warning

This ties up localhost:9090 so attempting to connect a local server instance on port 9090 at the same time as the tunnel is running fails

Direct access does not work

Because the request is not going via the local 9090 port setup:

simon:~ blyth$ curl http://130.87.106.59:9090/servlet/db/
^C

Socks aware commandline clients like curl

Some commandline tools support routing requests via the SOCKS proxy:

simon:~ blyth$ curl --socks5 localhost:9090 http://130.87.106.59:9090/servlet/db/
<exist:result xmlns:exist="http://exist.sourceforge.net/NS/exist">
    <exist:collection name="/db" owner="admin" group="dba" permissions="rwurwurwu">
        <exist:collection name="test" created="Jun 20, 2013 08:56:20" owner="guest" group="guest" permissions="rwur-ur-u"/>
        <exist:collection name="hfagc_tags" created="Jun 20, 2013 08:56:20" owner="admin" group="dba" permissions="rwur-ur-u"/>
        <exist:collection name="hfagc" created="Jun 20, 2013 08:56:14" owner="admin" group="dba" permissions="rwur-ur-u"/>
    </exist:collection>
</exist:result>

That is equivalent to ssh-ing into the remote node and running the query locally:

b2mc:~ heprez$ curl http://130.87.106.59:9090/servlet/db/
<exist:result xmlns:exist="http://exist.sourceforge.net/NS/exist">
    <exist:collection name="/db" owner="admin" group="dba" permissions="rwurwurwu">
        <exist:collection name="test" created="Jun 20, 2013 08:56:20" owner="guest" group="guest" permissions="rwur-ur-u"/>
        <exist:collection name="hfagc_tags" created="Jun 20, 2013 08:56:20" owner="admin" group="dba" permissions="rwur-ur-u"/>
        <exist:collection name="hfagc" created="Jun 20, 2013 08:56:14" owner="admin" group="dba" permissions="rwur-ur-u"/>
    </exist:collection>
</exist:result>

Configure OSX Safari to use the SOCKS proxy

Add an if section to the ~/env/proxy/socks.pac file corresponding to the URL want to check:

function FindProxyForURL(url, host) {
...
if (url.substring(0,25) ==   "http://130.87.106.59:9090" ){
   return "SOCKS 127.0.0.1:9090" ;
}
...
return "DIRECT" ;
}

Warning

experience suggests it is more reliable to use IP addresses rather than names

  1. go to System Preferences/Network/Advanced.../Ethernet/Proxies/Configure Proxies:Using a PAC file
  2. select the file ~/env/proxy/socks.pac
  3. Then click APPLY button and close the window with top left red icon
  4. exit Safari.app if already running and open it again
  1. test by enterinng URLs into Safari URL bar like,

NB this will stop working when the session establishing the tunnel is closed

Resuming a broken tunnel

Check the tunnel process:

simon:e blyth$ ps aux | grep localhost:9090
blyth    20464   0.0  0.0    77864    488   ??  Ss   12:43pm   0:00.01 ssh -fND localhost:9090 K

After killing the tunnel process, curl responds with connection fails almost instantaneously:

simon:e blyth$ kill -9 20464
simon:e blyth$ curl --socks5 localhost:9090 http://130.87.106.59:9090/servlet/db/
curl: (7) couldnt connect to host
simon:proxy blyth$

Similarly Safari says “Contacting 130.87.106.59” and after a minute or so gives an error page:

Safari cant open the page.
Safari cant open the page http://130.87.106.59:9090/xmldb/db/test/ because the server where this page is located isnt responding.

Starting another tunnel immediately gives curl and Safari access again.

How to handle scponly nodes + roots keys ?

Receive keys as copy/pastes within email on Mac laptop. Paste em into files and scp over to target:

simon:~ blyth$ pbpaste > D2.id_rsa.pub
simon:~ blyth$ pbpaste > D2.id_dsa.pub
simon:~ blyth$ scp D2* C:

[blyth@cms01 ~]$ sudo bash -c "cat D2* >> ~dayabayscp/.ssh/authorized_keys2 "
[blyth@cms01 ~]$ sudo vi  /home/dayabayscp/.ssh/authorized_keys2    # manually added some new lines

Utilities and informational functions

ssh–info
dump agent pid etc..
ssh–tunnel <tag:N> <port:8080>

tunnel remote port onto local machine ... remember you will probably also need to edit ~/e/proxy/socks.pac and reload it in Firefox > Preferences >

An issue with this is that privileged ports can only be forwarded by root, but the nodes that would want to tunnel to usually would have password access switched off so that means would have to setup ssh keys for root.

So probably easier to prick holes in the iptables for specific ips while testing

ssh–lskey

list keys in local authorized_keys2

the entries indicate nodes/accounts from which this one can be accessed via ssh key. These should be kept to the minimum needed

ssh–tags
list of remote nodes that are ssh accessible
ssh–rlskey
list keys in all the remote nodes

Server/Backup Management

Warning

not yet operational

When using a hub node which is backed up to multiple backup nodes, there can be quite a few keys to juggle.

ssh–designated-key
the pubkey for the node that is currently the designated server
ssh–designated-tags
tags of the backup nodes for the designated server
ssh–server-authkeys

Grabs the designated key, is not already present and distributes it to the backup nodes that need it.

This needs to be rerun after changing backup tags or designated server OR can be re-run just to check the keys are inplace

Deprecated early incarnation

ssh–rmkey <type> <name> <node>

delete keys from local authorized_keys2 things that fit into a perlre can be used ie:

ssh--rmkey ".*" ".*" "pal.nuu.edu.tw"
ssh--rmkey "..." "blyth" "al14"
ssh--rmkey  ".*" "blyth" "C2"

Basis functions for key management

ssh–delkey <tag> <path-to-key>
delete remote pubkey entry in authorized_keys{,2}
ssh–haskey <tag> <path-to-key>
remote grep of authorized_keys{,2} to see if pubkey is present
ssh–addkey <tag> <path-to-key>

This is useful to extend access to a node that accepts login only via key to a new node, via transferring the nodes key via a node that already has keyed access.:

cd /tmp  ; scp N:.ssh/id_rsa.pub id_rsa.pub   ## grab the key of the new node
ssh--addkey H id_rsa.pub                      ## append it on the target
rm id_rsa.pub
ssh–inikey <tag> <path-to-key>
Like addkey but scrub prior authorized_keys{,2} entries
ssh–distribute-key <path-to-key> tag1 tag2 etc
distribute the public key into the authorized_keys2 on the destination tags
ssh–retract-key <path-to-key> tag1 tag2 etc
delete the public key from the authorized keys of the destination tags

Functions depending/supporting a key naming convention

ssh–designated-key
path to designated key
ssh–key2base <path-to-key>
extracted base eg id_rsa assuming key naming convention
ssh–key2tag <path-to-key>
extracted tag eg P for name P.id_rsa
ssh–grab-key <local-path-to-key>

Copy the key from remote node and store at the specified path, the form of the basename must follow the naming convention in order to identify which node to get it from and which type of key to get. eg:

ssh--grab-key $HOME/.ssh/YY.id_rsa.pub   # grab remote key YY:.ssh/id_rsa.pub

Issues

openssh/openssl version mismatch

resolved by uninstall/reinstall : but git was a casualty

simon:~ blyth$ sudo port uninstall openssh @5.5p1_2
--->  Unable to uninstall openssh @5.5p1_2, the following ports depend on it:
--->  git-core @1.6.3.1_0+doc+svn
--->  git-core @1.7.2.2_0+doc
Error: port uninstall failed: Please uninstall the ports that depend on openssh first.
simon:~ blyth$

SSH Hardening suggestions

In /etc/sshd_config you might want to uncomment the lines:

PasswordAuthentication no
PermitEmptyPasswords no

Also, you want to make sure you have:

RSAAuthentication yes
PubkeyAuthentication yes

After this is done, you need to restart the ssh daemon. This is done in OSX with the following commands:

sudo launchctl stop com.openssh.sshd
sudo launchctl start com.openssh.sshd