Setting up a SOAP Server to use SSL

There are several ways to encrypt the requests to, and the repsonses from, a KCML SOAP server.


Direct SSL support using Apache mod_ssl.so

This is the simplest method of encrypting a SOAP server where Apache, running on the same host as the SOAP server, encrypts all the traffic between the SOAP client & server. Many Linux distributions, such as CentOS & Fedora, provide a mod_ssl package that installs mod_ssl.so and configures Apache, however it may not have been installed by default.
For example, Apache is running and has been configured to serve a SOAP via a /myApp/TestSoap location, but mod_ssl.so has not been installed yet

First try plain text:-

$ wget http://localhost/myApp/TestSoap?WSDL
Resolving localhost... ::1, 127.0.0.1
Connecting to localhost|::1|:16593... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1003 [text/html]

Plain text worked, now try https:-

$ wget https://localhost/myApp/TestSoap?WSDL
Resolving localhost... ::1, 127.0.0.1
Connecting to localhost|::1|:443... failed: Connection refused.
Connecting to localhost|127.0.0.1|:443... failed: Connection refused.

The connection has been refused because Apache is not listening on port 443 for https. Now install mod_ssl and restart Apache.

$ su -
Password: ********
# yum install -y mod_ssl
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package mod_ssl.x86_64 1:2.2.15-60.el6.centos.6 will be installed
Dependencies Resolved
===============================================================================
 Package         Arch            Version                     Repository   Size
===============================================================================
 Installing:
  mod_ssl        x86_64          1:2.2.15-60.el6.centos.6    updates      99 k
Transaction Summary
===============================================================================
Install       1 Package(s)
Downloading Packages
(1/1): mod_ssl-2.2.15-60.el6.centos.6.x86_64.rpm               |  99 kB   00:00 
Running Transaction
  Installing : 1:mod_ssl-2.2.15-60.el6.centos.6.x86_64                      1/1
Installed:
  mod_ssl.x86_64 1:2.2.15-60.el6.centos.6  
Complete!
# service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]
# exit
$

Now retry the request using https:

$ wget https://localhost/myApp/TestSoap?WSDL
Connecting to localhost|127.0.0.1|:443... connected.
ERROR: cannot verify localhost's certificate, 
  Self-signed certificate encountered.
      To connect to localhost insecurely, use '--no-check-certificate'

Here you can see we have now connected to the encrypted https: port, but the self-signed certifcate that was installed by the mod_ssl package has failed verification by wget. However, for testing purposes we will use the --no-check-certificate option to see that are now able to retrieve the SOAP server's WSDL using an encrypted connection:-

$ wget --no-check-certificate https://localhost/myApp/TestSoap?WSDL
Resolving localhost... ::1, 127.0.0.1
Connecting to localhost|::1|:16596... connected.
WARNING: cannot verify localhost's certificate
  Self-signed certificate encountered.
HTTP request sent, awaiting response... 200 OK
Length: 1004 [text/html]

This configuration is often sufficient for internal development and testing purposes, where servers will not be exposed to external requests from unknown clients however for customer systems this configuration should only be used if access to the server is only available through a VPN.

If a SOAP server is to handle requests from external, and potentially unknown, sources then an SSL Terminator is recommended as the application server running SOAP can be hidden behind a firewall so that it not directly accessible.


SSL Termination Proxy

In this configuration an intermediary proxy server, known as an SSL Termination Proxy, handles the encrypted requests from the SOAP client. It decrypts the request into plain text and then forwards the request on to the SOAP server which is running on a different machine. The plain text response from the SOAP server is then sent back to the proxy and encrypted before it is sent back to the SOAP client.

This configuration is more desireable than the direct mod_ssl configuration above as the proxy server the client connects to has very little, if any, sensitive information on it. The proxy server is usually configured with a minimal set of services running and the only route, from external sources, to it is via https port 443. The application server, which may well be storing sensitive data, is protected behind a firewall and there is no direct route from the client to it as the firewall only allows plain-text http, typically on port 80, from the proxy to the application server.

To preserve information about the original request, that was sent by the client, proxies can add extra HTTP headers to the request before forwarding the request to the next destination.

HTTP headerDescriptionCommentExample
X-Forwarded-HostOriginal host name used in the client's request.Extension header that is commonly supported by most HTTP servers and clients.X-Forwarded-Host: my.public.soap.server.com
X-Forwarded-ProtoOriginal transport protocol used by the clientExtension header that is commonly supported by most HTTP servers and clients.X-Forwarded-Proto: https
ForwardedRFC 7239 standard header that combines the X-Forward- family of headers.Not widely supported yet, can be emulated in nginx 1.12 or laterForwarded: host=my.public.soap.server.com; proto=https

