Shallow Thoughts : tags : ssh

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Mon, 22 Dec 2014

Passwordless ssh with a key: the part most tutorials skip

I'm working on my Raspberry Pi crittercam again. I got a battery, so it can be a standalone box -- it was such a hassle to set it up with two power cords dangling from it at all times -- and set it up to run automatically at boot time.

But there was one aspect of the camera that wasn't automated: if close enough to the house to see the wi-fi router, I want it to mount a filesystem from our server and store its image files there. That makes it a lot easier to check on its progress, and also saves wear on the Pi's SD card.

Only one problem: I was using sshfs to mount the disk remotely, and ssh always prompts me for a password.

Now, there are a gazillion tutorials on how to set up an ssh key. Just do a web search for ssh key or passwordless ssh key. They vary a bit in their details, but they're all the same in the important aspects. They're all the same in one other detail: none of them work for me. I generate a new key (various types) with no pass phrase, I copy it to the server's authorized keys file (several different ways, two possible filenames), I try to ssh -- and I'm prompted for a password.

After much flailing I finally found out what was missing. In addition to those two steps, you need to modify your .ssh/config file to tell it which key to use. This is especially critical if you have multiple keys on the client machine, or if you've named the file anything but the default id_dsa or id_rsa.

So here are the real steps for making an ssh key. Assume the server, the machine to which you want to ssh, is named "myserver". But these steps are all run on the client machine, the one from which you want to run ssh.

ssh-keygen -t rsa -C "Comment"
When it prompts you for a filename, give it a full pathname, e.g. ~/.ssh/id_rsa_myserver. Type in a pass phrase, or hit return twice if you want to be able to ssh without a password.
ssh-copy-id -i .ssh/id_rsa_myserver user@myserver
You can omit the user@ if you're using the same username on both machines. You'll have to type in your password on myserver.

Then edit ~/.ssh/config, and add an entry like this:

Host myserver
  User my_username
  IdentityFile ~/.ssh/id_rsa_myserver
The User line is optional, and refers to your username on myserver if it's different from the one on the client. For instance, on the Raspberry Pi, everything has to run as root because most of the hardware and camera libraries can't work any other way. But I want it using my user ID on the server side, not root.

Eliminating strict host key checking

Of course, you can use this to go the other way too, and ssh to your Pi without needing to type a password every time. If you do that, and if you have several Pis, Beaglebones, plug computers or other little Linux gizmos which sometimes share the same IP address, you may run into the annoying whine ssh is prone to:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
The only way to get around this once it happens is by editing ~/.ssh/known_hosts, finding the line corresponding to the pi, and removing it (or just removing the whole file).

You're supposed to be able to turn off this check with StrictHostKeyChecking no, but it doesn't work. Fortunately, there's a trick I discovered several years ago and discussed in Three SSH tips. Here's how the Pi entry ends up looking in my desktop's ~/.ssh/config:

Host pipi
  HostName pi
  User pi
  StrictHostKeyChecking no
  UserKnownHostsFile /dev/null
  IdentityFile ~/.ssh/id_pi

Tags: , , , ,
[ 16:25 Dec 22, 2014    More linux | permalink to this entry | comments ]

Wed, 27 Apr 2011

Three SSH tips

Today I have three tips I've found useful with ssh.

Clearing ssh control sockets

We had a network failure recently while I had a few ssh connections open. After the network came back up, when I tried to ssh to one host, it always complained Control socket connect(/home/username/ssh-username@example.com:port): Connection refused -- but then it proceeded to connect anyway. Another server simply failed to connect.

Here's how to fix that: on the local machine -- not the remote one -- there's a file named /home/username/ssh-username@example.com:port. Remove that file, and ssh will work normally again.

Connection Sharing

I think the stuck control socket happened because I was using ssh connection sharing, a nifty feature introduced a few years back that lets ssh-based commands re-use an existing connection without re-authenticating.

Suppose you have an interactive ssh session to a remote host, and you need to copy some files over with a program like scp. Normally, each scp command needs to authenticate with remotehost, sometimes more than once per command. Depending on your setup and whether you're running a setup like ssh-agent, that might mean you have to retype your password several times, or wait while it verifies your host key.

But you can make those scps re-use your existing connection. Add this to .ssh/config:

Host *
  ControlMaster auto
  ControlPath ~/ssh-%r@%h:%p

Eliminating strict host key checking

The final tip is for my biggest ssh pet peeve: strict host key checking. That's the one where you ssh to a machine you use all the time and you get:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
... and many more lines of stuff like that. And all it really means is something like

The really frustrating thing is that there's no flag you can pass to ssh to tell it "look, it's fine, just let me in." The only solution is to edit ~/.ssh/known_hosts, find the line corresponding with that host (not so easy if you've forgotten to add HashKnownHosts no) so you can actually see the hostnames) and delete it -- or delete the whole ~/.ssh/known_hosts file. ssh does have an option for StrictHostKeyChecking no, and the documentation implies it might help; but it doesn't get you past this error, and it doesn't prevent ssh asking for confirmation when it sees a new host, either. I'm not sure what it actually does.

What does get you past the error? Here's a fun trick. Add a stanza like this to .ssh/config:

Host 192.168.1.*
  StrictHostKeyChecking no
  UserKnownHostsFile /dev/null

Translation: for every host on your local net (assuming it's 192.168.1), pretend /dev/null has the list you'd normally get from ~/.ssh/known_hosts. Since there's definitely no host line there matching your intended remote host, it will ask you whether it's okay, then connect.

I wish I could find a way to eliminate the prompt too (I thought that was what StrictHostKeyChecking no was supposed to do); but at least you can just hit return, which is a lot easier than editing known_hosts every time.

And yes, this all makes ssh less secure. You know what? For hosts on my local network, that are sitting in the same room with me, I'm really not too concerned about that.

Tags: ,
[ 17:53 Apr 27, 2011    More linux | permalink to this entry | comments ]