-
Notifications
You must be signed in to change notification settings - Fork 58
/
config.go
261 lines (203 loc) · 9.92 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
package aperture
import (
"errors"
"fmt"
"path/filepath"
"time"
"github.com/btcsuite/btcd/btcutil"
"github.com/lightninglabs/aperture/aperturedb"
"github.com/lightninglabs/aperture/proxy"
)
var (
apertureDataDir = btcutil.AppDataDir("aperture", false)
defaultConfigFilename = "aperture.yaml"
defaultTLSKeyFilename = "tls.key"
defaultTLSCertFilename = "tls.cert"
defaultLogLevel = "info"
defaultLogFilename = "aperture.log"
defaultMaxLogFiles = 3
defaultMaxLogFileSize = 10
defaultSqliteDatabaseFileName = "aperture.db"
// defaultSqliteDatabasePath is the default path under which we store
// the SQLite database file.
defaultSqliteDatabasePath = filepath.Join(
apertureDataDir, defaultSqliteDatabaseFileName,
)
)
const (
defaultIdleTimeout = time.Minute * 2
defaultReadTimeout = time.Second * 15
defaultWriteTimeout = time.Second * 30
)
type EtcdConfig struct {
Host string `long:"host" description:"host:port of an active etcd instance"`
User string `long:"user" description:"user authorized to access the etcd host"`
Password string `long:"password" description:"password of the etcd user"`
}
type AuthConfig struct {
Network string `long:"network" description:"The network LND is connected to." choice:"regtest" choice:"simnet" choice:"testnet" choice:"mainnet" choice:"signet"`
Disable bool `long:"disable" description:"Whether to disable auth."`
// LndHost is the hostname of the LND instance to connect to.
LndHost string `long:"lndhost" description:"Hostname of the LND instance to connect to"`
TLSPath string `long:"tlspath" description:"Path to LND instance's tls certificate"`
MacDir string `long:"macdir" description:"Directory containing LND instance's macaroons"`
// The one-time-use passphrase used to set up the connection. This field
// identifies the connection that will be used.
Passphrase string `long:"passphrase" description:"the lnc passphrase"`
// MailboxAddress is the address of the mailbox that the client will
// use for the LNC connection.
MailboxAddress string `long:"mailboxaddress" description:"the host:port of the mailbox server to be used"`
// DevServer set to true to skip verification of the mailbox server's
// tls cert.
DevServer bool `long:"devserver" description:"set to true to skip verification of the server's tls cert."`
}
func (a *AuthConfig) validate() error {
// If we're disabled, we don't mind what these values are.
if a.Disable {
return nil
}
switch {
// If LndHost is set we connect directly to the LND node.
case a.LndHost != "":
log.Info("Validating lnd configuration")
if a.Passphrase != "" {
return errors.New("passphrase field cannot be set " +
"when connecting directly to the lnd node")
}
return a.validateLNDAuth()
// If Passphrase is set we connect to the LND node through LNC.
case a.Passphrase != "":
log.Info("Validating lnc configuration")
return a.validateLNCAuth()
default:
return errors.New("invalid authenticator configuration")
}
}
// validateLNDAuth validates the direct LND auth configuration.
func (a *AuthConfig) validateLNDAuth() error {
if a.LndHost == "" {
return errors.New("lnd host required")
}
if a.TLSPath == "" {
return errors.New("lnd tls required")
}
if a.MacDir == "" {
return errors.New("lnd mac dir required")
}
return nil
}
// validateLNCAuth validates the LNC auth configuration.
func (a *AuthConfig) validateLNCAuth() error {
switch {
case a.Passphrase == "":
return errors.New("lnc passphrase required")
case a.MailboxAddress == "":
return errors.New("lnc mailbox address required")
case a.Network == "":
return errors.New("lnc network required")
}
return nil
}
type HashMailConfig struct {
Enabled bool `long:"enabled"`
MessageRate time.Duration `long:"messagerate" description:"The average minimum time that should pass between each message."`
MessageBurstAllowance int `long:"messageburstallowance" description:"The burst rate we allow for messages."`
StaleTimeout time.Duration `long:"staletimeout" description:"The time after the last activity that a mailbox should be removed. Set to -1s to disable. "`
}
type TorConfig struct {
Control string `long:"control" description:"The host:port of the Tor instance."`
ListenPort uint16 `long:"listenport" description:"The port we should listen on for client requests over Tor. Note that this port should not be exposed to the outside world, it is only intended to be reached by clients through the onion service."`
VirtualPort uint16 `long:"virtualport" description:"The port through which the onion services created can be reached at."`
V3 bool `long:"v3" description:"Whether we should listen for client requests through a v3 onion service."`
}
type Config struct {
// ListenAddr is the listening address that we should use to allow Aperture
// to listen for requests.
ListenAddr string `long:"listenaddr" description:"The interface we should listen on for client requests."`
// ServerName can be set to a fully qualifying domain name that should
// be used while creating a certificate through Let's Encrypt.
ServerName string `long:"servername" description:"Server name (FQDN) to use for the TLS certificate."`
// AutoCert can be set to true if aperture should try to create a valid
// certificate through Let's Encrypt using ServerName.
AutoCert bool `long:"autocert" description:"Automatically create a Let's Encrypt cert using ServerName."`
// Insecure can be set to disable TLS on incoming connections.
Insecure bool `long:"insecure" description:"Listen on an insecure connection, disabling TLS for incoming connections."`
// StaticRoot is the folder where the static content served by the proxy
// is located.
StaticRoot string `long:"staticroot" description:"The folder where the static content is located."`
// ServeStatic defines if static content should be served from the
// directory defined by StaticRoot.
ServeStatic bool `long:"servestatic" description:"Flag to enable or disable static content serving."`
// DatabaseBackend is the database backend to be used by the server.
DatabaseBackend string `long:"dbbackend" description:"The database backend to use for storing all asset related data." choice:"sqlite" choice:"postgres" yaml:"dbbackend"`
// Sqlite is the configuration section for the SQLite database backend.
Sqlite *aperturedb.SqliteConfig `group:"sqlite" namespace:"sqlite"`
// Postgres is the configuration section for the Postgres database backend.
Postgres *aperturedb.PostgresConfig `group:"postgres" namespace:"postgres"`
// Etcd is the configuration section for the Etcd database backend.
Etcd *EtcdConfig `group:"etcd" namespace:"etcd"`
// Authenticator is the configuration section for connecting directly
// to the LND node.
Authenticator *AuthConfig `group:"authenticator" namespace:"authenticator"`
Tor *TorConfig `group:"tor" namespace:"tor"`
// Services is a list of JSON objects in string format, which specify
// each backend service to Aperture.
Services []*proxy.Service `long:"service" description:"Configurations for each Aperture backend service."`
// HashMail is the configuration section for configuring the Lightning
// Node Connect mailbox server.
HashMail *HashMailConfig `group:"hashmail" namespace:"hashmail" description:"Configuration for the Lightning Node Connect mailbox server."`
// Prometheus is the config for setting up an endpoint for a Prometheus
// server to scrape metrics from.
Prometheus *PrometheusConfig `group:"prometheus" namespace:"prometheus" description:"Configuration setting up an endpoint that a Prometheus server can scrape."`
// DebugLevel is a string defining the log level for the service either
// for all subsystems the same or individual level by subsystem.
DebugLevel string `long:"debuglevel" description:"Debug level for the Aperture application and its subsystems."`
// ConfigFile points aperture to an alternative config file.
ConfigFile string `long:"configfile" description:"Custom path to a config file."`
// BaseDir is a custom directory to store all aperture flies.
BaseDir string `long:"basedir" description:"Directory to place all of aperture's files in."`
// Profile is the port on which the pprof profile will be served.
Profile uint16 `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65535"`
// IdleTimeout is the maximum amount of time a connection may be idle.
IdleTimeout time.Duration `long:"idletimeout" description:"The maximum amount of time a connection may be idle before being closed."`
// ReadTimeout is the maximum amount of time to wait for a request to
// be fully read.
ReadTimeout time.Duration `long:"readtimeout" description:"The maximum amount of time to wait for a request to be fully read."`
// WriteTimeout is the maximum amount of time to wait for a response to
// be fully written.
WriteTimeout time.Duration `long:"writetimeout" description:"The maximum amount of time to wait for a response to be fully written."`
}
func (c *Config) validate() error {
if !c.Authenticator.Disable {
if err := c.Authenticator.validate(); err != nil {
return err
}
}
if c.ListenAddr == "" {
return fmt.Errorf("missing listen address for server")
}
return nil
}
// DefaultConfig returns the default configuration for a sqlite backend.
func DefaultSqliteConfig() *aperturedb.SqliteConfig {
return &aperturedb.SqliteConfig{
SkipMigrations: false,
DatabaseFileName: defaultSqliteDatabasePath,
}
}
// NewConfig initializes a new Config variable.
func NewConfig() *Config {
return &Config{
DatabaseBackend: "etcd",
Etcd: &EtcdConfig{},
Sqlite: DefaultSqliteConfig(),
Postgres: &aperturedb.PostgresConfig{},
Authenticator: &AuthConfig{},
Tor: &TorConfig{},
HashMail: &HashMailConfig{},
Prometheus: &PrometheusConfig{},
IdleTimeout: defaultIdleTimeout,
ReadTimeout: defaultReadTimeout,
WriteTimeout: defaultWriteTimeout,
}
}