Going more secure…

I have been trying to secure our digital life more and more these days. Most folks forget that it was until recently, think 2013, when Snowden revealed much of what we now know about various surveillance programs, most websites didn’t use HTTPS for anything other than purchases. Obviously, this this changed drastically and now you’d be hard-pressed to find a site which does not encrypt its communications with the user.

So for this reason I want to share our path towards evermore stringent security.

As a 21st century family, we make heavy use of Evernote. It’s a way to store and share information. And while communication between your device and evernote servers is encrypted, as you know, if a bad actor got access to your device he/she would have full access to all of your data, not to mention of Evernote servers were hacked. We used to keep (yes, pretty dumb) very sensitive information in Evernote. From passports to usernames, to passwords, you name it… everything.

So yes, dumb, but tell me what other service provides you the ability to store sensitive information in a secure way and the ability to share? We could encrypt it using GPG and store and share on Evernote, but that can get complicated amongst the entire family (GrandMa included).

The solution was LastPass family service. LastPass family is basically a water-down version of their enterprise offering. The best way to view it is as a discounted premium subscription at a cost of $0.66 per user (with a maximum of 6). For me, it’s costing me more like $1.00 per user per month because I only have 4 people in my family that can make use of it.

So why go with LastPass family vs just LastPass premium, other than the savings (I was already paying for two premium subscriptions), folder sharing.

Just like Evernote, you can create a folder/notebook, that you can use to share any type of data amongst users. You can share text and files (though the files needs to be enclosed as part of a note, just like on Evernote) and give access permissions to various members of the “family”.

Most people are used to LastPass on their browser, as an add-on, but they also offer an application for your computer, which makes the transition much easier.

So far, what I have moved over is anything that is sensitive. Passwords were already in LastPass since a few years back, but objects like passport photos, financial information, birth certificates, etc, have been imported into LastPass family.

Setup 2FA SSH on MacOS Sierra

For some time, I have been using 2FA for most of my sensitive logins on the Internet. From Google to FB to WordPress to Git. Any login with sensitive information is setup with 2FA using (FIDO U2F).

Anyway, the one setup that has been missing (don’t ask me why I had not done is sooner) was our home MacMini. Our MacMini stays on all of the time and serves as our home computer. We use it for everything, from a Plex Server to printer server, to file server, you name it.

I like to be able to access it remotely and as such I have setup SSH on it. However, until recently, it was pretty open. I looked online for support on how to setup 2FA and below are the steps I followed to get it to work:

Basic definitions

  • Server: This is the host to which you want to connect and on which you’ll be installing 2FA
  • Client: This is any host other the the server

Instructions

  1. You need to have xcode, command line tools and homebrew installed. You should do this from the
    1. Install xcode: That you need to do from the App Store. Just open the App Store,  look for xcode and install it
    2. Install command line tools:
      xcode-select --install

      That should bring up a prompt on the screen asking if you want to install command line tools. Click Installinstall xcode on mavericks step 1

    3. Install homebrew:
      /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew install/master/install)"
  2. Get the latest release of Google Authenticator. Download and unzip.
  3. Build and install Google Authenticator:
    ./bootstrap.sh
    ./configure
    make
    sudo make install
  4. Update sshd to use Google Authenticator
    1. Make a copy of /etc/pam.d/sshd:
      sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.org
    2. Make a copy of /etc/ssh/sshd_config:
      sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.org
    3. Update sshd to make use of the Google Authenticator shared object (pam_google_authenticator.so):
      //This will let you edit the file
      sudo vi /etc/pam.d/sshd
      //Add this line below the "auth" section 
      auth       required       /usr/local/lib/security/pam_google_authenticator.so
      //Save and exit 
      :wq!
      
      
    4. Update sshd_config:
      //Open the file for edit:
      sudo vi /etc/ssh/sshd_config
      //Look for #ChallengeResponseAuthentication yes and remove the hash
      ChallengeResponseAuthentication yes
      //Save and exit
      :wq!
  5. Restart sshd for the changes to take effect:
    sudo launchctl unload  /System/Library/LaunchDaemons/ssh.plist
    sudo launchctl load  /System/Library/LaunchDaemons/ssh.plist
  6. Setup Google Authenticator for the desired user
    1. Assuming you have performed all of the actions above logged in as the desired user, just continue, otherwise exit and login as the desired user.
    2. Setup Google Authenticator:
      //Locate the folder where you unzipped Google Authenticator and execute google-authenticator
      google-authenticator
      
      Do you want authentication tokens to be time-based (y/n) y
      https://www.google.com/chart?some-really-long-url-you-will-need-this
      Your new secret key is: ABCDEFGHIJKLMNOP 
      Your verification code is 000000
      Your emergency scratch codes are:
        00000000
        00000000
        00000000
        00000000
        00000000
      
      Do you want me to update your "/Users/<your-username>/.google_authenticator" file (y/n) y
      
      Do you want to disallow multiple uses of the same authentication
      token? This restricts you to one login about every 30s, but it increases
      your chances to notice or even prevent man-in-the-middle attacks (y/n) y
      
      By default, tokens are good for 30 seconds and in order to compensate for
      possible time-skew between the client and the server, we allow an extra
      token before and after the current time. If you experience problems with poor
      time synchronization, you can increase the window from its default
      size of 1:30min to about 4min. Do you want to do so (y/n) y
      
      If the computer that you are logging into isn't hardened against brute-force
      login attempts, you can enable rate-limiting for the authentication module.
      By default, this limits attackers to no more than 3 login attempts every 30s.
      Do you want to enable rate-limiting (y/n) y
    3. With a browser open the long URL. This will generate a QR Code. Scan the code using your favorite Google Authenticator App. I personally like Authy as it can sync between devices.
  7. Close all open SSH connections you may have with the server.
  8. From a client ssh into the host and voila, 2FA works 😀
    client.host:~ username$ ssh username@host.to.ssh
    Password:
    Verification code:
    Last login: Thu Dec  7 16:09:24 2017 from 192.168.2.1
    host.to.ssh:~ username$

