new plan
This commit is contained in:
186
readme.plan.md
186
readme.plan.md
@ -1,134 +1,90 @@
|
|||||||
# SmartProxy ACME Simplification Plan
|
# SmartProxy Development Plan
|
||||||
|
|
||||||
## Overview
|
cat /home/philkunz/.claude/CLAUDE.md
|
||||||
This plan addresses the certificate acquisition confusion in SmartProxy v19.0.0 and proposes simplifications to make ACME configuration more intuitive.
|
|
||||||
|
|
||||||
## Current Issues
|
## Critical Bug Fix: Missing Route Update Callback in updateRoutes Method
|
||||||
1. ACME configuration placement is confusing (route-level vs top-level)
|
|
||||||
2. SmartAcme initialization logic is complex and error-prone
|
|
||||||
3. Documentation doesn't clearly explain the correct configuration format
|
|
||||||
4. Error messages like "SmartAcme not initialized" are not helpful
|
|
||||||
|
|
||||||
## Proposed Simplifications
|
### Problem Statement
|
||||||
|
SmartProxy v19.2.2 has a bug where the ACME certificate manager loses its route update callback when routes are dynamically updated. This causes the error "No route update callback set" and prevents automatic certificate acquisition.
|
||||||
|
|
||||||
### 1. Support Both Configuration Styles
|
### Root Cause
|
||||||
- [x] Reread CLAUDE.md before starting implementation
|
When `updateRoutes()` creates a new SmartCertManager instance, it fails to set the route update callback that's required for ACME challenges. This callback is properly set in `initializeCertificateManager()` but is missing from the route update flow.
|
||||||
- [x] Accept ACME config at both top-level and route-level
|
|
||||||
- [x] Use top-level ACME config as defaults for all routes
|
|
||||||
- [x] Allow route-level ACME config to override top-level defaults
|
|
||||||
- [x] Make email field required when any route uses `certificate: 'auto'`
|
|
||||||
|
|
||||||
### 2. Improve SmartAcme Initialization
|
### Implementation Plan
|
||||||
- [x] Initialize SmartAcme when top-level ACME config exists with email
|
|
||||||
- [x] Initialize SmartAcme when any route has `certificate: 'auto'`
|
|
||||||
- [x] Provide clear error messages when initialization fails
|
|
||||||
- [x] Add debug logging for ACME initialization steps
|
|
||||||
|
|
||||||
### 3. Simplify Certificate Configuration
|
#### Phase 1: Fix the Bug
|
||||||
- [x] Create helper method to validate ACME configuration
|
1. **Update the updateRoutes method** in `/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts`
|
||||||
- [x] Auto-detect when port 80 is needed for challenges
|
- [ ] Add the missing callback setup before initializing the new certificate manager
|
||||||
- [x] Provide sensible defaults for ACME settings
|
- [ ] Ensure the callback is set after creating the new SmartCertManager instance
|
||||||
- [x] Add configuration examples in documentation
|
|
||||||
|
|
||||||
### 4. Update Documentation
|
#### Phase 2: Create Tests
|
||||||
- [x] Create clear examples for common ACME scenarios
|
2. **Write comprehensive tests** for the route update functionality
|
||||||
- [x] Document the configuration hierarchy (top-level vs route-level)
|
- [ ] Create test file: `test/test.route-update-callback.node.ts`
|
||||||
- [x] Add troubleshooting guide for common certificate issues
|
- [ ] Test that callback is preserved when routes are updated
|
||||||
- [x] Include migration guide from v18 to v19
|
- [ ] Test that ACME challenges work after route updates
|
||||||
|
- [ ] Test edge cases (multiple updates, no cert manager, etc.)
|
||||||
|
|
||||||
### 5. Add Configuration Helpers
|
#### Phase 3: Enhance Documentation
|
||||||
- [x] Create `SmartProxyConfig.fromSimple()` helper for basic setups (part of validation)
|
3. **Update documentation** to clarify the route update behavior
|
||||||
- [x] Add validation for common misconfigurations
|
- [ ] Add section to certificate-management.md about dynamic route updates
|
||||||
- [x] Provide warning messages for deprecated patterns
|
- [ ] Document the callback requirement for ACME challenges
|
||||||
- [x] Include auto-correction suggestions
|
- [ ] Include example of proper route update implementation
|
||||||
|
|
||||||
## Implementation Steps
|
#### Phase 4: Prevent Future Regressions
|
||||||
|
4. **Refactor for better maintainability**
|
||||||
|
- [ ] Consider extracting certificate manager setup to a shared method
|
||||||
|
- [ ] Add code comments explaining the callback requirement
|
||||||
|
- [ ] Consider making the callback setup more explicit in the API
|
||||||
|
|
||||||
### Phase 1: Configuration Support ✅
|
### Technical Details
|
||||||
1. ✅ Update ISmartProxyOptions interface to clarify ACME placement
|
|
||||||
2. ✅ Modify SmartProxy constructor to handle top-level ACME config
|
|
||||||
3. ✅ Update SmartCertManager to accept global ACME defaults
|
|
||||||
4. ✅ Add configuration validation and helpful error messages
|
|
||||||
|
|
||||||
### Phase 2: Testing ✅
|
#### Specific Code Changes
|
||||||
1. ✅ Add tests for both configuration styles
|
1. In `updateRoutes()` method (around line 535), add:
|
||||||
2. ✅ Test ACME initialization with various configurations
|
```typescript
|
||||||
3. ✅ Verify certificate acquisition works in all scenarios
|
// Set route update callback for ACME challenges
|
||||||
4. ✅ Test error handling and messaging
|
this.certManager.setUpdateRoutesCallback(async (routes) => {
|
||||||
|
await this.updateRoutes(routes);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
### Phase 3: Documentation ✅
|
2. Consider refactoring the certificate manager setup into a helper method to avoid duplication:
|
||||||
1. ✅ Update main README with clear ACME examples
|
```typescript
|
||||||
2. ✅ Create dedicated certificate-management.md guide
|
private async setupCertificateManager(
|
||||||
3. ✅ Add migration guide for v18 to v19 users
|
routes: IRouteConfig[],
|
||||||
4. ✅ Include troubleshooting section
|
certStore: string,
|
||||||
|
acmeOptions?: any
|
||||||
|
): Promise<SmartCertManager> {
|
||||||
|
const certManager = new SmartCertManager(routes, certStore, acmeOptions);
|
||||||
|
|
||||||
## Example Simplified Configuration
|
// Always set up the route update callback
|
||||||
|
certManager.setUpdateRoutesCallback(async (routes) => {
|
||||||
|
await this.updateRoutes(routes);
|
||||||
|
});
|
||||||
|
|
||||||
```typescript
|
if (this.networkProxyBridge.getNetworkProxy()) {
|
||||||
// Simplified configuration with top-level ACME
|
certManager.setNetworkProxy(this.networkProxyBridge.getNetworkProxy());
|
||||||
const proxy = new SmartProxy({
|
}
|
||||||
// Global ACME settings (applies to all routes with certificate: 'auto')
|
|
||||||
acme: {
|
|
||||||
email: 'ssl@example.com',
|
|
||||||
useProduction: false,
|
|
||||||
port: 80 // Automatically listened on when needed
|
|
||||||
},
|
|
||||||
|
|
||||||
routes: [
|
return certManager;
|
||||||
{
|
}
|
||||||
name: 'secure-site',
|
```
|
||||||
match: { domains: 'example.com', ports: 443 },
|
|
||||||
action: {
|
|
||||||
type: 'forward',
|
|
||||||
target: { host: 'localhost', port: 8080 },
|
|
||||||
tls: {
|
|
||||||
mode: 'terminate',
|
|
||||||
certificate: 'auto' // Uses global ACME settings
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
// Or with route-specific ACME override
|
### Success Criteria
|
||||||
const proxy = new SmartProxy({
|
- [ ] ACME certificate acquisition works after route updates
|
||||||
routes: [
|
- [ ] No "No route update callback set" errors occur
|
||||||
{
|
- [ ] All tests pass
|
||||||
name: 'special-site',
|
- [ ] Documentation clearly explains the behavior
|
||||||
match: { domains: 'special.com', ports: 443 },
|
- [ ] Code is more maintainable and less prone to regression
|
||||||
action: {
|
|
||||||
type: 'forward',
|
|
||||||
target: { host: 'localhost', port: 8080 },
|
|
||||||
tls: {
|
|
||||||
mode: 'terminate',
|
|
||||||
certificate: 'auto',
|
|
||||||
acme: { // Route-specific override
|
|
||||||
email: 'special@example.com',
|
|
||||||
useProduction: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Success Criteria ✅
|
### Timeline
|
||||||
1. ✅ Users can configure ACME at top-level for all routes
|
- Phase 1: Immediate fix (30 minutes)
|
||||||
2. ✅ Clear error messages guide users to correct configuration
|
- Phase 2: Test creation (1 hour)
|
||||||
3. ✅ Certificate acquisition works with minimal configuration
|
- Phase 3: Documentation (30 minutes)
|
||||||
4. ✅ Documentation clearly explains all configuration options
|
- Phase 4: Refactoring (1 hour)
|
||||||
5. ✅ Migration from v18 to v19 is straightforward
|
|
||||||
|
|
||||||
## Timeline
|
Total estimated time: 3 hours
|
||||||
- Phase 1: 2-3 days
|
|
||||||
- Phase 2: 1-2 days
|
|
||||||
- Phase 3: 1 day
|
|
||||||
|
|
||||||
Total estimated time: 5-6 days
|
### Notes
|
||||||
|
- This is a critical bug that affects production use of SmartProxy
|
||||||
## Notes
|
- The fix is straightforward but requires careful testing
|
||||||
- Maintain backward compatibility with existing route-level ACME config
|
- Consider backporting to v19.2.x branch if maintaining multiple versions
|
||||||
- Consider adding a configuration wizard for interactive setup
|
|
||||||
- Explore integration with popular DNS providers for DNS-01 challenges
|
|
||||||
- Add metrics/monitoring for certificate renewal status
|
|
Reference in New Issue
Block a user