|
| 1 | +# FIPS Mode and APR SSL Engine Fix |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +This fix addresses the OpenSSL 3.x compatibility issue with Tomcat Native APR library while maintaining the performance benefits of the native library by default, as requested in [PR #34068](https://github.com/dotCMS/core/pull/34068). |
| 6 | + |
| 7 | +## Problem Statement |
| 8 | + |
| 9 | +The Tomcat Native APR library (libtcnative-1) version 1.2.35 is incompatible with OpenSSL 3.x, causing JVM segmentation faults during startup on modern systems (Ubuntu 24.04+, RHEL 9+) running in FIPS mode. |
| 10 | + |
| 11 | +## Solution Design |
| 12 | + |
| 13 | +Instead of removing the native library entirely (as proposed in PR #34068), this solution: |
| 14 | + |
| 15 | +1. **Keeps the native library installed by default** for performance benefits |
| 16 | +2. **Automatically detects FIPS-enabled environments** and disables APR SSL when needed |
| 17 | +3. **Provides configuration flags** for manual control when automatic detection is insufficient |
| 18 | + |
| 19 | +## Implementation Details |
| 20 | + |
| 21 | +### 1. FIPS Detection Script |
| 22 | + |
| 23 | +**File**: `dotCMS/src/main/docker/original/ROOT/srv/15-detect-fips-and-set-ssl-engine.sh` |
| 24 | + |
| 25 | +This script runs during container startup and: |
| 26 | +- Checks if the system is running in FIPS mode by reading `/proc/sys/crypto/fips_enabled` |
| 27 | +- Checks if the user has set `CMS_DISABLE_APR_SSL` environment variable |
| 28 | +- Automatically sets `CMS_SSL_ENGINE=off` if FIPS mode is detected or manual disable is requested |
| 29 | +- Defaults to `CMS_SSL_ENGINE=on` for optimal performance in non-FIPS environments |
| 30 | +- Respects explicit `CMS_SSL_ENGINE` settings (user configuration takes precedence) |
| 31 | + |
| 32 | +### 2. Entrypoint Integration |
| 33 | + |
| 34 | +**File**: `dotCMS/src/main/docker/original/ROOT/srv/entrypoint.sh` |
| 35 | + |
| 36 | +The FIPS detection script is sourced early in the startup process (before other configuration scripts) to ensure the `CMS_SSL_ENGINE` environment variable is set before Tomcat starts. |
| 37 | + |
| 38 | +### 3. Documentation |
| 39 | + |
| 40 | +**File**: `dotCMS/src/main/resources/container/tomcat9/conf/server.xml` |
| 41 | + |
| 42 | +Added comprehensive documentation explaining: |
| 43 | +- APR SSL Engine functionality and benefits |
| 44 | +- FIPS mode auto-detection behavior |
| 45 | +- Configuration options available to users |
| 46 | +- Performance implications of each configuration |
| 47 | + |
| 48 | +## Configuration Options |
| 49 | + |
| 50 | +### Option 1: Automatic FIPS Detection (Default Behavior) |
| 51 | + |
| 52 | +The container automatically detects FIPS mode at startup: |
| 53 | + |
| 54 | +```bash |
| 55 | +# No configuration needed - FIPS detection is automatic |
| 56 | +docker run -p 8080:8080 dotcms/dotcms:latest |
| 57 | +``` |
| 58 | + |
| 59 | +**What happens:** |
| 60 | +- If `/proc/sys/crypto/fips_enabled` equals `1`: APR SSL is automatically disabled |
| 61 | +- If FIPS is not enabled: APR SSL remains enabled for optimal performance |
| 62 | + |
| 63 | +### Option 2: Manual Disable with CMS_DISABLE_APR_SSL |
| 64 | + |
| 65 | +Explicitly disable APR SSL Engine without FIPS mode: |
| 66 | + |
| 67 | +```bash |
| 68 | +docker run -e CMS_DISABLE_APR_SSL=true -p 8080:8080 dotcms/dotcms:latest |
| 69 | +``` |
| 70 | + |
| 71 | +**Use cases:** |
| 72 | +- Running on OpenSSL 3.x systems that aren't in FIPS mode but still experience issues |
| 73 | +- Testing Java JSSE performance |
| 74 | +- Corporate policies requiring pure Java implementations |
| 75 | + |
| 76 | +### Option 3: Direct CMS_SSL_ENGINE Control |
| 77 | + |
| 78 | +Override all automatic behavior with explicit setting: |
| 79 | + |
| 80 | +```bash |
| 81 | +# Force APR SSL on (even in FIPS environments - may cause crashes) |
| 82 | +docker run -e CMS_SSL_ENGINE=on -p 8080:8080 dotcms/dotcms:latest |
| 83 | + |
| 84 | +# Force APR SSL off (even in non-FIPS environments) |
| 85 | +docker run -e CMS_SSL_ENGINE=off -p 8080:8080 dotcms/dotcms:latest |
| 86 | +``` |
| 87 | + |
| 88 | +**Use cases:** |
| 89 | +- Advanced troubleshooting |
| 90 | +- Custom SSL configurations |
| 91 | +- Override automatic detection if needed |
| 92 | + |
| 93 | +## Priority of Configuration |
| 94 | + |
| 95 | +Configuration is applied in this order (highest to lowest priority): |
| 96 | + |
| 97 | +1. **Explicit `CMS_SSL_ENGINE` setting** - User-provided value always wins |
| 98 | +2. **`CMS_DISABLE_APR_SSL=true`** - Manual disable flag |
| 99 | +3. **FIPS auto-detection** - Automatic detection of FIPS mode |
| 100 | +4. **Default behavior** - APR SSL enabled for performance |
| 101 | + |
| 102 | +## Performance Impact |
| 103 | + |
| 104 | +| Configuration | SSL/TLS Implementation | Performance | Compatibility | |
| 105 | +|--------------|------------------------|-------------|---------------| |
| 106 | +| APR SSL enabled (default) | Native OpenSSL | Best | May crash on OpenSSL 3.x + FIPS | |
| 107 | +| APR SSL disabled | Java JSSE | Comparable | Works everywhere | |
| 108 | + |
| 109 | +**Note**: For most workloads, the performance difference between native OpenSSL and Java JSSE is minimal (< 5%). |
| 110 | + |
| 111 | +## Verification |
| 112 | + |
| 113 | +### Check FIPS Status |
| 114 | + |
| 115 | +```bash |
| 116 | +# Check if system is in FIPS mode |
| 117 | +cat /proc/sys/crypto/fips_enabled |
| 118 | +# Output: 1 (FIPS enabled) or 0 (FIPS disabled) |
| 119 | +``` |
| 120 | + |
| 121 | +### Check APR SSL Status in Container |
| 122 | + |
| 123 | +```bash |
| 124 | +# View startup logs to see FIPS detection output |
| 125 | +docker logs <container_id> | grep "FIPS Detection" |
| 126 | + |
| 127 | +# Expected output examples: |
| 128 | +# [FIPS Detection] System is running in FIPS mode (fips_enabled=1) |
| 129 | +# [FIPS Detection] Automatically disabling APR SSL Engine due to FIPS mode |
| 130 | +# [FIPS Detection] Final CMS_SSL_ENGINE value: off |
| 131 | + |
| 132 | +# OR (non-FIPS environment): |
| 133 | +# [FIPS Detection] APR SSL Engine enabled (default) for optimal performance |
| 134 | +# [FIPS Detection] Final CMS_SSL_ENGINE value: on |
| 135 | +``` |
| 136 | + |
| 137 | +### Test SSL Connectivity |
| 138 | + |
| 139 | +```bash |
| 140 | +# Test HTTPS endpoint |
| 141 | +curl -k https://localhost:8443 |
| 142 | + |
| 143 | +# Check Tomcat logs for SSL implementation in use |
| 144 | +docker exec <container_id> cat /srv/dotserver/tomcat/logs/catalina.out | grep -i "apr\|ssl" |
| 145 | +``` |
| 146 | + |
| 147 | +## Migration Guide |
| 148 | + |
| 149 | +### From PR #34068 (Native Library Removed) |
| 150 | + |
| 151 | +If you were testing PR #34068, no changes needed: |
| 152 | +- The native library is now kept by default |
| 153 | +- FIPS detection automatically disables it when needed |
| 154 | +- Your containers will have better performance in non-FIPS environments |
| 155 | + |
| 156 | +### From Current Production (Native Library Always On) |
| 157 | + |
| 158 | +No migration needed: |
| 159 | +- Default behavior remains the same (APR SSL enabled) |
| 160 | +- FIPS environments now work automatically |
| 161 | +- No configuration changes required |
| 162 | + |
| 163 | +## Testing |
| 164 | + |
| 165 | +### Test Scenario 1: Non-FIPS Environment (Default) |
| 166 | + |
| 167 | +```bash |
| 168 | +# Build and run container |
| 169 | +docker build -t dotcms-test . |
| 170 | +docker run -e CMS_HTTP_PORT=8080 -p 8080:8080 dotcms-test |
| 171 | + |
| 172 | +# Expected: APR SSL enabled, native library used |
| 173 | +# Verify in logs: "APR SSL Engine enabled (default)" |
| 174 | +``` |
| 175 | + |
| 176 | +### Test Scenario 2: FIPS Environment |
| 177 | + |
| 178 | +```bash |
| 179 | +# Simulate FIPS mode (requires root on host) |
| 180 | +echo 1 | sudo tee /proc/sys/crypto/fips_enabled |
| 181 | + |
| 182 | +# Run container |
| 183 | +docker run -e CMS_HTTP_PORT=8080 -p 8080:8080 dotcms-test |
| 184 | + |
| 185 | +# Expected: APR SSL automatically disabled, Java JSSE used |
| 186 | +# Verify in logs: "System is running in FIPS mode" |
| 187 | +``` |
| 188 | + |
| 189 | +### Test Scenario 3: Manual Disable |
| 190 | + |
| 191 | +```bash |
| 192 | +# Run with manual disable flag |
| 193 | +docker run -e CMS_DISABLE_APR_SSL=true -e CMS_HTTP_PORT=8080 -p 8080:8080 dotcms-test |
| 194 | + |
| 195 | +# Expected: APR SSL disabled regardless of FIPS mode |
| 196 | +# Verify in logs: "APR SSL Engine disabled via CMS_DISABLE_APR_SSL" |
| 197 | +``` |
| 198 | + |
| 199 | +## Compatibility |
| 200 | + |
| 201 | +| Environment | APR SSL Status | Behavior | |
| 202 | +|------------|---------------|----------| |
| 203 | +| Ubuntu 22.04 (OpenSSL 3.0.2) | Enabled by default | Works with FIPS auto-detection | |
| 204 | +| Ubuntu 24.04 (OpenSSL 3.0.13) | Enabled by default | Works with FIPS auto-detection | |
| 205 | +| RHEL 8 (OpenSSL 1.1.1) | Enabled by default | Full compatibility | |
| 206 | +| RHEL 9 (OpenSSL 3.0.7) | Enabled by default | Works with FIPS auto-detection | |
| 207 | +| Any system with FIPS enabled | Automatically disabled | Prevents JVM crashes | |
| 208 | + |
| 209 | +## Troubleshooting |
| 210 | + |
| 211 | +### Issue: Container crashes with SIGSEGV on startup |
| 212 | + |
| 213 | +**Cause**: APR SSL Engine is enabled in a FIPS/OpenSSL 3.x environment but auto-detection failed. |
| 214 | + |
| 215 | +**Solution**: |
| 216 | +```bash |
| 217 | +# Manually disable APR SSL |
| 218 | +docker run -e CMS_DISABLE_APR_SSL=true ... dotcms/dotcms:latest |
| 219 | +``` |
| 220 | + |
| 221 | +### Issue: FIPS detection not working |
| 222 | + |
| 223 | +**Cause**: Container might not have access to `/proc/sys/crypto/fips_enabled`. |
| 224 | + |
| 225 | +**Solution**: |
| 226 | +```bash |
| 227 | +# Explicitly set CMS_SSL_ENGINE |
| 228 | +docker run -e CMS_SSL_ENGINE=off ... dotcms/dotcms:latest |
| 229 | +``` |
| 230 | + |
| 231 | +### Issue: Want to force APR SSL on in FIPS environment |
| 232 | + |
| 233 | +**Warning**: This may cause crashes. Only do this if you've verified compatibility. |
| 234 | + |
| 235 | +**Solution**: |
| 236 | +```bash |
| 237 | +# Override automatic detection |
| 238 | +docker run -e CMS_SSL_ENGINE=on ... dotcms/dotcms:latest |
| 239 | +``` |
| 240 | + |
| 241 | +## Related Issues |
| 242 | + |
| 243 | +- [#34067](https://github.com/dotCMS/core/issues/34067) - JVM crash with OpenSSL 3.x in FIPS mode |
| 244 | +- [PR #34068](https://github.com/dotCMS/core/pull/34068) - Original fix (removed native library entirely) |
| 245 | + |
| 246 | +## References |
| 247 | + |
| 248 | +- [Apache Tomcat Native Library Documentation](https://tomcat.apache.org/native-doc/) |
| 249 | +- [OpenSSL FIPS Module](https://www.openssl.org/docs/fips.html) |
| 250 | +- [Tomcat APR/Native Connector](https://tomcat.apache.org/tomcat-9.0-doc/apr.html) |
0 commit comments