Skip to content

Commit

Permalink
Adding auth to grpc ng (#53)
Browse files Browse the repository at this point in the history
* created handleling for grpc client to have token based auth only in NG

* added pull_request_template to consolidate with templates repo

* added .env file

* added library to read .env file if they exist

* reformatted .env

* added env variable to inject token

* added error handler when nodeguard token is not set

* improved readability of monitoring liquidation rules

* removed restriction about NODEGUARD_TOKEN is set

* removing internal pr template
  • Loading branch information
daliclovr authored Oct 17, 2023
1 parent 91ca050 commit 3b82492
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 30 deletions.
12 changes: 12 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
LNDCONNECTURIS=lndconnect://127.0.0.1:10003?cert=MIICJTCCAcygAwIBAgIQLYfp6m1vP9wFBXOcE-UsaDAKBggqhkjOPQQDAjAxMR8wHQYDVQQKExZsbmQgYXV0b2dlbmVyYXRlZCBjZXJ0MQ4wDAYDVQQDEwVjYXJvbDAeFw0yMzAzMjkxNTM4MjBaFw0yNDA1MjMxNTM4MjBaMDExHzAdBgNVBAoTFmxuZCBhdXRvZ2VuZXJhdGVkIGNlcnQxDjAMBgNVBAMTBWNhcm9sMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcXT4dekJnAiZWd8Pk3FgL1BSFXMRwLGSAlk7Di5hIJnIA1B_o8RWKzlPz7u3Aw5mmWHhN8B2MWMylWlWB2130KOBxTCBwjAOBgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH_BAUwAwEB_zAdBgNVHQ4EFgQUDOS-19_0LFGf62WRyaaUSLc3j98wawYDVR0RBGQwYoIFY2Fyb2yCCWxvY2FsaG9zdIIFY2Fyb2yCDnBvbGFyLW4xLWNhcm9sggR1bml4ggp1bml4cGFja2V0ggdidWZjb25uhwR_AAABhxAAAAAAAAAAAAAAAAAAAAABhwSsFQAFMAoGCCqGSM49BAMCA0cAMEQCHxYe59PCXrTtSmGsOjfQo6V-sS8j73cqWOzTQbvgI3gCIQCj7sOxnZWBwilec7t8bBXjwPgX9frv8408JW4QhNFOUg&macaroon=AgEDbG5kAvgBAwoQHsW2NwwWb2yOKFMWQQkUWhIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgjpV-eOw554EPrSXPxDhQuOnnwHmEO47Hu1Uiu6EiMNY
POLLINGINTERVAL=5s
RETRIESBEFOREBACKOFF=3
BACKOFFCOEFFICIENT=0.99
BACKOFFLIMIT=0.1
LOGLEVEL=DEBUG
LOGFORMAT=text
NODEGUARDHOST=localhost:50051
NODEGUARD_API_KEY=8rvSsUGeyXXdDQrHctcTey/xtHdZQEn945KHwccKp9Q=
LOOPDCONNECTURIS=lndconnect://localhost:11010?cert=MIIC1zCCAn2gAwIBAgIQRWr7OVVAidkjx3rY1Fui1DAKBggqhkjOPQQDAjA6MSAwHgYDVQQKExdsb29wIGF1dG9nZW5lcmF0ZWQgY2VydDEWMBQGA1UEAxMNRG9vbW1hYy5sb2NhbDAeFw0yMzA0MTExMDIyMTJaFw0yNDA2MDUxMDIyMTJaMDoxIDAeBgNVBAoTF2xvb3AgYXV0b2dlbmVyYXRlZCBjZXJ0MRYwFAYDVQQDEw1Eb29tbWFjLmxvY2FsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZ4oLXzeFkXnnnjZvbHoJLWTBkzovapwkv43lMFAGvD3EUYjapn9UN63LOamwSW67S2p4fyDbZykRVi5KdGuHWqOCAWMwggFfMA4GA1UdDwEB_wQEAwICpDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH_MB0GA1UdDgQWBBQ_C-VsxCCp7hIukcSQY66T_1-wwDCCAQYGA1UdEQSB_jCB-4INRG9vbW1hYy5sb2NhbIIJbG9jYWxob3N0ggR1bml4ggp1bml4cGFja2V0ggdidWZjb25uhwR_AAABhxAAAAAAAAAAAAAAAAAAAAABhxD-gAAAAAAAAAAAAAAAAAABhxD-gAAAAAAAAFSCWv_--hJchxD-gAAAAAAAAFSCWv_--hJahxD-gAAAAAAAAFSCWv_--hJbhxD-gAAAAAAAAAAtb1hMXkTshwTAqAHlhxD-gAAAAAAAAHQf-P_-JUMfhwQKkK07hxD-gAAAAAAAANx-KvMiB6mphxD-gAAAAAAAAIdaqQYVUHbchxD-gAAAAAAAAM6BCxy9LAaeMAoGCCqGSM49BAMCA0gAMEUCIHmOfHbewxWmX0JoItg8vF84A3GWfYLvjbnGxoapsaH4AiEAlGk3QVSDSHjP7vntLEK37tJ3ZCZAYeuLJKYSjbgbdI8&macaroon=AgEEbG9vcAJ3AwoQSQHLuEtbfDxGeNmwvABdRRIBMBoMCgRhdXRoEgRyZWFkGg8KBGxvb3ASAmluEgNvdXQaGgoLc3VnZ2VzdGlvbnMSBHJlYWQSBXdyaXRlGhUKBHN3YXASB2V4ZWN1dGUSBHJlYWQaDQoFdGVybXMSBHJlYWQAAAYgHb_8HcZwROzXASOxItpkbD3XAWHy1Ye32vlc1ccLeg8
OTEL_RESOURCE_ATTRIBUTES=service.name=liquidator,service.version=0.1.0
OTEL_EXPORTER_OTLP_ENDPOINT=host.docker.internal:4317
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
liquidator
regtest.polar/
.loop
.idea
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
require go.uber.org/goleak v1.2.1

require (
github.com/joho/godotenv v1.5.1 // indirect
golang.org/x/exp v0.0.0-20230807204917-050eac23e9de // indirect
golang.org/x/sync v0.3.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230807174057-1744710a1577 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,8 @@ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
Expand Down
18 changes: 8 additions & 10 deletions liquidator.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/Elenpay/liquidator/rpc"
"github.com/lightninglabs/loop/looprpc"
"github.com/lightningnetwork/lnd/lnrpc"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
Expand All @@ -40,7 +39,6 @@ var (

// Entrypoint of liquidator main logic
func startLiquidator() {

//Init opentelemetry tracer
if os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT") != "" {

Expand Down Expand Up @@ -185,8 +183,12 @@ func startNodeGuardPolling(nodeInfo lnrpc.GetInfoResponse, nodeguardClient nodeg
NodePubkey: pubkey,
})

if err != nil {
log.Errorf("startNodeguardPolling: didn't get liquitadtionRules due to the following error: %v", err)
}

if liquidationRules == nil || len(liquidationRules.LiquidityRules) == 0 {
log.Debugf("no liquidation rules found for node %v", pubkey)
log.Debugf("startNodeguardPolling: no liquidation rules found for node %v, retrying in %s...", pubkey, pollingInterval.String())
time.Sleep(pollingInterval)
continue
}
Expand All @@ -198,13 +200,9 @@ func startNodeGuardPolling(nodeInfo lnrpc.GetInfoResponse, nodeguardClient nodeg
derefRules = append(derefRules, *rule)
}

if err != nil {
log.Errorf("failed to get liquidation rules from nodeguard: %v", err)
} else {
//Store liquidation rules in cache
x := nodeInfo.GetIdentityPubkey()
rulesCache.SetLiquidityRules(x, derefRules)
}
//Store liquidation rules in cache
x := nodeInfo.GetIdentityPubkey()
rulesCache.SetLiquidityRules(x, derefRules)

//Sleep for 10 seconds
time.Sleep(pollingInterval)
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ THE SOFTWARE.
package main

import (
_ "github.com/joho/godotenv/autoload"
"time"
)

Expand Down
22 changes: 22 additions & 0 deletions rpc/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package rpc

import "context"

type TokenAuth struct {
Token string
HeaderName string
}

func NewTokenAuth(token string, header string) *TokenAuth {
return &TokenAuth{Token: token, HeaderName: header}
}

func (ta *TokenAuth) GetRequestMetadata(context.Context, ...string) (map[string]string, error) {
return map[string]string{
ta.HeaderName: ta.Token,
}, nil
}

func (ta *TokenAuth) RequireTransportSecurity() bool {
return false
}
54 changes: 34 additions & 20 deletions rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/x509"
"encoding/base64"
"fmt"
"os"

"github.com/Elenpay/liquidator/lndconnect"
"github.com/Elenpay/liquidator/nodeguard"
Expand All @@ -18,6 +19,34 @@ import (

var maxMessageSize = 200 * 1024 * 1024 // 200MB

// getConn generates the gRPC connection based on the node endpoint and the credentials
func getConn(grpcEndpoint string, creds credentials.TransportCredentials, newOptions ...grpc.DialOption) (*grpc.ClientConn, error) {
baseOptions := []grpc.DialOption{
grpc.WithTransportCredentials(creds),
grpc.WithDefaultCallOptions(
grpc.MaxCallRecvMsgSize(maxMessageSize),
grpc.MaxCallSendMsgSize(maxMessageSize)),
grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()),
}

options := append(baseOptions, newOptions...)
conn, err := grpc.Dial(
grpcEndpoint,
options...)

if err != nil {
log.Errorf("did not connect: %v", err)
return nil, err
}

return conn, nil
}

func WithTokenAuth(token string, header string) grpc.DialOption {
return grpc.WithPerRPCCredentials(NewTokenAuth(token, header))
}

// Generates the gRPC lightning client∏
func CreateLightningClient(lndConnectParams lndconnect.LndConnectParams) (lnrpc.LightningClient, *grpc.ClientConn, error) {
creds, err := generateCredentials(lndConnectParams.Cert)
Expand Down Expand Up @@ -57,12 +86,14 @@ func CreateSwapClientClient(lndConnectParams lndconnect.LndConnectParams) (loopr
return swapClient, conn, nil
}

// Creates the NodeGuard grpc client
// CreateNodeGuardClient creates the NodeGuard grpc client
func CreateNodeGuardClient(nodeGuardEndpoint string) (nodeguard.NodeGuardServiceClient, *grpc.ClientConn, error) {

//TODO ADD TLS to NodeGuard API

conn, err := getConn(nodeGuardEndpoint, insecure.NewCredentials())
token := os.Getenv("NODEGUARD_API_KEY")

conn, err := getConn(nodeGuardEndpoint, insecure.NewCredentials(), WithTokenAuth(token, "auth-token"))
if err != nil {
return nil, nil, err
}
Expand All @@ -72,24 +103,7 @@ func CreateNodeGuardClient(nodeGuardEndpoint string) (nodeguard.NodeGuardService
return client, conn, nil
}

// generates the gRPC connection based on the node endpoint and the credentials
func getConn(gRPCEndpoint string, creds credentials.TransportCredentials) (*grpc.ClientConn, error) {
conn, err := grpc.Dial(gRPCEndpoint, grpc.WithTransportCredentials(creds),
grpc.WithDefaultCallOptions(
grpc.MaxCallRecvMsgSize(maxMessageSize),
grpc.MaxCallSendMsgSize(maxMessageSize)),
grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()))

if err != nil {
log.Errorf("did not connect: %v", err)
return nil, err
}

return conn, nil
}

// Generates gRPC credentials for the clients
// generateCredentials generates gRPC credentials for the clients
func generateCredentials(certDer string) (credentials.TransportCredentials, error) {

base64decoded, err := base64.RawURLEncoding.DecodeString(certDer)
Expand Down

0 comments on commit 3b82492

Please sign in to comment.