Skip to main content

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

info

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.

warning

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.

note

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.