Welcome

Welcome to my external memory and information on what I'm currently working on. Here you will find snippets of code, tricks and solutions I, or maybe you, may need to reference.

Feel free to comment your suggestions and any constructive criticisms that you may have.

Wednesday, 19 February 2014

Java Keystores: A Quick Reference

Overview

One of the biggest headaches I have to deal with are web services with self signed SSL certificates for web services. This is a common issue for applications in development because development and preview environments rarely have properly signed certificates. So in order to debug and develop you have to get around this.

Get the Certificate

Perhaps this is the lazy way of getting a certificate for a self signed web service but it does work and it's fairly easy. You simply use your browser (Chrome or Firefox).
  1. Navigate to your WSDL
  2. Click the lock icon in the navigation bar to the left of the URL
  3. If you're using Chrome (See the screen shot below for an example):
    1. Click the Connection Tab
    2. Click the Certificate Information
    3. Click Details
    4. Click Export
  4. If you're using Firefox:
    1. Click More Information
    2. Click View Certificate
    3. Click Details
    4. Click Export
  5. Select a location you can easily access and click Save
Exporting an SSL certificate in Chrome
Exporting a SSL certificate in Chrome

Add the certificate to your Keystore

  1. Open a terminal and navigate to where you saved the certificate and execute the following command:
  2. keytool -import -trustcacerts -alias myAlias -file mycert.ca --keystore mykeystore.jks. There are several things to note here:
    • -trustcacerts will probably not help but its a nice to have. Basically if the root certificate is already in your cacerts file located at jdk/jre/lib/security/cacerts you wont be pestered about accepting this certificate via a yes/no prompt.
    • -alias this is a unique name that identifies the certificate. Usually the domain name the certificate belongs to is a good choice here.
    • -file this is the certificate file you downloaded via your browser
    • --keystore (optional) this is the keystore you're going to store the certificate in. If it doesn't already exist it will be created. If this option is left out the user's keystore will be used.
  3. You will be prompted for the keystore password. By default this is changeit if you left the --keystore option off. If you're creating a new keystore this will be its password.
  4. If asked about importing the certificate type "yes" and hit enter.

Using a non-default keystore in Java

This is done by including 3 JVM options when running your java application:
  • Dsun.security.ssl.allowUnsafeRenegotiation=true 
  • Djavax.net.ssl.trustStore=/path/to/your/keystore
  • Djavax.net.ssl.trustStorePassword=changeit
For example executing an application with a custom keystore would look like this:
java -Dsun.security.ssl.allowUnsafeRenegotiation=true -Djavax.net.ssl.trustStore=/home/bradley/liferay-preview-keystore -Djavax.net.ssl.trustStorePassword=changeit -jar myapp.jar

A Trick When Working with Multiple Environments

Since it's better to develop and debug with an environment that mimics your preview and production environments I've taken to copying the java keystore in our preview environments, which is  managed by our middle ware team and/or application admins, to my local machine and have my local environments/applications use it instead of importing certificates manually. This file is located at <JDK>/jre/lib/security/cacerts (In my case the full path is:  /usr/lib/jvm/java-7-oracle/jre/lib/security/cacerts). What this accomplishes is guaranteeing that my environment has the same certificates as our preview instance. Couple this with setting up an SSH tunnel to our preview instance for the application running locally and development and migration between dev and preview environments for applications that consume a web service becomes trivial.

A Tool For Working with Web Services

A critical tool for debugging and setting up a web service/client is SoapUI. This application allows you to load a WSDL, either remotely or locally, and it will generate a SOAP envelope that you can use to query the web service. The results of the query are then returned and displayed in SoapUI.

A word of caution: I've had a lot of trouble getting SoapUI to use keystores I've set up via the GUI. If you're running into this problem you can use the instructions in the "Using a non-default keystore in Java" section and add the JVM options to SoapUI/bin/soapui.sh. Once I did this my SSL certificates were recognized (even though the exact same keystore was set up in SoapUI's preferences and my project) and everything worked perfectly.

Running an SSH tunnel using PUTTY

Why would you want to do this?

For many reasons. Mostly I do this when I need to appear to be a server in order to test a web service, network connection, or some other resource where access is restricted to a set of IP Addresses. This will let me use tools such as SoapUI and Firefox to debug/test things.

What is Putty

It's a cross platform SSH client that saves sessions and makes using SSH just a little easier and more convent. SSH can easily be done from a shell but the convince of having pre-defined sessions with things like tunnelling all ready configured makes Putty win out in my books. 

The basic usage of putty itself is outside the scope of this article but below are links as to where it can be obtained and a documentation:

What To Do

  1. Start up Putty
  2. Fill out your session details
  3. Go to Connection -> SSH -> Tunnels
  4. Set up your tunnel configuration (See image below)
    1. Enter your source port number (This is the port local clients will connect to)
    2. Select Dynamic
    3. Click Add
  5. Go back to Session and save your session
  6. Click Open
Putty Tunnel Configuration
Putty Tunnel Configuration

Connecting To Your Proxy

Each program is different but here are my two most common methods/use cases:

Firefox

  1. Edit -> Preferences -> Advanced -> Settings
  2. Select Manual proxy configuration
    1. Set HTTP Proxy to 127.0.0.1 and Port to 1080 (or what ever port your defined)
    2. Ensure SOCKS v5 is selected
    3. Click OK

Java Applicaitons

