Add Shadowsocks over WebSocket (SS over WSS) Support
needs more infoserverapikey/management
# Feature Request: Add Shadowsocks over WebSocket (SS over WSS) Support
Fork where changes were made: https://github.com/unredacted/outline-server
## Summary
Add support for tunneling Shadowsocks traffic over WebSocket connections to enhance censorship resistance and improve connectivity in restrictive network environments.
## Motivation
### Current Limitations
The current Outline Server implementation only supports direct Shadowsocks connections, which can be problematic in several scenarios:
1. **Deep Packet Inspection (DPI)**: Modern censorship systems can detect and block Shadowsocks traffic patterns
2. **Corporate Firewalls**: Many enterprise networks only allow HTTP/HTTPS traffic through proxies
3. **Network Restrictions**: Some networks block non-standard ports or protocols
4. **Protocol Fingerprinting**: Direct Shadowsocks connections have identifiable characteristics
## Proposed Solution
I've implemented a complete solution that adds WebSocket transport support while maintaining backward compatibility. The implementation allows servers to support both traditional Shadowsocks connections and WebSocket-tunneled connections simultaneously.
### Key Features
1. **Flexible Configuration**: Each access key can optionally enable WebSocket transport
2. **Dual Protocol Support**: Separate paths for TCP and UDP over WebSocket
3. **Dynamic Client Configuration**: Automatically generates appropriate client configs
4. **Backward Compatible**: Servers without WebSocket keys continue using the legacy format
5. **Mixed Mode Operation**: Supports both WebSocket and traditional clients simultaneously
### API Changes
New WebSocket configuration options for access keys:
```json
{
"name": "User with WebSocket",
"websocket": {
"enabled": true,
"tcpPath": "/tcp",
"udpPath": "/udp",
"domain": "example.com",
"tls": true
}
}
```
### Configuration Format
The implementation automatically generates the appropriate outline-ss-server configuration:
**When WebSocket keys exist:**
```yaml
web:
servers:
- id: outline-ws-server
listen:
- '127.0.0.1:8080'
services:
- listeners:
- type: tcp
address: '[::]:443'
- type: udp
address: '[::]:443'
keys:
- id: '0'
cipher: chacha20-ietf-poly1305
secret: <secret>
- listeners:
- type: websocket-stream
web_server: outline-ws-server
path: /tcp
- type: websocket-packet
web_server: outline-ws-server
path: /udp
keys:
- id: '1'
cipher: chacha20-ietf-poly1305
secret: <secret>
```
### Client Configuration
WebSocket-enabled keys return dynamic YAML configuration:
```yaml
transport:
$type: tcpudp
tcp:
$type: shadowsocks
endpoint:
$type: websocket
url: 'wss://example.com/tcp'
cipher: chacha20-ietf-poly1305
secret: <secret>
udp:
$type: shadowsocks
endpoint:
$type: websocket
url: 'wss://example.com/udp'
cipher: chacha20-ietf-poly1305
secret: <secret>
```
## Implementation Details
### Components Modified
1. **API Schema** (`api.yml`): Added WebSocketConfig schema
2. **Data Model** (`access_key.ts`): Extended interfaces for WebSocket support
3. **Manager Service** (`manager_service.ts`): Added validation and dynamic config generation
4. **Access Key Repository** (`server_access_key.ts`): Stores WebSocket configuration
5. **Shadowsocks Server** (`outline_shadowsocks_server.ts`): Generates WebSocket-aware configs
6. **Dependencies**: Updated to outline-ss-server v1.9.2 with WebSocket support
### Reverse Proxy Setup
The WebSocket server runs on a separate port (8080) and requires reverse proxy configuration with nginx example below:
```nginx
location /tcp {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /udp {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
```
This can also be fronted by using something like Cloudflare Tunnel.
## Testing
The implementation has been thoroughly tested with:
- Creating WebSocket-enabled access keys via API
- Generating proper server configurations for mixed environments
- Client connections using dynamic access key configurations
- Simultaneous traditional and WebSocket client connections
- Multi-platform Docker image builds (amd64/arm64)
## Future Enhancements
1. **Configurable WebSocket Port**: Currently hardcoded to 8080
2. **Custom Headers**: Support for additional WebSocket headers
3. **Path Randomization**: Generate random paths for enhanced security
## Contribution
I have a working implementation in my fork that I'm ready to contribute. The code:
- Maintains backward compatibility
- Follows existing code patterns and conventions
- Includes proper error handling and validation
- Has been tested in production environments
Would the team be interested in reviewing a pull request for this feature? I'm happy to make any adjustments to align with the project's goals and standards.
## References
- [[outline-ss-server v1.9.2](https://github.com/Jigsaw-Code/outline-ss-server/releases/tag/v1.9.2)](https://github.com/Jigsaw-Code/outline-ss-server/releases/tag/v1.9.2) - Includes WebSocket support
- [[WebSocket Protocol RFC 6455](https://datatracker.ietf.org/doc/html/rfc6455)](https://datatracker.ietf.org/doc/html/rfc6455)
10 条评论