NSAKEY / happy-dance

Automated OpenSSH hardening
Other
41 stars 9 forks source link

Automatically determine the keysize of rsa_id file #1

Closed akhepcat closed 9 years ago

akhepcat commented 9 years ago

it's pretty simple:

$ openssl rsa -in ~/.ssh/id_rsa -noout -text | grep Private Private-Key: (1024 bit)

or, alternatively

$ BITS=$( openssl rsa -in ~/.ssh/id_rsa -noout -text | grep Private | sed 's/.(([0-9]).*/\1/g' ) $ echo $BITS 1024

obviously this works with dsa keys, which is of course unnecessary, and base ec, but not ed25519 keys on most versions of openssl.

NSAKEY commented 9 years ago

That sed command didn't work for me. See if this produces satisfactory output for you:

openssl rsa -in ~/.ssh/id_rsa -noout -text | grep Private | awk '{print $2}' | sed 's/(//g'

That only works on Linux, by the way. The portability problem looks to be related to this question on Stack Overflow, but changing "OPENSSH" to "RSA" caused even more errors. A better solution that works across platforms is to do:

ssh-keygen -l -f ~/.ssh/id_rsa.pub | awk '{print $1}'

Since rming someone's ssh keys is rude, I'm thinking I should bake in a check for the size of their RSA key and recommend that they manually generate a better key on their own. Of course, syntax that can be copied and pasted would be provided.

Is this a good solution for you? If so, I'll add it and push it out.

akhepcat commented 9 years ago

If that's more portable, then that's probably the right way to do it.

