-
Notifications
You must be signed in to change notification settings - Fork 137
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
Tinkerbell GRPC Insecure Mode #567
Changes from all commits
8f71358
12e37dc
4af9470
c91e7b8
aba55c1
1f564b4
be6b4ac
ddde0da
a21393b
ae0df5f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,8 +5,8 @@ import ( | |
"io/ioutil" | ||
"log" | ||
"net/http" | ||
"os" | ||
|
||
"github.com/packethost/pkg/env" | ||
"github.com/pkg/errors" | ||
"github.com/spf13/pflag" | ||
"github.com/tinkerbell/tink/protos/hardware" | ||
|
@@ -44,42 +44,55 @@ 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) | ||
if err != nil { | ||
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()), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. excellent :) Might want to add a client option to print the trace id in this case e.g. in the logs, so it's easy to take to a search box. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you have an example elsewhere of how to do that I can crib from? |
||
) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "connect to tinkerbell server") | ||
} | ||
|
@@ -88,29 +101,22 @@ 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") | ||
opts := ConnOptions{ | ||
CertURL: env.Get("TINKERBELL_CERT_URL"), | ||
GRPCAuthority: env.Get("TINKERBELL_GRPC_AUTHORITY"), | ||
TLS: env.Bool("TINKERBELL_TLS", true), | ||
} | ||
|
||
grpcAuthority := os.Getenv("TINKERBELL_GRPC_AUTHORITY") | ||
if grpcAuthority == "" { | ||
if opts.GRPCAuthority == "" { | ||
return nil, errors.New("undefined TINKERBELL_GRPC_AUTHORITY") | ||
} | ||
|
||
creds, err := grpcCredentialFromCertEndpoint(certURL) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "obtain trusted certificate") | ||
if opts.TLS { | ||
if opts.CertURL == "" { | ||
return nil, errors.New("undefined TINKERBELL_CERT_URL") | ||
} | ||
} | ||
conn, err := grpc.Dial(grpcAuthority, | ||
grpc.WithTransportCredentials(creds), | ||
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. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we didn't create this issue, but I just realized that
err
here isnil
.An improvement would be decoding the certificate's PEM and parsing the resulting ASN.1 DER using the
x509
library. That, or creating a new error that says something likefailed to parse cert - cert pool append certs from pem failed
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd agree, but I'm actually looking to drop the
/cert
completely so this will go away anyway.