Tuesday, November 4, 2014

Recently we had a task to provide a secure connection from Java application (Play2!) running in  Heroku to Oracle database that lives in internal datacenter. The example of stunnel configuration for Oracle is described in this post http://www.ritzyblogs.com/OraTalk/PostID/104/How-to-configure-stunnel-for-Oracle-with-example. In this article I describe what needs to be done to implement stunnel when your app lives in Heroku cloud and your database is somewhere else (in our case it is in internal datacenter):
First, you need to change default Heroku behavior to run a single application per node and run two pieces - one Java (or Scala) applications as usual which will talk to stunnel client instead of connecting to the database directly. For this you can specify custom buildpack in your application environment variables:

$ heroku config:add BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git

Then in the root of your Play project you need to specify which buildpacks to use

$ cat .buildpacks 
https://github.com/heroku/heroku-buildpack-scala.git
https://github.com/timshadel/heroku-buildpack-stunnel.git

The first buildpack is your usual buildpack for Play2! application (It can be anything else - Ruby on Rails, NodeJS etc.) The second is the buildpack which will compile stunnel client in your slug (shown as a yellow box on the diagram).
Next piece is you stunnel.conf file, which you can put into conf folder in Play2! application.

$ cat conf/stunnel.conf 
service = stunnel-client
cert = /app/conf/client.pem
CAfile = /app/conf/cacert_chain.pem
verify = 3
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
debug = 7
foreground = no
session = 86400
TIMEOUTidle = 86400
client = yes
output = /app/conf/stunnel.log
[internal.yourappname]
accept = localhost:1600
connect = stunnel.yourcompany.com:1601

As you can see you need to provide your certificate files locations (I put them in the conf folder as well), your port which stunnel will listen to (1600), and the port for outbound stunnel connection (1601). All details specific to stunnel configuration are described here.  
Now we should tell Heroku how to run our Play2! application. That can be done using Procfile:

$ cat Procfile 
web: target/universal/stage/bin/stunnel-java -Dhttp.port=$PORT

My application name is stunnel-java and I'm using standard Play2! stage task to build it. Make sure you change it according to your application name. 
Now we need to tell Heroku to run stunnel 

cat .profile 
CONFIG_FILE=$HOME/conf/stunnel.conf
echo "at=info service=stunnel action=start config=$CONFIG_FILE"
$HOME/vendor/stunnel/bin/stunnel $CONFIG_FILE &

In your conf/application.conf you can specify database connection details as follows

db.default.driver=oracle.jdbc.driver.OracleDriver
db.default.url=jdbc:oracle:thin:@//localhost:1600/your_ora_srv
db.default.user=your_user
db.default.password=your_password

Another change I had to make in the application settings is to add -Duser.timezone=MST to my JAVA_OPTS.
In the application you can use the database connection as you would do normally - no adapters or other magic are needed.  

No comments:

Post a Comment