# How S-UI Handles TLS/SSL Certificates for Secure Connections

> Learn how S-UI uses configurable HTTPS, dynamic TLS management, and self-signed certificates to create secure connections. Explore certificate handling in our documentation.

- Repository: [Alireza Ahmadi/s-ui](https://github.com/alireza0/s-ui)
- Tags: how-to-guide
- Published: 2026-05-22

---

**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`](https://github.com/alireza0/s-ui/blob/main/service/setting.go) and applying them via `tls.LoadX509KeyPair` in [`web/web.go`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/web/web.go), the server checks for configured certificate paths and constructs a `tls.Config` with the loaded key pair:

```go
// 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`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/service/tls.go), the system propagates changes to all associated inbounds and restarts the affected services:

```go
// 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`](https://github.com/alireza0/s-ui/blob/main/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:

```go
// 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`](https://github.com/alireza0/s-ui/blob/main/util/subToJson.go), the transport explicitly disables validation to accommodate self-signed or untrusted certificates on remote subscription servers:

```go
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`](https://github.com/alireza0/s-ui/blob/main/service/setting.go) verifies that files exist at the specified paths when saving `webCertFile` or `webKeyFile` settings:

```go
// 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:

```json
{
  "webCertFile": "/etc/s-ui/cert.pem",
  "webKeyFile":  "/etc/s-ui/key.pem"
}

```

## Summary

- **Web UI Security**: S-UI enables HTTPS via `tls.LoadX509KeyPair` in [`web/web.go`](https://github.com/alireza0/s-ui/blob/main/web/web.go) when `webCertFile` and `webKeyFile` settings are provided, falling back to HTTP otherwise.
- **Dynamic Service Updates**: The [`service/tls.go`](https://github.com/alireza0/s-ui/blob/main/service/tls.go) handler propagates TLS configuration changes to related inbounds via database relationships, restarting only affected services.
- **Auto-Generation**: Built-in `generateTLSKeyPair` in [`service/server.go`](https://github.com/alireza0/s-ui/blob/main/service/server.go) creates temporary self-signed certificates using the sing-box library.
- **Subscription Fetching**: External HTTPS subscriptions are fetched with `InsecureSkipVerify` enabled in [`util/subToJson.go`](https://github.com/alireza0/s-ui/blob/main/util/subToJson.go) to handle untrusted certificates.
- **Path Validation**: File existence checks in [`service/setting.go`](https://github.com/alireza0/s-ui/blob/main/service/setting.go) prevent 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`](https://github.com/alireza0/s-ui/blob/main/service/setting.go) and initializes a TLS listener in [`web/web.go`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/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.