Showing posts with label openssl. Show all posts
Showing posts with label openssl. Show all posts

Monday, 7 March 2016

Apache httpd reverse proxy for Tomcat with SSL self signed certificates.

Recalling from the previous article on how to install Apache Tomcat 7 and Httpd on Fedora 22 we are now going to present how to configure Apache Httpd working as a reverse proxy for Apache Tomcat.

In more details, we are going to implement the following setup:
  • Setup Tomcat 7 listening on port 8080
  • Redirect port 80 (HTTP) to port 443 (HTTPS)
  • Use self signed RSA server certificates to authenticate our HTTPs server on clients and secure the TCP session.

Public and Private Server Key

In order to create the Server Public/Private key set we are going to use openSSL tools. 
 To install them in you Fedora 22 server do:
# dnf install openssl
# or for older Fedora systems
# yum install openssl

Then openssl tools are installed to:
# which openssl
/bin/openssl

Go to the apache httpd configuration directory and do the following:
# cd  /etc/httpd/conf/

Generate a PEM RSA private key key using DES3
# openssl genrsa -des3 -passout pass:mypass  -out server.pass.key 2048
Generating RSA private key, 2048 bit long modulus
..............................+++
...................................................................................+++
e is 65537 (0x10001)

Create a Server PEM certificate request using the server key:
# openssl req -new -key server.pass.key -out server.csr
Enter pass phrase for server.pass.key:     # put mypass here
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:GR
State or Province Name (full name) [Some-State]:Athens
Locality Name (eg, city) []:Athens
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Illumine IT Consulting
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:www.illumineit.com
Email Address []:info@illumine.gr

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:                      # press enter here to skip password
An optional company name []:  Illumine IT Consulting 


Finally, create the server certificate using the PEM Certificate Request
# openssl x509 -req -in server.csr -signkey server.pass.key -out server.crt  -days 365

Signature ok
subject=/C=GR/ST=Athens/L=Athens/O=Illumine IT Consulting/CN=www.illumineit.com/emailAddress=info@illumineit.com
Getting Private key
Enter pass phrase for server.pass.key:  # put mypass here


By the end of this operation you should have the following files created:
# ls -l
-rw-r--r--. 1 root root 1318 Mar  7 18:11 server.crt
-rw-r--r--. 1 root root 1115 Mar  7 18:07 server.csr
-rw-r--r--. 1 root root 1743 Mar  7 18:05 server.pass.key
  • server.ctr: is the server certificate
  • server.csr: is the server PEM certificate request
  • server.pass.key : server´s private RAS key.

Configure Apache HTTPd working with SSL certificates and reverse proxy to Tomcat

# vi /etc/httpd/conf/httpd.conf

Add the following section:
ServerRoot "/etc/httpd"
# Port 80 (HTTP) will be redirected to 443 (HTTPS)
Listen 80

   ServerName www.illumineit.com
   Redirect permanent / https://www.illumineit.com

# Port 443 HTTPS will be default
Listen 443

  ServerName www.illumineit.com
  ServerAdmin my-mail-here
  #
  # Configure SSL engine on and add your certificates
  #
  SSLEngine on
  SSLCertificateFile     conf/server.crt
  SSLCertificateKeyFile  conf/server.key
  #
  # proxypass configuration to your tomcat server running on 8080
  #
  ProxyPass        /zsecure-pdf/   http://www.illumineit.com:8080/zsecure-pdf/
  ProxyPassReverse /zsecure-pdf/   http://www.illumineit.com:8080/zsecure-pdf/
  ProxyPassReverseCookieDomain www.illumineit.com www.illumineit.com
  ProxyPassReverseCookiePath /zsecure-pdf  /zsecure-pdf
  
     ProxyPassReverse /
     SetOutputFilter  proxy-html
     RequestHeader    unset  Accept-Encoding
  

  BrowserMatch "MSIE [2-5]" \
  nokeepalive ssl-unclean-shutdown \
  downgrade-1.0 force-response-1.0

The first section VirtualHost configures Apache to redirect whatever goes to port 80 to be redirected to port 443 (HTTPS)

The second section VirtualHost configures Apache to use Tomcat as reverse Proxy. So if someone requests URI path /zsecure-pdf/ this will be redirected to port 8080 where tomcat listens.

Save and restart the Apache HTTPD:
# service httpd restart
Redirecting to /bin/systemctl restart  httpd.service

Test Apache

Hit with browser http://www.illumineit.com this will redirect you to https://www.illumineit.com

if you also navigate to the path that was reverse pass: https://31.171.245.82/zsecure-pdf/secure-my-pdf-to-image-password-encrypt-and-watermark.html then you will be served from Tomcat serving your application.

Potential problems

AH01114: HTTP: failed to make connection to backend
To get rid of this log to your server as root and run those commands:
/usr/sbin/setsebool httpd_can_network_connect 1
/usr/sbin/setsebool -P httpd_can_network_connect 1


Page does not renders correctly: images and CSS are missing. That is very common since HTML pages might taken from other sites by A HREF. The only think you can do is copy them locally to WebContent directory of your WAR deployment.

