Securing the Agent with SSL/TLS
- Motivation
- Apache HTTP
- Nginx
- Microsoft IIS
- Managing of SSL certificates for the hosts in local network
- Known Issues
- Useful links
Motivation
Agent has a fully functional built-in HTTP server, however plain HTTP is not secure, it is easy to alter the agent reply, mangling the validation result. This security threat can be mitigated by encrypting connection with SSL/TLS, however this requires proper managing of SSL certificate, which is not supported by the Agent alone. Solution is to delegate SSL/TLS handling to the external HTTP server, forwarding plain HTTP requests to NetLicensing Agent within local secure environment.
Below you will find configuration instructions for some popular HTTP servers, as well as recommendations to managing of SSL certificates.
Apache HTTP
You can find the latest Apache HTTP Server at https://httpd.apache.org/. Below you will find examples for Apache 2.2 and 2.4.
httpd.conf
-
Ensure these modules are loaded:
httpd.conf
# Proxy LoadModule proxy_module lib/httpd/modules/mod_proxy.so LoadModule proxy_http_module lib/httpd/modules/mod_proxy_http.so # SSL/TLS LoadModule ssl_module lib/httpd/modules/mod_ssl.so
-
Enable virtual hosts configuration:
httpd.conf
Include conf/extra/httpd-vhosts.conf
-
Enable SSL configuration:
httpd.conf
Include conf/extra/httpd-ssl.conf
httpd-vhosts.conf
-
Forward insecure connection to secure URL:
conf/extra/httpd-vhosts.conf
<VirtualHost *:80> ServerName "yourhost.com" Redirect permanent / https://yourhost.com/ </VirtualHost>
-
Proxy requests over secure connection to NetLicensing Agent:
conf/extra/httpd-vhosts.conf
<VirtualHost *:443> ServerName "yourhost.com" ProxyRequests Off ProxyVia Off <Proxy *> AddDefaultCharset off ## Apache 2.2 #Order deny,allow #Allow from all ## Apache 2.4 Require all granted </Proxy> ProxyPass / http://localhost:8080/ SSLEngine On #path to you local sectificate SSLCertificateFile /usr/local/etc/httpd/server.crt SSLCertificateKeyFile /usr/local/etc/httpd/server.key </VirtualHost>
-
Replace port
8080
with the actual port Agent is listening on -
Replace
yourhost.com
with the actual host name of your server
Running Agent and Apache
-
Start Agent with ‘
run-agent-offline
’ or ‘run-agent
’ action. Pay attention to the port specified inconf/extra/httpd-vhosts.conf
java -jar netlicensing-agent.jar --action=run-agent-offline --port=8080
-
Start Apache
-
NetLicensing Agent will respond to the validation requests sent over HTTPS to
yourhost.com:443
Nginx
You can find the latest Nginx HTTP Server at https://nginx.org/en/download.html. For this example we are using Nginx 1.13.9.
nginx.conf
-
Forward insecure connection to secure URL:
nginx.conf
server { listen 80; server_name yourhost.com alias yourhost.com.alias; return 301 https://yourhost.com; }
-
Proxy requests over secure connection to NetLicensing Agent:
nginx.conf
# HTTPS server server { listen 443 ssl; server_name yourhost.com alias yourhost.com.alias; #path to you local sectificate ssl_certificate /usr/local/etc/httpd/server.crt; ssl_certificate_key /usr/local/etc/httpd/server.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { proxy_pass http://localhost:8080; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; } }
-
Replace port
8080
with the actual port Agent is listening on -
Replace
yourhost.com
with the actual host name of your server
Running Agent and Nginx ———————–
-
Start Agent with
'run-agent-offline'
or'run-agent'
action. Pay attention to the port specified innginx.conf
java -jar netlicensing-agent.jar --action=run-agent-offline --port=8080
-
Start Nginx
-
NetLicensing Agent will respond to the validation requests sent over HTTPS to
yourhost.com:443
Microsoft IIS
You can find the latest Internet Information Services(IIS) at https://www.iis.net/downloads. For this example we are using IIS 7.
-
Forward insecure connection to secure URL:
C:\inetpub\wwwroot\<your site folder>\web.config
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <rewrite> <rules> <clear /> <rule name="Forward to https" stopProcessing="true"> <match url="(.*)" /> <conditions logicalGrouping="MatchAll" trackAllCaptures="false"> <add input="{HTTPS}" pattern="^OFF$" /> </conditions> <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" /> </rule> </rules> </rewrite> </system.webServer> </configuration>
-
Proxy the requests over the secure connection to NetLicensing Agent:</span>
C:\inetpub\wwwroot\<your site folder>\web.config
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <rewrite> <rules> <clear /> <rule name="ReverseProxyInboundRule1" stopProcessing="true"> <match url="(.*)" /> <conditions logicalGrouping="MatchAll" trackAllCaptures="false" /> <action type="Rewrite" url="http://localhost:8080/{R:1}" /> </rule> </rules> </rewrite> </system.webServer> </configuration>
-
Replace port
8080
with the actual port Agent is listening on
Running Agent and IIS
-
Start Agent with ‘
run-agent-offline
’ or ‘run-agent
’ action. Pay attention to the port specified in C:\inetpub\wwwroot\<your site folder>\web.configjava -jar netlicensing-agent.jar --action=run-agent-offline --port=8080
-
Start Site from IIS Manager
-
NetLicensing Agent will respond to the validation requests sent over HTTPS to
yourhost.com:443
Managing of SSL certificates for the hosts in local network
Certificates signed by a Certificate Authority (CA)
In case you have a public or private Certificate Authority (CA) infrastructure available within your network, the preferable way is to let CA issue the SSL certificate. Details are not in scope of this document, but should be normally available from the corresponding CA.
This external resource maybe helpful: https://roll.urown.net/ca/index.html
Self-signed certificates
For creating self-signed certificate you can use openssl tool or a number of other methods.
Here are some useful links:
- How to create a self-signed certificate with openssl
- Keychain for Mac: Create self-signed certificates using Keychain Access
- Windows: How to: Create Your Own Test Certificate
Self-signed certificate must be explicitly trusted by a client side via appropriate installation, it can not be automatically validated against a known certificate authority. Certificate installation procedure depends on the environment your client is running on, below you can find some hints:
Java uses its own keystore for certificates (separate from the OS keystore). Therefore, you must install the appropriate certificate in Java’s keystore.
Mac OS X
$ cd $JAVA_HOME/bin
$ sudo keytool -import -trustcacerts -keystore <path-to-keystore> -storepass changeit -noprompt -alias <alias-name> -file <path-to-certificate>
Windows
> cd %JAVA_HOME%\bin
> keytool.exe -import -trustcacerts -keystore "<path-to-keystore>" -storepass changeit -noprompt -alias <alias-name> -file "<path-to-certificate>"
Linux
$ sudo $JAVA_HOME/bin/keytool -import -trustcacerts -keystore <path-to-keystore> -storepass changeit -noprompt -alias <alias-name> -file <path-to-certificate>
Where:
- <alias-name> - some descriptive name of your choice that will identify your key in keystore
- <path-to-certificate> - path to the self-signed certificate
- <path-to-keystore> - depends on the operating system and java installation path, here are some standard locations:
- Mac OS X: $JAVA_HOME/lib/security/cacerts
- Windows: %JAVA_HOME%\lib\security\cacerts
- Linux: $JAVA_HOME/lib/security/cacerts
C# uses OS keystore, add the self-signed certificate to the Local Computer Trusted Root Certification Authorities
Mac OS X
$ sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain <path-to-certificate>
Windows
> certutil -addstore -f "ROOT" <path-to-certificate>
Linux (Ubuntu, Debian)
$ sudo cp <path-to-certificate> /usr/local/share/ca-certificates/
$ sudo update-ca-certificates
Specify path to self-signed certificate:
PHP
curl_setopt($ch, CURLOPT_CAINFO, <path-to-certificate>);
- Download the certificate bundle.
- Add your certificate to the dowloaded file.
- Set up curl.cainfo and openssl.cafile in
php.ini
files:
` curl.cainfo=”" ` ` openssl.cafile=" "` - Restart httpd server.
-
Verify the correct certificate bundle is used by calling:
PHP
openssl_get_cert_locations();
Specify path to self-signed certificate:
Node.js
const axios = require('axios');
const fs = require('fs');
const https = require('https');
const netLicensing = require('netlicensing-client');
const instance = axios.create({
httpsAgent: new https.Agent({
ca: fs.readFileSync('<path-to-certificate>')
})
});
netLicensing.Service.setAxiosInstance(instance);
Add Security Exception for specified host of NetLicensing Agent server.
In browser host environments, origin security policy may apply in addition, see “Known Issues” below.
Known Issues
-
CORS problem: If your client is using JavaScript library, JS engine may block requests to NetLicensing Agent server for security reasons (more info: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). To fix this problem, your NetLicensing Agent server must provide appropriate HTTP CORS headers. Below are setting examples for Apache and Nginx:
conf/extra/httpd-vhosts.conf
<VirtualHost *:443> ServerName "yourhost.com" ProxyRequests Off ProxyVia Off <Proxy *> AddDefaultCharset off #Apache 2.2 Order deny,allow Allow from all #Apache 2.4 #Require all denied </Proxy> ProxyPass / http://localhost:8080/ SSLEngine On #path to you local sectificate SSLCertificateFile /usr/local/etc/httpd/server.crt SSLCertificateKeyFile /usr/local/etc/httpd/server.key #CORS Headers Header always set Access-Control-Allow-Origin "*" Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" Header always set Access-Control-Allow-Headers "Content-Type, Accept, Authorization, NetLicensing-Origin" Header always set Access-Control-Max-Age: "3600" RewriteEngine On RewriteCond %{REQUEST_METHOD} OPTIONS RewriteRule ^(.*)$ $1 [R=200,L] </VirtualHost>
nginx.conf
# HTTPS server server { listen 443 ssl; server_name yourhost.com alias yourhost.com.alias; #path to you local sectificate ssl_certificate /usr/local/etc/httpd/server.crt; ssl_certificate_key /usr/local/etc/httpd/server.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; #CORS Headers add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"; add_header Access-Control-Allow-Headers "Content-Type, Accept, Authorization, NetLicensing-Origin"; add_header Access-Control-Max-Age: "3600"; location / { proxy_pass http://localhost:8080; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; } }
-
If you get a warning about the contents of a self-signed certificate, make sure you have specified CN (The Common Name) when creating the certificate.
-
Windows servers (IIS) use .pfx files to contain the public key files and the associated private key file. There are openssl examples how to convert certificate to .pfx format bellow.
nginx.conf
#PEM (.pem, .crt, .cer) to PFX openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt #PKCS#7/P7B (.p7b, .p7c) to PFX openssl pkcs7 -print_certs -in certificate.p7b -out certificate.crt
Useful links
- https://wiki.eclipse.org/Jetty/Tutorial/Apache
- https://wiki.eclipse.org/Jetty/Howto/Configure_mod_proxy#Proxying_SSL_on_Apache_to_HTTP_on_Jetty
- https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html
- https://nginx.org/en/docs/
- https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
- https://www.namecheap.com/support/knowledgebase/article.aspx/9953/38/iis-redirect-http-to-https
- https://developers.coveo.com/display/public/SearchREST/Configuring+HTTPS+Reverse+Proxy+in+IIS
- https://www.ssl.com/how-to/create-a-pfx-p12-certificate-file-using-openssl/