From 8f7135831b004c84b00436072f43aac56a87edcb Mon Sep 17 00:00:00 2001 From: Nahum Shalman Date: Fri, 10 Dec 2021 15:23:08 +0000 Subject: [PATCH 01/10] client: support connecting to GRPC servers without TLS This is useful for local development and should never be used in production environments. Signed-off-by: Nahum Shalman Signed-off-by: Manuel Mendez --- client/main.go | 54 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/client/main.go b/client/main.go index f9f7d5ced..7d4a2859b 100644 --- a/client/main.go +++ b/client/main.go @@ -6,6 +6,7 @@ import ( "log" "net/http" "os" + "strconv" "github.com/pkg/errors" "github.com/spf13/pflag" @@ -44,17 +45,19 @@ func NewFullClient(conn grpc.ClientConnInterface) *FullClient { type ConnOptions struct { CertURL string GRPCAuthority string + TLS bool } func (o *ConnOptions) SetFlags(flagSet *pflag.FlagSet) { flagSet.StringVar(&o.CertURL, "tinkerbell-cert-url", "http://127.0.0.1:42114/cert", "The URL where the certificate is located") - flagSet.StringVar(&o.GRPCAuthority, "tinkerbell-grpc-authority", "127.0.0.1:42113", "Link to tink-server grcp api") + flagSet.StringVar(&o.GRPCAuthority, "tinkerbell-grpc-authority", "127.0.0.1:42113", "Connection info for tink-server") + flagSet.BoolVar(&o.TLS, "tinkerbell-tls", true, "Connect to server via TLS or not") } // This function is bad and ideally should be removed, but for now it moves all the bad into one place. // This is the legacy of packethost/cacher running behind an ingress that couldn't terminate TLS on behalf // of GRPC. All of this functionality should be ripped out in favor of either using trusted certificates -// or moving the establishment of trust in the certificate out to the environment (or running in insecure mode +// or moving the establishment of trust in the certificate out to the environment (or running in no-tls mode // e.g. for development.) func grpcCredentialFromCertEndpoint(url string) (credentials.TransportCredentials, error) { resp, err := http.Get(url) @@ -62,24 +65,35 @@ func grpcCredentialFromCertEndpoint(url string) (credentials.TransportCredential return nil, errors.Wrap(err, "fetch cert") } defer resp.Body.Close() + certs, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, errors.Wrap(err, "read cert") } + cp := x509.NewCertPool() ok := cp.AppendCertsFromPEM(certs) if !ok { return nil, errors.Wrap(err, "parse cert") } + return credentials.NewClientTLSFromCert(cp, ""), nil } func NewClientConn(opt *ConnOptions) (*grpc.ClientConn, error) { - creds, err := grpcCredentialFromCertEndpoint(opt.CertURL) - if err != nil { - return nil, errors.Wrap(err, "obtain trusted certificate") + method := grpc.WithInsecure() + if opt.TLS { + creds, err := grpcCredentialFromCertEndpoint(opt.CertURL) + if err != nil { + return nil, err + } + method = grpc.WithTransportCredentials(creds) } - conn, err := grpc.Dial(opt.GRPCAuthority, grpc.WithTransportCredentials(creds)) + conn, err := grpc.Dial(opt.GRPCAuthority, + method, + grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()), + grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()), + ) if err != nil { return nil, errors.Wrap(err, "connect to tinkerbell server") } @@ -88,22 +102,32 @@ func NewClientConn(opt *ConnOptions) (*grpc.ClientConn, error) { // GetConnection returns a gRPC client connection. func GetConnection() (*grpc.ClientConn, error) { - certURL := os.Getenv("TINKERBELL_CERT_URL") - if certURL == "" { - return nil, errors.New("undefined TINKERBELL_CERT_URL") - } - grpcAuthority := os.Getenv("TINKERBELL_GRPC_AUTHORITY") if grpcAuthority == "" { return nil, errors.New("undefined TINKERBELL_GRPC_AUTHORITY") } - creds, err := grpcCredentialFromCertEndpoint(certURL) - if err != nil { - return nil, errors.Wrap(err, "obtain trusted certificate") + method := grpc.WithInsecure() + tls := true + if val, isSet := os.LookupEnv("TINKERBELL_TLS"); isSet { + if b, err := strconv.ParseBool(val); err == nil { + tls = b + } + } + + if tls { + certURL := os.Getenv("TINKERBELL_CERT_URL") + if certURL == "" { + return nil, errors.New("undefined TINKERBELL_CERT_URL") + } + creds, err := grpcCredentialFromCertEndpoint(certURL) + if err != nil { + return nil, err + } + method = grpc.WithTransportCredentials(creds) } conn, err := grpc.Dial(grpcAuthority, - grpc.WithTransportCredentials(creds), + method, grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()), grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()), ) From 12e37dcc97d83fd1fa4707241cd0e3eb07a4fd28 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Thu, 27 Jan 2022 10:58:53 -0500 Subject: [PATCH 02/10] docs: Sort envvars table Helps for visually scanning. Signed-off-by: Manuel Mendez --- docs/ENVVARS.md | 64 ++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/ENVVARS.md b/docs/ENVVARS.md index f44d9c8dc..cb5066ce3 100644 --- a/docs/ENVVARS.md +++ b/docs/ENVVARS.md @@ -2,35 +2,35 @@ The follow describes environment variables available to be set when running Tink Server, Tink CLI, or Tink Worker. -| Name | Type | Service(s) | Description | -| ---------------------------------------------------------------------------------------------- | ------ | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| `TINKERBELL_CERT_URL=http://127.0.0.1:42114/cert` | string | cli/worker | url from which to get a TLS certificate, needed when Tink Server's TLS cert is signed by an unknown certificate authority, ie self-signed | -| `CERTS_DIR=/certs` | string | server | a directory which contains the `bundle.pem` and `server-key.pem` files, for use when running Tink with TLS | -| `TINKERBELL_CERTS_DIR=/certs` | string | server | same as `CERTS_DIR`, deprecated in server | -| `TLS_CERT="-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----\n"` | string | server | a TLS certificate for use with Tink server | -| `TINKERBELL_TLS_CERT="-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----\n"` | string | server | same as `TLS_CERT`, deprecated in server | -| `GRPC_AUTHORITY=127.0.0.1:42113` | string | server | url of the Tink gRPC server | -| `TINKERBELL_GRPC_AUTHORITY=127.0.0.1:42113` | string | server/cli/worker | same as `GRPC_AUTHORITY`, deprecated in server | -| `HTTP_AUTHORITY=127.0.0.1:42114` | string | server | url of the Tink HTTP server | -| `TINKERBELL_HTTP_AUTHORITY=127.0.0.1:42114` | string | server | same as `HTTP_AUTHORITY`, deprecated in server | -| `FACILITY=onprem` | string | server/cli | location for which the Tink server serves, deprecated in server | -| `POSTGRES_DATABASE=tinkerbell` | string | server | name of the PostgreSQL database for use in the Tink server | -| `PGDATABASE=tinkerbell` | string | server | same as `POSTGRES_DATABASE`, deprecated in server | -| `POSTGRES_USER=tink` | string | server | PostgreSQL username for connecting to the DB | -| `PGUSER=tink` | string | server | same as `POSTGRES_USER`, deprecated in server | -| `POSTGRES_PASSWORD=tink` | string | server | PostgreSQL password for connecting to the DB | -| `PGPASSWORD=tink` | string | server | same as `POSTGRES_PASSWORD`, deprecated in server | -| `POSTGRES_SSLMODE=disable` | string | server | sets the PostgreSQL SSL priority [docs](https://www.postgresql.org/docs/10/libpq-connect.html#LIBPQ-CONNECT-SSLMODE) | -| `PGSSLMODE=disable` | string | server | same as `POSTGRES_SSLMODE`, deprecated in server | -| `MAX_WORKFLOW_DATA_VERSIONS=` | int | server | maximum number of workflow data versions to be kept in database | -| `EVENTS_TTL=60` | string | server | purges the events in the events table that have passed this TTL in minutes | -| `ONLY_MIGRATION=true` | bool | server | if set to true, only POSTGRES migrations are executed | -| `TINK_CLI_VERSION="0.0.0"` | string | cli | if set to `0.0.0`, the old get command is used | -| `DOCKER_REGISTRY=` | string | worker | the docker registry to use for pulling images | -| `REGISTRY_PASSWORD=` | string | worker | the password for the docker registry | -| `REGISTRY_USERNAME=` | string | worker | the username for the docker registry | -| `ID=` | string | worker | the id of the workflow to be executed | -| `RETRY_INTERVAL=` | int | worker | the interval in seconds between retries for setting up connections to, querying for workflows from, and sending status reports to Tink Server | -| `MAX_RETRIES=` | int | worker | the maximum number of retries for setting up connections and sending status reports to Tink Server | -| `MAX_FILE_SIZE=` | int | worker | the maximum size in bytes for the Tink worker data file | -| `CAPTURE_ACTION_LOGS=` | bool | worker | Capture action container output as part of worker logs | +| Name | Type | Service(s) | Description | +| ---------------------------------------------------------------------------------------------- | ------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `CAPTURE_ACTION_LOGS=` | bool | worker | capture action container output as part of worker logs | +| `CERTS_DIR=/certs` | string | server | a directory which contains the `bundle.pem` and `server-key.pem` files, for use when running Tink with TLS | +| `DOCKER_REGISTRY=` | string | worker | the docker registry to use for pulling images | +| `EVENTS_TTL=60` | string | server | purges the events in the events table that have passed this TTL in minutes | +| `FACILITY=onprem` | string | clients | location for which the Tink server serves, deprecated in server | +| `GRPC_AUTHORITY=127.0.0.1:42113` | string | server | url of the Tink gRPC server | +| `HTTP_AUTHORITY=127.0.0.1:42114` | string | server | url of the Tink HTTP server | +| `ID=` | string | worker | the id of the workflow to be executed | +| `MAX_FILE_SIZE=` | int | worker | the maximum size in bytes for the Tink worker data file | +| `MAX_RETRIES=` | int | worker | the maximum number of retries for setting up connections and sending status reports to Tink Server | +| `MAX_WORKFLOW_DATA_VERSIONS=` | int | server | maximum number of workflow data versions to be kept in database | +| `ONLY_MIGRATION=true` | bool | server | if set to true, only POSTGRES migrations are executed | +| `PGDATABASE=tinkerbell` | string | server | same as `POSTGRES_DATABASE`, deprecated in server | +| `PGPASSWORD=tink` | string | server | same as `POSTGRES_PASSWORD`, deprecated in server | +| `PGSSLMODE=disable` | string | server | same as `POSTGRES_SSLMODE`, deprecated in server | +| `PGUSER=tink` | string | server | same as `POSTGRES_USER`, deprecated in server | +| `POSTGRES_DATABASE=tinkerbell` | string | server | name of the PostgreSQL database for use in the Tink server | +| `POSTGRES_PASSWORD=tink` | string | server | PostgreSQL password for connecting to the DB | +| `POSTGRES_SSLMODE=disable` | string | server | sets the PostgreSQL SSL priority [docs](https://www.postgresql.org/docs/10/libpq-connect.html#LIBPQ-CONNECT-SSLMODE) | +| `POSTGRES_USER=tink` | string | server | PostgreSQL username for connecting to the DB | +| `REGISTRY_PASSWORD=` | string | worker | the password for the docker registry | +| `REGISTRY_USERNAME=` | string | worker | the username for the docker registry | +| `RETRY_INTERVAL=` | int | worker | the interval in seconds between retries for setting up connections to, querying for workflows from, and sending status reports to Tink Server | +| `TINK_CLI_VERSION="0.0.0"` | string | cli | if set to `0.0.0`, the old get command is used | +| `TINKERBELL_CERTS_DIR=/certs` | string | server | same as `CERTS_DIR`, deprecated in server | +| `TINKERBELL_CERT_URL=http://127.0.0.1:42114/cert` | string | clients | url from which to get a TLS certificate, needed when Tink Server's TLS cert is signed by an unknown certificate authority, ie self-signed | +| `TINKERBELL_GRPC_AUTHORITY=127.0.0.1:42113` | string | all | same as `GRPC_AUTHORITY`, deprecated in server | +| `TINKERBELL_HTTP_AUTHORITY=127.0.0.1:42114` | string | server | same as `HTTP_AUTHORITY`, deprecated in server | +| `TINKERBELL_TLS_CERT="-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----\n"` | string | server | same as `TLS_CERT`, deprecated in server | +| `TLS_CERT="-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----\n"` | string | server | a TLS certificate for use with Tink server | From 4af94702a843c43554d6620d303165023e7fc1a9 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Tue, 18 Jan 2022 13:41:03 -0500 Subject: [PATCH 03/10] client: Use packethost/pkg/env helper functions instead of stdlib We already import packethost/pkg might as well make the most of it. Signed-off-by: Manuel Mendez --- client/main.go | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/client/main.go b/client/main.go index 7d4a2859b..ad16928e1 100644 --- a/client/main.go +++ b/client/main.go @@ -5,9 +5,8 @@ import ( "io/ioutil" "log" "net/http" - "os" - "strconv" + "github.com/packethost/pkg/env" "github.com/pkg/errors" "github.com/spf13/pflag" "github.com/tinkerbell/tink/protos/hardware" @@ -102,21 +101,16 @@ func NewClientConn(opt *ConnOptions) (*grpc.ClientConn, error) { // GetConnection returns a gRPC client connection. func GetConnection() (*grpc.ClientConn, error) { - grpcAuthority := os.Getenv("TINKERBELL_GRPC_AUTHORITY") + grpcAuthority := env.Get("TINKERBELL_GRPC_AUTHORITY") if grpcAuthority == "" { return nil, errors.New("undefined TINKERBELL_GRPC_AUTHORITY") } method := grpc.WithInsecure() - tls := true - if val, isSet := os.LookupEnv("TINKERBELL_TLS"); isSet { - if b, err := strconv.ParseBool(val); err == nil { - tls = b - } - } + tls := env.Bool("TINKERBELL_NO_TLS", true) - if tls { - certURL := os.Getenv("TINKERBELL_CERT_URL") + if !tls { + certURL := env.Get("TINKERBELL_CERT_URL") if certURL == "" { return nil, errors.New("undefined TINKERBELL_CERT_URL") } From c91e7b829015cfc53d7ca55c81cb165c009c1494 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Tue, 18 Jan 2022 13:38:26 -0500 Subject: [PATCH 04/10] client: refactor GetConnection to use NewClientConn NewClientConn already exists to make the grpc connection, no reason not to use it. Signed-off-by: Manuel Mendez --- client/main.go | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/client/main.go b/client/main.go index ad16928e1..0a0620481 100644 --- a/client/main.go +++ b/client/main.go @@ -101,34 +101,22 @@ func NewClientConn(opt *ConnOptions) (*grpc.ClientConn, error) { // GetConnection returns a gRPC client connection. func GetConnection() (*grpc.ClientConn, error) { - grpcAuthority := env.Get("TINKERBELL_GRPC_AUTHORITY") - if grpcAuthority == "" { - return nil, errors.New("undefined TINKERBELL_GRPC_AUTHORITY") + opts := ConnOptions{ + CertURL: env.Get("TINKERBELL_CERT_URL"), + GRPCAuthority: env.Get("TINKERBELL_GRPC_AUTHORITY"), + TLS: env.Bool("TINKERBELL_TLS", true), } - method := grpc.WithInsecure() - tls := env.Bool("TINKERBELL_NO_TLS", true) + if opts.GRPCAuthority == "" { + return nil, errors.New("undefined TINKERBELL_GRPC_AUTHORITY") + } - if !tls { - certURL := env.Get("TINKERBELL_CERT_URL") - if certURL == "" { + if opts.TLS { + if opts.CertURL == "" { return nil, errors.New("undefined TINKERBELL_CERT_URL") } - creds, err := grpcCredentialFromCertEndpoint(certURL) - if err != nil { - return nil, err - } - method = grpc.WithTransportCredentials(creds) } - conn, err := grpc.Dial(grpcAuthority, - method, - grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()), - grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()), - ) - if err != nil { - return nil, errors.Wrap(err, "connect to tinkerbell server") - } - return conn, nil + return NewClientConn(&opts) } // Setup : create a connection to server. From aba55c13ed8b3abdffef705844c274bb394f0298 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Mon, 24 Jan 2022 13:20:11 -0500 Subject: [PATCH 05/10] http: Do the right thing if no cert is passed to SetupHTTP Do not setup tls in the grpc dial opts and do not setup /cert path. Signed-off-by: Manuel Mendez --- http-server/http_server.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/http-server/http_server.go b/http-server/http_server.go index 9b612402c..8e5547306 100644 --- a/http-server/http_server.go +++ b/http-server/http_server.go @@ -27,9 +27,11 @@ type Config struct { // SetupHTTP setup and return an HTTP server. func SetupHTTP(ctx context.Context, logger log.Logger, config *Config, errCh chan<- error) { - http.HandleFunc("/cert", func(w http.ResponseWriter, r *http.Request) { - http.ServeContent(w, r, "server.pem", config.ModTime, bytes.NewReader(config.CertPEM)) - }) + if config.CertPEM != nil { + http.HandleFunc("/cert", func(w http.ResponseWriter, r *http.Request) { + http.ServeContent(w, r, "server.pem", config.ModTime, bytes.NewReader(config.CertPEM)) + }) + } http.Handle("/metrics", promhttp.Handler()) http.HandleFunc("/version", getGitRevJSONHandler()) http.HandleFunc("/healthz", healthCheckHandler) From 1f564b41aeb92bfb388b28107cbfffcf7151701d Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Tue, 25 Jan 2022 16:32:40 -0500 Subject: [PATCH 06/10] Minor tweak of docker-compose Sort services. Sort env bars. Sort depends_on services. Reorder defs so they are ordered in->out, e.g.: image/build first followed by entrypoint/cmd finishing with things needed to talk to it idk just wanted to have a similar order to compare services. Signed-off-by: Manuel Mendez --- docker-compose.yaml | 48 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 2cb3a21fb..739322a50 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,21 +1,9 @@ version: "3.8" services: - tls-gen: - image: cfssl/cfssl - entrypoint: /bin/bash - command: - - /code/tls/generate.sh - environment: - FACILITY: ${FACILITY:-onprem} - volumes: - - ${PWD}/deploy:/code - - certs:/certs/${FACILITY:-onprem}:rw - tinkerbell: build: context: ./cmd/tink-server/ dockerfile: Dockerfile - restart: unless-stopped environment: FACILITY: ${FACILITY:-onprem} PACKET_ENV: ${PACKET_ENV:-testing} @@ -30,27 +18,38 @@ services: PGUSER: tinkerbell TINKERBELL_GRPC_AUTHORITY: :42113 TINKERBELL_HTTP_AUTHORITY: :42114 + volumes: + - certs:/certs/${FACILITY:-onprem}:rw + ports: + - 42113:42113/tcp + - 42114:42114/tcp depends_on: - tink-server-migration: - condition: service_started db: condition: service_healthy + tink-server-migration: + condition: service_started tls-gen: condition: service_started - volumes: - - certs:/certs/${FACILITY:-onprem}:rw healthcheck: test: ["CMD-SHELL", "wget -qO- 127.0.0.1:42114/cert"] # port needs to match TINKERBELL_HTTP_AUTHORITY interval: 5s timeout: 2s retries: 3 - ports: - - 42113:42113/tcp - - 42114:42114/tcp + restart: unless-stopped + + tls-gen: + image: cfssl/cfssl + entrypoint: /bin/bash + command: + - /code/tls/generate.sh + environment: + FACILITY: ${FACILITY:-onprem} + volumes: + - ${PWD}/deploy:/code + - certs:/certs/${FACILITY:-onprem}:rw tink-server-migration: image: quay.io/tinkerbell/tink:latest - restart: on-failure environment: ONLY_MIGRATION: "true" FACILITY: ${FACILITY:-onprem} @@ -65,10 +64,10 @@ services: depends_on: db: condition: service_healthy + restart: on-failure db: image: postgres:14-alpine - restart: unless-stopped environment: POSTGRES_DB: tinkerbell POSTGRES_PASSWORD: tinkerbell @@ -82,20 +81,19 @@ services: interval: 1s timeout: 1s retries: 30 + restart: unless-stopped tink-cli: build: context: ./cmd/tink-cli/ dockerfile: Dockerfile - restart: unless-stopped environment: - TINKERBELL_GRPC_AUTHORITY: tinkerbell:42113 TINKERBELL_CERT_URL: http://tinkerbell:42114/cert + TINKERBELL_GRPC_AUTHORITY: tinkerbell:42113 depends_on: tinkerbell: condition: service_healthy - db: - condition: service_healthy + restart: unless-stopped volumes: postgres_data: From be6b4acdac4c54efa00c02f663e51a4e0fc5c683 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Tue, 25 Jan 2022 16:48:41 -0500 Subject: [PATCH 07/10] Use /healthz for docker-compose healthcheck /cert does not exist when in non-tls mode. Also, why use /cert when /healthz exists and is made for exactly for this. Signed-off-by: Manuel Mendez --- docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 739322a50..af13d9a89 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -31,7 +31,7 @@ services: tls-gen: condition: service_started healthcheck: - test: ["CMD-SHELL", "wget -qO- 127.0.0.1:42114/cert"] # port needs to match TINKERBELL_HTTP_AUTHORITY + test: ["CMD-SHELL", "wget -qO- 127.0.0.1:42114/healthz"] # port needs to match TINKERBELL_HTTP_AUTHORITY interval: 5s timeout: 2s retries: 3 From ddde0da297a88196a66fb8c55d9095ee15f4fc60 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Tue, 18 Jan 2022 13:41:03 -0500 Subject: [PATCH 08/10] tink-server: Use packethost/pkg/env helper functions instead of stdlib We already import packethost/pkg might as well make the most of it. Signed-off-by: Manuel Mendez --- cmd/tink-server/main.go | 46 ++++++++++++----------------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/cmd/tink-server/main.go b/cmd/tink-server/main.go index 66f3adb93..773e23e93 100644 --- a/cmd/tink-server/main.go +++ b/cmd/tink-server/main.go @@ -6,11 +6,11 @@ import ( "fmt" "os" "os/signal" - "strconv" "strings" "syscall" "github.com/equinix-labs/otel-init-go/otelinit" + "github.com/packethost/pkg/env" "github.com/packethost/pkg/log" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -53,38 +53,18 @@ func (c *DaemonConfig) AddFlags(fs *pflag.FlagSet) { } func (c *DaemonConfig) PopulateFromLegacyEnvVar() { - if f := os.Getenv("FACILITY"); f != "" { - c.Facility = f - } - if pgdb := os.Getenv("PGDATABASE"); pgdb != "" { - c.PGDatabase = pgdb - } - if pguser := os.Getenv("PGUSER"); pguser != "" { - c.PGUSer = pguser - } - if pgpass := os.Getenv("PGPASSWORD"); pgpass != "" { - c.PGPassword = pgpass - } - if pgssl := os.Getenv("PGSSLMODE"); pgssl != "" { - c.PGSSLMode = pgssl - } - if onlyMigration, isSet := os.LookupEnv("ONLY_MIGRATION"); isSet { - if b, err := strconv.ParseBool(onlyMigration); err != nil { - c.OnlyMigration = b - } - } - if tlsCert := os.Getenv("TINKERBELL_TLS_CERT"); tlsCert != "" { - c.TLSCert = tlsCert - } - if certDir := os.Getenv("TINKERBELL_CERTS_DIR"); certDir != "" { - c.CertDir = certDir - } - if grpcAuthority := os.Getenv("TINKERBELL_GRPC_AUTHORITY"); grpcAuthority != "" { - c.GRPCAuthority = grpcAuthority - } - if httpAuthority := os.Getenv("TINKERBELL_HTTP_AUTHORITY"); httpAuthority != "" { - c.HTTPAuthority = httpAuthority - } + c.Facility = env.Get("FACILITY", c.Facility) + + c.PGDatabase = env.Get("PGDATABASE", c.PGDatabase) + c.PGUSer = env.Get("PGUSER", c.PGUSer) + c.PGPassword = env.Get("PGPASSWORD", c.PGPassword) + c.PGSSLMode = env.Get("PGSSLMODE", c.PGSSLMode) + c.OnlyMigration = env.Bool("ONLY_MIGRATION", c.OnlyMigration) + + c.TLSCert = env.Get("TINKERBELL_TLS_CERT", c.TLSCert) + c.CertDir = env.Get("TINKERBELL_CERTS_DIR", c.CertDir) + c.GRPCAuthority = env.Get("TINKERBELL_GRPC_AUTHORITY", c.GRPCAuthority) + c.HTTPAuthority = env.Get("TINKERBELL_HTTP_AUTHORITY", c.HTTPAuthority) } func main() { From a21393b187cfc50820e1aa0018eb4bcfece44c37 Mon Sep 17 00:00:00 2001 From: Nahum Shalman Date: Fri, 10 Dec 2021 15:24:52 +0000 Subject: [PATCH 09/10] tink-server: support GRPC insecure mode Signed-off-by: Nahum Shalman Signed-off-by: Manuel Mendez --- cmd/tink-server/main.go | 22 +++++++++++++++------- docker-compose.yaml | 3 +++ grpc-server/grpc_server.go | 13 +++++++++---- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/cmd/tink-server/main.go b/cmd/tink-server/main.go index 773e23e93..4908c2e50 100644 --- a/cmd/tink-server/main.go +++ b/cmd/tink-server/main.go @@ -16,7 +16,7 @@ import ( "github.com/spf13/pflag" "github.com/spf13/viper" "github.com/tinkerbell/tink/db" - rpcServer "github.com/tinkerbell/tink/grpc-server" + grpcServer "github.com/tinkerbell/tink/grpc-server" httpServer "github.com/tinkerbell/tink/http-server" "github.com/tinkerbell/tink/metrics" ) @@ -37,6 +37,7 @@ type DaemonConfig struct { TLSCert string CertDir string HTTPAuthority string + TLS bool } func (c *DaemonConfig) AddFlags(fs *pflag.FlagSet) { @@ -50,6 +51,7 @@ func (c *DaemonConfig) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&c.TLSCert, "tls-cert", "", "") fs.StringVar(&c.CertDir, "cert-dir", "", "") fs.StringVar(&c.HTTPAuthority, "http-authority", ":42114", "The address used to expose the HTTP server") + fs.BoolVar(&c.TLS, "tls", true, "Run in tls protected mode (disabling should only be done for development or if behind TLS terminating proxy)") } func (c *DaemonConfig) PopulateFromLegacyEnvVar() { @@ -65,6 +67,7 @@ func (c *DaemonConfig) PopulateFromLegacyEnvVar() { c.CertDir = env.Get("TINKERBELL_CERTS_DIR", c.CertDir) c.GRPCAuthority = env.Get("TINKERBELL_GRPC_AUTHORITY", c.GRPCAuthority) c.HTTPAuthority = env.Get("TINKERBELL_HTTP_AUTHORITY", c.HTTPAuthority) + c.TLS = env.Bool("TINKERBELL_LS", c.TLS) } func main() { @@ -152,18 +155,23 @@ func NewRootCommand(config *DaemonConfig, logger log.Logger) *cobra.Command { logger.Info("Your database schema is not up to date. Please apply migrations running tink-server with env var ONLY_MIGRATION set.") } - cert, modT := rpcServer.SetupGRPC(ctx, logger, &rpcServer.ConfigGRPCServer{ + grpcConfig := &grpcServer.ConfigGRPCServer{ Facility: config.Facility, - TLSCert: config.TLSCert, + TLSCert: "insecure", GRPCAuthority: config.GRPCAuthority, DB: tinkDB, - }, errCh) + } + if config.TLS { + grpcConfig.TLSCert = config.TLSCert + } + cert, modT := grpcServer.SetupGRPC(ctx, logger, grpcConfig, errCh) - httpServer.SetupHTTP(ctx, logger, &httpServer.Config{ + httpConfig := &httpServer.Config{ + HTTPAuthority: config.HTTPAuthority, CertPEM: cert, ModTime: modT, - HTTPAuthority: config.HTTPAuthority, - }, errCh) + } + httpServer.SetupHTTP(ctx, logger, httpConfig, errCh) select { case err = <-errCh: diff --git a/docker-compose.yaml b/docker-compose.yaml index af13d9a89..3016697b0 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -18,6 +18,7 @@ services: PGUSER: tinkerbell TINKERBELL_GRPC_AUTHORITY: :42113 TINKERBELL_HTTP_AUTHORITY: :42114 + TINKERBELL_TLS: ${TINKERBERLL_TLS:"true"} volumes: - certs:/certs/${FACILITY:-onprem}:rw ports: @@ -61,6 +62,7 @@ services: PGUSER: tinkerbell TINKERBELL_GRPC_AUTHORITY: :42113 TINKERBELL_HTTP_AUTHORITY: :42114 + TINKERBELL_TLS: ${TINKERBERLL_TLS:"true"} depends_on: db: condition: service_healthy @@ -90,6 +92,7 @@ services: environment: TINKERBELL_CERT_URL: http://tinkerbell:42114/cert TINKERBELL_GRPC_AUTHORITY: tinkerbell:42113 + TINKERBELL_TLS: ${TINKERBERLL_TLS:"true"} depends_on: tinkerbell: condition: service_healthy diff --git a/grpc-server/grpc_server.go b/grpc-server/grpc_server.go index 2722be8b5..383aca2c4 100644 --- a/grpc-server/grpc_server.go +++ b/grpc-server/grpc_server.go @@ -60,14 +60,19 @@ func SetupGRPC(ctx context.Context, logger log.Logger, config *ConfigGRPCServer, dbReady: true, logger: logger, } - if cert := config.TLSCert; cert != "" { - server.cert = []byte(cert) - server.modT = time.Now() - } else { + cert := config.TLSCert + switch cert { + case "insecure": + // server.cert *must* be nil, which it is because that is the default value + // server.modT doesn't matter + case "": tlsCert, certPEM, modT := getCerts(config.Facility, logger) params = append(params, grpc.Creds(credentials.NewServerTLSFromCert(&tlsCert))) server.cert = certPEM server.modT = modT + default: + server.cert = []byte(cert) + server.modT = time.Now() } // register servers From ae0df5f17271d0f8a9987edee558ab8c5011e542 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Thu, 27 Jan 2022 11:31:39 -0500 Subject: [PATCH 10/10] docs: Add TINKERBELL_TLS ENVVARS.md Signed-off-by: Manuel Mendez --- docs/ENVVARS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/ENVVARS.md b/docs/ENVVARS.md index cb5066ce3..a08f97746 100644 --- a/docs/ENVVARS.md +++ b/docs/ENVVARS.md @@ -32,5 +32,6 @@ The follow describes environment variables available to be set when running Tink | `TINKERBELL_CERT_URL=http://127.0.0.1:42114/cert` | string | clients | url from which to get a TLS certificate, needed when Tink Server's TLS cert is signed by an unknown certificate authority, ie self-signed | | `TINKERBELL_GRPC_AUTHORITY=127.0.0.1:42113` | string | all | same as `GRPC_AUTHORITY`, deprecated in server | | `TINKERBELL_HTTP_AUTHORITY=127.0.0.1:42114` | string | server | same as `HTTP_AUTHORITY`, deprecated in server | +| `TINKERBELL_TLS="true"` | string | all | configures grpc service or client connections for tls vs plaintext | | `TINKERBELL_TLS_CERT="-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----\n"` | string | server | same as `TLS_CERT`, deprecated in server | | `TLS_CERT="-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----\n"` | string | server | a TLS certificate for use with Tink server |