$ for i in ~/.ssh/*.pub; do ssh-keygen -l -f $i; done

works across all keytypes, so you could add checks for everything and make recommendations as necessary.

(hopefully nobody's using a 128b ed25519 key!)

NSAKEY commented 9 years ago

Done. I'll leave this open long enough for you to confirm or deny your satisfaction with the fix.

As for the other key types, checking them isn't needed. ED25519 only uses 256-bit for public keys (Which is roughly equivalent to 3072-bit RSA in terms of key strength), and the other key types aren't encouraged at all. DSA is ancient and broken and ECDSA uses NIST curves, which are suspect because of NSA involvement in the standardization process.

akhepcat commented 9 years ago

You should probably hold off on the KEYSIZE check until after you know that there's an existing id_rsa.pub.

I.e., move it from line 38 to just before the current line 74 (between 'else' and 'if [ "$KEYSIZE" -ge 4096 ]; then"

NSAKEY commented 9 years ago

The KEYSIZE check is at line 74. What you're referring to at line 38 is just where I set the KEYSIZE variable. If there's no key, one gets generated. If the key is 4096 bits or bigger, the old dialog is printed. If the key is too small, the user is told how to make things right by hand.

akhepcat commented 9 years ago

If you don't move line 38 "KEYSIZE=ssh-keygen -l -f ~/.ssh/id_rsa.pub | awk '{print $1}'"

to just before line 74, if no file exists, an error is printed.

If you move it, there's no error, because the variable isn't set until after you've validated the file exists.

that's what i was trying to say

NSAKEY commented 9 years ago

That's really odd. KEYSIZE is only used if you already have an RSA key. That check is ignored completely if you've already got an RSA key. What Linux distro are you using? I don't mind pushing out a fix, especially since your way doesn't break anything. However, I would like to be able to reproduce this for my own personal curiosity.

akhepcat commented 9 years ago

the variable KEYSIZE is set every time the script is run, regardless of the existence of the id_rsa.pub file.

Which means, if there's no id_rsa.pub file, you get this error: "${HOME}/.ssh/id_rsa.pub: No such file or directory"

moving the variable assignment to after the check for the existence of the file means that you don't cause this unintentional error to trip.

NSAKEY commented 9 years ago

I'm not getting that error at all, which is why I asked what distro you're using. I've already updated my local copy, but want to do more testing before pushing it out. I started testing on platforms like Solaris and *BSD because it was a good way to weed out errors and bashisms. If whatever you're using is producing an error like that, I want to add it to my test platforms.

akhepcat commented 9 years ago

ubuntu precise and trusty, centos, and a couple others.

but moving the variable assignment won't have any negative impacts - only positive ones.

NSAKEY commented 9 years ago

Just rmed id_rsa and id_rsa.pub on my Ubuntu 14.04 and CentOS 7 test VMs and re-ran the newest version of happy-dance. I still can't reproduce the problem. It's not making any difference from a "Does the code run?" standpoint whether the KEYSIZE variable is at line 38 or line 74.

The bright side to all of this is that in doing this testing, I uncovered some barely related edge cases for Solaris (The -o flag isn't supported in ssh-keygen) and OpenBSD (It doesn't like my use of break;;).

akhepcat commented 9 years ago

ssh-keygen -o doesn't work on ubuntu precise either.

Of course, neither does ed25519 , but that's a different issue. Sigh.

NSAKEY commented 9 years ago

Ubuntu Precise uses OpenSSH 5.9, while this script is for OpenSSH 6.5 and above. I'd be surprised if that was your only issue with an Ubuntu version that's that old. I know when I was testing on Debian Wheezy (Which is roughly the same vintage as Ubuntu Precise), I had errors related to unsupported key exchange methods and some other fun things. The fix was to get openssh-server from wheezy-backports.

I've been thinking of putting in a simple check for the SSH version, and refusing to run if it's too old. Another possibility I thought of would be to provide a band-aid fix of a config, generate a 4096-bit RSA key, and encourage the user to upgrade their version of OpenSSH.

akhepcat commented 9 years ago

yeah, that's exactly what I'm doing, getting the moduli file fixed, upgrading all the keys, and then looking for a compatible backport for precise.

NSAKEY commented 9 years ago

Does the current version of happy-dance break on any of your test distros which have a supported OpenSSH version?

akhepcat commented 9 years ago

Lemme test it.

I notice you didn't remove the old KEYSIZE= assignment (now) on line 40... ;-)

so I get: $ mkdir .ssh/KEEP && mv ~/.ssh/id_* ~/.ssh/KEEP/ $ bash happy-dance.sh -c ~/.ssh/id_rsa.pub: No such file or directory This script will give you an ssh config for clients and servers that should force the NSA to work for a living.

For an explanation of everything used in the configs, check out Secure Secure Shell: https://stribika.github.io/2015/01/04/secure-secure-shell.html Check out the README and the script's source if you want to see how the sausage is made.

Flags: -c Set up a client -s Set up a server Generating public/private ed25519 key pair. Enter file in which to save the key (~/.ssh/id_ed25519): ^C

akhepcat commented 9 years ago

Some other feedback:

"client" to me (and others) really means "user configs" and "server" means "system" configurations.

It might make a bit more sense to move the ssh_config changes into the "server" section, so that folks who only want to touch their user configs aren't confused by the sudden sudo request.

NSAKEY commented 9 years ago

Do you object to the users being asked if they want to replace their ssh_config file? If they select no, it can skip on to generating keys. That plus some more detailed explanation of what's happening seems like the sanest course.

akhepcat commented 9 years ago

Yeah. Replacing wholesale without intervention isn't good.

I've got host-specific configs in a few of my managed servers, and I wouldn't want them to go away.

Especially since you're not even backing up the originals.

NSAKEY commented 9 years ago

Fixed. I made my explanations of what the flags do and what's happening slightly less terse, on top of making the call to the ssh_client(); function not auto-destroy the old ssh_config. If you think it needs anything extra, I'm open to suggestions.

EDIT: Looks like I broke stuff while adding that extra while loop.

akhepcat commented 9 years ago

"~/.ssh/id_rsa.pub: No such file or directory"

it's because you duplicated the KEYCHECK=... line instead of moving it.

NSAKEY commented 9 years ago

Ok, it's functional again. Would you mind testing the newest version and seeing if it breaks? I moved $KEYSIZE. It hasn't broken for me when left in its original location or just before the if that requires it, so I don't care about its placement from that standpoint. I just like keeping things like variables in one place at the top, and it's a fairly common practice to declare variables first and then move on to doing work.

akhepcat commented 9 years ago

it's not "breakage" it's just an extraneous error message that's easily resolved by moving the variable assignment.

If you really want it to live up top, you should change it to:

KEYSIZE=test -r ~/.ssh/id_rsa.pub && ssh-keygen -l -f ~/.ssh/id_rsa.pub | awk '{print $1}'

so that you avoid running ssh-keygen when the file doesn't exist.

NSAKEY commented 9 years ago

That's a great idea, made even better by the fact that it works on all my weird test platforms too. Thanks. I gave you credit in the commit message and the comment.

Got any other outstanding issues? Squashing your bugs is fun, because it's made me find even more bugs to fix along the way.

akhepcat commented 9 years ago

Line 70 should be moved, and inserted prior to the exit on line 114 - reason: it's a duplicate message for "yes", and "no" just exits without a warning of why.

You're still using the '-o' option in a couple of the ssh-keygen lines, but don't have it predicated on the ssh version:

SSHV=$(ssh -V 2>&1 | sed 's/._([0-9].[0-9]).*/\1/; s/.//g') test $SSHV -gt 62 && KEYFMT="-o" || KEYFMT=""

