WebSocket Support (SS over WSS) and OutlineCaddy Integration
This PR adds WebSocket transport support for Shadowsocks connections, enabling SS over WSS to bypass restrictive network filters. It fixes https://github.com/Jigsaw-Code/outline-server/issues/1676 where much of the work was discussed.
## Features
### WebSocket Transport Support
- New listener-based API model allowing access keys to specify WebSocket listeners alongside traditional Shadowsocks
- WebSocket server automatically enabled when a WebSocket access key is created
- `GET /access-keys/{id}` returns YAML configuration for WebSocket-enabled keys (Outline Client v1.15.0+)
- Supports both TCP over WebSocket (`websocket-stream`) and UDP over WebSocket (`websocket-packet`)
### Embedded OutlineCaddy Server
- New [outline_caddy_server.ts](cci:7://file:///Users/lunar/Documents/git/outline-server/src/shadowbox/server/outline_caddy_server.ts:0:0-0:0) module for managing Caddy as the WebSocket reverse proxy
- YAML-based Caddyfile configuration with automatic HTTPS via ACME
- API proxy support allowing the management API to be accessed via TLS-terminated Caddy
- Internal API proxy uses HTTPS with self-signed cert verification skipped
---
## API Changes
### New Endpoints
- `PUT /server/listeners-for-new-access-keys` - Configure listener types for new keys
- `PUT /server/web-server` - Configure embedded Caddy web server
### Modified Endpoints
- `GET /access-keys/{id}` - Returns JSON for traditional keys, **YAML for WebSocket keys**
- `POST /access-keys` - Now accepts `listeners` array parameter
### AccessKey Schema
- Added optional `listeners` field (`tcp`, `udp`, `websocket-stream`, `websocket-packet`)
- Added optional `dynamicConfig` field for WebSocket transport configuration
- `password`, `port`, `method`, `accessUrl` are now optional (omitted for WSS-only keys)
---
## Build & CI Changes
### Docker Build Workflow
- Rewrote multi-arch build to use Task-based builds instead of Docker buildx matrix
- Added Node.js, Go, and Task setup steps
- Builds both `amd64` and `arm64` images sequentially
- Creates and pushes multi-arch manifest
### GitHub Actions Concurrency
- Added workflow-specific prefixes to concurrency groups to prevent cross-workflow cancellation
- `build-and-test-*` for build workflow
- `license-*` for license checks
### Taskfile Changes
- Added `download_xcaddy` task for cross-platform xcaddy downloads
- Build task now includes OutlineCaddy binary built via xcaddy with plugins:
- `outlinecaddy@v0.0.1`
- `caddy_yaml_adapter`
- `caddy-l4@v0.0.0-20251201210923-0c96591f5650`
---
## Dependencies
### Go Dependencies (`go.mod`, `go.sum`)
- Updated `prometheus/client_golang` to v1.20.5
- Updated `prometheus/common` to v0.62.0
- Updated `oschwald/geoip2-golang` to v1.11.0
- Updated `golang.org/x/crypto` to v0.32.0
- Updated `golang.org/x/sync` to v0.11.0
- Updated `google.golang.org/protobuf` to v1.36.4
- Bumped outline-ss-server to v1.9.2
---
## Documentation
### README.md
- Added "WebSocket Support (SS over WSS)" section with usage examples
- Documented listener configuration API
- Added YAML response example for WebSocket keys
### api.yml
- Full OpenAPI documentation for new endpoints
- Updated AccessKey schema with optional SS fields
- Documented dual response types (JSON/YAML) for `GET /access-keys/{id}`
---
## Usage Examples
```sh
### Configure WebSocket Listeners
curl --insecure -X PUT -H "Content-Type: application/json" \
-d '{
"tcp": {"port": 443},
"udp": {"port": 443},
"websocketStream": {"path": "/tcp", "webServerPort": 8080},
"websocketPacket": {"path": "/udp", "webServerPort": 8080}
}' \
$API_URL/server/listeners-for-new-access-keys
### Enable Caddy Web Server
curl --insecure -X PUT -H "Content-Type: application/json" \
-d '{
"enabled": true,
"autoHttps": true,
"email": "admin@example.com",
"domain": "your-domain.com"
}' \
$API_URL/server/web-server
### Create WebSocket-Enabled Access Key
curl --insecure -X POST -H "Content-Type: application/json" \
-d '{"name": "WSS User", "listeners": ["tcp", "udp", "websocket-stream", "websocket-packet"]}' \
$API_URL/access-keys
### Get WebSocket Key Config (returns YAML)
curl --insecure $API_URL/access-keys/1
合并状态:未合并 2 条评论