mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 00:45:19 +00:00
Added support to read jwt and mysql password from a file (#141)
The current implementation of FleetDM doesn't support Docker secrets for supplying the MySQL password and JWT key. This PR provides the ability for a file path to read in secrets. The goal of this PR is to avoid storing secrets in a static config or in an environment variable. Example config for Docker: ```yaml mysql: address: mysql:3306 database: fleet username: fleet password_path: /run/secrets/mysql-fleetdm-password redis: address: redis:6379 server: address: 0.0.0.0:8080 cert: /run/secrets/fleetdm-tls-cert key: /run/secrets/fleetdm-tls-key auth: jwt_key_path: /run/secrets/fleetdm-jwt-key filesystem: status_log_file: /var/log/osquery/status.log result_log_file: /var/log/osquery/result.log enable_log_rotation: true logging: json: true ```
This commit is contained in:
parent
522bff0b82
commit
626429c38e
@ -1,3 +1,2 @@
|
||||
*
|
||||
!build/binary-bundle/linux/fleet
|
||||
!build/binary-bundle/linux/fleetctl
|
||||
!build/binary-bundle/linux/fleet
|
||||
!build/binary-bundle/linux/fleet
|
@ -163,14 +163,26 @@ the way that the Fleet server works.
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if config.Auth.JwtKey == "" {
|
||||
if config.Auth.JwtKey != "" && config.Auth.JwtKeyPath != "" {
|
||||
initFatal(err, "A JWT key and a JWT key file were provided - please specify only one")
|
||||
}
|
||||
|
||||
if config.Auth.JwtKeyPath != "" {
|
||||
fileContents, err := ioutil.ReadFile(config.Auth.JwtKeyPath)
|
||||
if err != nil {
|
||||
initFatal(err, "Could not read the JWT Key file provided")
|
||||
}
|
||||
config.Auth.JwtKey = strings.TrimSpace(string(fileContents))
|
||||
}
|
||||
|
||||
if config.Auth.JwtKey == "" && config.Auth.JwtKeyPath == "" {
|
||||
jwtKey, err := kolide.RandomText(24)
|
||||
if err != nil {
|
||||
initFatal(err, "generating sample jwt key")
|
||||
}
|
||||
fmt.Printf("################################################################################\n"+
|
||||
"# ERROR:\n"+
|
||||
"# A value must be supplied for --auth_jwt_key. This value is used to create\n"+
|
||||
"# A value must be supplied for --auth_jwt_key or --auth_jwt_key_path. This value is used to create\n"+
|
||||
"# session tokens for users.\n"+
|
||||
"#\n"+
|
||||
"# Consider using the following randomly generated key:\n"+
|
||||
|
@ -174,7 +174,20 @@ The password to use when connecting to the MySQL instance.
|
||||
password: kolide
|
||||
```
|
||||
|
||||
###### `mysql_tls_ca`
|
||||
##### `mysql_password_path`
|
||||
|
||||
File path to a file that contains the password to use when connecting to the MySQL instance.
|
||||
|
||||
- Default value: `""`
|
||||
- Config file format:
|
||||
|
||||
```
|
||||
mysql:
|
||||
password_path: '/run/secrets/fleetdm-mysql-password
|
||||
```
|
||||
|
||||
|
||||
##### `mysql_tls_ca`
|
||||
|
||||
The path to a PEM encoded certificate of MYSQL's CA for client certificate authentication.
|
||||
|
||||
@ -418,7 +431,19 @@ The [JWT](https://jwt.io/) key to use when signing and validating session keys.
|
||||
jwt_key: JVnKw7CaUdJjZwYAqDgUHVYP
|
||||
```
|
||||
|
||||
###### `auth_bcrypt_cost`
|
||||
##### `auth_jwt_key_path`
|
||||
|
||||
File path to a file that contains the [JWT](https://jwt.io/) key to use when signing and validating session keys.
|
||||
|
||||
- Default value: `""`
|
||||
- Config file format:
|
||||
|
||||
```
|
||||
auth:
|
||||
jwt_key_path: '/run/secrets/fleetdm-jwt-token
|
||||
```
|
||||
|
||||
##### `auth_bcrypt_cost`
|
||||
|
||||
The bcrypt cost to use when hashing user passwords.
|
||||
|
||||
|
@ -21,6 +21,7 @@ type MysqlConfig struct {
|
||||
Address string
|
||||
Username string
|
||||
Password string
|
||||
PasswordPath string `yaml:"password_path"`
|
||||
Database string
|
||||
TLSCert string `yaml:"tls_cert"`
|
||||
TLSKey string `yaml:"tls_key"`
|
||||
@ -59,6 +60,7 @@ type ServerConfig struct {
|
||||
// AuthConfig defines configs related to user authorization
|
||||
type AuthConfig struct {
|
||||
JwtKey string `yaml:"jwt_key"`
|
||||
JwtKeyPath string `yaml:"jwt_key_path"`
|
||||
BcryptCost int `yaml:"bcrypt_cost"`
|
||||
SaltKeySize int `yaml:"salt_key_size"`
|
||||
}
|
||||
@ -168,8 +170,10 @@ func (man Manager) addConfigs() {
|
||||
"MySQL server address (host:port)")
|
||||
man.addConfigString("mysql.username", "kolide",
|
||||
"MySQL server username")
|
||||
man.addConfigString("mysql.password", "kolide",
|
||||
man.addConfigString("mysql.password", "",
|
||||
"MySQL server password (prefer env variable for security)")
|
||||
man.addConfigString("mysql.password_path", "",
|
||||
"Path to file containg MySQL server password")
|
||||
man.addConfigString("mysql.database", "kolide",
|
||||
"MySQL database name")
|
||||
man.addConfigString("mysql.tls_cert", "",
|
||||
@ -213,6 +217,8 @@ func (man Manager) addConfigs() {
|
||||
// Auth
|
||||
man.addConfigString("auth.jwt_key", "",
|
||||
"JWT session token key (required)")
|
||||
man.addConfigString("auth.jwt_key_path", "",
|
||||
"Path to file containg JWT session token key")
|
||||
man.addConfigInt("auth.bcrypt_cost", 12,
|
||||
"Bcrypt iterations")
|
||||
man.addConfigInt("auth.salt_key_size", 24,
|
||||
@ -314,6 +320,7 @@ func (man Manager) LoadConfig() KolideConfig {
|
||||
Address: man.getConfigString("mysql.address"),
|
||||
Username: man.getConfigString("mysql.username"),
|
||||
Password: man.getConfigString("mysql.password"),
|
||||
PasswordPath: man.getConfigString("mysql.password_path"),
|
||||
Database: man.getConfigString("mysql.database"),
|
||||
TLSCert: man.getConfigString("mysql.tls_cert"),
|
||||
TLSKey: man.getConfigString("mysql.tls_key"),
|
||||
@ -340,6 +347,7 @@ func (man Manager) LoadConfig() KolideConfig {
|
||||
},
|
||||
Auth: AuthConfig{
|
||||
JwtKey: man.getConfigString("auth.jwt_key"),
|
||||
JwtKeyPath: man.getConfigString("auth.jwt_key_path"),
|
||||
BcryptCost: man.getConfigInt("auth.bcrypt_cost"),
|
||||
SaltKeySize: man.getConfigInt("auth.salt_key_size"),
|
||||
},
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/WatchBeam/clock"
|
||||
@ -109,6 +110,21 @@ func New(config config.MysqlConfig, c clock.Clock, opts ...DBOption) (*Datastore
|
||||
setOpt(options)
|
||||
}
|
||||
|
||||
if config.PasswordPath != "" && config.Password != "" {
|
||||
return nil, errors.New("A MySQL password and a MySQL password file were provided - please specify only one")
|
||||
}
|
||||
|
||||
// Check to see if the flag is populated
|
||||
// Check if file exists on disk
|
||||
// If file exists read contents
|
||||
if config.PasswordPath != "" {
|
||||
fileContents, err := ioutil.ReadFile(config.PasswordPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.Password = strings.TrimSpace(string(fileContents))
|
||||
}
|
||||
|
||||
if config.TLSConfig != "" {
|
||||
err := registerTLS(config)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user