Skip to content

Commit

Permalink
Add Trillian TLS support for ct_server (#1551)
Browse files Browse the repository at this point in the history
* Add Trillian TLS support for ct_server

Signed-off-by: Firas Ghanmi <fghanmi@redhat.com>

* update CHANGELOG.md

Signed-off-by: Firas Ghanmi <fghanmi@redhat.com>

* update trillianTLSCACertFile variable name

Signed-off-by: Firas Ghanmi <fghanmi@redhat.com>

---------

Signed-off-by: Firas Ghanmi <fghanmi@redhat.com>
  • Loading branch information
fghanmi authored Aug 8, 2024
1 parent 66f08c2 commit f94433c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 61 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## HEAD

* Add TLS support for Trillian: By using `--trillian_tls_ca_cert_file` flag, users can provide a CA certificate, that is used to establish a secure communication with Trillian log server. In https://github.com/google/certificate-transparency-go/pull/1525
* Add TLS support for Trillian: By using `--trillian_tls_ca_cert_file` flag, users can provide a CA certificate, that is used to establish a secure communication with Trillian log server. In https://github.com/google/certificate-transparency-go/pull/1551

* Add TLS support for ct_server: By using `--tls_certificate` and `--tls_key` flags, users can provide a service certificate and key, that enables the server to handle HTTPS requests. In https://github.com/google/certificate-transparency-go/pull/1523

Expand Down
59 changes: 35 additions & 24 deletions trillian/ctfe/ct_server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import (
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/client/v3/naming/endpoints"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/resolver/manual"
"google.golang.org/protobuf/proto"
Expand All @@ -57,29 +58,30 @@ import (

// Global flags that affect all log instances.
var (
httpEndpoint = flag.String("http_endpoint", "localhost:6962", "Endpoint for HTTP (host:port)")
tlsCert = flag.String("tls_certificate", "", "Path to server TLS certificate")
tlsKey = flag.String("tls_key", "", "Path to server TLS private key")
metricsEndpoint = flag.String("metrics_endpoint", "", "Endpoint for serving metrics; if left empty, metrics will be visible on --http_endpoint")
rpcBackend = flag.String("log_rpc_server", "", "Backend specification; comma-separated list or etcd service name (if --etcd_servers specified). If unset backends are specified in config (as a LogMultiConfig proto)")
rpcDeadline = flag.Duration("rpc_deadline", time.Second*10, "Deadline for backend RPC requests")
getSTHInterval = flag.Duration("get_sth_interval", time.Second*180, "Interval between internal get-sth operations (0 to disable)")
logConfig = flag.String("log_config", "", "File holding log config in text proto format")
maxGetEntries = flag.Int64("max_get_entries", 0, "Max number of entries we allow in a get-entries request (0=>use default 1000)")
etcdServers = flag.String("etcd_servers", "", "A comma-separated list of etcd servers")
etcdHTTPService = flag.String("etcd_http_service", "trillian-ctfe-http", "Service name to announce our HTTP endpoint under")
etcdMetricsService = flag.String("etcd_metrics_service", "trillian-ctfe-metrics-http", "Service name to announce our HTTP metrics endpoint under")
maskInternalErrors = flag.Bool("mask_internal_errors", false, "Don't return error strings with Internal Server Error HTTP responses")
tracing = flag.Bool("tracing", false, "If true opencensus Stackdriver tracing will be enabled. See https://opencensus.io/.")
tracingProjectID = flag.String("tracing_project_id", "", "project ID to pass to stackdriver. Can be empty for GCP, consult docs for other platforms.")
tracingPercent = flag.Int("tracing_percent", 0, "Percent of requests to be traced. Zero is a special case to use the DefaultSampler")
quotaRemote = flag.Bool("quota_remote", true, "Enable requesting of quota for IP address sending incoming requests")
quotaIntermediate = flag.Bool("quota_intermediate", true, "Enable requesting of quota for intermediate certificates in submitted chains")
handlerPrefix = flag.String("handler_prefix", "", "If set e.g. to '/logs' will prefix all handlers that don't define a custom prefix")
pkcs11ModulePath = flag.String("pkcs11_module_path", "", "Path to the PKCS#11 module to use for keys that use the PKCS#11 interface")
cacheType = flag.String("cache_type", "noop", "Supported cache type: noop, lru (Default: noop)")
cacheSize = flag.Int("cache_size", -1, "Size parameter set to 0 makes cache of unlimited size")
cacheTTL = flag.Duration("cache_ttl", -1*time.Second, "Providing 0 TTL turns expiring off")
httpEndpoint = flag.String("http_endpoint", "localhost:6962", "Endpoint for HTTP (host:port)")
tlsCert = flag.String("tls_certificate", "", "Path to server TLS certificate")
tlsKey = flag.String("tls_key", "", "Path to server TLS private key")
metricsEndpoint = flag.String("metrics_endpoint", "", "Endpoint for serving metrics; if left empty, metrics will be visible on --http_endpoint")
rpcBackend = flag.String("log_rpc_server", "", "Backend specification; comma-separated list or etcd service name (if --etcd_servers specified). If unset backends are specified in config (as a LogMultiConfig proto)")
rpcDeadline = flag.Duration("rpc_deadline", time.Second*10, "Deadline for backend RPC requests")
getSTHInterval = flag.Duration("get_sth_interval", time.Second*180, "Interval between internal get-sth operations (0 to disable)")
logConfig = flag.String("log_config", "", "File holding log config in text proto format")
maxGetEntries = flag.Int64("max_get_entries", 0, "Max number of entries we allow in a get-entries request (0=>use default 1000)")
etcdServers = flag.String("etcd_servers", "", "A comma-separated list of etcd servers")
etcdHTTPService = flag.String("etcd_http_service", "trillian-ctfe-http", "Service name to announce our HTTP endpoint under")
etcdMetricsService = flag.String("etcd_metrics_service", "trillian-ctfe-metrics-http", "Service name to announce our HTTP metrics endpoint under")
maskInternalErrors = flag.Bool("mask_internal_errors", false, "Don't return error strings with Internal Server Error HTTP responses")
tracing = flag.Bool("tracing", false, "If true opencensus Stackdriver tracing will be enabled. See https://opencensus.io/.")
tracingProjectID = flag.String("tracing_project_id", "", "project ID to pass to stackdriver. Can be empty for GCP, consult docs for other platforms.")
tracingPercent = flag.Int("tracing_percent", 0, "Percent of requests to be traced. Zero is a special case to use the DefaultSampler")
quotaRemote = flag.Bool("quota_remote", true, "Enable requesting of quota for IP address sending incoming requests")
quotaIntermediate = flag.Bool("quota_intermediate", true, "Enable requesting of quota for intermediate certificates in submitted chains")
handlerPrefix = flag.String("handler_prefix", "", "If set e.g. to '/logs' will prefix all handlers that don't define a custom prefix")
pkcs11ModulePath = flag.String("pkcs11_module_path", "", "Path to the PKCS#11 module to use for keys that use the PKCS#11 interface")
cacheType = flag.String("cache_type", "noop", "Supported cache type: noop, lru (Default: noop)")
cacheSize = flag.Int("cache_size", -1, "Size parameter set to 0 makes cache of unlimited size")
cacheTTL = flag.Duration("cache_ttl", -1*time.Second, "Providing 0 TTL turns expiring off")
trillianTLSCACertFile = flag.String("trillian_tls_ca_cert_file", "", "CA certificate file to use for secure connections with Trillian server")
)

const unknownRemoteUser = "UNKNOWN_REMOTE"
Expand Down Expand Up @@ -135,7 +137,16 @@ func main() {
metricsAt = *httpEndpoint
}

dialOpts := []grpc.DialOption{grpc.WithInsecure()}
dialOpts := []grpc.DialOption{}
if *trillianTLSCACertFile != "" {
creds, err := credentials.NewClientTLSFromFile(*trillianTLSCACertFile, "")
if err != nil {
klog.Exitf("Failed to create TLS credentials from Trillian CA certificate: %v", err)
}
dialOpts = append(dialOpts, grpc.WithTransportCredentials(creds))
} else {
dialOpts = append(dialOpts, grpc.WithInsecure())
}
if len(*etcdServers) > 0 {
// Use etcd to provide endpoint resolution.
cfg := clientv3.Config{Endpoints: strings.Split(*etcdServers, ","), DialTimeout: 5 * time.Second}
Expand Down
37 changes: 1 addition & 36 deletions trillian/migrillian/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,16 @@ package main

import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"flag"
"fmt"
"net/http"
"os"
"path/filepath"
"strings"
"time"

clientv3 "go.etcd.io/etcd/client/v3"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"k8s.io/klog/v2"

Expand Down Expand Up @@ -61,7 +57,6 @@ var (

maxIdleConnsPerHost = flag.Int("max_idle_conns_per_host", 10, "Max idle HTTP connections per host (0 = DefaultMaxIdleConnsPerHost)")
maxIdleConns = flag.Int("max_idle_conns", 100, "Max number of idle HTTP connections across all hosts (0 = unlimited)")
tlsCACertFile = flag.String("trillian_tls_ca_cert_file", "", "CA certificate file to use for secure connections with Trillian server")
)

func main() {
Expand All @@ -82,11 +77,7 @@ func main() {
}

klog.Infof("Dialling Trillian backend: %v", *backend)
creds, err := newTrillianTransportCredentialsFromFlags(*backend)
if err != nil {
klog.Exitf("Failed to get credentials: %v", err)
}
conn, err := grpc.Dial(*backend, grpc.WithTransportCredentials(creds), grpc.WithBlock())
conn, err := grpc.Dial(*backend, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock())
if err != nil {
klog.Exitf("Could not dial Trillian server: %v: %v", *backend, err)
}
Expand Down Expand Up @@ -126,32 +117,6 @@ func main() {
core.RunMigration(cctx, ctrls)
}

// newTrillianTransportCredentialsFromFlags returns "creds" of type credentials.TransportCredentials to be
// passed as credentials arguments to grpc.WithTransportCredentials. It configures TLS credentials
// if a CA certificate file is specified, otherwise it uses insecure credentials.
func newTrillianTransportCredentialsFromFlags(backend string) (credentials.TransportCredentials, error) {
var creds credentials.TransportCredentials

if len(*tlsCACertFile) > 0 {
tlsCaCert, err := os.ReadFile(filepath.Clean(*tlsCACertFile))
if err != nil {
return nil, err
}
certPool := x509.NewCertPool()
if !certPool.AppendCertsFromPEM(tlsCaCert) {
return nil, fmt.Errorf("failed to append CA certificate to pool")
}
creds = credentials.NewTLS(&tls.Config{
ServerName: backend,
RootCAs: certPool,
MinVersion: tls.VersionTLS12,
})
} else {
creds = insecure.NewCredentials()
}
return creds, nil
}

// getController creates a single log migration Controller.
func getController(
ctx context.Context,
Expand Down

0 comments on commit f94433c

Please sign in to comment.