Proxy with Client Certificate

From iDempiere en
Jump to navigation Jump to search

This page is about an enhanced network configuration. I have some iDempiere instances and other servers like a webserver etc. in my own local network and want to open some of them to the internet. The idea is to have one central apache server that works as a proxy. This single system should care for all security issues and not let unauthorized people see anything.

For this to work you need one single "proxy" system that is connected to the internet. This machine needs to be reachable by a DNS name. The proxy itself has to be connected to the real servers. It may be that the proxy machine is the router of your local network. It may also be that this machine is in a public data center and has a VPN connection to your internal network. (You find more information about these routing issues down in this article.)


Example: bugtracker

As an example for this documentation I want to use my internal redmine bug tracking system from the internet. I have an internal nameserver (but an internal /etc/hosts on all machines will also work) and I can access it at http://bugtracker.internal .

I want to access my bug tracker at http://bugtracker.bayen.eu


Basic Server Setup

The first thing to do is to set up the redmine installation and see if everything works as expected when I use it from inside my network.

Depending on your server configuration you set a ServerName directive (if you use this webserver for different purposes with different domain names). If this is the case you have to set a second directive ServerAlias

 ServerName bugtracker.internal
 ServerAlias bugtracker.bayen.org

Sometimes a web application has to know its full name. These apps do not allow to access them with a different name. If you have such a case you are a bit in trouble. Then you can test the application with the first address until you feel experienced with it. Later you should change it. In this moment you have to change all your bookmarks etc...

It is not a problem if the server is secured with TLS/SSL. Because the Proxy will de-cencrypt everything this will secure the communication between the server and the proxy. If both are very near (say - they are on the same physical host) or are directly connected through a VPN it may be worthless to encrypt (and cost some performance). But in most cases it can't be a bad idea to have additional encryption also inside your lan.


Nameserver

At first you need the dns name for your proxy server. Either you have a dynamic DNS name (like "bayenshome.dyndns.org") or you have a name (or a fixed IP) from your datacenter provider (my provider generates dns names like "j51376.servers.jiffybox.net"). Now you need a global usable address (inside your own domain) and you need access to the nameserver for this domain so you can set an A record or an CNAME record to this domain.

In my case I go to the nameserver configuration for the "bayen.org" and set a CNAME record that points from "bugtracker.bayen.org" to "j51376.servers.jiffybox.net". That's it!

dynamic DNS

If you want to access your real server in your lan but you don't have internet access with a fixed IP you can use dynamic DNS. See Dynamisches DNS for my notes (in german) about that. In short: You need someone who provides this as a service or you have to set up you own nameserver (and register that for some subdomain).


SSL

Preparing SSL is out of the scope of this article. If you have no experience: I recommend strongly that you first set up an ssl webserver that serves one single test page at http://bugtracker.bayen.org. If you got that you can deal with things like client certificates, proxys and such.

To be short: We need to create an Certificate Authority. There is a certificate file (bayen-ca.crt) that we need. Then we create a key file (bugtracker-bayen-org.key) for our domain (set "bugtracker.bayen.org" as the CN/common name!) and sign this certificate so that we get a signed certificate for our server (bugtracker-bayen-org.crt).

These files have to be copied into these places:

 /etc/ssl/certs/bugtracker-bayen-org.crt
 /etc/ssl/private/bugtracker-bayen-org.key
 /usr/local/share/ca-certificates/bayen-ca.crt
 /var/www/bayen-ca.crt

Then you start the following command to register the new ca in the system. This command read the ca from /usr/local/share/ca-certificates/ and integrates it into the system-wide certificate authority store. After that many well-configured debian packages will automatically accept your signed certificates.

 update-ca-certificates

The last directory is the standard webserver directory. To have the CA file on your webserver allows to just download it with several different browsers and install it inside the browser's CA list. So your browser will not moan any more about self-signed certificates or such.

client certificate

If you are at it you should also create client certificates. This is a normal certificate with your user name as a CN (common name). You also sign it with your CA and the result is a key file and a certificate file. No big deal if you already set up the server certificate.

