Hacker News new | past | comments | ask | show | jobs | submit login
SSH Tricks (tychoish.com)
223 points by ahalan on Sept 19, 2011 | hide | past | favorite | 59 comments



The most magical command he didn't mention is 'ssh-copy-id'. If you can log-in to a host with password, you just 'ssh-copy-id myuser@thishost', supply the password once, and from that moment you can ssh with public key authentication. Extreme magic.

Also, sshfs works great, but has some issues with memory mapped files that silently lose writes. Luckily (?) most programs don't use mmap to write files, so it's not very noticeable.

All in all, ssh is one of the greatest tools.


I'm always sad that OS X doesn't support ssh-copy-id natively.


apparently it's in homebrew (see other comment), but for half an eternity, I've always been using this:

    ssh user@host "mkdir .ssh && cat >> .ssh/authorized_keys" < ~/.ssh/id_rsa.pub
(remove the mkdir if .ssh already exists)

This works as well and is using nothing but the power of the unix shell and the concept of pipes.


Use mkdir -p to avoid failing if .ssh already exists.

    ssh user@host "mkdir -p .ssh && cat >> .ssh/authorized_keys" < ~/.ssh/id_rsa.pub


Agreed, but that's easy enough to deal with:

`brew install ssh-copy-id`


man this was an awesome find for me. thank you.


Since it's basically just a bash-script you can just copy it from any of the major Linux-distros. I've copied mine from Debian Lenny, and it works great.


My favorite idiom when dealing with new cloud servers is: ssh-copy-id user@host-ip <Paste random password> ssh !$

Saves copying/pasting the host ip a second time. Trivial Bash trick I know -- but it is a time saver...


> /dev/null .known_hosts

This is not a good idea (and far from "awesome"). I get why he's doing it, but suggesting that weakening the security of a tool that is meant to enhance it is bad advice.


Eh... bad advice in general, but awesome advice for the case he's using it in. Like he says in the post: Don't set these values for hosts that you actually care about.


It doesn't seem like a good idea at all. SSH caches those keys because computers are more capable of flawlessly comparing long strings of random characters than humans are. The cache is so that you, presumably a human, don't need to compare the reported host key to its known value each time you connect.

I understand his specific application, and why it works for him, but including it as advice for the general SSH-consuming public is nuts.


Or hosts that you use passwords on that you actually care about. Or hosts that have access to a network you care about. Or...

There's just too much that can go wrong.


I think "hosts that you care about" captures them all. Yes, there is too much that can go wrong, but for this tiny case the advice is useful. Let me quote GJ Sussman: "It is OK if it is not user-friendly, I am not a user".


Security advice from someone making it easier to login as root on boxes...

The first things I do with sshd on any machine are 1) disable remote root login and 2) disable password login.


same here

plus move it to a high non-standard port


But security through obscurity... oh, wait, you actually secured the box!


I move the port after doing the stuff he notes above, but it is for reducing the junk in the log about failed logins.


Seconded!

Our fail2ban processes were using a not-insignificant amount of resources while sshd was listening on port 22. Moving to a high port shifted it to somewhere in the "dead last" range in the CPU time column.


You should never do it in general; however, it makes great sense for the specific case mentioned in the article: a test system on an internal network which frequently gets reinstalled and thus re-keyed.


Agreed. I always found strict host key checking a bit annoying, and then it saved my butt a couple years ago. The other tips seem great though.


How did SSH strict host key checking save your butt? Was the host compromised?


Can't answer for peterjmag, but DNS spoofing is more prevalent than ever (certainly compared to when host key checking was built into the SSH spec) - I'm thinking about WiFi Hotspot login pages that pretend to live at any domain you type in, things like that.

It's host key checking that stops you typing in your root password into a different server that isn't who it says it is.


I was under the impression that connecting as root via ssh was a bad idea in general, ie. that it was better to connect as an unprivileged user and then su. What are your thoughts on that?


I always disable remote root login and password authentication. Then I create purpose-specific remote users with sudo access only to the commands they need (and never access to sudo su). This is not only more security-conscious in my mind, but also allows me to just drop a friend or coworker's public key in the authorized_keys file for a certain user to allow that person to perform the function that user was purposed for (for instance, when I'm on vacation).


Ok, or any other user account then - you're right you should disable root login, I was just using it as example


Another handy trick: put this script on your path somewhere, and name it "ssh-argv0":

    #!/bin/sh
    exec ssh "${0##*/}" "$@"
Then create symlinks to ssh-argv0 for common hostnames you ssh to, shortened using host aliases as suggested in the article. You now have a command for each host, which you can use as a prefix like sudo to run a single command on that host. For instance, "myth sudo reboot".

If you're used to using "ssh user@box foo", and not always for the same user (in which case you could use "User" in .ssh/config), you can do the same thing via "box -l user foo"


Huh. ssh used to offer this feature natively -- just symlink any hostname to the ssh binary -- but it turns out that they removed this about ten years ago.

(I feel old...)


A feature which was copied from rlogin and rsh, I seem to remember.

Me too.