should work. (i don't recall if the -o parameter is available on ssh versions before 6.2, but it's definitely not available on 6.2 on my system )

NSAKEY commented 9 years ago

I decided to put the warning about needing root or sudo access in the read command. That seemed to make the most sense.

As for the -o flag, that was introduced in OpenSSH 6.5 according to the release notes. happy-dance has always required OpenSSH 6.5 or above, for a variety of reasons. Chief among those reasons is the fact that 6.5 introduced support for ed25519 keys. It also has some other enhancements, which are listed in the release notes. A good rule of thumb is that if you can't generate an ed25519 key, happy-dance is not going to work with your installed copy of OpenSSH. A lot of the current versions of Linux distros use OpenSSH 6.5 or above, so it seemed like a good release to standardize on.

That being said, I think now's a good time to look into just what will or won't work on some slightly older distros in happy-dance. If the compromises in NSA-resistant sshing aren't too steep, I might make something like "happy-dance-legacy.sh" for people who for whatever reason can't upgrade.

akhepcat commented 9 years ago

A bit of restructuring of the code, and a single script can take care of it all, based on the local ssh version. Probably simpler than maintaining two disparate forks as well.

Alternatively, for people that don't like to read a lot, a big fat warning when run "Hey, your SSH version isn't up to snuff, so we're exiting with a 'not-compatible-error' go upgrade" might be a good idea.

NSAKEY commented 9 years ago

I decided to go with generating a test ED25519 key, since that feature was introduced in 6.5. If the exit status is greater than 0, the user's told to upgrade OpenSSH. Since I don't have any test VMs with older SSH versions, now seems like a good time to grab some VM templates and test.

NSAKEY commented 9 years ago

Regarding your problem with Ubuntu 12.04 not being supported, have you looked into adding a PPA? This looks like it would probably work. If you want some more variety, the results on this page have a bunch of other OpenSSH-related PPAs.

akhepcat commented 9 years ago

I've looked a few times.

I've tried a few of the others, but nothing has gotten me past 6.2p2 due to them not really being true backports (i.e., built on upstream libraries from trusty, etc)

The unpm PPA is broken, with no successful builds, but I might try doing a source-build. We'll see.

akhepcat commented 9 years ago

Ah! I finally found a ppa that works.

http://ppa.launchpad.net/dirk-computer42/c42-backport/ubuntu

it also looks like neurodebian -might- work as a ppa resource, but I didn't give them a try. http://neuro.debian.net/

NSAKEY commented 9 years ago

I'm going to link to your last reply in the comments for happy-dance.sh and close this ticket out.