You have to install the client certificate inside your browser (To be clear: you already installed the CA certificate so this is the second file to install).

Please search the internet for documentation how to get the client certificate into your beloved browser. There are too many brands in too many versions to explain this here. But most browsers need a certificate in the P12 format. You can transform it with this command:

 openssl pkcs12 -export -clcerts -in thomasbayen.crt -inkey tbayen-key.pem -out thomasbayen.P12

I had some trouble installing the certificates (CA and client) on android. I found two ways to do that:

  • I copied the files to a webserver and downloaded them. For the .P12 file I had to create a small page with a link to it. I could only download it with the right filename extension by clicking on the link and choosing "save as". To just enter the url of the file didn't work.
  • In principle it should work to send an email with the files as attachments. It should be possible to save these attachments. I did not try it. (But I saw some articles proposing this way for iOS devices.)


user configuration

You have to create a password file. You can use the htpasswd utility (it can create entries with encrypted passwords). The entries for the client certificates are not created with htpasswd but directly. You use the "Subject" of the certificate as a username and "xxj31ZMTZzkVA" as the password entry.

You can use the following command to get the "Subject" out of the certificate:

 openssl x509 -in thomasbayen.crt -noout -subject

The resulting line in /etc/apache2/passwords is like that:

 /C=DE/ST=NRW/O=BXS GmbH/CN=thomasbayen/emailAddress=tbayen@bayen.de:xxj31ZMTZzkVA


Proxy configuration

I used a cloud server in a datacenter as a proxy. I installed Debian Jessie, then apache and then I created the following file at /etc/apache2/bugtracker_bayen_org:

  <VirtualHost bucktracker.bayen.org:443>
	ServerName bugtracker.bayen.org

	# proxying to another server
	#ProxyPreserveHost On
	ProxyPass 		/	https://bugtracker.internal/
	ProxyPassReverse	/	https://bugtracker.internal/
	# this is needed because I want ssl between proxy and real server
	SSLProxyEngine On

	# SSL between the client and this proxy server
	SSLEngine On
        SSLCertificateFile    /etc/ssl/certs/bugtracker-bayen-org.crt
        SSLCertificateKeyFile /etc/ssl/private/bugtracker-bayen-org.key

	# authentication
	<Location />
	  AuthType		Basic
	  AuthName		"access restricted"
	  AuthBasicProvider	file
	  AuthUserFile		/etc/apache2/passwords
	  Require		valid-user
	  # this may be an alternative to restrict access to only a group of users:
	  #AuthGroupFile	/etc/apache2/groups
	  #Require		group AllUsersGroup

	  # we use client certificates
	  # can be e.g. require or optional
	  SSLVerifyClient optional
	  SSLVerifyDepth 2
	  SSLOptions +FakeBasicAuth
	  # I did not give the CAPath but this CAFile to not let every verisign customer into my system ;-)
	  SSLCACertificateFile /etc/ssl/certs/bayen-ca.crt
	</Location>

	# logging
        ErrorLog ${APACHE_LOG_DIR}/error.log
        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn
        CustomLog ${APACHE_LOG_DIR}/access.log combined

  </VirtualHost>

There are some things you have to think about when configuring this. The above configuration allows both Client Certificate and Basic Authentification. When the browser accesses the page the first time it asks you if you want to use your client certificate (That's what chrome does, I am not sure about other browsers). If you use the certificate everything is ok. If not (or if you don't even have any certificate) it asks you for a username and password.

After giving either the client certificate or the username/password credentials you can see the internal webpage. :-)


more to know

VPN into my home server(s)

You can use ~OpenSSH to create a VPN into your home server but this is out of scope of this article. See OpenSSH for my (german) article about this (including an example script).

Browsers and Client Certificates

Chrome on Android give a strange message with every reboot if you install a CA. This is a bug of android and google says "works as intended". :-(

TODO: My chrome browser asks after every restart of the browser if I want to use the client certificate. I would like to change that.

automatic Authenticate in iDempiere

That's finally the reason for this page... this is still to do!