References

The internet is nothing, if not for a bunch of really smart people that love to share their experiences and findings. I was able to get this to work thanks to these posts:

 

You 2.0: Getting Unstuck

At one time or another, many of us feel stuck: in the wrong job, the wrong relationship, the wrong city – the wrong life. Psychologists and self-help gurus have all kinds of advice for us when we feel rudderless. This week on Hidden Brain, we conclude our You 2.0 series with a favorite episode exploring a new idea from an unlikely source: Silicon Valley.

* Duration: 29:09, Played: 14:23

* Published: 8/29/17 03:01:18

* Episode Download Link (27 MB): https://play.podtrac.com/npr-510308/npr.mc.tritondigital.com/NPR_510308/media/anon.npr-mp3/npr/hiddenbrain/2017/08/20170828_hiddenbrain_ep56.mp3?orgId=1&d=1749&p=510308&story=546598801&t=podcast&e=546598801&ft=pod&f=510308

* Episode Feed: Hidden Brain – https://www.npr.org/rss/podcast.php?id=510308

Updated my resume

It’s been a while since I had updated my resume. I feel it is a good time make sure everything is up to date.

If you know of an interesting opportunity, or project, please be sure to let me know.

IvanAlonso.Resume

How to fix Plex server external access

Recently after installing a new router, I ran into an issue where my Plex server was not accessible from the internet.

The way Plex is setup to work seems to be like: Internet --> External-IP:random-port --> Internal-IP-of-Plex-Server:32400

Originally, I had forgotten to enable port-forwarding on my router for port 32400. The solution seemed simple, enable that port (32400) to my Plex Server’s internal IP and while at it, also enable that random port (which didn’t seem so random at the time). That was a problem.

Enabling the both port causes a problem (not really sure why). So I looked at the option on Plex to set the external port to 32400 with no luck. The solution was the simplest one; only enable port forwarding for port 32400 at the internal network level. Meaning, just turn on port forwarding for port 32400 to the Internal-IP-of-Plex-Server. Leave the rest alone. Do not set an external port and do not enable port forwarding for the random port (even if it does not seem random).

Fixing double NAT on Jazztel DSL and Asus RT AC87U

Recently I purchased an Asus router. Our old Netgear router died and we needed a replacement. The installation was almost plug and play with the new Asus, almost.

After the setup was complete I ran into an issue where the router was reporting a double-NAT issue.

With our previous router I had setup port-forwarding at the DSL modem level. The port forwarding was setup to forward all traffic from ports 1:65000 to the IP address of the Netgear router, something like this: internet --> DSL modem --> port forwarding (1:65000) --> 192.168.1.nnn (local IP of the Netgear router)

That approach solved the double-NAT problem by having all traffic on those ports forwarded to the Netgear router.

However, for better or for worse, because the local IP for the Asus router changed (no longer 192.168.1.nnn, but now 192.168.1.xxx) this still didn’t work (and I didn’t immediately realize it). So as a result I began to dig deeper into the issue.

According to this post, there are three solutions:

  • Setup the DSL modem in bridge-mode (described here)
  • Forward traffic to the Asus router (partly what I had done, minus the oversight on the IP address)
  • Setup the Asus router as a DMZ (similar to forwarding the port traffic, but with less control)

To setup my DSL modem into bridge mode I did the following:

  • Edit the WAN service under: Advanced Setup --> WAN service --> ppp1.1 (that was the one that was enabled for me)
  • Get the password by “editing” the page using FF webtools
    • You will need it later
  • Enable fullcone NAT
  • Enable Bridge PPPoE frames between WAN and local ports
  • Click save and exit

