Posts Tagged ‘SSH’

2011w43

Sunday, October 30th, 2011

Misc tools and other goodies

Another work week, another set of “discoveries”, like less -S, crontab -r and that when you issue a command which in turn uses $EDITOR to launch an appropriate text editor, and you instead of an editor window is greated with vim: no such command, well then perhaps in one of your profile- or config-files for the shell you have a line looking something like this:

EDITOR=`which vim`

Yes, this happened to me at work on a box which only had vi installed.

Pontus also showed me some SSH escape sequences which could come in handy. The first thing to know about them is how to “activate” them, which is done with the tilde-sign (~).

So on my setup, this would mean “AltGr+¨AltGr+¨” followed by a some sequence (? for help, . to close the connection (very good for when the remote server has rebooted, i.e. the ssh session has died, but the terminal never got wind of it, so it just sits there), or C^z to suspend it.)

cp importantFile{,.bak} is a pretty nice pattern as well.

Finally, I found a new (and totally inappropriate but functional) way of using mscgen: to generate staffing schedules.

In this case, being the “tech responsible” at FSCONS, this means scheduling my eight slave^H^H^H^H^Hcamera persons across the four tracks and two days.

Experiences from last year made me divide each day up into two pieces (AM and PM) which makes for sixteen blocks, divided evenly across the eight volunteers (who I am ever greatful to) for a total of two blocks per person.

For that small amount of data, mscgen worked wonders and gave me a wonderful overview :)

As a sidenote, I really should try to post a “my picks” from the FSCONS schedule soon. Yet another TODO to push onto the stack… ;D

Java

A couple of nights ago Pontus told me about an “array shuffling algorithm” (e.g. good for when you have an array representing a deck of cards and want it shuffled) which basically revolves around iterating through the array once, starting at the back of the array, counting down and for each iteration use the loop-counter as the max value for the random number generator so that it always delivers a number (index) which is within the array itself, and then swap places if the index:th place and the loop-counter:th place of the array. That was a fun excercise :)

Scripting NetworkManager

Sunday, May 2nd, 2010

At home I have a laptop acting as a central mercurial server (from here on referenced as myserver). This is great, being able to synchronize my desktop and netbook through an intermediary gives me three hard drives on which my data is stored. The setup was, however, not especially useful since my netbook goes with me almost everywhere (read: outside the home network).

This presents a problem as when I clone a repository and my .hg/hgrc file now contain a link to the server using at best a name defined in my /etc/hosts file, and at worst a local IP address (192.168.0.xyz).

