This guide provides a detailed explanation of the essential Liferay properties (portal-ext.properties) required to correctly integrate Liferay Portal or Liferay DXP with a Reverse Proxy server like Nginx or Apache, covering dual access and proxy-only access scenarios.
Texto
Comprehensive Guide to Configuring Liferay Behind a Reverse Proxy (Nginx / Apache)
This guide provides a detailed explanation of the essential Liferay properties (portal-ext.properties) required to correctly integrate Liferay Portal or Liferay DXP with a Reverse Proxy server like Nginx or Apache, covering dual access and proxy-only access scenarios.
I. Understanding Liferay's web.server.forwarded Properties
When Liferay runs behind a reverse proxy, the application server (Tomcat, for example) only sees the connection coming from the proxy (e.g., http://nginx_ip:80). To correctly generate URLs for assets, links, and forms, especially when using HTTPS, Liferay must be informed of the original client request headers.
This is achieved by enabling and mapping the X-Forwarded-* headers, which are injected by the proxy.
Liferay Property (portal-ext.properties) |
Corresponding Header (Proxy) | Purpose |
|---|---|---|
web.server.forwarded.host.header |
X-Forwarded-Host |
Tells Liferay the original domain name requested by the client (e.g., dominio.ejemplo.com). |
web.server.forwarded.port.header |
X-Forwarded-Port |
Tells Liferay the original port used by the client (e.g., 80 or 443). |
web.server.forwarded.protocol.header |
X-Forwarded-Proto |
Crucial: Tells Liferay the original protocol (http or https), preventing mixed content errors. |
Summary of Liferay Access Scenarios
| Scenario | Direct Tomcat Access (e.g., http://[IP]:8081) |
Proxy Access (HTTPS) | Key Liferay portal-ext.properties |
|---|---|---|---|
| 1. Dual Access | ✅ FUNCTIONAL. Liferay uses the incoming request's IP/Port to generate URLs. | ✅ FUNCTIONAL. Liferay uses the X-Forwarded-* headers. |
web.server.host and web.server.protocol properties are COMMENTED OUT. |
| 2. Proxy-Only Access | ❌ BLOCKED. Liferay generates URLs with the frontend domain (https://domain.com), breaking resource loading for direct IP access. |
✅ FUNCTIONAL. Liferay uses the X-Forwarded-* headers. |
web.server.host and web.server.protocol properties are UNCOMMENTED and set to the frontend domain (e.g., https). |
| 3. Proxy with Custom Header | Functions according to Scenario 1 or 2 (depends on whether static host is active). | ✅ FUNCTIONAL. Liferay looks for the custom header (e.g., My-Custom-Proto) instead of X-Forwarded-Proto. |
web.server.forwarded.protocol.header property is adjusted to the custom header (e.g., My-Custom-Proto). |
Scenario 1: Dual Access (Proxy AND Tomcat Direct)
This configuration allows users to access Liferay through the frontend domain (HTTPS) or directly via the backend Tomcat port (HTTP) (e.g., for troubleshooting or internal development).
To achieve dual access, we must enable the forwarded headers but leave the static web.server.host properties commented out. This instructs Liferay to use the incoming request details if forwarded headers are missing.
1. Liferay Configuration (portal-ext.properties)
# --- Configuration for Reverse Proxy (Nginx/Apache) ---
# Enable the use of X-Forwarded-* headers
web.server.forwarded.host.enabled=true
web.server.forwarded.host.header=X-Forwarded-Host
web.server.forwarded.port.enabled=true
web.server.forwarded.port.header=X-Forwarded-Port
web.server.forwarded.protocol.enabled=true
web.server.forwarded.protocol.header=X-Forwarded-Proto
# IMPORTANT: Static server properties must be commented out for dual access.
# If these are active, direct Tomcat access will break.
#web.server.host=dominio.ejemplo.com
#web.server.protocol=https
#web.server.http.port=80
#web.server.https.port=443
2. Access Behavior Summary
| Access Method | Headers Present | Liferay Action | Generated URLs |
|---|---|---|---|
| Proxy (HTTPS) | Yes (X-Forwarded-Proto: https) |
Uses Forwarded Headers | https://dominio.ejemplo.com (Correct) |
| Tomcat Direct | No | Uses Tomcat's request data (IP:Port) |
http://[IP]:8081 (Correct for direct access) |
Scenario 2: Proxy-Only Access (Blocking Direct Tomcat)
If you want to ensure Liferay is only usable via the secure frontend domain and block direct backend access, you must activate the static server properties.
1. Liferay Configuration (portal-ext.properties)
Uncomment and set the static values to your public domain and protocol:
# ... forwarded headers are enabled as in Scenario 1 ...
# --- Configuration to force frontend domain and protocol ---
web.server.host=dominio.ejemplo.com
web.server.protocol=https
web.server.http.port=80
web.server.https.port=443
2. Access Behavior Summary (Blocking Direct Access)
| Access Method | Headers Present | Liferay Action | Resulting Functionality |
|---|---|---|---|
| Proxy (HTTPS) | Yes | Uses Forwarded Headers | Fully functional. |
| Tomcat Direct | No | Uses Static Properties (dominio.ejemplo.com) |
All generated links point to the frontend domain, breaking resource loading for direct IP access. Direct access is effectively blocked. |
Scenario 3: Using a Custom Protocol Header
If security standards require you to use a custom HTTP header instead of the standard X-Forwarded-Proto, you must update both Liferay and the proxy configuration.
1. Liferay Configuration (portal-ext.properties)
Change the mapping to your custom header name (e.g., My-Custom-Proto):
web.server.forwarded.protocol.enabled=true
web.server.forwarded.protocol.header=My-Custom-Proto
2. Nginx Configuration (nginx.conf)
Nginx must now inject the protocol value into the custom header:
# Nginx Configuration (only the relevant header change)
location / {
proxy_pass http://liferay:8080;
# ... other headers remain the same ...
# Custom Protocol Header
proxy_set_header My-Custom-Proto $scheme;
}
3. Apache Configuration (liferay.conf)
Apache uses the RequestHeader set directive:
# Apache Configuration (only the relevant header change)
<VirtualHost *:443>
# ... other configurations ...
# Custom Protocol Header
RequestHeader set My-Custom-Proto "https"
ProxyPass / http://liferay:8080/
ProxyPassReverse / http://liferay:8080/
</VirtualHost>
Complete Proxy Configuration Examples (HTTPS Termination)
1. Nginx Reverse Proxy Configuration
This block handles HTTPS termination and forwards the correct headers to Liferay running on the internal liferay:8080 network.
# Redirect HTTP (Port 80) to HTTPS
server {
listen 80;
server_name dominio.ejemplo.com;
return 301 https://$host$request_uri;
}
# HTTPS Proxy Block (Port 443)
server {
listen 443 ssl;
server_name dominio.ejemplo.com;
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
location / {
proxy_pass http://liferay:8080;
# Forwarded Headers (Essential for Liferay)
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header X-Forwarded-Proto https;
# Standard Proxy Headers
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Other settings
proxy_redirect off;
proxy_connect_timeout 240;
proxy_send_timeout 240;
proxy_read_timeout 240;
}
}
2. Apache Reverse Proxy Configuration
This configuration uses mod_rewrite for redirection and mod_proxy for forwarding.
# Requires mod_proxy, mod_proxy_http, mod_ssl, mod_headers, mod_rewrite
# HTTP Block (Port 80) - Redirect to HTTPS
<VirtualHost *:80>
ServerName dominio.ejemplo.com
RewriteEngine On
RewriteRule ^/(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</VirtualHost>
# HTTPS Block (Port 443) - Reverse Proxy
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName dominio.ejemplo.com
# SSL/TLS Configuration (adjust paths as needed)
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
ProxyRequests Off
ProxyPreserveHost On
# Forwarded Headers using mod_headers
RequestHeader set X-Forwarded-Host "%{Host}i"
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
# X-Forwarded-For is typically handled by ProxyPreserveHost or mod_remoteip
# Proxy Pass to Liferay Backend
ProxyPass / http://liferay:8080/
ProxyPassReverse / http://liferay:8080/
</VirtualHost>
</IfModule>
Ready-to-Use Example on GitHub (Docker Compose)
To expedite testing and deployment, a complete, working example of the Docker Compose setup discussed in this guide, including Nginx configuration and Liferay persistence is available on GitHub.
This repository provides a concrete implementation of the Nginx and Liferay services, allowing you to quickly launch and test the proxy forwarding mechanism.
How to Run the Example:
- Clone the Repository:
git clone https://github.com/dmcisneros/liferay-behind-proxy - Navigate to the Directory:
cd liferay-behind-proxy - Start the Services:
Usedocker-composeto build and start the Liferay and Nginx containers:
docker compose up -d
After the containers are up, you will be able to test both access methods:
- Proxy Access: Access through the domain configured in the Nginx/hosts file (Add this to you host file
https://dominio.ejemplo.com). - Direct Tomcat Access: Access directly via the exposed port (e.g.,
http://localhost:8081).
