Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tink GRPC client panics on bad TINKERBELL_CERT_URL #324

Closed
invidian opened this issue Oct 8, 2020 · 2 comments · Fixed by #584
Closed

tink GRPC client panics on bad TINKERBELL_CERT_URL #324

invidian opened this issue Oct 8, 2020 · 2 comments · Fixed by #584
Labels
good first issue Denotes an issue ready for a new contributor, according to the "help wanted" guidelines. help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. kind/bug Categorizes issue or PR as related to a bug. priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete.
Milestone

Comments

@invidian
Copy link
Contributor

invidian commented Oct 8, 2020

Expected Behaviour

Tink should gracefully return error if it's not able to initialize the client.

Current Behaviour

Tink panics on bad TINKERBELL_CERT_URL environment variable.

Steps to Reproduce (for bugs)

With CLI on latest master (a686336):

0 ✓ (97.6ms) 00:42:48 invidian@dellxps15mateusz ~/repos/kinvolk/tink (master)*$ TINKERBELL_CERT_URL=http://10.17.3.2:42114/cert TINKERBELL_GRPC_AUTHORITY=10.17.3.2:42113 ./tink-cli hardware list
+----+-------------+------------+----------+
| ID | MAC ADDRESS | IP ADDRESS | HOSTNAME |
+----+-------------+------------+----------+
+----+-------------+------------+----------+
0 ✓ (56.7ms) 00:42:51 invidian@dellxps15mateusz ~/repos/kinvolk/tink (master)*$ TINKERBELL_CERT_URL=http://10.17.3.2:42114/ceert TINKERBELL_GRPC_AUTHORITY=10.17.3.2:42113 ./tink-cli hardware list
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x1b0 pc=0x9d1157]

goroutine 1 [running]:
google.golang.org/grpc.(*ClientConn).NewStream(0x0, 0xcaec80, 0xc00019a010, 0x10a34e0, 0xbf18b4, 0x3f, 0x0, 0x0, 0x0, 0x0, ...)
        /home/invidian/go/pkg/mod/google.golang.org/[email protected]/stream.go:144 +0x37
github.com/tinkerbell/tink/protos/hardware.(*hardwareServiceClient).All(0xc000010028, 0xcaec80, 0xc00019a010, 0xc00063c120, 0x0, 0x0, 0x0, 0xc000334360, 0xc00053fd70, 0x5d3af7, ...)
        /home/invidian/repos/kinvolk/tink/protos/hardware/hardware.pb.go:824 +0xb5
github.com/tinkerbell/tink/cmd/tink-cli/cmd/hardware.glob..func1(0x10a9b40, 0x10f12c0, 0x0, 0x0)
        /home/invidian/repos/kinvolk/tink/cmd/tink-cli/cmd/hardware/all.go:25 +0x162
github.com/spf13/cobra.(*Command).execute(0x10a9b40, 0x10f12c0, 0x0, 0x0, 0x10a9b40, 0x10f12c0)
        /home/invidian/go/pkg/mod/github.com/spf13/[email protected]/command.go:846 +0x2c2
github.com/spf13/cobra.(*Command).ExecuteC(0x10a9360, 0xc000000180, 0xc00053ff78, 0x407ea5)
        /home/invidian/go/pkg/mod/github.com/spf13/[email protected]/command.go:950 +0x375
github.com/spf13/cobra.(*Command).Execute(...)
        /home/invidian/go/pkg/mod/github.com/spf13/[email protected]/command.go:887
github.com/tinkerbell/tink/cmd/tink-cli/cmd.Execute(...)
        /home/invidian/repos/kinvolk/tink/cmd/tink-cli/cmd/root.go:34
main.main()
        /home/invidian/repos/kinvolk/tink/cmd/tink-cli/main.go:14 +0x65

With unit tests:

$ cat foo/foo_test.go
package main

import (
        "context"
        "os"
        "testing"

        "github.com/tinkerbell/tink/client"
        "github.com/tinkerbell/tink/protos/hardware"
)

func TestFoo(t *testing.T) {
        if err := os.Setenv("TINKERBELL_GRPC_AUTHORITY", "10.17.3.2:42113"); err != nil {
                t.Fatalf("setting TINKERBELL_GRPC_AUTHORITY environment variable: %v", err)
        }

        if err := os.Setenv("TINKERBELL_CERT_URL", "http://10.17.3.2:42114/ceert"); err != nil {
                t.Fatalf("setting TINKERBELL_CERT_URL environment variable: %v", err)
        }

        conn, err := client.GetConnection()
        if err != nil {
                t.Fatalf("creating tink client: %v", err)
        }

        c := hardware.NewHardwareServiceClient(conn)

        if _, err := c.All(context.TODO(), &hardware.Empty{}); err == nil {
                t.Fatalf("bad cert url should fail")
        }
}
$ go test -v ./foo/...
=== RUN   TestFoo
--- FAIL: TestFoo (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x1b0 pc=0x8ce1b7]