Wednesday, 22 January 2014

Implementing 2-way SSL in Java using TLS and Self Signed Certificates part3

Step 3: The Client (Get the complete code here)

The client also requires the Keystore/Trustore created in Part-1

Again in the client we have to do a couple of things similar to the server:

The first is to specify the Java Keystore/Trustore we created in  Part-1 of this article:

System.setProperty("javax.net.ssl.keyStore","mysystem.jks");
System.setProperty("javax.net.ssl.keyStorePassword","welcome");

System.setProperty("javax.net.ssl.trustStore","mysystem.jks");
System.setProperty("javax.net.ssl.trustStorePassword","welcome");

Similarly with the server side described in Part-2, we have to create the client socket as an SSLSocket:

SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();    
SSLSocket sslSock = (SSLSocket) factory.createSocket("localhost",8095);

The entire code of the client can be downloaded here.

Next article, Part-4, of this Blog series will assist you to debug the SSL/TLS client/server communication.

Implementing 2-way SSL in Java using TLS and Self Signed Certificates part2

Step 2: The server (Get the complete server code here)

Requires the Trustore/Keystore created in Step-1.

To write the server process in Java is pretty simple. You just have to do a couple of steps:
Specify a couple of properties so that the Trustore/Keystore can be loaded like the following code fragment shows:

System.setProperty("javax.net.ssl.keyStore","mysystem.jks");
System.setProperty("javax.net.ssl.keyStorePassword","welcome");

System.setProperty("javax.net.ssl.trustStore","mysystem.jks");
System.setProperty("javax.net.ssl.trustStorePassword","welcome");

Create the ServerSocket as anSSLServerSocketlike the following code fragment shows:
 
char ksPass[] = "welcome".toCharArray();
char ctPass[] = "welcome".toCharArray();

//Create and load the Keystore
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("ianalyzer.jks"), ksPass);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, ctPass);

//Create the ServerSocket as an SSLServerSocket
SSLContext secureSocket = SSLContext.getInstance("TLS");
secureSocket.init(kmf.getKeyManagers(), null, null);
SSLServerSocketFactory ssf = secureSocket.getServerSocketFactory();
ssocket = (SSLServerSocket) ssf.createServerSocket(8095);
SSLServerSocket ss = (SSLServerSocket) ssocket;

//This explicitly states TLS with 2-way authentication
ss.setNeedClientAuth(true); 

The entire code for server implementation can be downloaded here.

Implementing 2-way SSL in Java using TLS and Self Signed Certificates part1

Consider that we want to implement in Java a secure communication (Transport Layer Security ) for a system called MySystem.

The problem

The security scenario for the implementation of  MySystem is simple:
  • Authentication only between peers that both share the Keystore/Trustore file
  • Session establishment only between peers that have the Keystore/Trustore file
Doing so, the entire communication between client and server requires authentication and is encrypted:



Before going further on this study, pay a visit to this site for Java SSL: ssljavaguide.

To implement the scenario, there are three basic steps:
  1. Create the Java Keystore/Trustore that will be used for Authentication and Encryption of Transport/Session. This will be used from both Client and Server parties. (Current Part)
  2. Implement the Client side: (See blog article Part-2)
  3. Implement the Server side: (See blog article Part-3)
Part-4 deals with debugging the Client/Server SSL/TLS communication.

Step 1: Create the Keystore/Trustore
Following steps of this section, results in the creation of a  Keystore/Trustore .jks file that contains:
  • MySystem Private key 
  • MySystem Selfsigned Certificate
To do so we are going to use the tools openssl  and keytool. We prefer using openssl because it can work silently - without prompt the user to put passwords, domains, server names....

The steps are:
1) Generate RSA 1024 bit private key. The key will be password protected:
openssl genrsa -out mysystem.key 1024 -passin pass:welcome

2) Generate Certificate Request for CA (.csr) using the private key
openssl req -x509 -sha256 -new -subj '/C=GR/ST=Athens/L=Chalandri/CN=mysystem'  -key mysystem.key -out mysystem.csr

3) Generate self signed certificate expiry-time 10 years from the certificate request
openssl x509 -sha256 -days 3652 -in mysystem.csr -signkey mysystem.key -out mysystem.crt


4) Import the pair (private key and selfsigned certificate) in a new JKS (Trustore/Keystore together)
First we need to create PKCS12 keystore from private key and self signed certificate.
openssl pkcs12 -export -name mysystem -in mysystem.crt -inkey mysystem.key -out mysystem.p12 -passin pass:welcome -password pass:welcome

Then we need to convert PKCS12 keystore into a JKS keystore
keytool -importkeystore -destkeystore mysystem.jks -srckeystore mysystem.p12 -srcstoretype pkcs12 -alias mysystem -srcstorepass welcome  -storepass welcome  -noprompt

At this point we have created the Java  Keystore/Trustore mysystem.jks file.

Copy mysystem.jks on both client and server machines.

Download all the commands for the Keystore/Trustore .jks file generation here