I had long since done away with the IP address links, replacing them with hostname links (i.e. ssh://hg@myserver/repo instead of ssh://hg@192.168.0.xyz/repo) which was the first step. Now all I needed to do was make myserver accessible through the firewall (forwarding the appropriate port (since we are talking ssh here that would be 22, unless you are paranoid and have switched the port which sshd listen on) in the router, make the server listen on that port, and finally come up with a way to dynamically switch what IP address myserver should point to.

There probably is a better solution for this, configuring the router to make all this would be one way, but I’m not sure that my router has that capability, and even if it did, I’m not sure I would have the skills to configure it. Software and shell scripting on the other hand, those are things I know how to work.

My solution, was simply to create two new hosts-files in /etc :

# touch /etc/hosts-{home,not-home}

and then insert appropriate information into them such as

# echo "myserver    192.168.0.xyz" > hosts-home
# echo "myserver    aaa.bbb.ccc.ddd" > hosts-not-home

(where aaa.bbb.ccc.ddd is my external IP as seen on http://whatismyip.org/).

I also made a backup of my current hosts file just to be on the safe side

# cp /etc/hosts /etc/hosts.bak

So, the overall plan is that once I’ve identified if I am at home, or somewhere else (i.e. not home) I will overwrite (copy) /etc/hosts with the “correct” hosts-file (-home or -not-home).

And this is where NetworkManager comes into play. Every time there is a change in the connection status of any identified network interface, NetworkManager reacts by executing every script found in /etc/NetworkManager/dispatcher.d/.

Every script is called with two parameters, the first being which interface changed (e.g. “eth0″, “wlan0″, etc.) and the second being how it changed (e.g. “up”, “down”). What I wanted to do was, every time a new interface went up, check if it had connected to a device in my home network (wlan or ethernet).

So, how do you distinguish different devices in a simple manner? For me, distinguishing different MAC addresses (two known addresses at home (wlan and ethernet), and every other address was essentially not home) would do nicely.

Enter the “arp” command. From it, using flag “-i” (for interface) I can discover the IP and MAC address  of the device I’m connected to. When I first discovered the example usage used flag “-a” as well which, according to the man-page, outputs results in an alternate BSD style format, using no fixed columns. This had some benefits, but as I read it again now, the “no fixed columns” remark begin to worry me. The fact that it has worked so far isn’t good enough proof that it will always work. Needless to say, ymmv.

Putting it all together:

#!/bin/sh
# filename: /etc/NetworkManager/dispatcher.d/99switchHosts.sh

# Unless the status is "up" I'm not interested
if [ "$2" != "up" ];
then
    exit 0;
fi

# I am interested in two interfaces, eth0 and wlan0
# each connect through different IP addresses and
# these devices have separate MAC addresses
if [ "$1" == "eth0" ];
then
    TARGETIP="192.168.0.1"
    TARGETMAC="aa:bb:cc:dd:ee:ff"
else
    TARGETIP="192.168.1.1"
    TARGETMAC="12:34:56:78:90:ab"
fi

# Sometimes arp hasn't gotten hold of any IP/MAC addresses
# pinging and waiting does wonders for this
ping -c 1 "$TARGETIP" 1>/dev/null 2>&1
sleep 5
CURMAC=$(arp -ai "$1" | grep "$TARGETIP" | awk '{ print $4 }')

while [ -z "$CURMAC" ];
do
    # Again, arp might not have gotten hold of IP/MAC
    sleep 3
    CURMAC=$(arp -ai "$1" | grep "$TARGETIP" | awk '{ print $4 }')
done

# If MACs match, it is a known address, i.e. home
if [ "$TARGETMAC" == "$CURMAC" ];
then
    cp /etc/hosts-home /etc/hosts
else
    cp /etc/hosts-not-home /etc/hosts
fi

exit 0

This should be put in /etc/NetworkManager/dispatcher.d/99switchHosts.sh (and the script should be made execute:able)

# chmod +x /etc/NetworkManager/dispatcher.d/99switchHosts.sh

All done, not too shabby eh?

mercurial-server

Saturday, July 18th, 2009

I have just found a pretty cool way to set up a centralized mercurial server called “mercurial-server”, but unfortunately I haven’t got it all quite working yet. Installation was dead simple:

$ cd src/tarballs
$ wget http://hg.opensource.lshift.net/mercurial-server/archive/release_0.6.tar.gz
$ cd ..
$ tar -zxvf tarballs release_0.6.tar.gz
$ cd mercurial-server-release_0.6
$ sudo ./install

With that done you need to upload your ssh public key (i.e. ~/.ssh/id_rsa.pub on your local machine, not the server on which you are installing mercurial-server) and place it in /etc/mercurial-server/keys/root/[username]/[hostname_of_local_machine], although I am assuming that the extra directory ([username]) and naming your pubkey after your local hostname is for ease of administration only.

I had set up some rather restrictive rules about what groups could enter the server by ssh, in my /etc/ssh/sshd_config file, which  effectively thwarted my first attempts at doing anything (say cloning the hgadmin repo) by ignoring my pubkeys and asking for the password to the hg user. I was rather stumped at that for a while until I remembered my sshd_config being… paranoid. ;)

With that out of the way I could attempt a hg clone ssh://hg@jupiter/hgadmin, which failed miserably with a stack trace indicating that I didn’t have the python-dispatch package installed. I tried Googling for a list of dependencies, but the name “mercurial-server” doesn’t seem to be well established with Google yet, so most results end up with questions about “mercurial” and “server” (placing mercurial-server inside quotes, it does nothing!). Anyhow, one sudo apt-get install python-dispatch later and I got a new stack trace:

$ hg clone ssh://hg@jupiter/hgadmin
remote: Traceback (most recent call last):
remote:   File "/usr/local/share/mercurial-server/hg-ssh", line 89, in <module>
remote:     try_cmd(os.environ.get('SSH_ORIGINAL_COMMAND', '?'))
remote:   File "/usr/local/share/mercurial-server/hg-ssh", line 56, in try_cmd
remote:     dispatch.dispatch(['-R', repo, 'serve', '--stdio'])
remote:   File "/var/lib/python-support/python2.5/mercurial/demandimport.py", line 75, in __getattribute__
remote:     return getattr(self._module, attr)
remote: AttributeError: 'module' object has no attribute 'dispatch'
abort: no suitable response from remote hg!

This was, as I realized when installing the mercurial-server temporarily on another much more up to date system, due to an outdated version of mercurial installed on the system. I really ought to do a dist upgrade or a complete reinstall of the entire box now while I don’t have much of value on it, but I opted for the less time consuming way of just uninstalling the old (repository version) mercurial and installing from source. And now all is well :D

All there is to it now is experiment by managing the server from its hgadmin repository and see if it is as awesome as it seems.

The one really nifty thing about this is that this way I could expose my repository to people I know and trust simply by adding their ssh pubkey, without having to worry about giving them a shell on the server. Very cool.

Pidgin buddy pounces

Tuesday, March 17th, 2009

I’m in an ambivalent state about Pidgin, I really have no love for the “expanding input field” “feature” the developers introduced a couple of versions back. Frankly, I think it sucks and I am not alone (search for “input” on that page), which is why, when I update to a newer version, download the source, modify it to always show, and ONLY show, four lines of text. No expanding, manual or automatic. Hard coded. I find that to be better than the alternative. My opinion is simply that the developers could have handled that issue much better.

But, Pidgin is not all suck. Far from it actually. Take the buddy pounce system for instance. That is a work of pure genius. There are so many options available! Your imagination is the limiting factor here.

Pidgin buddy pounce window

Pidgin buddy pounce window (click for full size)

Other than the devilishly annoying game you can play with other people by having  Pidgin send them a message as they start typing to you (preempting them), or return a message when you status is away and they have just sent a message.  But all this fades in comparison once you look at what options I have checked in the screenshot. When a user comes online, execute a command. I tested this, my Python script ran perfectly.

So what then could you do with this? You could turn Pidgin into a computer remote control (although I would probably advise against it) by doing something along these lines:

  1. Register a new account, and set it up to always be online on the computer to be remotely controlled
  2. Add your normal user to the contact list of the new user (disallow anyone else, for security reasons)
  3. Set up a buddy pounce for this new account, so that anytime a message is sent to it a script is executed, which reads the last line in the latest log-file for that account
  4. Do a little parsing perhaps, and then execute whatever command was sent in the message

I don’t think that I would ever use it for that, I have SSH for such things. But another thing one might do, is to create a second account, add it to the contact-list of the primary account, and have the primary account pounce when the new account sign on. And the executed command could be something as simple as opening a port in the firewall on the home computer. There would of course need to be a pounce for when the user sign off as well, to close the hole.

One could probably do something more advanced as well since, through the application, you can access databases, and thus can synchronize data over several users (what I’m thinking is that executing the same pounce for several users will mean that a command (inside the script being run for each of the users) can be executed when all of the users are online, offline or whatever, but otherwise do nothing. As I said, my/your imagination is the limiting factor here.

I’m not sure how “robust” (or fragile) the command execution is, if you have to return a value to Pidgin at end of execution, but I had my Python script terminate with a sys.exit(0) just to be on the safe side.