KCML 7.18 & 6.20 from build 24090 will use these HTTP headers to ensure the location endpoint in a SOAP server's WSDL is correct.


Apache SSL Termination Proxy

The configuration of an Apache SSL Termination Proxy requires the use of mod_ssl, like the Direct SSL support, and mod_proxy. However the Apache SSL Termination instance does not, and should not, require mod_wcm.so.
A minimal example to redirect all URLs to the machine running the KCML SOAP server:-

	# Forward all requests on port 443 (https) to my.private.soap.server.com after decrypting.
	# my.private.soap.server.com is not visible (nor resolveable) to the outside world.
	# Eg SOAP-client -> https://my.public.soap.server.com -> http://my.private.soap.server.com
	Listen 443
	<VirtualHost *:443>
		ProxyPreserveHost On
		SSLEngine On
		SSLCertificateFile /path/to/ssl.cert
		SSLCertificateKeyFile /path/to/ssl.key
		# Disable insecure SSLv2, SSLv3 and TLSv1.0 protocols
		SSLProtocol all -SSLv2 -SSLv3 -TLSv1
		SSLProxyProtocol all -SSLv2 -SSLv3 -TLSv1
		<Location / >
			SSLRequireSSL
		</Location >
		ProxyPass / http://my.private.soap.server.com/
		ProxyPassReverse / http://my.private.soap.server.com/
		# Add X-Forwarded-Proto header so that the SOAP server knows the original request came via https
		RequestHeader	set	X-Forwarded-Proto	https
	</VirtualHost>

Note: some of mod_ssl's configuration, such as session cache, random seed & allowed ciphers have been omitted for clarity.

Apache adds the X-Forwarded-Host header by default, but it does need to be configured to add the X-Forwarded-Proto header. It does not support, yet, the Forwarded header.

The SSL certificate should be issued by a recognized certificate authority and match the proxy's DNS name so as to avoid verification failure by a SOAP client. SSL protocols that are known to be vulnerable, such as SSLv2, SSLv3 and TLSv1.0 should be disabled as well using the SSLProtocol & SSLProxyProtocol directives.
See Apache mod_ssl: SSL Protocols


Nginx SSL Termination Proxy

Nginx can also act as an SSL Termination, which then proxies the request on to the SOAP server. Nginx can be configured to support the X-Forwarded-Proto & X-Forwarded-Host headers.
The following location fragment performs a similar role to the Apache SSL Termination Proxy fragment above:-

	# Forward all requests to port 443 (https) to my.private.soap.server.com after decrypting.
	# my.private.soap.server.com is not visible (nor resolveable) to the outside world.
	# Eg SOAP-client -> https://my.public.soap.server.com -> http://my.private.soap.server.com
	location / {
		proxy_set_header	Host			\$host:\$server_port;
		proxy_set_header	X-Real-IP		\$remote_addr;
		proxy_set_header	X-Forwarded-For		\$proxy_add_x_forwarded_for;
		proxy_set_header	X-Forwarded-Proto	\$scheme;
		proxy_set_header	X-Forwarded-Host	\$host:\$server_port;
		proxy_pass		http://my.private.soap.server.com/;
	}

Although Nginx has no built-in support for the RFC 7239 compliant Forwarded header it can be partially emulated in Nginx 1.12 or later. After including the $proxy_fowraded_elem & $proxy_add_forwared examples from NGINX: Using the Forwarded header into your Nginx configuration, you can use those to emulate the Forwarded header in the location block.

	# Forward all requests to port 443 (https) to my.private.soap.server.com after decrypting.
	# my.private.soap.server.com is not visible (nor resolveable) to the outside world.
	# Eg SOAP-client -> https://my.public.soap.server.com -> http://my.private.soap.server.com
	location / {
		proxy_set_header	Host			\$host:\$server_port;
		proxy_set_header	X-Real-IP		\$remote_addr;
		proxy_set_header	X-Forwarded-For		\$proxy_add_x_forwarded_for;
		proxy_set_header	X-Forwarded-Proto	\$scheme;
		proxy_set_header	X-Forwarded-Host	\$host:\$server_port;
		# Add RFC 7239 Forwarded header
		proxy_set_header	Forwarded		"\$proxy_add_forwarded;proto=\$scheme;host=\$host:\$server_port";
		proxy_pass		http://my.private.soap.server.com/;
	}

When Nginx has been configured to issue a Forwarded header then mod_wcm.so that is used on the SOAP server must be version 07.18 build 24094 or later.