Now you’ll need to update the Asus’s WAN setup to use PPPoE login like this:

  • Go to WAN
  • Under connection type choose PPPoE
  • For PPP user and pass, use those from the DSL modem
  • Under MAC address choose “MAC Clone” (it should pick the MAC of the DSL modem)
  • Click “Apply” and you are done

This solved my double-NAT problem. Now the router got the external IP the DSL modem was getting.

The reality, however, is that I could have just as easily fixed the issue through either port-forwarding and DMZ, but by the time I realized it I was too focused on solving it through the bridge approach.

 

 

javax.net.ssl.SSLHandshakeException in JMeter against some URLs

Problem

Recently I had to investigate an issue where certain JMeter tests pointing to an HTTPS end-point were resulting in this error:

javax.net.ssl.SSLHandshakeException

Initially I thought it would be an easily fix by simply using the HTTP3.x sampler, rather than the default HTTP4.x.

Solution

The solution was to upgrade JMeter to version 3.2 (we were running 2.13 for good reasons).

How it was troubleshooted

Bad Certificates

If you do a search on that error you will be led to believe it’s an issue with the validity of the certificate being issued. To address this, it is suggested to:

  1. Upgrade Java to the latest
  2. Replace the UnlimitedJCEPolicyJDK8 JARs under <java>/jre/lib/security/
  3. Download the certificates from the server and added to the trusted cacerts

It’s the SNI

Given it was not the bad certificates, I enabled SSL debugging and got the following:

Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1495568515 bytes = { 82, 170, 89, 172, 24, 224, 26, 122, 144, 41, 158, 48, 243, 159, 93, 186, 63, 66, 119, 137, 96, 246, 218, 179, 67, 45, 163, 50 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
***
[write] MD5 and SHA1 hashes:  len = 239
0000: 01 00 00 EB 03 03 59 25   91 83 52 AA 59 AC 18 E0  ......Y%..R.Y...
0010: 1A 7A 90 29 9E 30 F3 9F   5D BA 3F 42 77 89 60 F6  .z.).0..].?Bw.`.
0020: DA B3 43 2D A3 32 00 00   64 C0 24 C0 28 00 3D C0  ..C-.2..d.$.(.=.
0030: 26 C0 2A 00 6B 00 6A C0   0A C0 14 00 35 C0 05 C0  &.*.k.j.....5...
0040: 0F 00 39 00 38 C0 23 C0   27 00 3C C0 25 C0 29 00  ..9.8.#.'.<.%.).
0050: 67 00 40 C0 09 C0 13 00   2F C0 04 C0 0E 00 33 00  g.@...../.....3.
0060: 32 C0 2C C0 2B C0 30 00   9D C0 2E C0 32 00 9F 00  2.,.+.0.....2...
0070: A3 C0 2F 00 9C C0 2D C0   31 00 9E 00 A2 C0 08 C0  ../...-.1.......
0080: 12 00 0A C0 03 C0 0D 00   16 00 13 00 FF 01 00 00  ................
0090: 5E 00 0A 00 34 00 32 00   17 00 01 00 03 00 13 00  ^...4.2.........
00A0: 15 00 06 00 07 00 09 00   0A 00 18 00 0B 00 0C 00  ................
00B0: 19 00 0D 00 0E 00 0F 00   10 00 11 00 02 00 12 00  ................
00C0: 04 00 05 00 14 00 08 00   16 00 0B 00 02 01 00 00  ................
00D0: 0D 00 1C 00 1A 06 03 06   01 05 03 05 01 04 03 04  ................
00E0: 01 04 02 03 03 03 01 03   02 02 03 02 01 02 02     ...............
TestPlan_ThreadGroup 1-1, RECV TLSv1.2 ALERT:  fatal, handshake_failure
TestPlan_ThreadGroup 1-1, called closeSocket()
TestPlan_ThreadGroup 1-1, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
TestPlan_ThreadGroup 1-1, called close()
TestPlan_ThreadGroup 1-1, called closeInternal(true)

I confirmed the cipher suites available were compatible with the cipher used in the certificate and by searching for errors around the RECV TLSv1.2 ALERT: fatal, handshake_failure error, the SNI possibility showed itself.

Remember that we could run the same test (same load, specs, etc) against some URLs that we also encrypted using TLSv1.2 so we knew the delta was in how TLS was setup (and we unfortunately didn’t have access to the server logs).

To confirm if SNI was the problem we ran this:

openssl s_client -connect <your host>:443

If you get an error, your host requires SNI. To confirm, SNI is the solution do this:

openssl s_client -connect <your host>:443 -servername '<your host>'

If you get a valid response (which you should), your server requires SNI.

Now that we knew the server required it, we just need to find out how to enable it.

And if you search for “sni jmeter” you get this post. Which basically confirms it was broken on HTTPClient4.x but later fixed. And given we used JMeter 2.13, it meant upgrading to JMeter 3.2 (at the time of this writing it was the latest)

Upgrading to JMeter 3.2 solved the issue. Good luck.