goroutine 6 [running]:
testing.tRunner.func1.1(0x971040, 0xddd1e0)
        /usr/lib/go/src/testing/testing.go:1076 +0x30d
testing.tRunner.func1(0xc00029c180)
        /usr/lib/go/src/testing/testing.go:1079 +0x41a
panic(0x971040, 0xddd1e0)
        /usr/lib/go/src/runtime/panic.go:969 +0x175
google.golang.org/grpc.(*ClientConn).NewStream(0x0, 0xabfce0, 0xc000024188, 0xde5a20, 0xa309fd, 0x3f, 0x0, 0x0, 0x0, 0xc000308120, ...)
        /home/invidian/go/pkg/mod/google.golang.org/grpc@v1.32.0/stream.go:145 +0x37
github.com/tinkerbell/tink/protos/hardware.(*hardwareServiceClient).All(0xc000314010, 0xabfce0, 0xc000024188, 0xc000304080, 0x0, 0x0, 0x0, 0x31b2f5dd2e8d0, 0xa702a3c, 0xa702a3c0000000f, ...)
        /home/invidian/go/pkg/mod/github.com/tinkerbell/tink@v0.0.0-20200930194128-08601fea303b/protos/hardware/hardware.pb.go:824 +0xb5
github.com/kinvolk/terraform-provider-tinkerbell/foo.TestFoo(0xc00029c180)
        /home/invidian/repos/kinvolk/terraform-provider-tinkerbell/foo/foo_test.go:28 +0x279
testing.tRunner(0xc00029c180, 0xa3b0c8)
        /usr/lib/go/src/testing/testing.go:1127 +0xef
created by testing.(*T).Run
        /usr/lib/go/src/testing/testing.go:1178 +0x386
FAIL    github.com/kinvolk/terraform-provider-tinkerbell/foo    0.007s
FAIL

Notice TINKERBELL_CERT_URL using ceert instead of correct cert, which works as expected (as set address has running Tink instance.

@tstromberg tstromberg added kind/bug Categorizes issue or PR as related to a bug. good first issue Denotes an issue ready for a new contributor, according to the "help wanted" guidelines. help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. labels Jul 27, 2021
@tstromberg
Copy link
Contributor

This should be an easy fix. Help wanted!

@nshalman nshalman added priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete. and removed priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. labels Oct 19, 2021
@mmlb
Copy link
Contributor

mmlb commented Feb 8, 2022

this will go away soon as the TINKERBELL_CERT_URL will just go away on its own (#584)

@mergify mergify bot closed this as completed in #584 Apr 18, 2022
mergify bot added a commit that referenced this issue Apr 18, 2022
## Description

- Stops serving the gRPC cert via http and stops fetching it.
- Cleans up a ton of code that was confusing to read in the clients due to dealing with the gRPC certificate.
- Removes a few Config structs that are passed into funcs
  These were used to get around having lots of parameters and the long lines that caused, but now are just one or two values.

## Why is this needed

The whole serving of the gRPC certificate via http as `/cert` should never have made it to tinkerbell.
It's too easy to use incorrectly and fall into a sense of security that may not be there.
Its also a pain to actually use in production when following modern best practices of short lived TLS certificates.
Clients can't use gRPC's/Go's builtin certificate handling of when certs are rotated.

This is not a lot of good, yet a bunch of bad only to make a corner case easier at the expense of normal route.
`/cert` makes self-sigend certs "easy"ish (see cert rotation issue still) but it's just not worth it.
If someone can handle the implications of self-signed certs in production (#567 can be used for dev envs) then they can figure out how to embed their CA into hook or roll their own tink-worker environment.

## How Has This Been Tested?

Compiles and tests pass.

## How are existing users impacted? What migration steps/scripts do we need?

This is a breaking change for out-of-tree clients, I think its worth it compared to the ops / security benefits.

Fixes #324
@displague displague added this to the 0.7.0 milestone Aug 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Denotes an issue ready for a new contributor, according to the "help wanted" guidelines. help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. kind/bug Categorizes issue or PR as related to a bug. priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants