How S-UI Handles TLS/SSL Certificates for Secure Connections
S-UI secures connections through configurable HTTPS for the web panel, dynamic TLS management for proxy inbounds/outbounds, and built-in self-signed certificate generation, validating certificate paths in service/setting.go and applying them via tls.LoadX509KeyPair in web/web.go.
S-UI, a web-based management panel for the sing-box proxy platform, implements comprehensive TLS/SSL certificate handling across its architecture. The system supports production-grade HTTPS for the administrative interface, per-service TLS configuration for proxy traffic, and automatic certificate generation for testing environments.
Web UI HTTPS Configuration
The S-UI web panel supports HTTPS by loading certificate and private key files specified in the application settings. When webCertFile and webKeyFile values are configured, the application initializes a TLS-enabled listener instead of plain HTTP.
In web/web.go, the server checks for configured certificate paths and constructs a tls.Config with the loaded key pair:
// web/web.go – start the listener
certFile, _ := s.settingService.GetCertFile()
keyFile, _ := s.settingService.GetKeyFile()
if certFile != "" || keyFile != "" {
cert, err := tls.LoadX509KeyPair(certFile, keyFile) // ← loads PEM files
c := &tls.Config{Certificates: []tls.Certificate{cert}}
listener = network.NewAutoHttpsListener(listener)
listener = tls.NewListener(listener, c) // ← TLS‑enabled listener
}
If certificate files are not provided, S-UI falls back to standard HTTP. The certificate paths are validated for existence before persistence in service/setting.go using the fileExists helper function.
Dynamic TLS for Inbound and Outbound Services
Beyond the web interface, S-UI manages TLS settings for individual proxy services through the model.Tls database table and the service/tls.go handler. Each inbound or outbound configuration can reference a specific TLS entry via a tls_id foreign key.
When a TLS configuration is modified through service/tls.go, the system propagates changes to all associated inbounds and restarts the affected services:
// service/tls.go – after editing a TLS entry
var inbounds []model.Inbound
tx.Model(model.Inbound{}).Preload("Tls").
Where("tls_id = ?", tls.Id).Find(&inbounds)
// …update links, out‑json, and restart inbounds/services
This architecture allows administrators to update certificates for proxy services without restarting the entire S-UI application, ensuring minimal disruption to active connections.
Automatic Certificate Generation
For testing environments or rapid deployment, S-UI includes a self-signed certificate generation feature in service/server.go. The ServerService provides a generateTLSKeyPair method that leverages the sing-box library to create valid PEM-encoded certificates programmatically.
The implementation uses tls.GenerateCertificate from the sing-box common package:
// service/server.go – generate a self‑signed TLS pair
privateKeyPem, publicKeyPem, err := tls.GenerateCertificate(
nil, nil, time.Now, serverName, time.Now().AddDate(0, 12, 0))
This generates a 12-month self-signed certificate for the specified server name, returning both the private key and public certificate in PEM format. Administrators can save these to disk or apply them directly for temporary secure connections.
TLS Behavior for External Subscriptions
When fetching external subscription files from HTTPS endpoints, S-UI configures the HTTP client to skip certificate verification. In util/subToJson.go, the transport explicitly disables validation to accommodate self-signed or untrusted certificates on remote subscription servers:
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // ← ignore cert verification
}
This lenient approach applies strictly to subscription fetching operations and does not affect the security of proxy traffic or the web administrative interface.
Configuration Validation and Storage
Certificate file paths undergo validation before persistence. The SettingService in service/setting.go verifies that files exist at the specified paths when saving webCertFile or webKeyFile settings:
// service/setting.go – validate existence before saving
if key == "webCertFile" || key == "webKeyFile" {
err = s.fileExists(obj) // returns error if path missing
}
Users configure certificates through the Settings UI or REST API by providing absolute paths to PEM-encoded files:
{
"webCertFile": "/etc/s-ui/cert.pem",
"webKeyFile": "/etc/s-ui/key.pem"
}
Summary
- Web UI Security: S-UI enables HTTPS via
tls.LoadX509KeyPairinweb/web.gowhenwebCertFileandwebKeyFilesettings are provided, falling back to HTTP otherwise. - Dynamic Service Updates: The
service/tls.gohandler propagates TLS configuration changes to related inbounds via database relationships, restarting only affected services. - Auto-Generation: Built-in
generateTLSKeyPairinservice/server.gocreates temporary self-signed certificates using the sing-box library. - Subscription Fetching: External HTTPS subscriptions are fetched with
InsecureSkipVerifyenabled inutil/subToJson.goto handle untrusted certificates. - Path Validation: File existence checks in
service/setting.goprevent configuration of non-existent certificate files.
Frequently Asked Questions
How do I enable HTTPS for the S-UI web panel?
Provide valid certificate and private key file paths in the Settings UI or via API using the webCertFile and webKeyFile keys. The application validates file existence in service/setting.go and initializes a TLS listener in web/web.go using tls.LoadX509KeyPair. If these settings are empty, S-UI serves the web interface over HTTP.
Can S-UI generate TLS certificates automatically?
Yes. The ServerService in service/server.go includes a generateTLSKeyPair method that calls tls.GenerateCertificate from the sing-box library to create self-signed certificates valid for 12 months. This feature is intended for testing and temporary deployments before production certificates are obtained.
How does S-UI update TLS certificates for active proxy services?
TLS configurations are stored in the model.Tls table and managed through service/tls.go. When a TLS record is modified, the service queries all inbounds referencing that tls_id, updates their JSON configurations, and restarts only the affected inbounds. This targeted restart approach updates certificates without restarting the entire application.
Why does S-UI skip TLS verification for subscriptions?
In util/subToJson.go, the HTTP client sets InsecureSkipVerify: true when fetching external subscription URLs. This design choice accommodates subscription servers using self-signed or expired certificates, ensuring users can import configurations from various sources. This behavior is isolated to subscription fetching and does not compromise the TLS security of the web panel or proxy connections.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →