Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a growing number of remote machines that ssh home and setup a connection to allow subsequent access via tunnel so I can get into them for maintenance.

Currently, I must manually configure these machines with a unique forward ssh port prior to install at the remote location by editing a script. The rest of the install is automated (PXE). It becomes tiresome (and risks error) setting this port manually, and prevents me confidently handing the full process off to a tech.

Question> Given a clean, debian install is it feasible to write a numeric hash function of (say) the mac address on eth0 that would be deterministic and fall in some range (say 30000-60000) and you could reasonably expect to be unique(++). I guess I've got bash, awk etc to play with. I would prefer to stick to shell related tools if possible but could use python if pushed.

(++) I would amend the tunnelling script to increment the port if it had problems on the first port tried.

Example Suggested Input: ifconfig eth0 | grep HWaddr | awk '{ print $5 }' == 08:00:27:aa:bb:cc

Example Required Output: 34567

share|improve this question
add comment

3 Answers

up vote 1 down vote accepted

Your hwaddr is just a big number, so you could always just take that mod whatever your range is and add the offset.

#!/usr/bin/perl

$iface = $ARGV[0] || "eth0";
open(IFCONFIG, "-|") || exec "/sbin/ifconfig", $iface;
while (<IFCONFIG>) {
    if (/HWaddr ([0-9a-f:]{17})/i) {
        ($hwaddr = $1) =~ s/://g;
        $hwint = hex($hwaddr);
        print $hwint % 30000 + 30000, "\n";
    }
}
close(IFCONFIG);

Here's the Math::BigInt version:

#!/usr/bin/perl -w

use Math::BigInt;

$iface = $ARGV[0] || "eth0";
open(IFCONFIG, "-|") || exec "/sbin/ifconfig", $iface;
while (<IFCONFIG>) {
    if (/HWaddr ([0-9a-f:]{17})/i) {
        ($hwaddr = $1) =~ s/://g;
        $hwint = Math::BigInt->new("0x" . $hwaddr);
        print $hwint % 30000 + 30000, "\n";
    }
}
close(IFCONFIG);
share|improve this answer
    
This is pretty much what I imagined, but my perl is appaling :) It works great, I get the number, but I also get a warning message "Integer overflow in hexadecimal number at /tmp/hash.pl line 8, <IFCONFIG> line 1." Can this be eliminated? –  Aitch Mar 28 '11 at 9:22
    
You can use Math::BigInt to avoid that. I'll add it! –  Cakemox Mar 28 '11 at 9:33
    
This is equally a great answer and works very well, albeit slightly more complicated, but would be ideal if my tunnel script was in perl. Sadly I can only mark one as answered. –  Aitch Mar 28 '11 at 10:35
    
With the benefit of hindsight, and further investigation, on the face of it, this is actually the better answer. The answer is deterministic (same each time) and therefore meets what I need. Having this as a separate little script is not that big a deal as I need to generate this number in more than one place, and my "out of the box" minimal Debian 6.0 runs it with no additional software –  Aitch Mar 30 '11 at 10:56
add comment

This should also do what is required.

port=$(/sbin/ifconfig eth0 | grep HWaddr | awk '{ print $5 }' | md5sum | cut -d ' ' -f1)
port=${port:25}
let "port = 0x$port"
let "port %= 30000"
let port="$port + 30000"
echo $port
share|improve this answer
    
You live and learn. I'd never really come across RANDOM in bash, nor the pre-seeding –  Aitch Mar 28 '11 at 10:26
    
@Aitch: A day without learning is wasted. –  Iain Mar 28 '11 at 10:27
    
I'm marking this one as answered, this is exactly what I was after and elegantly simple using shell. I appreciate you taking the time to post. –  Aitch Mar 28 '11 at 10:33
    
On further investigation this method is not deterministic (same result each time) - Debian Squeeze 6.0 root@myserver:/my/bin# ./portgen.sh 31101 root@myserver:/my/bin# ./portgen.sh 43840 root@myserver:/my/bin# ./portgen.sh 32097 –  Aitch Mar 30 '11 at 10:54
1  
@Aitch: I've figured out what's going on. I built a debian 6 system to test it and this system gave changeable results. The problem is a difference in the way that bash v3 and v4 deal with assigning hex values to RANDOM. if it begins with a-f then v4 acts like it was never assigned and prints a random number. –  Iain Mar 30 '11 at 21:52
show 4 more comments

I really like your thinking and I'm curious to see your tunneling script but the cynic in me says someone will mention SSH keys :-)

We just use cssh for lots of small shell windows.

share|improve this answer
    
We use ssh keys on each machine as well but they are equally a pain to manage and add to the authorized keys! I may have a look at using a generic key. I had a look at cssh as suggested and it appears to me to be used for concurrent execution on multiple machines; although i wouldn't rule it out, that isn't what we need this for. The port problem is just to make the remote machines more and more commodity like (eg for swap out in the event of problems) –  Aitch Mar 28 '11 at 9:10
    
I'm with you. We keep things really simple and have a stock build with about 20 mins worth of tarball-and-drop configs to keep our boxes almost the same for failover. Tempting as it is I wouldn't go for the same key approach even with TCP wrappers. There's always port-knocking ! HTH, JR –  Jonathan Ross Mar 28 '11 at 9:14
    
One trick I had in mind (this is slightly OT) is to have the machines email home (or use cfengine or a web API or something like that) their config/public keys when they boot. That way I'd have a copy of the keys. So when they were switched on remotely, they would be knocking on the door, so as to speak, but not allowed in. I could take the config they had sent home, add it to the landing pad machine and then they would be allowed in. Yes I know there are some obvious flaws in this approach! –  Aitch Mar 28 '11 at 9:19
1  
Hehe. There's some merit in that approach. If there's web services on the machines then you could have a SSL login on a hidden URL (Or at least a similar login option which (from a service perspective) is easily accessible but secure. Have you seen Google's 2-step auth for example ?) which would effectively open up access to the tunnel/SSH for a specified period. Along the lines of port-knocking. I've heard of a Web-based SSL login adding the user's source IP to hosts.allow for an hour for example. HTH, JR –  Jonathan Ross Mar 28 '11 at 9:30
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.