rules: pass in lnd connection identifier

We pass a random lnd connection identifier to the rule enforcer that is
unique per lnd connection lifetime. It is used to generate unique
request identifiers that amend the non-unique request identifiers that
are passed from lnd.
This commit is contained in:
bitromortac 2024-06-21 09:37:47 +02:00
parent 916ddec0d7
commit 7489f0a0b2
No known key found for this signature in database
GPG key ID: 1965063FC13BEBE2
4 changed files with 51 additions and 2 deletions

View file

@ -44,6 +44,11 @@ type RuleEnforcer struct {
lndClient lndclient.LightningClient
ruleMgrs rules.ManagerSet
// lndConnID is a random identifier for an lnd run. It is used to
// generate unique request identifiers that amend the non-unique request
// identifiers that are passed from lnd.
lndConnID string
}
// featurePerms defines the signature of a function that can be used to fetch
@ -56,7 +61,8 @@ func NewRuleEnforcer(ruleDB firewalldb.RulesDB,
sessionIDIndex firewalldb.SessionDB,
getFeaturePerms featurePerms, permsMgr *perms.Manager, nodeID [33]byte,
routerClient lndclient.RouterClient,
lndClient lndclient.LightningClient, ruleMgrs rules.ManagerSet,
lndClient lndclient.LightningClient, lndConnID string,
ruleMgrs rules.ManagerSet,
markActionErrored func(reqID uint64, reason string) error,
privMap firewalldb.NewPrivacyMapDB) *RuleEnforcer {
@ -72,6 +78,7 @@ func NewRuleEnforcer(ruleDB firewalldb.RulesDB,
markActionErrored: markActionErrored,
newPrivMap: privMap,
sessionDB: sessionIDIndex,
lndConnID: lndConnID,
}
}
@ -415,6 +422,7 @@ func (r *RuleEnforcer) initRule(reqID uint64, name string, value []byte,
RouterClient: r.routerClient,
LndClient: r.lndClient,
ReqID: int64(reqID),
LndConnID: r.lndConnID,
}
return r.ruleMgrs.InitEnforcer(cfg, name, ruleValues)

View file

@ -32,6 +32,9 @@ type Config interface {
// used to link a request with a response.
GetReqID() int64
// GetLndConnID returns the unique identifier for the lnd connection.
GetLndConnID() string
// GetLndClient returns an lnd client.
GetLndClient() lndclient.LightningClient
}
@ -61,6 +64,9 @@ type ConfigImpl struct {
// to link a request with a response.
ReqID int64
// LndConnID is the unique identifier for the lnd connection.
LndConnID string
// LndClient is a connection to the Lit node's LND node.
LndClient lndclient.LightningClient
}
@ -95,6 +101,12 @@ func (c *ConfigImpl) GetReqID() int64 {
return c.ReqID
}
// GetLndConnID returns the unique identifier for the lnd connection to create
// unique request ids per lnd runtime.
func (c *ConfigImpl) GetLndConnID() string {
return c.LndConnID
}
// GetLndClient returns an lnd client.
func (c *ConfigImpl) GetLndClient() lndclient.LightningClient {
return c.LndClient

View file

@ -10,6 +10,10 @@ import (
// ErrUnknownRule indicates that LiT is unaware of a values name.
var ErrUnknownRule = fmt.Errorf("unknown rule")
// LndConnIdLen is the length of the random connection ID used to create
// unique request identifiers.
const LndConnIdLen = 16
// ManagerSet is a map from a rule name to a rule Manager.
type ManagerSet map[string]Manager

View file

@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"io/fs"
"math/rand"
"net"
"net/http"
"os"
@ -162,6 +163,7 @@ type LightningTerminal struct {
wg sync.WaitGroup
errQueue *queue.ConcurrentQueue[error]
lndConnID string
lndConn *grpc.ClientConn
lndClient *lndclient.GrpcLndServices
basicClient lnrpc.LightningClient
@ -542,6 +544,15 @@ func (g *LightningTerminal) start() error {
return fmt.Errorf("could not connect to LND")
}
// In order to be able to create unique middleware request identifiers,
// we set a new unique connection ID. This should be refreshed every
// time we (re)connect to LND.
// TODO: This assumes that litd needs to be restarted when the
// connection to LND is interrupted, leading to a unique connection ID.
// When automatic reconnection is implemented, we need to make sure that
// the connection ID is refreshed when the connection is re-established.
g.lndConnID = randId(rules.LndConnIdLen)
// Initialise any connections to sub-servers that we are running in
// remote mode.
g.subServerMgr.ConnectRemoteSubServers()
@ -990,7 +1001,7 @@ func (g *LightningTerminal) startInternalSubServers(
g.autopilotClient.ListFeaturePerms,
g.permsMgr, g.lndClient.NodePubkey,
g.lndClient.Router,
g.lndClient.Client, g.ruleMgrs,
g.lndClient.Client, g.lndConnID, g.ruleMgrs,
func(reqID uint64, reason string) error {
return requestLogger.MarkAction(
reqID, firewalldb.ActionStateError,
@ -1893,3 +1904,17 @@ func toLocalAddress(listenerAddress string) string {
func isRESTRequest(req *http.Request) bool {
return patternRESTRequest.MatchString(req.URL.Path)
}
// randId generates a random character string of length n.
func randId(n int) string {
var letters = []rune(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
)
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))] //nolint: gosec
}
return string(b)
}