I think your set up is like mine. I’ll post here the entire set up. I use AJP and JK with Apache to hand off CF requests to Tomcat.
The part you may be interested in especially is the file /etc/apache2/my-apache-cf-rewrite.conf which I use to pass off URL rewrites to CF. That allows me to have friendly URL’s.
This is a guide that you can follow and only have to do once. After that, you can upgrade any piece of the stack you want without breaking it. So, you can upgrade Apache and not worry about anything else unless Apache has made some groundbreaking, earth shattering change. You can upgrade Tomcat or OpenJDK or Lucee independent of anything else as well.
THE “STACK”
Ubuntu 20.04.02 LTS - everything is up to date
Apache 2.4.41
MySQL 8.0.23
Open SSL 1.1.1f
Tomcat 9.0.41
Open JDK 16
Lucee 5.3.7.47
PHP 7.4.3
I don’t use any package manager or anything - though I probably should because all the cool kids do. I just like to know how to work each piece of the stack and also, I can change or upgrade OpenJDK versions in just a few seconds which is nice to be able to do to stay up to date with Java.
I have several Cold Fusion sites as well as several Word Press sites. I try to keep everything as “stock” as possible so that upgrades are timely and easy. I don’t like to break things.
STARTING WITH APACHE
Apache modules enabled:
core_module (static)
so_module (static)
watchdog_module (static)
http_module (static)
log_config_module (static)
logio_module (static)
version_module (static)
unixd_module (static)
access_compat_module (shared)
alias_module (shared)
auth_basic_module (shared)
authn_core_module (shared)
authn_file_module (shared)
authz_core_module (shared)
authz_host_module (shared)
authz_user_module (shared)
autoindex_module (shared)
deflate_module (shared)
dir_module (shared)
env_module (shared)
expires_module (shared)
filter_module (shared)
headers_module (shared)
jk_module (shared)
mime_module (shared)
mpm_event_module (shared)
negotiation_module (shared)
proxy_module (shared)
proxy_ajp_module (shared)
proxy_connect_module (shared)
proxy_fcgi_module (shared)
proxy_html_module (shared)
proxy_http_module (shared)
reqtimeout_module (shared)
rewrite_module (shared)
setenvif_module (shared)
socache_shmcb_module (shared)
ssl_module (shared)
unique_id_module (shared)
xml2enc_module (shared)
In /etc/apache2/apache2.conf - mostly stock, the things you might want to check are:
# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
Options +FollowSymLinks +Includes -Indexes
AllowOverride None
Require all denied
</Directory>
<Directory /usr/share>
AllowOverride None
Require all denied
</Directory>
# set root of web directory here
<Directory /path/to/your/websites/>
Options +FollowSymLinks +Includes -Indexes
AllowOverride None
Require all granted
</Directory>
#<Directory /srv/>
# Options Indexes FollowSymLinks
# AllowOverride None
# Require all granted
#</Directory>
Once Apache is up and running, no problems, let’s create 3 custom includes for Apache 2 that I use in virtual host conf files:
/etc/apache2/my-apache-cf-ajp.conf
# Start: Tomcat for Lucee configuration with proxy+ajp13:
#
# added [ProxyRequests Off] seems to have no effect, left it here because why not
#
ProxyRequests Off
#
#
#
ProxyPreserveHost On
#
#
# Skip over these directories
#
ProxyPass /images !
ProxyPass /lib !
ProxyPass /ANY-DIRECTORY-YOU-MAY-WANT-CF-NOT-TO-PROCESS !
#
# Skip over these fles types
#
ProxyPass ^/(.+\.js)$ !
ProxyPass ^/(.+\.html)$ !
ProxyPass ^/(.+\.htm)$ !
ProxyPass ^/(.+\.php)$ !
ProxyPass ^/(.+\.gif)$ !
ProxyPass ^/(.+\.gz)$ !
ProxyPass ^/(.+\.ico)$ !
ProxyPass ^/(.+\.jpg)$ !
ProxyPass ^/(.+\.jpeg)$ !
ProxyPass ^/(.+\.mov)$ !
ProxyPass ^/(.+\.png)$ !
ProxyPass ^/(.+\.tar)$ !
ProxyPass ^/(.+\.tif)$ !
ProxyPass ^/(.+\.tiff)$ !
ProxyPass ^/(.+\.pdf)$ !
ProxyPass ^/(.+\.txt)$ !
ProxyPass ^/(.+\.xml)$ !
ProxyPass ^/(.+\.zip)$ !
#
# Main directives
#
ProxyPassMatch ^/(.+\.cf[cm])(/.*)?$ ajp://127.0.0.1:8009/$1$2
ProxyPassMatch ^/(.+\.cfchart)(/.*)?$ ajp://127.0.0.1:8009/$1$2
ProxyPassMatch ^/(.+\.cfml)(/.*)?$ ajp://127.0.0.1:8009/$1$2
#
# ProxyPassReverse does not matter in our case
#
ProxyPassReverse / ajp://127.0.0.1:8009/
#
#
#
# Alternate, minimum settings (remove everything above this) if you need to do this
#
# ProxyPreserveHost On
# ProxyPassMatch ^/(.+.cf[cm])(/.)?$ ajp://127.0.0.1:8009/$1$2
# ProxyPassMatch ^/((flashservices/gateway|messagebroker/|flex2gateway/|openamf/gateway/).) ajp://127.0.0.1:8009/$1
#
/etc/apache2/my-apache-cf-rewrite.conf
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.cfm?varString=$1 [L,QSA]
I also use a file to secure Lucee admin:
/etc/apache2/my-apache-cf-secure-lucee.conf
##
## secure the lucee admin behind SSL and basic auth
##
<Location /lucee-context>
SSLRequireSSL
</Location>
<Location /lucee/admin>
SSLRequireSSL
AuthType Basic
AuthName "XXXXXXXXX"
AuthUserFile /etc/apache2/passwords/webauth
Require user YZYZYZYZYZ
</Location>
<Location /lucee-server>
SSLRequireSSL
AuthType Basic
AuthName "XXXXXXXX"
AuthUserFile /etc/apache2/passwords/webauth
Require user YZYZYZYZYZ
</Location>
##
## secure the lucee admin behind SSL and basic auth
##
Now, assuming that Tomcat and Java / Lucee are correctly installed (I will come back to that), here is an example CONF file for a virtual host
virtual-host.conf example
SSLStrictSNIVHostCheck on
<VirtualHost *:443>
ServerAdmin admin@email.com
ServerName www.mysite.com
DocumentRoot /path/to/your/web/site
DirectoryIndex index.html index.cfm
RewriteEngine On
RewriteOptions Inherit
SSLEngine on
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/www.mysite.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.mysite.com/privkey.pem
Include /etc/apache2/my-apache-cf-ajp.conf
Define luceeadmin "XXXXXX"
Include /etc/apache2/my-apache-cf-secure-lucee.conf
Define listofusers "XXXXXX AAAAAAA"
Include /etc/apache2/my-apache-secure-directories.conf
<Directory "/path/to/your/web/site">
AllowOverride None
Include /etc/apache2/my-apache-cf-rewrite.conf
</Directory>
CustomLog /path/to/your/web/site/log/www.mysite.com.ssl.access.log vhost_combined
ErrorLog /path/to/your/web/site/log/www.mysite.com.ssl.error.log
LogLevel error
# CF Site
</VirtualHost>
Now let’s look at Tomcat
I put Tomcat in /opt/tomcat and this is a complete “HOW-TO” for installing Tomcat and having it load at boot and always running - YMMV
- Make sure you have a valid openssl version, you probably do:
openssl version
should show 1.1.1b or greater
- Make /opt/tomcat and change permissions
chgrp -R tomcat /opt/tomcat
chown -R tomcat:tomcat /opt/tomcat
I then CURL the latest Tomcat to /tmp
cd /tmp
curl -O https://mirrors.sonic.net/apache/tomcat/tomcat-9/v9.0.41/bin/apache-tomcat-9.0.41.tar.gz
unpack into /OPT
mkdir /opt/tomcat
(you are still in /tmp which is correct, we unpack from there and move it)
tar xzvf apache-tomcat-9*tar.gz -C /opt/tomcat --strip-components=1
Set up new tomcat group on the system
groupadd tomcat
then add tomcat user
useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat
Give the tomcat group ownership over the entire installation directory:
chgrp -R tomcat /opt/tomcat
chown -R tomcat:tomcat /opt/tomcat
cd /opt/tomcat
Next, give the tomcat group read access to the conf directory and all of its contents, and execute access to the directory itself
chmod -R g+r conf
chmod g+x conf
Make the various shell scripts executable:
cd /opt/tomcat/bin
chmod +x *.sh
Next, set up a start up script in /etc/systemd/system/tomcat.service
Note: this script depends on the information found in the section on installing java because the environment varibale shown below has to be the same as in /etc/environment and /etc/systemd/system/tomcat.service.
nano /etc/systemd/system/tomcat.service
[Unit]
Description=Apache Tomcat Web Application Container
After=network.target
[Service]
Type=forking
Environment=JAVA_HOME=/opt/java
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
Environment='CATALINA_OPTS=-Xms2G -Xmx2G -server -XX:+ZGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
User=tomcat
Group=tomcat
UMask=0007
RestartSec=10
Restart=always
[Install]
WantedBy=multi-user.target
Save that and exit
Reload system daemon
systemctl enable tomcat
systemctl daemon-reload
Now, make sure you have /opt/tomcat/setenv.sh and the entire contents will be:
export CATALINA_OPTS="-Xms2G -Xmx2G -Xmn2048m -Xss1024k -XX:+UseZGC -XX:ConcGCThreads=4 -Djava.awt.headless=true -Duser.timezone=America/New_York -Djava.security.egd=file:/dev/./urandom";
Start tomcat
systemctl start tomcat
Test to see if it is running
systemctl status tomcat
If not already, update firewall (we will close it later)
ufw allow 8080
For Tomcat web manager which we are only going to use to test the setup
In /opt/tomcat/conf/tomcat-users.xml
<role rolename="manager-gui"/>
<role rolename="admin-gui"/>
<user username="ABC123" password="DEF456" roles="manager-gui,admin-gui"/>
**In BOTH **
/opt/tomcat/webapps/manager/META-INF/context.xml
and
/opt/tomcat/webapps/host-manager/META-INF/context.xml
Inside those files, comment out the IP address restriction to allow connections from anywhere. Alternatively, if you would like to allow access only to connections coming from your own IP address, you can add your public IP address to the list:
<Context antiResourceLocking="false" privileged="true" >
<!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" /> -->
</Context>
Now. Open /opt/tomcat/conf/server.xml
change
<Server port="8005" shutdown="SHUTDOWN">
to
<Server port="8005" shutdown="-1">
Save and close.
*Now. Open /opt/tomcat/conf/web.xml
Around line 600~ make the following changes:
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
</session-config>
Save and close.
Restart Tomcat - this is the correct way now to stop and start
systemctl restart tomcat
If Tomcat is working, you can point your browser to the domain where you set it up and append the :8080 port and you should see the welcome screen.
At this point, a hard reboot is nice to do just to make sure everything is solid. YMMV
Once rebooted, let’s close port 8080
ufw deny 8080
INSTALLING OPEN JDK (versions 10, 11, 12, 13, 14, 15, 16)
create teh jdk directory
mkdir /opt/java
cd /opt/java
VERSION 16
curl -O https://download.java.net/java/GA/jdk16/7863447f0ab643c585b9bdebf67c69db/36/GPL/openjdk-16_linux-x64_bin.tar.gz
Uncompress and unpack and change to your directory name
tar -zxvf openjdk-16_linux-x64_bin.tar.gz -C /opt
Now, rename the unpacked directory to “java”
mv -v /opt/dk-16 /opt/java
*NOTE: If later on, you upgrade to v17, just stop Tomcat, change the directory name of /opt/java to something like /opt/java-16 then upack the new version and rename it to /opt/java
Now, we’ll set the Java home variable for the system.
JAVA_HOME="/opt/java"
restart your shell and run
echo $JAVA_HOME
nano /etc/environment
add:
JAVA_HOME="/opt/java"
Finally, for good measure
systemctl daemon-reload
INSTALL LUCEE
I like to clear out Tomcat logs when I do this:
systemctl stop tomcat
echo "" > /opt/tomcat/logs/catalina.*.log
echo "" > /opt/tomcat/logs/*.out
rm -R /opt/tomcat/logs/*
Then download Lucee (make sure you have the right URL)
cd /tmp
curl -O https://release.lucee.org/rest/update/provider/war/5.3.7.47.war /tmp/lucee-5.3.7.47.war
rm -R /opt/tomcat/webapps/ROOT
OR
mv -v /opt/tomcat/webapps/ROOT /opt/tomcat/webapps/mytomcat
cp -p /tmp/lucee-5.3.7.47.war /opt/tomcat/webapps/ROOT.war
Restart Tomcat and Lucee should now be running
systemctl start tomcat
Open 8443 (temporarily)
UFW allow 8443
Test: Go to Splash page
https://www.mysite.com:8443
I have done this process now on Ubuntu 10, 12, 14, 18 and 20, on both my own server hardware as well as on droplets at Digital Ocean, as well as on several versions of Mac OS.