feat(entrypoint): add inbound mTLS profiles for HTTPS

Add root-level inbound_mtls_profiles combining optional system CAs with PEM
CA files, and entrypoint.inbound_mtls_profile to require client certificates
on every HTTPS connection. Route-level inbound_mtls_profile is allowed only
without a global profile; per-handshake TLS picks ClientCAs from SNI, and
requests fail with 421 when Host and SNI would select different mTLS routes.

Compile pools at init (SetInboundMTLSProfiles from state.initEntrypoint) and
reject unknown profile refs or mixed global-plus-route configuration.

Extend config.example.yml and package READMEs; add entrypoint and config
tests for TLS mutation, handshakes, and validation.
This commit is contained in:
yusing
2026-04-09 17:51:18 +08:00
parent 6cafbcf669
commit 2a3823091d
18 changed files with 886 additions and 17 deletions

View File

@@ -0,0 +1,15 @@
package types
import "errors"
type InboundMTLSProfile struct {
UseSystemCAs bool `json:"use_system_cas,omitempty"`
CAFiles []string `json:"ca_files,omitempty" validate:"omitempty,dive,filepath"`
}
func (cfg InboundMTLSProfile) Validate() error {
if !cfg.UseSystemCAs && len(cfg.CAFiles) == 0 {
return errors.New("at least one trust source is required for inbound mTLS profile")
}
return nil
}

View File

@@ -0,0 +1,34 @@
package types
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestInboundMTLSProfileValidate(t *testing.T) {
t.Run("requires at least one trust source", func(t *testing.T) {
var profile InboundMTLSProfile
err := profile.Validate()
require.Error(t, err)
require.ErrorContains(t, err, "trust source")
})
t.Run("system CA only", func(t *testing.T) {
profile := InboundMTLSProfile{UseSystemCAs: true}
require.NoError(t, profile.Validate())
})
t.Run("CA file only", func(t *testing.T) {
profile := InboundMTLSProfile{CAFiles: []string{"/tmp/ca.pem"}}
require.NoError(t, profile.Validate())
})
t.Run("system CA and CA files", func(t *testing.T) {
profile := InboundMTLSProfile{
UseSystemCAs: true,
CAFiles: []string{"/tmp/ca.pem"},
}
require.NoError(t, profile.Validate())
})
}

View File

@@ -37,6 +37,7 @@ type (
HomepageItem() homepage.Item
DisplayName() string
ContainerInfo() *Container
InboundMTLSProfileRef() string
GetAgent() *agentpool.Agent