Feb 022014
 

If you use ssh agent forwarding in combination with screen and disconnect from the screen session just to reconnect later to maybe connect to another host you are asked for the password. The reason is quickly explained. When you start a screen session for the first time it sets the SHELL variables for the current SSH session:

root@test1:~# export | egrep 'TERM|SSH'
declare -x SSH_AUTH_SOCK="/tmp/ssh-XFKYAHW930/agent.930"
declare -x SSH_CLIENT="192.168.122.1 10841 22"
declare -x SSH_CONNECTION="192.168.122.1 10841 192.168.122.10 22"
declare -x SSH_TTY="/dev/pts/0"
declare -x TERM="screen"
declare -x TERMCAP="SC|screen|VT 100/ANSI X3.64 virtual terminal:\\
root@test1:~# 

When you disconnect from the host and reconnect later, the SHELL variables were already set in the existing screen session. Below the variables direclty after reconnecting to the host:

root@test1:~# export | egrep 'SSH|TERM'
declare -x SSH_AUTH_SOCK="/tmp/ssh-oPRczk7046/agent.7046"
declare -x SSH_CLIENT="192.168.122.1 10875 22"
declare -x SSH_CONNECTION="192.168.122.1 10875 192.168.122.10 22"
declare -x SSH_TTY="/dev/pts/0"
declare -x TERM="xterm"
root@test1:~# 

And the variables after reconnecting and within the screen session:

root@test1:~# export | egrep 'TERM|SSH'
declare -x SSH_AUTH_SOCK="/tmp/ssh-XFKYAHW930/agent.930"
declare -x SSH_CLIENT="192.168.122.1 10841 22"
declare -x SSH_CONNECTION="192.168.122.1 10841 192.168.122.10 22"
declare -x SSH_TTY="/dev/pts/0"
declare -x TERM="screen"
declare -x TERMCAP="SC|screen|VT 100/ANSI X3.64 virtual terminal:\\
root@test1:~# 

The solution is quite easy and can be found on a number of pages, e.g. http://www.deadman.org/sshscreen.php or (as I just noticed) even more comfortable by linking the SSH_AUTH_SOCK variable.

I might give the linking SSH_AUTH_SOCK variable a go, though in the past I used the PROMPT_COMMAND variable, which get’s called prior running a command in bash, for zsh you can use the precmd (man zshmisc) function.

Add the following to the ~/.bashrc

if [ $TERM != "screen" ]; then
    ${HOME}/bin/setssh.sh
fi
PROMPT_COMMAND=". ${HOME}/tmp/fixssh"

Create 2 directories in your home directory:

# mkdir -p ~/{tmp,bin}

Place the below setssh.sh script (original from http://www.deadman.org/sshscreen.php) in ~/bin/

#!/bin/sh
SSHVARS="SSH_CLIENT SSH_TTY SSH_AUTH_SOCK SSH_CONNECTION DISPLAY"

for x in ${SSHVARS} ; do
    (eval echo $x=\$$x) | sed  's/=/="/
                                s/$/"/
                                s/^/export /'
done 1>$HOME/tmp/fixssh

Whenever you reconnet to the host it will run the setssh.sh scrip and sets the SSH variables for the current session. In the screen session you have to run one command before (or just hit “return”) to source the values from ~/tmp/fixssh.

May 212012
 

Last night I looked at a few bash scripts that were a bit ugly. Each of them did more or less the same just used a different array. So I ended up merging them. The little issue I run into was that the used array name was passed as an argument to the script.

The solution was fairly easy by using indirect shell expansion, the important bit is the “!” in front of the variable c.

Below a simple example:

#!/bin/bash

a1=(a b c); 
a2=(x y z); 

while getopts "p:" OPT; do
    case $OPT in 
        p) parameter=${OPTARG};;
    esac
done

c="${parameter}[*]"; 

for i in ${!c}; do
     echo ${i};
done
May 022012
 

Had to look up the outgoing IP from a server today. To my surprise the usual curl request to http://whatismyipaddress.com/  failed with the following:

[@sphere: ~]$ curl "http://whatismyipaddress.com/"
 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 <html><head>
 <title>403 Forbidden</title>
 </head><body>
 <h1>Forbidden</h1>
 <p>You don't have permission to access /
 on this server.</p>
 <p>Additionally, a 500 Internal Server Error
 error was encountered while trying to use an ErrorDocument to handle the request.</p>
 </body></html>

Didn’t expect a plain curl would cause a 500. 🙂

So I ended up with the follwing small CGI script, which output can be seen under ip.ps-xaf.de

#!/usr/bin/perl -w
use CGI;
my $q = new CGI;
print $q->header;
print $q->remote_addr . "\n";
exit;