Install and Configure Apache
Prerequisites
Before proceeding with this guide, make sure that you have access to the following on your development machine:
- Fedora/Red Hat Environment
- Sudo Privileges
Install Apache HTTPD
The Apache HTTPD package and its dependencies can be installed via the dnf package manager:
sudo dnf install httpd mod_ssl
Additionally, the Apache Web Server (httpd) service must be enabled and started:
sudo systemctl enable --now httpd
# enable: Configures httpd to start automatically at system boot.
# --now: Starts the httpd service immediately
Configuring Apache HTTPD as a Reverse Proxy
This guide focuses on three kinds of proxy traffic:
- Galvanometer over HTTP or HTTPS
- TCP or TCPS connections using HTTP Preflight
- WS or WSS connections using WebSocket upgrade
For connections over SSL, use tcps:// and wss:// on the client side, /tcps/ and /wss/ on the Apache side, and https:// backend targets for the secure AMPS transports.
For non-SSL connections, use tcp:// and ws:// on the client side, /tcp/ and /ws/ on the Apache side, and http:// backend targets.
If you are unsure which connection type to use, see TLS/SSL Transports in the AMPS User Guide.
Create a virtual host configuration file under /etc/httpd/conf.d/ such as /etc/httpd/conf.d/amps-proxy.conf (sudo access is required).
The first step in configuring Apache is to define a VirtualHost and configure the address *:443 to listen for all HTTPS requests. For a non-SSL configuration, we will use *:80 to listen for all HTTP requests.
Next, we have to enable the SSL functionality in Apache by including SSLEngine and SSLProxyEngine, and by defining the necessary certificates. For this demonstration, we will use the Fedora localhost certificates located at /etc/pki/tls/certs/localhost.crt and /etc/pki/tls/private/localhost.key.
Because the backend AMPS services also use those localhost certificates, this example disables backend certificate verification with SSLProxyVerify, SSLProxyCheckPeerName, and SSLProxyCheckPeerExpire.
The Fedora localhost certificate is suitable only for local development. If clients or browsers connect using a different hostname, the certificate must match that hostname. For browser-based access to Galvanometer, the certificate must also be trusted by the browser.
To support HTTP upgrade requests, we will also include the Header, RequestHeader, and ProxyPreserveHost directives so Apache can forward the requests properly.
Start with the base VirtualHost and SSL configuration:
<VirtualHost *:443>
ServerName ApacheReverseProxyExample
SSLEngine On
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
</VirtualHost>
Now we can define the proxy configuration by adding ProxyPass and ProxyPassReverse directives for each endpoint we want Apache to forward. We can also add a RedirectMatch directive for tools like the Galvanometer which expect the URL with a trailing slash.
This guide assumes the AMPS server is running on the same host as the reverse proxy. If this is not the case, replace 127.0.0.1 with the address of your AMPS server.
Add the following directives to forward /admin/ traffic to the backend service on port 8085:
ProxyPass "/admin/" "https://127.0.0.1:8085/"
ProxyPassReverse "/admin/" "https://127.0.0.1:8085/"
ProxyPassReverseCookiePath "/" "/admin/"
RedirectMatch 301 ^/admin$ /admin/
Next, add a /tcps/ block that forwards TCPS connections to port 9007 with upgrade=tcps:
ProxyPass "/tcps/" "https://127.0.0.1:9007/" timeout=86400 upgrade=tcps
ProxyPassReverse "/tcps/" "https://127.0.0.1:9007/"
Finally, add a block for /wss/ that forwards Secure WebSocket traffic to port 9008 with upgrade=websocket:
ProxyPass "/wss/" "https://127.0.0.1:9008/" timeout=86400 upgrade=websocket
ProxyPassReverse "/wss/" "https://127.0.0.1:9008/"
The complete Apache configuration for SSL connections:
<VirtualHost *:443>
ServerName ApacheReverseProxyExample
SSLEngine On
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
# -----------------------------------------
# Galvanometer UI: /admin -> :8085
# Provides access to https://proxy_host_address:443/admin and /admin/
# -----------------------------------------
ProxyPass "/admin/" "https://127.0.0.1:8085/"
ProxyPassReverse "/admin/" "https://127.0.0.1:8085/"
ProxyPassReverseCookiePath "/" "/admin/"
# Handle /admin without trailing slash
RedirectMatch 301 ^/admin$ /admin/
# -------------------------
# TCPS Connections: /tcps -> :9007
# Client connection string: tcps://proxy_host_address:443/tcps/...?http_preflight=true
# -------------------------
ProxyPass "/tcps/" "https://127.0.0.1:9007/" timeout=86400 upgrade=tcps
ProxyPassReverse "/tcps/" "https://127.0.0.1:9007/"
# -------------------------
# Secure WebSockets: /wss -> :9008
# Client connection string: wss://proxy_host_address:443/wss/...
# -------------------------
ProxyPass "/wss/" "https://127.0.0.1:9008/" timeout=86400 upgrade=websocket
ProxyPassReverse "/wss/" "https://127.0.0.1:9008/"
</VirtualHost>
The standard non-SSL deployment Apache configuration:
<VirtualHost *:80>
ServerName ApacheReverseProxyExample
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "http"
# -----------------------------------------
# Galvanometer UI: /admin -> :8085
# Provides access to http://proxy_host_address:80/admin and /admin/
# -----------------------------------------
ProxyPass "/admin/" "http://127.0.0.1:8085/"
ProxyPassReverse "/admin/" "http://127.0.0.1:8085/"
ProxyPassReverseCookiePath "/" "/admin/"
# Handle /admin without trailing slash
RedirectMatch 301 ^/admin$ /admin/
# -------------------------
# TCP: /tcp -> :9007
# Client connection string: tcp://proxy_host_address:80/tcp/...?http_preflight=true
# -------------------------
ProxyPass "/tcp/" "http://127.0.0.1:9007/" timeout=86400 upgrade=tcp
ProxyPassReverse "/tcp/" "http://127.0.0.1:9007/"
# -------------------------
# WebSockets: /ws -> :9008
# Client connection string: ws://proxy_host_address:80/ws/...
# -------------------------
ProxyPass "/ws/" "http://127.0.0.1:9008/" timeout=86400 upgrade=websocket
ProxyPassReverse "/ws/" "http://127.0.0.1:9008/"
</VirtualHost>
Validate and Apply the Apache Configuration
Validate the Apache configuration file:
sudo apachectl configtest
Restart the Apache HTTP server to pick up the new configuration file:
sudo systemctl restart httpd
Verify the Apache HTTP server is running:
sudo systemctl status httpd
The examples above show both SSL and non-SSL Apache reverse proxy configurations for AMPS TCP, WebSocket, and Galvanometer connections.