${0##*/} ... are you looking for the basename(1) command? Posix requires support for this usage, but it does not work with many traditional shells, e.g., Solaris 10 /bin/sh.

Here's how to work around it:

    #!/bin/sh
    exec ssh "$(basename "$0")" "$@"
FWIW it's a little easier to read, too.


Sun was so into keeping backward compatibility intact they would not update the default /bin/sh because of some compatibility issues that could affect customers. So they included the newer XPG4 sh in a different location (it is a POSIX-compliant ksh88): /usr/xpg4/bin/sh. So you can write:

  #!/usr/bin/env sh
So that users who have setup PATH=/usr/xpg4/bin:$PATH get the correct shell and everything works fine.


No, I'm not looking to fork and exec a second program, and short of busybox most shells don't have basename built in.

Common idiom, works in POSIX /bin/sh, bash, dash, ash, and every other sh I've encountered. I make a point of avoiding bashisms in /bin/sh scripts, but I have no problem counting on POSIX sh. :)


The ssh escape sequence "~" (without quotes) comes in handy at times.

    "~ C" Gives you a ssh command prompt.
              Press ? for help.

    "~ ." Closes the ssh connection; useful for
              unresponsive ssh connections!


Worth noting that you need a newline before the ~ for it to work.

Another useful tip to know is how to set your own escape key.

    ssh -e ^ example.com
This will set the escape key to ^ instead of ~.

I had to use this recently to terminate an ssh connection that was initiated inside of a screen session on a machine I was sshed into from my laptop. Obviously, the generic ~. killed the first ssh session (on my machine), not the one in the screen. Connecting to the middle machine with ssh -e^ let me send ~. to the proper ssh session.


Instead of changing the escape, you can tap it one more time. So, to drop your 2nd (nested) connection: ~ ~ .


Ok, not techically part of SSH itself but I think SShuttle[1] is one of the most awesome SSH tricks around.

[1] https://github.com/apenwarr/sshuttle


SShuttle is brilliant. For those who don't know/are skimming the comments, it's basically VPN built on SSH. You just sshuttle -r user@host 0/0 and all your outbound connections are now securely tunneled through that server. I mainly use it for watching Hulu and pretending I'm being oppressed by the government, but I suspect it's useful for other things too.


too hard , you should just use -D and tsocks


I'm surprised that you'd say that if you actually understand what sshuttle does and you've read the tsocks (8) manpage. The ssh -D/tsocks combination is significantly more fragile due it how SOCKS proxying works & potential LD_PRELOAD problems, doesn't work at all with static binaries, works only for programs started with the preload (sshuttle is system-wide), doesn't handle async sockets, has issues with DNS, and fails with programs that do syscall() directly. The tsocks solution also fails miserably for anything but the use case of "have this program act (mostly, sorta) like it's running on this other machine's network" and can only do all or nothing for a program, no discrimination based on routes or ip. If it's too hard to alias "./sshuttle -r user@ssh 0/0 -vv" I'm not sure you should be playing with sharp objects like LD_PRELOAD...


What I say too hard, is saying this is way too much trouble for a problem that should be solved at another perspective. that is, fix the network or authorization problem.


I put together a little script for just this purpose: https://github.com/PHLAK/Soxy


I hadn't known about sshfs - that sounds great and I'll have to look it up.

One of my favorite features is ssh forced commands, http://oreilly.com/catalog/sshtdg/chapter/ch08.html#22858 which I use on infrequently used remote servers to present menus of pre-defined commands to me or to others. And at other times, I can use it to kick off a daemon on a remote server just by ssh'ing to that remote server with the proper key.

It's a simple way to create a "compile server" and then use one command line from my preferred machine to tell the compile server to check a certain directory and compile everything within it.

Yeah, ssh is nice.


Another trick I especially like is to use the command="" syntax inside of an authorized_keys file to allow a user to execute certain commands via ssh, especially handy for git-shell.


Anyone know how to ensure 8 bits worth of keyboard are passed? (Run emacs over ssh and you sometimes get stuck without the meta key working.)


I have a lot of machines I regularly connect to. Parsing the known_hosts file and adding to my shell's tab completion was a nice timesaver. Here's the line from my .bash_profile

complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\["`;)" ssh


I'm not sure how this could omit "ssh -D".

Also, is it just me, or might his ssh-reagent bash function add keys to some other user's ssh agent process if they've sufficiently modified the permissions on their socket file in the temporary directory to allow you to write to it?


many shells can be setup to autocomplete a list of hosts parsed from ~/.ssh/known_hosts.

for tcsh, see http://www.opensource.apple.com/source/tcsh/tcsh-63.1/tcsh/c...


This was useful back before known_hosts got obfuscated for security. Now not so much.


So disable known host hashing :) See man ssh_config


I use SuperPutty on my Windows PC to manage many putty sessions at a time...it is a little clunky, however it is better than having putty open 5 or 10 times.


my personal favorite, a one liner to set up an email tunnel on a non-privileged port:

ssh -f username@mymailserver.com -L 2000:mymailserver.com:25 -N


Why not connect to mymailserver.com's port 25 directly?


Because plenty of ISP's will block outgoing traffic on port 25.


Another reason is in case you don't want your access ISP reading your outbound mail (in the case where the smtpd doesn't support STARTTLS).



+1 for sshfs, which comes in handy for backing up my hard drive to an external machine.


In case the article's author stops by:

- loose rhymes with "goose". The word is "lose".


gpg-agent. ;-)


Nice use of /tmp, I hope you're the only one on your machine.


I believe ssh-agent has always written it's socket files to /tmp, in directories readable only by the user. If you disagree with this, criticize the program, not the user.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: