fix(mediaserver): handle custom hostname with self-signed certs
This commit is contained in:
parent
4a863a3212
commit
7afa84505e
internal
@ -296,6 +296,74 @@ func testIntegration(t *testing.T, mediaServerConfig config.MediaServerSource) {
|
||||
<-done
|
||||
}
|
||||
|
||||
func TestIntegrationCustomHost(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(t.Context(), 10*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
logger := testhelpers.NewTestLogger(t).With("component", "integration")
|
||||
dockerClient, err := dockerclient.NewClientWithOpts(dockerclient.FromEnv, dockerclient.WithAPIVersionNegotiation())
|
||||
require.NoError(t, err)
|
||||
|
||||
configService := setupConfigService(t, config.Config{
|
||||
Sources: config.Sources{
|
||||
MediaServer: config.MediaServerSource{
|
||||
Host: "rtmp.example.com",
|
||||
RTMP: config.RTMPSource{Enabled: true},
|
||||
},
|
||||
},
|
||||
})
|
||||
screen, screenCaptureC, getContents := setupSimulationScreen(t)
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer func() {
|
||||
done <- struct{}{}
|
||||
}()
|
||||
|
||||
require.NoError(t, app.Run(ctx, buildAppParams(t, configService, dockerClient, screen, screenCaptureC, logger)))
|
||||
}()
|
||||
|
||||
time.Sleep(time.Second)
|
||||
sendKey(t, screen, tcell.KeyF1, ' ')
|
||||
|
||||
require.EventuallyWithT(
|
||||
t,
|
||||
func(t *assert.CollectT) {
|
||||
assert.True(t, contentsIncludes(getContents(), "rtmp://rtmp.example.com:1935/live"), "expected to see custom host name")
|
||||
},
|
||||
waitTime,
|
||||
time.Second,
|
||||
"expected to see custom host name",
|
||||
)
|
||||
printScreen(t, getContents, "Ater opening the app with a custom host name")
|
||||
|
||||
require.EventuallyWithT(
|
||||
t,
|
||||
func(c *assert.CollectT) {
|
||||
conn, err := tls.Dial("tcp", "localhost:9997", &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
})
|
||||
require.NoError(c, err)
|
||||
|
||||
require.Nil(
|
||||
c,
|
||||
conn.
|
||||
ConnectionState().
|
||||
PeerCertificates[0].
|
||||
VerifyHostname("rtmp.example.com"),
|
||||
"expected to verify custom host name",
|
||||
)
|
||||
},
|
||||
waitTime,
|
||||
time.Second,
|
||||
"expected to connect to API using self-signed TLS cert with custom host name",
|
||||
)
|
||||
|
||||
cancel()
|
||||
|
||||
<-done
|
||||
}
|
||||
|
||||
func TestIntegrationCustomTLSCerts(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(t.Context(), 10*time.Minute)
|
||||
defer cancel()
|
||||
@ -335,7 +403,6 @@ func TestIntegrationCustomTLSCerts(t *testing.T) {
|
||||
block, _ := pem.Decode(certPEM)
|
||||
require.NotNil(c, block, "failed to decode PEM block containing certificate")
|
||||
require.True(c, block.Type == "CERTIFICATE", "expected PEM block to be a certificate")
|
||||
certDERBytes := block.Bytes
|
||||
|
||||
rootCAs := x509.NewCertPool()
|
||||
require.True(c, rootCAs.AppendCertsFromPEM(certPEM), "failed to append cert to root CA pool")
|
||||
@ -347,12 +414,10 @@ func TestIntegrationCustomTLSCerts(t *testing.T) {
|
||||
})
|
||||
require.NoError(c, err)
|
||||
|
||||
state := conn.ConnectionState()
|
||||
peerCert := state.PeerCertificates[0]
|
||||
|
||||
expectedCert, err := x509.ParseCertificate(certDERBytes)
|
||||
peerCert := conn.ConnectionState().PeerCertificates[0]
|
||||
wantCert, err := x509.ParseCertificate(block.Bytes)
|
||||
require.NoError(c, err)
|
||||
require.True(c, peerCert.Equal(expectedCert), "expected peer certificate to match the expected certificate")
|
||||
require.True(c, peerCert.Equal(wantCert), "expected peer certificate to match the expected certificate")
|
||||
},
|
||||
waitTime,
|
||||
time.Second,
|
||||
@ -365,52 +430,6 @@ func TestIntegrationCustomTLSCerts(t *testing.T) {
|
||||
<-done
|
||||
}
|
||||
|
||||
func TestIntegrationCustomRTMPURL(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(t.Context(), 10*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
logger := testhelpers.NewTestLogger(t).With("component", "integration")
|
||||
dockerClient, err := dockerclient.NewClientWithOpts(dockerclient.FromEnv, dockerclient.WithAPIVersionNegotiation())
|
||||
require.NoError(t, err)
|
||||
|
||||
configService := setupConfigService(t, config.Config{
|
||||
Sources: config.Sources{
|
||||
MediaServer: config.MediaServerSource{
|
||||
Host: "rtmp.live.tv",
|
||||
RTMP: config.RTMPSource{Enabled: true},
|
||||
},
|
||||
},
|
||||
})
|
||||
screen, screenCaptureC, getContents := setupSimulationScreen(t)
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer func() {
|
||||
done <- struct{}{}
|
||||
}()
|
||||
|
||||
require.NoError(t, app.Run(ctx, buildAppParams(t, configService, dockerClient, screen, screenCaptureC, logger)))
|
||||
}()
|
||||
|
||||
time.Sleep(time.Second)
|
||||
sendKey(t, screen, tcell.KeyF1, ' ')
|
||||
|
||||
require.EventuallyWithT(
|
||||
t,
|
||||
func(t *assert.CollectT) {
|
||||
assert.True(t, contentsIncludes(getContents(), "rtmp://rtmp.live.tv:1935/live"), "expected to see custom host name")
|
||||
},
|
||||
waitTime,
|
||||
time.Second,
|
||||
"expected to see custom host name",
|
||||
)
|
||||
printScreen(t, getContents, "Ater opening the app with a custom host name")
|
||||
|
||||
cancel()
|
||||
|
||||
<-done
|
||||
}
|
||||
|
||||
func TestIntegrationRestartDestination(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(t.Context(), 10*time.Minute)
|
||||
defer cancel()
|
||||
|
@ -98,7 +98,12 @@ type OptionalNetAddr struct {
|
||||
//
|
||||
// Callers must consume the state channel exposed via [C].
|
||||
func NewActor(ctx context.Context, params NewActorParams) (_ *Actor, err error) {
|
||||
keyPairInternal, err := generateTLSCert()
|
||||
dnsNames := []string{"localhost"}
|
||||
if params.Host != "" {
|
||||
dnsNames = append(dnsNames, params.Host)
|
||||
}
|
||||
|
||||
keyPairInternal, err := generateTLSCert(dnsNames...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("generate TLS cert: %w", err)
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
// generateTLSCert generates a self-signed TLS certificate and private key.
|
||||
func generateTLSCert() (domain.KeyPair, error) {
|
||||
func generateTLSCert(dnsNames ...string) (domain.KeyPair, error) {
|
||||
privKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
if err != nil {
|
||||
return domain.KeyPair{}, err
|
||||
@ -37,7 +37,7 @@ func generateTLSCert() (domain.KeyPair, error) {
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
||||
BasicConstraintsValid: true,
|
||||
DNSNames: []string{"localhost"},
|
||||
DNSNames: dnsNames,
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &privKey.PublicKey, privKey)
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func TestGenerateTLSCert(t *testing.T) {
|
||||
keyPair, err := generateTLSCert()
|
||||
keyPair, err := generateTLSCert("localhost", "rtmp.example.com")
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, keyPair.Cert)
|
||||
require.NotEmpty(t, keyPair.Key)
|
||||
@ -33,6 +33,8 @@ func TestGenerateTLSCert(t *testing.T) {
|
||||
assert.True(t, cert.BasicConstraintsValid, "basic constraints should be valid")
|
||||
assert.Contains(t, cert.ExtKeyUsage, x509.ExtKeyUsageServerAuth)
|
||||
assert.Contains(t, cert.ExtKeyUsage, x509.ExtKeyUsageClientAuth)
|
||||
assert.Contains(t, cert.DNSNames, "localhost", "DNS names should include localhost")
|
||||
assert.Contains(t, cert.DNSNames, "rtmp.example.com", "DNS names should include rtmp.example.com")
|
||||
|
||||
block, _ = pem.Decode(keyPair.Key)
|
||||
require.NotNil(t, block, "failed to decode private key PEM")
|
||||
|
Loading…
x
Reference in New Issue
Block a user