smartproxy/docs/http-01-acme-fix.md

106 lines
3.6 KiB
Markdown

# HTTP-01 ACME Challenge Fix (v19.3.8)
## Problem Description
In SmartProxy v19.3.7 and earlier, ACME HTTP-01 challenges would fail when port 80 was configured to use HttpProxy via the `useHttpProxy` configuration option. The issue was that non-TLS connections on ports listed in `useHttpProxy` were not being forwarded to HttpProxy, instead being handled as direct connections.
## Root Cause
The bug was located in the `RouteConnectionHandler.handleForwardAction` method in `ts/proxies/smart-proxy/route-connection-handler.ts`. The method only forwarded connections to HttpProxy if they had TLS settings with mode 'terminate' or 'terminate-and-reencrypt'. Non-TLS connections (like HTTP on port 80) were always handled as direct connections, regardless of the `useHttpProxy` configuration.
## Solution
The fix adds a check for non-TLS connections on ports listed in the `useHttpProxy` array:
```typescript
// No TLS settings - check if this port should use HttpProxy
const isHttpProxyPort = this.settings.useHttpProxy?.includes(record.localPort);
if (isHttpProxyPort && this.httpProxyBridge.getHttpProxy()) {
// Forward non-TLS connections to HttpProxy if configured
if (this.settings.enableDetailedLogging) {
console.log(
`[${connectionId}] Using HttpProxy for non-TLS connection on port ${record.localPort}`
);
}
this.httpProxyBridge.forwardToHttpProxy(
connectionId,
socket,
record,
initialChunk,
this.settings.httpProxyPort || 8443,
(reason) => this.connectionManager.initiateCleanupOnce(record, reason)
);
return;
}
```
## Configuration
To enable ACME HTTP-01 challenges on port 80 with HttpProxy:
```typescript
const proxy = new SmartProxy({
useHttpProxy: [80], // Must include port 80 for HTTP-01 challenges
httpProxyPort: 8443, // Default HttpProxy port
acme: {
email: 'ssl@example.com',
port: 80, // ACME challenge port
useProduction: false
},
routes: [
{
name: 'https-route',
match: {
ports: 443,
domains: 'example.com'
},
action: {
type: 'forward',
target: { host: 'localhost', port: 8080 },
tls: {
mode: 'terminate',
certificate: 'auto',
acme: {
email: 'ssl@example.com',
useProduction: false
}
}
}
}
]
});
```
## Testing
The fix is verified by unit tests in `test/test.http-fix-unit.ts`:
1. **Test 1**: Verifies that non-TLS connections on ports in `useHttpProxy` are forwarded to HttpProxy
2. **Test 2**: Confirms that ports not in `useHttpProxy` still use direct connections
3. **Test 3**: Validates that ACME HTTP-01 challenges on port 80 work correctly with HttpProxy
## Impact
This fix enables proper ACME HTTP-01 challenge handling when:
1. Port 80 is configured in the `useHttpProxy` array
2. An ACME challenge route is configured to use HTTP-01 validation
3. Certificate provisioning with `certificate: 'auto'` is used
Without this fix, HTTP-01 challenges would fail because the challenge requests would not reach the ACME handler in HttpProxy.
## Migration Guide
If you were experiencing ACME HTTP-01 challenge failures:
1. Update to SmartProxy v19.3.8 or later
2. Ensure port 80 is included in your `useHttpProxy` configuration
3. Verify your ACME configuration includes the correct email and port settings
4. Test certificate renewal with staging ACME first (`useProduction: false`)
## Related Issues
- ACME HTTP-01 challenges timing out on port 80
- HTTP requests not being parsed on configured HttpProxy ports
- Certificate provisioning failing with "connection timeout" errors