Run the Java application with the following java options set:
Dhttp.proxyHost=127.0.0.1 Dhttp.proxyPort=8010
For example executing the application via command line may look like:
java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8010 -jar myApplication.jar

Saturday, 1 February 2014

Setting up OpenVPN on a Virtual Private Server (VPS)

Overview

I recently set up my own VPS. I had installed OpenVPN on my own virtual machines and systems before but setting it up on a VPS created a few unexpected problems. Below is the process that I used to get things up and working.

Assumptions and Out of Scope Items

  • You have OpenVPN already installed at /etc/openvpn
  • You have Easy-RSA 2.0 located at /etc/openvpn/easy-rsa/
  • You have root access (I'm going to assume you're either logged in as root or running under su)
  • Your VPS has provisioned you a Static IP address.
  • OpenVPN Client instillation and configuration.

Special VPS Considerations

Note: A VPS typically operates with a shared kernel between all of it's Guests. Since a VPS operates on the hardware level (unlike a regular virtual machine which is typically hosted by a piece of software like Virtual Box or VMWare) the hardware/kernel level is shared among all systems. You can read more on this on Wikipedia: Virtual Machine.

Because of this we run into two main issues:
  1. OpenVPN requires the Tun kernel module which isn't usually present by default. And since you don't have access to the kernel you can't load it. To get around this you can usually ask your provider to enable it on your VPS or it is an option on your provider's VPS management page.
  2. In order to tunnel traffic you need to set up routing rules with iptables which, in my experience, is typically done using the MASQUERADE option which isn't supported by my VPS Host (OpenVZ). I would assume this is the case for most if not all VPS hosts.

The Process

Creating RSA Keys

If you can use encryption keys to access your VPN server why not? Unless you're making this service open to a large number of people the standard Username/Password approach just isn't as secure. And since, in this case, I can easily control and distribute my private key(s) I can't see a reason not to.
  1. Navigate to /etc/openvpn/easy-rsa/2.0/ and create a directory called keys
  2. Edit the /etc/openvpn/easy-rsa/2.0/vars file and set the following values. Note: These will be your default values when generating keys so you will get an opportunity to override them during the process.
    export KEY_COUNTRY="US"        # Your Country
    export KEY_PROVINCE="CA"       # Your State/Province/Territory 
    export KEY_CITY="SanFrancisco" # Your City
    export KEY_ORG="None"          # Your Organization Name
    export KEY_EMAIL="mail@domain" # Mail Address
    export KEY_EMAIL=mail@domain   # Mail Address
    Note: You can also add/alter the additional fields below, however, typically these values will not be the default when you generate your keys.
    export KEY_CN=OpenVPN.yourdomain.com # Common Name
    export KEY_NAME=yourname             # Your Name
    export KEY_OU=servername             # Organizational Unit
  3. Execute the following commands from the /etc/openvpn/easy-rsa/2.0/ directory. Note: You will be prompted for information when generating keys and this will create all your keys and certs in the /etc/openvpn/easy-rsa/2.0/keys folder:
    ./vars            # Sets up environment variables for key creation
    ./clean-all       # Cleans up any generated files in the folder
    ./build-ca        # Creates the certificate authority key
    ./build-key-server server # Creates the server key
    ./build-dh        # Creates the Diffie-Hellman key
    ./build-key clientname # Creates the client's private key
  4. Transfer, physically if possible encrypted if not, the  ca.crt, clientname.crt, clientname.key files to your client and place them in it's openvpn folder.

Creating a TLS-Auth key (ta.key)

  1. Navigate to /etc/openvpn/
  2. run the command:
    openvpn --genkey --secret ta.key
  3. Done.

Configuring the Server (server.conf)

To make this a little simpler I've included a sample server.conf file. I'd recommend backing up your current server.conf file as it has comments that will help you further configure your server to your needs.

Set up routing/forwarding

  1. We need to enable ip traffic forwarding:
    1. Enable forwarding by executing the following:
      echo 1 > /proc/sys/net/ipv4/ip_forward
    2. Make the change permanent by editing /etc/sysctl.conf and un-commenting the line:
       net.ipv4.ip_forward = 1
  2. Set up IPTables rules to forward the traffic coming in from the tunnel (tun0) to our ethernet adapter (venet0). This is done by setting up forwarding between the client and server's network adapters (tun0 and venet0) as well as traffic coming back to the client (venet0 to tun0). The final step maps the incomming local 10.8.0.0/24 address to the servers IP (This is the step that differs on a VPS).
    1. Enter the following into the command line:
      iptables -A FORWARD -i venet0 -o tun0 -m state --state ESTABLISHED,RELATED -j ACCEPT
      iptables -A FORWARD -s 10.8.0.0/24 -o venet0 -j ACCEPT
    2. The following is the standard way of setting up the ip mapping which uses MASQUERADE but will not work on a VPS
      iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o venet0 -j MASQUERADE
      Because MASQUERADE isn't implemented in the VPS's kernel we have to complete the mapping manually. Keep in mind that as long as you have a static IP this method will work.
      iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o venet0 -j SNAT --to-source <server ip>
  3. Make the changes to iptables persist between reboots. I found some tools to help out with this but I tend to prefer solutions that don't require additional packges. And this one is simple so why not!
    1. Store the current state of your iptables in a iptables rule file.
      iptables-save > /etc/iptables.openvpn.rules
    2. Add the following to to /etc/network/interfaces.
      #Define OpenVPN IP address forwarding
      post-up /sbin/iptables-restore < /etc/iptables.openvpn.rules
      

Sources