config+lnd: introduce new invoice-only macaroon
In this commit, we wrap up the prior ones and introduce config settings, as well as proper generation for a new invoice-only macaroon. All prior invoice path rules are also properly enforced of this new invoice.macaroon.
This commit is contained in:
parent
a07579c541
commit
4c0dcdafa5
55
config.go
55
config.go
@ -35,6 +35,7 @@ const (
|
||||
defaultTLSKeyFilename = "tls.key"
|
||||
defaultAdminMacFilename = "admin.macaroon"
|
||||
defaultReadMacFilename = "readonly.macaroon"
|
||||
defaultInvoiceMacFilename = "invoice.macaroon"
|
||||
defaultLogLevel = "info"
|
||||
defaultLogDirname = "logs"
|
||||
defaultLogFilename = "lnd.log"
|
||||
@ -57,14 +58,17 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
defaultLndDir = btcutil.AppDataDir("lnd", false)
|
||||
defaultConfigFile = filepath.Join(defaultLndDir, defaultConfigFilename)
|
||||
defaultDataDir = filepath.Join(defaultLndDir, defaultDataDirname)
|
||||
defaultTLSCertPath = filepath.Join(defaultLndDir, defaultTLSCertFilename)
|
||||
defaultTLSKeyPath = filepath.Join(defaultLndDir, defaultTLSKeyFilename)
|
||||
defaultAdminMacPath = filepath.Join(defaultLndDir, defaultAdminMacFilename)
|
||||
defaultReadMacPath = filepath.Join(defaultLndDir, defaultReadMacFilename)
|
||||
defaultLogDir = filepath.Join(defaultLndDir, defaultLogDirname)
|
||||
defaultLndDir = btcutil.AppDataDir("lnd", false)
|
||||
defaultConfigFile = filepath.Join(defaultLndDir, defaultConfigFilename)
|
||||
defaultDataDir = filepath.Join(defaultLndDir, defaultDataDirname)
|
||||
defaultLogDir = filepath.Join(defaultLndDir, defaultLogDirname)
|
||||
|
||||
defaultTLSCertPath = filepath.Join(defaultLndDir, defaultTLSCertFilename)
|
||||
defaultTLSKeyPath = filepath.Join(defaultLndDir, defaultTLSKeyFilename)
|
||||
|
||||
defaultAdminMacPath = filepath.Join(defaultLndDir, defaultAdminMacFilename)
|
||||
defaultReadMacPath = filepath.Join(defaultLndDir, defaultReadMacFilename)
|
||||
defaultInvoiceMacPath = filepath.Join(defaultLndDir, defaultInvoiceMacFilename)
|
||||
|
||||
defaultBtcdDir = btcutil.AppDataDir("btcd", false)
|
||||
defaultBtcdRPCCertFile = filepath.Join(defaultBtcdDir, "rpc.cert")
|
||||
@ -150,6 +154,7 @@ type config struct {
|
||||
NoMacaroons bool `long:"no-macaroons" description:"Disable macaroon authentication"`
|
||||
AdminMacPath string `long:"adminmacaroonpath" description:"Path to write the admin macaroon for lnd's RPC and REST services if it doesn't exist"`
|
||||
ReadMacPath string `long:"readonlymacaroonpath" description:"Path to write the read-only macaroon for lnd's RPC and REST services if it doesn't exist"`
|
||||
InvoiceMacPath string `long:"invoicemacaroonpath" description:"Path to the invoice-only macaroon for lnd's RPC and REST services if it doesn't exist"`
|
||||
LogDir string `long:"logdir" description:"Directory to log output."`
|
||||
|
||||
RPCListeners []string `long:"rpclisten" description:"Add an interface/port to listen for RPC connections"`
|
||||
@ -205,15 +210,16 @@ type config struct {
|
||||
// 4) Parse CLI options and overwrite/add any specified options
|
||||
func loadConfig() (*config, error) {
|
||||
defaultCfg := config{
|
||||
LndDir: defaultLndDir,
|
||||
ConfigFile: defaultConfigFile,
|
||||
DataDir: defaultDataDir,
|
||||
DebugLevel: defaultLogLevel,
|
||||
TLSCertPath: defaultTLSCertPath,
|
||||
TLSKeyPath: defaultTLSKeyPath,
|
||||
AdminMacPath: defaultAdminMacPath,
|
||||
ReadMacPath: defaultReadMacPath,
|
||||
LogDir: defaultLogDir,
|
||||
LndDir: defaultLndDir,
|
||||
ConfigFile: defaultConfigFile,
|
||||
DataDir: defaultDataDir,
|
||||
DebugLevel: defaultLogLevel,
|
||||
TLSCertPath: defaultTLSCertPath,
|
||||
TLSKeyPath: defaultTLSKeyPath,
|
||||
AdminMacPath: defaultAdminMacPath,
|
||||
InvoiceMacPath: defaultInvoiceMacPath,
|
||||
ReadMacPath: defaultReadMacPath,
|
||||
LogDir: defaultLogDir,
|
||||
Bitcoin: &chainConfig{
|
||||
MinHTLC: defaultBitcoinMinHTLCMSat,
|
||||
BaseFee: defaultBitcoinBaseFeeMSat,
|
||||
@ -282,6 +288,7 @@ func loadConfig() (*config, error) {
|
||||
defaultCfg.TLSCertPath = filepath.Join(lndDir, defaultTLSCertFilename)
|
||||
defaultCfg.TLSKeyPath = filepath.Join(lndDir, defaultTLSKeyFilename)
|
||||
defaultCfg.AdminMacPath = filepath.Join(lndDir, defaultAdminMacFilename)
|
||||
defaultCfg.InvoiceMacPath = filepath.Join(lndDir, defaultInvoiceMacFilename)
|
||||
defaultCfg.ReadMacPath = filepath.Join(lndDir, defaultReadMacFilename)
|
||||
defaultCfg.LogDir = filepath.Join(lndDir, defaultLogDirname)
|
||||
}
|
||||
@ -327,6 +334,7 @@ func loadConfig() (*config, error) {
|
||||
cfg.TLSKeyPath = cleanAndExpandPath(cfg.TLSKeyPath)
|
||||
cfg.AdminMacPath = cleanAndExpandPath(cfg.AdminMacPath)
|
||||
cfg.ReadMacPath = cleanAndExpandPath(cfg.ReadMacPath)
|
||||
cfg.InvoiceMacPath = cleanAndExpandPath(cfg.InvoiceMacPath)
|
||||
cfg.LogDir = cleanAndExpandPath(cfg.LogDir)
|
||||
cfg.BtcdMode.Dir = cleanAndExpandPath(cfg.BtcdMode.Dir)
|
||||
cfg.LtcdMode.Dir = cleanAndExpandPath(cfg.LtcdMode.Dir)
|
||||
@ -591,10 +599,19 @@ func loadConfig() (*config, error) {
|
||||
// directory has changed from the default path, then we'll also update
|
||||
// the path for the macaroons to be generated.
|
||||
if cfg.DataDir != defaultDataDir && cfg.AdminMacPath == defaultAdminMacPath {
|
||||
cfg.AdminMacPath = filepath.Join(cfg.DataDir, defaultAdminMacFilename)
|
||||
cfg.AdminMacPath = filepath.Join(
|
||||
cfg.DataDir, defaultAdminMacFilename,
|
||||
)
|
||||
}
|
||||
if cfg.DataDir != defaultDataDir && cfg.ReadMacPath == defaultReadMacPath {
|
||||
cfg.ReadMacPath = filepath.Join(cfg.DataDir, defaultReadMacFilename)
|
||||
cfg.ReadMacPath = filepath.Join(
|
||||
cfg.DataDir, defaultReadMacFilename,
|
||||
)
|
||||
}
|
||||
if cfg.DataDir != defaultDataDir && cfg.InvoiceMacPath == defaultInvoiceMacPath {
|
||||
cfg.InvoiceMacPath = filepath.Join(
|
||||
cfg.DataDir, defaultInvoiceMacPath,
|
||||
)
|
||||
}
|
||||
|
||||
// Append the network type to the log directory so it is "namespaced"
|
||||
|
46
lnd.go
46
lnd.go
@ -228,10 +228,15 @@ func lndMain() error {
|
||||
srvrLog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Create macaroon files for lncli to use if they don't exist.
|
||||
if !fileExists(cfg.AdminMacPath) && !fileExists(cfg.ReadMacPath) {
|
||||
err = genMacaroons(ctx, macaroonService,
|
||||
cfg.AdminMacPath, cfg.ReadMacPath)
|
||||
if !fileExists(cfg.AdminMacPath) && !fileExists(cfg.ReadMacPath) &&
|
||||
!fileExists(cfg.InvoiceMacPath) {
|
||||
|
||||
err = genMacaroons(
|
||||
ctx, macaroonService, cfg.AdminMacPath,
|
||||
cfg.ReadMacPath, cfg.InvoiceMacPath,
|
||||
)
|
||||
if err != nil {
|
||||
ltndLog.Errorf("unable to create macaroon "+
|
||||
"files: %v", err)
|
||||
@ -751,12 +756,33 @@ func genCertPair(certFile, keyFile string) error {
|
||||
|
||||
// genMacaroons generates a pair of macaroon files; one admin-level and one
|
||||
// read-only. These can also be used to generate more granular macaroons.
|
||||
func genMacaroons(ctx context.Context, svc *macaroons.Service, admFile,
|
||||
roFile string) error {
|
||||
func genMacaroons(ctx context.Context, svc *macaroons.Service,
|
||||
admFile, roFile, invoiceFile string) error {
|
||||
|
||||
// First, we'll generate a macaroon that only allows the caller to
|
||||
// access invoice related calls. This is useful for merchants and other
|
||||
// services to allow an isolated instance that can only query and
|
||||
// modify invoices.
|
||||
invoiceMac, err := svc.Oven.NewMacaroon(
|
||||
ctx, bakery.LatestVersion, nil, invoicePermissions...,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
invoiceMacBytes, err := invoiceMac.M().MarshalBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(invoiceFile, invoiceMacBytes, 0644)
|
||||
if err != nil {
|
||||
os.Remove(invoiceFile)
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate the read-only macaroon and write it to a file.
|
||||
roMacaroon, err := svc.Oven.NewMacaroon(ctx, bakery.LatestVersion, nil,
|
||||
readPermissions...)
|
||||
roMacaroon, err := svc.Oven.NewMacaroon(
|
||||
ctx, bakery.LatestVersion, nil, readPermissions...,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -770,8 +796,10 @@ func genMacaroons(ctx context.Context, svc *macaroons.Service, admFile,
|
||||
}
|
||||
|
||||
// Generate the admin macaroon and write it to a file.
|
||||
admMacaroon, err := svc.Oven.NewMacaroon(ctx, bakery.LatestVersion,
|
||||
nil, append(readPermissions, writePermissions...)...)
|
||||
adminPermissions := append(readPermissions, writePermissions...)
|
||||
admMacaroon, err := svc.Oven.NewMacaroon(
|
||||
ctx, bakery.LatestVersion, nil, adminPermissions...,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user