Sunday, November 21. 2021
Configuring nginx as reverse proxy for wildfly
Another quick entry this time about nginx and wildfly. Some days ago I needed to configure a nginx web server as a reverse proxy for wildfly, but with the special requirement to be the TLS terminator. So the nginx is the one that offers the https and behind it the wildfly application server works in plain http. Today's entry is going to show that setup and, in order to do the demo complete, the application server will be configured to understand all the information from the reverse proxy, client certificate and SSL data included. I personally do not use nginx a lot so I prefer to have this recorded in the blog.
There is a lot of information about this web server and how to configure it in SSL and/or as a reverse proxy. In this case this useful entry was used as my starting point.
A debian 11.1 was installed and the nginx server is just added via its distribution package.
apt-get install nginx
As https is a requirement, some certificates are needed, one will be for the nginx server (debian11 files) and one for the client (client1 files). For this point remember that I always follow this old entry with minor modifications. In the file /etc/nginx/sites-enabled/default the certificate and key files are added to the configuration.
listen 443 ssl default_server; listen [::]:443 ssl default_server; ssl_certificate /etc/ssl/debian11.chain.pem; ssl_certificate_key /etc/ssl/private/debian11.key; ssl_client_certificate /etc/ssl/cacert.pem; ssl_verify_client optional;
Note that file debian11.chain.pem contains the full chain with the final server and the CA certificates (cat debian11.pem cacert.pem > debian11.chain.pem). The setup asks for a client certificate but it is optional.
Time to configure the nginx as a reverse proxy. For this part it is important to add all the headers that wildfly is going to manage to know that is behind another server. The final configuration for the root location is the following.
location / { proxy_pass http://192.168.100.1:8080; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header SSL_CIPHER $ssl_cipher; proxy_set_header SSL_SESSION_ID $ssl_session_id; proxy_set_header SSL_CLIENT_CERT $ssl_client_cert; }
The server is configured to proxy everything to the backend server (http://192.168.100.1:8080) and several headers are setup to pass the needed X_Forwarded and SSL information. The wildfly project is mainly developed having apache in mind, therefore the headers are mimicking those used by the apache web server. Note the SSL_CLIENT_CERT header includes the deprecated ssl_client_cert variable (instead of the recommended ssl_client_escaped_cert) because wildfly understands that format (which is also the apache format). You have more information about the nginx SSL configuration in the project documentation.
At this point the configuration is checked and the service restarted.
nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful systemctl restart nginx
In the wildfly side the configuration is easier. Just download the current 25.0.1 zip file and add an admin user.
wget https://github.com/wildfly/wildfly/releases/download/25.0.1.Final/wildfly-25.0.1.Final.zip unzip wildfly-25.0.1.Final.zip cd wildfly-25.0.1.Final/bin ./add-user.sh -u admin -p admin ./standalone.sh
The following CLI commands configure the application sever to be behind a reverse proxy (it will use headers to obtain final addresses and certificates).
./jboss-cli.sh --connect /subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=certificate-forwarding, value=true) /subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding, value=true) reload
For testing a simple index.jsp is added as an application. The file displays some interesting information from the JavaEE request.
jar cvf info.war index.jsp ${JBOSS_HOME}/bin/jboss-cli.sh --connect -c "deploy --force info.war"
- And that is all. Send a request with the client certificate and check the information retrieved by wildfly (client certificate included) is displayed correctly by the JSP file.
The client certificate was also imported in my firefox and the following video shows that the wildfly server is setup in plain http. But when accessing the debian virtual machine the certificate is requested. Note that all the information is now correct (protocol, server name, remote host, client certificate,...) because it was retrieved from the headers.
curl -v --cacert cacert.pem --cert client1.pem --key private/client1.key https://debian11.demo.kvm/info/index.jsp
Today's entry is a quick setup to use a nginx server as a reverse proxy and TLS terminator for wildfly. Theoretically the wildfly application server is thought to be used with apache and mod-cluster, but any other web server can usually be configured to mimic the same behavior. The important point is using the proper headers to feed the server with the expected values (X-Forwarded and SSL headers).
Proxied regards!
Comments