top | item 2802020

Who's your SSH buddy?

149 points| jgrahamc | 14 years ago |blog.jgc.org | reply

102 comments

order
[+] nodata|14 years ago|reply
This is a perfect example of what not to do: the guy has ignored the lessons of denyhosts (etc.) and came up with his own regular expression that doesn't do the right thing.

Code re-use please!

[+] ars|14 years ago|reply
Or:

apt-get install fail2ban

Works out of the box to prevent brute force attacks against ssh, and can also be configured for other services, like web authentication, POP, IMAP, etc.

[+] rb2k_|14 years ago|reply
> someone I could call and give credentials to so they could log in and shutdown the machine.

I'm not going to be able to read out my private key over the phone. I guess this is only for password based authentication.

[+] JoachimSchipper|14 years ago|reply
An alternative: give out a public key, but restrict it to run e.g. reboot only. Put something like the following in your ~/.ssh/authorized_keys:

    command="/sbin/reboot",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa AAAAB3Nza...LiPk== [email protected]
See sshd(8) "AUTHORIZED_KEYS FILE FORMAT" for details.
[+] buro9|14 years ago|reply
Why not just pastebin your private key, shortURL it and when the time comes you only have to give the shortURL.

A key alone, with no idea what it will unlock, is going to be a useless thing for anyone else.

Obviously I'm aware how crazy a public store of private keys sounds, but keys are really only useful if you know what lock they fit.

[+] bhousel|14 years ago|reply
Well, ideally you'd work all this out with your friend before the emergency...
[+] markbao|14 years ago|reply
Maybe a play off of In case of emergency, break glass with hammer and copy private key: a one-time-only retrieval of a private key at some URL, so when your buddy retrieves it, it triggers an email that goes out to you.
[+] espo|14 years ago|reply
My SSH buddy is iSSH from the App Store. Always available when I need him.
[+] ceejayoz|14 years ago|reply
Assuming you've got a data connection, that is.
[+] forgotusername|14 years ago|reply
This is a pretty pointless idea. If someone has root on your machine for even 500ms that's already too late to trust any of its state without a complete reinstall (and even this is not enough for an advanced attacker).

Inevitably, if you have such a buddy, all they can really say is "yup, I'm not the only user here", and you're back at square one.

A better investment of the time would be systematizing your configurations, so in this situation you can just rebuild a new machine and kill the old one (ideally, after figuring out how the password was compromised in the first place).

[+] ceejayoz|14 years ago|reply
> This is a pretty pointless idea. If someone has root on your machine for even 500ms that's already too late to trust any of its state without a complete reinstall (and even this is not enough for an advanced attacker).

As the article says, he just wanted it shut down. Fixing it can come later, but stopping it from sitting on your network sending out millions of spam e-mails is still useful.

[+] davidw|14 years ago|reply
Presumably the point is not "have someone that can fix your machine if it actually gets rooted", but "have someone you can call in case of an emergency who is competent".

Seems like for a business, this would be a great service to have available from the likes of Linode, which pays people to be there in any event, rather than your 'buddy', who might go on vacation when you do.

[+] ErrantX|14 years ago|reply
My custom monitoring program (probably not as advanced, it only does some light monitoring) accepts a text message back to shutdown the machine.

Not perfect but can work well as a line of defence.

[+] markbao|14 years ago|reply
That's cool. How does it work? Is the text message just via email, and the server can accept an email back with a specific command?
[+] ma2rten|14 years ago|reply
I'm not an expert in this things, but can't sms messages be spoofed quite easily?
[+] yock|14 years ago|reply
> But it made me realize that I need to tighten up my SSH buddy plans for the next time.

I'm going to ask a really audacious question: Why?

His systems all worked as expected. Injection attacks were thwarted and login attempts failed. He received (as it turns out, erroneous) notification about the login attempts and knows he needs to do something about it for the future.

Why is that something the sharing of credentials? Why is it that people still allow for remote root login? Why do people still allow user SSH access via password?

There's a better way, and it leaves you a damn sight better prepared for intrusion attempts than receiving SMS messages that, as he so perfectly demonstrated, were not actionable. Limit logons to PKI-only. Live happier. Sleep easier.

[+] hardy263|14 years ago|reply
Though the main problem if someone breaks into your system, the first person you'd suspect is your SSH buddy, because there is a possibility of them using a public machine to log in. Who would want to carry the burden of being your first suspect?
[+] davidandgoliath|14 years ago|reply
Something to sincerely rethink is the idea of shutting the system down in the first place. Call the network provider & have them unplug the ethernet.

Turning the system off could potentially reduce your ability to audit where they originally got in. Anywhom.

SSH keys :)

