In this part, we are going to configure and personalize EJBCA, and use Apache2 as front for EJBCA to work.
Table of content
Fully Qualified Domain Names for your EJBCA instance
You’ll need to have some FQDN for your EJBCA instance.
%fqdn% will represent your EJBCA FQDN. For example, my personal EJBCA FQDN is pki.fladnag.net
%ocsp-fqdn% will represent your OCSP responder’s FQDN. It will be easier to have a short and clear FQDN to access OCSP responder. For example, my EJBCA OCSP responder as the FQDN ocsp.fladnag.net
Apache and Let’s Encrypt certificate for public web and enrollment
Now, we would like a few things.
- Listen to standard HTTP/HTTPS ports,
- Use Apache 2 as front web server proxying Wildfly,
- Automagically redirect all HTTP requests to HTTPS,
- Use a valid and autorenewed Let’s Encrypt certificate for public web pages.
Get Management Certificate Authority Root Certificate
We will need to get the Management CA Root Certificate to configure Apache 2 for TLS Client Authentication. Please go with your browser to https://%fqdn%:8442/ejbca/retrieve/ca_certs.jsp and copy the link of ‘CA certificate: Download as PEM’. On your EJBCA instance, start the command:
# wget --no-check-certificate -O /home/%user%/ejbca-custom/managementca.pem "%pasteURLhere%"
Don’t forget quotes around the URL 😉
Installing Apache 2
Let’s start by installing Apache2 to your server:
# apt install apache2
We’re going to need few Apache2 mods to be active for our configuration to work.
# a2enmod proxy proxy_http proxy_ajp proxy_balancer lbmethod_byrequests ssl rewrite
Let’s put ‘Hello!’ index page.
# echo 'Hello!' > /var/www/index.html
Let’s also disable and remove all default sites configurations.
# a2dissite 000-default default-ssl
# rm /etc/apache2/sites-available/*
# service apache2 restart
Don’t forget to configure /etc/apache2/conf-available/security.conf to secure your Apache 2 instance…
Let’s Encrypt – Getting a certificate for the first time
To get the certificate the first time, we’ll to a small trick with a temporary Apache 2 configuration file.
Let’s create a temporary site configuration file /etc/apache2/sites-available/certbot-temp.conf, mostly for certbot to validate our domain and get certificate. We will then discard it to the real configuration we’re going to use for EJBCA.
<VirtualHost *:80> ServerName %fqdn% ServerAlias %ocsp-fqdn% DocumentRoot /var/www/ LogLevel warn ErrorLog /var/log/apache2/error.log CustomLog /var/log/apache2/access.log combined </VirtualHost>
Now we can enable this configuration and restart Apache 2.
# a2ensite certbot-temp
# service apache2 restart
Afterwars, to install CertBot, we need to enable backports:
# echo 'deb http://deb.debian.org/debian stretch-backports main contrib' > /etc/apt/sources.list.d/backports.list
# apt update
And install CertBot:
# apt install python-certbot-apache -t stretch-backports
We can now run certbot to request the certificate:
# certbot --authenticator webroot --installer apache
Your website should be online, with HTTPS on your FQDN and display ‘Hello!’ 🙂
Apache 2 EJBCA configuration
First, lets copy for later the certificate and key paths on Let’s Encrypt HTTPS configuration, then destroy it.
Open /etc/apache2/sites-available/certbot-temp-le-ssl.conf and saves the lines SSLCertificateFile and SSLCertificateKeyFile, we will need them later.
Let’s now disable and destory our temp configuration:
# a2dissite certbot-temp certbot-temp-le-ssl
# rm /etc/apache2/sites-available/*
# service apache2 restart
The first configuration file we’ll create will be the HTTP (cleartext) part. It will:
- Automagically redirect HTTP to HTTPS,
- Except for OCSP responder (not supported it seems)
- Allow Let’s Encrypt CertBot to use the part of the webroot it needs to automagically renew certificate.
So let’s create /etc/apache2/sites-available/http.conf
<VirtualHost *:80> ServerName %fqdn% DocumentRoot /var/www/ Alias /.well-known/acme-challenge /var/www/.well-known/acme-challenge <Directory /var/www/.well-known/acme-challenge> Options None AllowOverride None Order allow,deny Allow from all </Directory> <Proxy balancer://mycluster-kerb> BalancerMember ajp://localhost:8009/ejbca/ </Proxy> ProxyPreserveHost On ProxyRequests Off Order deny,allow Allow from all ProxyPass /.well-known/acme-challenge ! ProxyPass / balancer://mycluster-kerb/ RewriteEngine On RewriteCond %{THE_REQUEST} !(/publicweb/webdist/certdist.*cmd=crl|/publicweb/status/) RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R] # Treat reqeusts to / and /ejbca/ as the same. Required by EJBCA's Admin Web. RewriteCond %{THE_REQUEST} /ejbca/ RewriteRule ^/ejbca/(.*)$ /$1 [PT] # Configure log LogLevel warn ErrorLog /var/log/apache2/http-error.log CustomLog /var/log/apache2/http-access.log combined </VirtualHost>
Now, let’s work on /etc/apache2/sites-available/https.conf
<VirtualHost *:443> ServerName %fqdn% DocumentRoot /var/www/ Alias /.well-known/acme-challenge /var/www/.well-known/acme-challenge <Directory /var/www/.well-known/acme-challenge> Options None AllowOverride None Order allow,deny Allow from all </Directory> RewriteEngine On RewriteCond %{THE_REQUEST} /ejbca/ RewriteRule ^/ejbca/(.*)$ /$1 [PT] # Configure secure SSL for this server using SSL certificate generated by EJBCA SSLEngine on Include /etc/letsencrypt/options-ssl-apache.conf # Replace %user% below with your EJBCA user. This is what we downloaded before... SSLCACertificateFile /home/%user%/ejbca-custom/managementca.pem # Paste here SSLCertificateFile and SSLCertificateKeyFile lines from before... # Require Client SSL certificate for the Admin GUI <Location /adminweb> SSLVerifyClient require SSLVerifyDepth 1 </Location> <Location /ra> SSLVerifyClient require SSLVerifyDepth 1 </Location> # Proxy requests to EJBCA instances (only one on local machine configured) <Proxy balancer://mycluster-kerb1> BalancerMember ajp://localhost:8009/ejbca/ </Proxy> ProxyPass / balancer://mycluster-kerb1/ LogLevel warn ErrorLog /var/log/apache2/https-error.log CustomLog /var/log/apache2/https-access.log combined </VirtualHost>
Next, let’s create OSCP HTTP configuration file at /etc/apache2/sites-available/ocsp.conf.
<VirtualHost *:80> ServerName %ocsp-fqdn% DocumentRoot /var/www/ Alias /.well-known/acme-challenge /var/www/.well-known/acme-challenge <Directory /var/www/.well-known/acme-challenge> Options None AllowOverride None Order allow,deny Allow from all </Directory> <Proxy *> Order deny,allow Allow from all </Proxy> ProxyPreserveHost On ProxyRequests Off Order deny,allow Allow from all ProxyPass /.well-known/acme-challenge ! ProxyPass / http://127.0.0.1:8080/ejbca/publicweb/status/ocsp ProxyPassReverse / http://127.0.0.1:8080/ejbca/publicweb/status/ocsp # Configure log LogLevel warn ErrorLog /var/log/apache2/ocsp-error.log CustomLog /var/log/apache2/ocsp-access.log combined </VirtualHost>
Let’s now activate both sites configuration and restart Apache 2:
# a2ensite http https ocsp
# service apache2 restart
You can now navigate to https://%fqdn% and see that your public web pages are served via HTTPS, using Let’s Encrypt certificate!
Customizing EJBCA
You may need at some point to customize EJBCA for it to fit your needs. It’s quite easy, but they are few things to do.
Let’s say we want to fine tune EJBCA core settings, such as mail sending, etc. First, we are going to copy the conf folder from ejbca to ejbca-custom with
$ cp -r ~/ejbca/conf ~/ejbca-custom/
If you want to modify a file, check if a %filename%.properties exist, then edit it. If only a %filename%.properties.sample exists, rename it to %filename%.properties
In web.properties, you can do the following changes, it will allow only localhost connections and disable links to the documentation in the public web as it is not required 😉
[...] httpsserver.bindaddress.pubhttp=127.0.0.1 httpsserver.bindaddress.pubhttps=127.0.0.1 httpsserver.bindaddress.privhttps=127.0.0.1 [...] web.docbaseuri=disabled [...]
Now let’s edit ocsp.properties
[...] ocsp.untilNextUpdate = 600 [...] ocsp.maxAge = 600 [...]
At last, configure mail sending service using mail.properties. Change the settings according to your mail service.
For mails, you’ll also need to run some dirty JBoss command lines to get it to work:
$ ./wildfly/bin/jboss-cli.sh -c '/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=ejbca-mail-smtp:add(port="%smtp-port%", host="%mailserver-fqdn%")'
$ ./wildfly/bin/jboss-cli.sh -c '/subsystem=mail/mail-session="java:/EjbcaMail":add(jndi-name=java:/EjbcaMail, from=%from-mail%)'
$ ./wildfly/bin/jboss-cli.sh -c '/subsystem=mail/mail-session="java:/EjbcaMail"/server=smtp:add(outbound-socket-binding-ref=ejbca-mail-smtp, tls=%true or false%, username=%smtp-username%, password=%smtp-password%)'
$ ./wildfly/bin/jboss-cli.sh -c ':reload'
Also, we would like to change the ‘Administration’ link on public web pages to the real URL. Then, will need to dig a bit into JSP pages. Let’s first create directory structure:
$ mkdir -p ~/ejbca-custom/modules/publicweb-gui/resources/{enrol,inspect,retrieve}
And copy the files to respected folders:
$ cp ~/ejbca/modules/publicweb-gui/resources/header.jsp ~/ejbca-custom/modules/publicweb-gui/resources/header.jsp
$ cp ~/ejbca/modules/publicweb-gui/resources/enrol/header.jsp ~/ejbca-custom/modules/publicweb-gui/resources/enrol/header.jsp
$ cp ~/ejbca/modules/publicweb-gui/resources/inspect/header.jsp ~/ejbca-custom/modules/publicweb-gui/resources/inspect/header.jsp
$ cp ~/ejbca/modules/publicweb-gui/resources/retrieve/header.jsp ~/ejbca-custom/modules/publicweb-gui/resources/retrieve/header.jsp
Don’t forget to create copies, just in case you break something. Now, on each header.jsp file, replace
<% java.net.URL adminURL = new java.net.URL("https",org.ejbca.util.HTMLTools.htmlescape(request.getServerName()), org.ejbca.config.WebConfiguration.getExternalPrivateHttpsPort(), "/"+org.ejbca.config.InternalConfiguration.getAppNameLower()+"/adminweb/"); %> <a href="<%=adminURL.toString() %>">Administration</a>
by
<a href="https://%fqdn%/adminweb">Administration</a>
Once ready to update your EJBCA instance, run
$ cd ~/ejbca; ant clean deployear
ant
will recompile many things, deploy to Wildfly and then you’ll be good to go. The deployment can make your instance to be unavailable few seconds, displaying a 404 error. if it persists, you’ve done something very wrong, and prepare to roll back.
ant
command. Many are gonna break your instance.Trust me, i broke more than 20.
EJBCA systemd unit
The command line we’ve used before to start, stop and reload EJBCA are not very sexy, and we should create a systemd service unit for EJBCA.
Create a new file at /etc/systemd/system/ejbca.service containing:
[Unit] Description=EJBCA Server Daemon After=network-online.target [Service] Type=simple User=worker Group=worker UMask=007 WorkingDirectory=/home/%user% ExecStart=/home/%user%/wildfly/bin/standalone.sh -b 0.0.0.0 ExecReload=/home/%user%/wildfly/bin/jboss-cli.sh --connect :reload ExecStop=/home/%user%/wildfly/bin/jboss-cli.sh --connect :shutdown Restart=on-failure TimeoutStopSec=300 [Install] WantedBy=multi-user.target
Now, if EJBCA is running, we must stop it using the old command seen in Part 2.
$ cd ~ && ./wildfly/bin/jboss-cli.sh --connect :shutdown
Then activate the systemd service:
# systemctl daemon-reload
# systemctl enable ejbca.service
# systemctl start ejbca.service
After few seconds, EJBCA should be back online 🙂 You can now use
# systemctl start/stop/restart/reload ejbca.service
Leave a Reply