NerdVana

Our software never has bugs; it just develops random features.

Reverse shell via socat

Written by Eric Schwimmer

I had a grumpy EC2 instance that wasn't allowing any inbound connections after it initialized (turns out it had a rogue firewalld rule that was shutting me down). I was able to get in to debug it by running this on my VPS:

openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem && \
    socat `tty`,raw,echo=0 openssl-listen:1237,reuseaddr,cert=cert.pem,verify=0

And then setting this up as a cron job in the grumpy EC2 instance's AMI:

* * * * * ps -ef | grep -q '[o]penssl-connect' || \
    socat openssl-connect:<MY_VPS_IP>:1237,verify=0 exec:bash,pty,stderr,setsid

One minute after the EC2 instance came up, bam, I had a remote shell running on my VPS.

Adventures in Centos7 AMI building

Written by Eric Schwimmer

I created a bash script that will pretty much automate the build process of a Centos7 Amazon Machine Image (for both PV & HVM instance types). It's available here.

All told, it was a bit of an experience getting it to work properly. The portion that gave me those most grief was getting GRUB2 to successfully install itself on a partitioned file system, which had itself had been created from an dev mapper volume mounted from a loopback device. Easy, right? ;)

Version sorting in Perl

Written by Eric Schwimmer

Need to sort two or more numeric version strings in Perl? Hate life? Then consider using this little beaut:

sub verComp                                                    
{                                                              
    my ($a,$b) = map [split '\.'], @_;                         
    for (0..($#$a,$#$b)[$#$a>$#$b])                            
      { return $a->[$_] <=> $b->[$_] if $a->[$_] <=> $b->[$_] }
    return $#$a <=> $#$b;                                      
}                                                              

my @versions = ('1.2.3.4','1.2.3','3.2.3','1.2.3.4.5','2.3.4');
print join ' -> ', sort { verComp($a,$b) } @versions;          

It works!

$ ./vercomp.pl
1.2.3 -> 1.2.3.4 -> 1.2.3.4.5 -> 2.3.4 -> 3.2.3

s3wipe 0.2

Written by Eric Schwimmer

New version of s3wipe just got released! You can now delete all keys under an arbitrary path, instead of only being able to delete entire buckets. It's a christmas miracle!

https://github.com/eschwim/s3wipe

Nginx: speed AND security? Yes, please.

Written by Eric Schwimmer

So now that everybody is giving SSL the good lovin' that it deserves, people are starting to find that SSL can be kind of slow... especially when it's not properly configured. However, well-configured SSL can actually be FASTER than a non-encrypted connection (assuming you are running a newer browser).

For instance, the current incarnation of Nerdvana uses SPDY, SSL session caching and TLS Certificate Status Requests (a.k.a. OCSP Stapling) to make things run like greased lightning.

For greater security, we support only TLSv1+, use a select subset of ciphers, turn on HTTP Strict Transport Security (HSTS), and use a SSL cert generated with RSA 2048+ bit cert signed with SHA-256.

Here are the relevant bits from our Nginx config:

# Redirect all HTTP connections to HTTPS
server {
    listen 80 default;
    return 301 https://nerdvana.org$request_uri;
}

# Our HTTPS server
server {
    # Enable SSL, with support for SPDY
    listen 443 ssl spdy;

    # SSL certificate setup
    ssl_certificate /etc/ssl/nginx/nerdvana.org/nyx.crt;
    ssl_certificate_key /etc/ssl/nginx/nerdvana.org/nyx.key;
    ssl_trusted_certificate /etc/ssl/nginx/nerdvana.org/ca-certs.pem;
    ssl_dhparam /etc/ssl/nginx/nerdvana.org/dhparam.pem;

    # OCSP stapling setup
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 206.253.164.3 69.85.88.3 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 15s;

    # Support HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";

    # SSL session caching
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 5m;

    # SSL cipher/protocol setup
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "AES256+EECDH:AES256+EDH";

    # Prevent click-jacking and mime-sniffing
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;

}

This gets us an A+ with the Qualsys SSL test.

Note that you are going to want Nginx 1.5.10 or later to get the latest non-draft version of the SPDY protocol and OCSP stapling.

Also, you'll want to create your own DH key with 2048+ bits, since the OpenSSL default is 1024 bits and this will degrade the security of the initial key exchange (arguably the most critical part of the process). So run 'openssl dhparam -out dhparam.pem 4096', and then be prepared to wait for a good long time before the key is finally generated.

For a great resource on setting up Nginx in a secure yet speedy manner, check out:

https://www.mare-system.de/guide-to-nginx-ssl-spdy-hsts/ https://raymii.org/s/tutorials/Strong\_SSL\_Security\_On\_nginx.html

Benchmarking SSH cipher/HMACs

Written by Eric Schwimmer

Want to benchmark all of the possible SSH cipher/MAC permutations on your Linux box? Okay:

#!/bin/bash

RAMDISK=/mnt/cipherspeed
DATA=$RAMDISK/data
OUTPUT=/tmp/cipherspeed
TMP=$OUTPUT.$$

CIPHERS="aes128-ctr aes192-ctr aes256-ctr arcfour256 arcfour128  
aes128-cbc 3des-cbc blowfish-cbc cast128-cbc aes192-cbc 
aes256-cbc arcfour"

MACS="hmac-md5 hmac-sha1 umac-64@openssh.com hmac-ripemd160 
hmac-sha1-96 hmac-md5-96"

[[ -d $RAMDISK ]] && (umount $RAMDISK &> /dev/null ; rm -rf $RAMDISK)
mkdir $RAMDISK
mount -t tmpfs -o size=512m tmpfs $RAMDISK
dd if=/dev/zero bs=1M count=512 2>/dev/null | \
    openssl enc -rc4-40 -pass pass:weak > $DATA

for c in $CIPHERS; do for m in $MACS; do
    ( ssh -o 'compression no' -2 -m $m -c $c localhost \
        "dd of=/dev/null" < $DATA ) 2>&1 | \
    awk '/copied/ { printf "%.0f %s %s", $1/$6, $8, $9}' >> $TMP
   [[ $? ]] && (echo " $c/$m" >> $TMP ;  tail -1 $TMP)
done; done

CIPHERS="3des blowfish"
for c in $CIPHERS; do
    ( ssh -o 'compression no' -1 -c $c localhost \
        "dd of=/dev/null" < $DATA ) 2>&1 | \
    awk '/copied/ { printf "%.0f %s %s", $1/$6, $8, $9}' >> $TMP
    [[ $? ]] && (echo " $c" >> $TMP ;  tail -1 $TMP)
done;

sort -rn $TMP >> $OUTPUT
rm -f $TMP
echo "Results available in $OUTPUT"
sleep 1
umount $RAMDISK
rmdir $RAMDISK

Adjust the CIPHER and MAC strings to your liking (if anybody knows how to programatically determine the available ciphers and/or MACs, drop me a line).

If you are running a semi-recent version of Linux on semi-newish Intel box (i.e. one that supports AES-NI, which should be all post-Nehalem CPUs), "aes128-ctr/umac-64@openssh.com" is probably going to be the fastest combo for you (I get around 360 MB/s on my dev box).