[+] sixtofour|14 years ago|reply
Many messages here like "why not do X?" or "why in the world are you doing Y?" All good suggestions, but sometimes X or Y may not be good enough, or you may have implemented them incorrectly (like the author's errant regex), or the completely unexpected Z might happen; no one expects Z.

I don't see anything wrong with having a human backup. Heck, what if you die and things need to be wound down?

[+] peterwwillis|14 years ago|reply
Dying is outside the scope of application. Please contact nearest heavenly body for ticket submission process.
[+] skrebbel|14 years ago|reply
i don't get this. is it about a personal site? if so, how paranoid can you be? or is it about a professional site? if so, who not try calling a colleague?
[+] jerf|14 years ago|reply
At the risk of talking about the actual topic at hand instead of diving off into minutia about putting SSH on your phone, I'm not sure what this gets you, from a paranoia point of view. Assuming the idea is that you want 100% coverage of your server, this might marginally increase your odds, but not really all that much. Times when you aren't available to administer your server are likely to correlate highly with the times when your buddy isn't available. And what if you'd never gotten the SMS in the first place because you were entirely out of service?

One person simply can't cover a server 100%, adding a "buddy" doesn't help much. Either you need a full-on netops operation, or you need to be able to deal with not having 100%.

[+] kondro|14 years ago|reply
Umm... my iPhone, iPad and MacBook are my SSH buddies?
[+] dmoney|14 years ago|reply
Why not have the IDS shut down the machine itself?
[+] jarofgreen|14 years ago|reply
Isn't the real problem that he only has 1 sys-admin for his servers (as far as I can tell)? I mean he can have as many SSH Buddies as he wants but if the alert comes in when he is asleep or drunk or whatever it's pointless.

Maybe the alert goes to multiple buddies who have the tech skills to handle it ... maybe he could be their SSH Buddy in return? In other words, rather than a SSH-Buddy, have a pool of server sysadmin friends for emergencies.

ps. If the original poster is reading this, I would have posted this on your blog but I didn't have other account passwords to hand ... if your moderating all comments anyway, why not allow anonymous comments?

[+] antics|14 years ago|reply
I can't believe no one has suggested this yet: this is the PERFECT argument for two-factor authentication. He's even already sending texts to himself.

For every new connector, send some sort of code to your phone, and require it to be inputted back into the computer before any access is given whatsoever. Summarily disregard every single connection and command given without this code re-input.

You're even most of the way there: if you're sending messages to yourself, you might as well implement this behavior with it.

[+] tingletech|14 years ago|reply
The unix on call operator in my data center is my ssh buddy
[+] koushikn|14 years ago|reply
No ssh client still on iphones?
[+] jgrahamc|14 years ago|reply
I should have had one installed. Now I do. But I still need an SSH buddy because I might not have data access (for example, if I am abroad).
[+] nhooey|14 years ago|reply
I've had an "ssh buddy" for years, but for a variety of things such as asking for a "download on how to hotwire a motorcycle".

I have an agreement with many friends to be an operator so they can look something up on the web, or anything else requiring some efficient technical prowess.

We just call up each other and say "operator", and if you're near a computer, you help out with whatever it is.

[+] naner|14 years ago|reply
Ultimately this turned out to be a false alarm. Although the machine was under attack (on many levels: there was activity hitting the packet filter, trying all sorts of injection at the Apache level and having a go at SSH) the actual alert (based on looking in auth.log) was a false alarm based on a bad regexp.

Any particular reason you didn't want to use Snort or Bro?

[+] peterwwillis|14 years ago|reply
Alternative Solution, with iptables and perl below.

You send the magic string to any tcp port and it'll instantly kill all SSH logins and disable the root shell. Send the string again and the process is reversed. Caveat: if your syslog contains trigger entries more than a year old this will blow up.

I also recommend you disable root logins and password authentication, but if you insist on enabling them, this may work for you. Modify as necessary.

  iptables -t raw -A PREROUTING -p tcp -m string --algo bm --string "_-()ThisIsAReallyLongAndComplicatedRandomStringToMatchOn()-_" --from 0 --to lengthofthelongstring -j LOG --log-prefix "29CharacterMaxTriggerString "

  #!/usr/bin/perl
  # sentinel - disable root based on a syslog trigger
  # Copyright (C) 2011 Peter Willis <[email protected]>
  use strict;
  use POSIX qw(mktime);
  my $LOG = "/var/log/syslog";
  my $LOCKED = 0;
  my $TRIGGER = "29CharacterMaxTriggerString";
  my %M = ( "jan"=>0, "feb"=>1, "mar"=>2, "apr"=>3, "may"=>4, "jun"=>5, "jul"=>6, "aug"=>7, "sep"=>8, "oct"=>9, "nov"=>10, "dec"=>11 );
  
  for ( ;; ) {
      sleep(1);
      open(F, "<$LOG") || die "Error: $!";
      for ( ;; ) {
          sleep(1);
          while ( <F> ) {
              select(undef, undef, undef, 0.001);
              #print STDERR "Reading \"$_\"\n";
              if ( /^(\w+) (\d+) (\d+):(\d+):(\d+) \w+ kernel: $TRIGGER / ) {
                  my $time = time();
                  my $stamp = mktime($5, $4, $3, $2, $M{lc $1}, (localtime($time))[5]);
                  if ( $stamp > $^T ) {
                      #print STDERR "Found Trigger\n";
                      trigger();
                  } else {
                      #print STDERR "Error: found trigger but timestamp $stamp is before script begin time $^T\n";
                  }
              }
          }
      }
      close(F);
  }
  
  sub trigger {
      if ( $LOCKED ) {
          system("/usr/bin/chsh -s /bin/bash root");
          $LOCKED=0;
      } else {
          my @procs = map { @_=split(/\s+/,$_); $_[1] } grep(/^root\s+.*sshd:/, `ps -aux 2>/dev/null`);
          #print STDERR "Killing processes: @procs\n";
          kill(15, @procs);
          kill(9, @procs);
          system("/usr/bin/chsh -s /bin/false root");
          $LOCKED=1;
      }
  }