1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-04-26 13:48:53 +08:00

MF-448 - Option for Postgres SSL Mode (#449)

* MF-448 - Option for Postgres SSL Mode

Adds an option to choose the ssl mode when connecting to postgres.
Only supporting disable or require for now with verify-ca and verify-full to come after more discussion.

Signed-off-by: Michael Finley <Michael.Finley@target.com>

* Changing package name back

Accidentally changed the package name so reverting that!

Signed-off-by: Michael Finley <Michael.Finley@target.com>

* Adding section in getting-started for securing pgsql connections

Signed-off-by: Michael Finley <Michael.Finley@target.com>
This commit is contained in:
Michael Finley 2018-11-07 14:54:51 -06:00 committed by Aleksandar Novaković
parent ec0a148ad4
commit eb38c36f80
9 changed files with 64 additions and 42 deletions

View File

@ -43,6 +43,7 @@ const (
defDBUser = "mainflux"
defDBPass = "mainflux"
defDBName = "things"
defDBSSLMode = "disable"
defCACerts = ""
defCacheURL = "localhost:6379"
defCachePass = ""
@ -58,6 +59,7 @@ const (
envDBUser = "MF_THINGS_DB_USER"
envDBPass = "MF_THINGS_DB_PASS"
envDBName = "MF_THINGS_DB"
envDBSSLMode = "MF_THINGS_DB_SSL_MODE"
envCACerts = "MF_THINGS_CA_CERTS"
envCacheURL = "MF_THINGS_CACHE_URL"
envCachePass = "MF_THINGS_CACHE_PASS"
@ -76,6 +78,7 @@ type config struct {
DBUser string
DBPass string
DBName string
DBSSLMode string
CACerts string
CacheURL string
CachePass string
@ -126,6 +129,7 @@ func loadConfig() config {
DBUser: mainflux.Env(envDBUser, defDBUser),
DBPass: mainflux.Env(envDBPass, defDBPass),
DBName: mainflux.Env(envDBName, defDBName),
DBSSLMode: mainflux.Env(envDBSSLMode, defDBSSLMode),
CACerts: mainflux.Env(envCACerts, defCACerts),
CacheURL: mainflux.Env(envCacheURL, defCacheURL),
CachePass: mainflux.Env(envCachePass, defCachePass),
@ -154,7 +158,7 @@ func connectToCache(cacheURL, cachePass string, cacheDB string, logger logger.Lo
}
func connectToDB(cfg config, logger logger.Logger) *sql.DB {
db, err := postgres.Connect(cfg.DBHost, cfg.DBPort, cfg.DBName, cfg.DBUser, cfg.DBPass)
db, err := postgres.Connect(cfg.DBHost, cfg.DBPort, cfg.DBName, cfg.DBUser, cfg.DBPass, cfg.DBSSLMode)
if err != nil {
logger.Error(fmt.Sprintf("Failed to connect to postgres: %s", err))
os.Exit(1)

View File

@ -40,6 +40,7 @@ const (
defDBUser = "mainflux"
defDBPass = "mainflux"
defDBName = "users"
defDBSSLMode = "disable"
defHTTPPort = "8180"
defGRPCPort = "8181"
defSecret = "users"
@ -51,6 +52,7 @@ const (
envDBUser = "MF_USERS_DB_USER"
envDBPass = "MF_USERS_DB_PASS"
envDBName = "MF_USERS_DB"
envDBSSLMode = "MF_USERS_DB_SSL_MODE"
envHTTPPort = "MF_USERS_HTTP_PORT"
envGRPCPort = "MF_USERS_GRPC_PORT"
envSecret = "MF_USERS_SECRET"
@ -65,6 +67,7 @@ type config struct {
DBUser string
DBPass string
DBName string
DBSSLMode string
HTTPPort string
GRPCPort string
Secret string
@ -106,6 +109,7 @@ func loadConfig() config {
DBUser: mainflux.Env(envDBUser, defDBUser),
DBPass: mainflux.Env(envDBPass, defDBPass),
DBName: mainflux.Env(envDBName, defDBName),
DBSSLMode: mainflux.Env(envDBSSLMode, defDBSSLMode),
HTTPPort: mainflux.Env(envHTTPPort, defHTTPPort),
GRPCPort: mainflux.Env(envGRPCPort, defGRPCPort),
Secret: mainflux.Env(envSecret, defSecret),
@ -115,7 +119,7 @@ func loadConfig() config {
}
func connectToDB(cfg config, logger logger.Logger) *sql.DB {
db, err := postgres.Connect(cfg.DBHost, cfg.DBPort, cfg.DBName, cfg.DBUser, cfg.DBPass)
db, err := postgres.Connect(cfg.DBHost, cfg.DBPort, cfg.DBName, cfg.DBUser, cfg.DBPass, cfg.DBSSLMode)
if err != nil {
logger.Error(fmt.Sprintf("Failed to connect to postgres: %s", err))
os.Exit(1)

View File

@ -465,6 +465,17 @@ By default gRPC communication is not secure.
### Server configuration
### Securing PostgreSQL connections
By default, Mainflux will connect to Postgres using insecure transport.
If a secured connection is required, you can select the SSL mode.
`MF_USERS_DB_SSL_MODE` the SSL connection mode for Users.
`MF_THINGS_DB_SSL_MODE` the SSL connection mode for Things.
Currently supported modes are: `disabled` and `required`
#### Users
If either the cert or key is not set, the server will use insecure transport.

View File

@ -17,23 +17,24 @@ The service is configured using the environment variables presented in the
following table. Note that any unset variables will be replaced with their
default values.
| Variable | Description | Default |
|-----------------------|-------------------------------------------------|----------------|
| MF_THINGS_LOG_LEVEL | Log level for Things (debug, info, warn, error) | error |
| MF_THINGS_DB_HOST | Database host address | localhost |
| MF_THINGS_DB_PORT | Database host port | 5432 |
| MF_THINGS_DB_USER | Database user | mainflux |
| MF_THINGS_DB_PASS | Database password | mainflux |
| MF_THINGS_DB | Name of the database used by the service | things |
| MF_THINGS_CA_CERTS | Path to trusted CAs in PEM format | |
| MF_THINGS_CACHE_URL | Cache database URL | localhost:6379 |
| MF_THINGS_CACHE_PASS | Cache database password | |
| MF_THINGS_CACHE_DB | Cache instance that should be used | 0 |
| MF_THINGS_HTTP_PORT | Things service HTTP port | 8180 |
| MF_THINGS_GRPC_PORT | Things service gRPC port | 8181 |
| MF_THINGS_SERVER_CERT | Path to server certificate in pem format | 8181 |
| MF_THINGS_SERVER_KEY | Path to server key in pem format | 8181 |
| MF_USERS_URL | Users service URL | localhost:8181 |
| Variable | Description | Default |
|-----------------------|--------------------------------------------------|----------------|
| MF_THINGS_LOG_LEVEL | Log level for Things (debug, info, warn, error) | error |
| MF_THINGS_DB_HOST | Database host address | localhost |
| MF_THINGS_DB_PORT | Database host port | 5432 |
| MF_THINGS_DB_USER | Database user | mainflux |
| MF_THINGS_DB_PASS | Database password | mainflux |
| MF_THINGS_DB | Name of the database used by the service | things |
| MF_THINGS_DB_SSL_MODE | Database connection SSL mode (disable or require)| disable |
| MF_THINGS_CA_CERTS | Path to trusted CAs in PEM format | |
| MF_THINGS_CACHE_URL | Cache database URL | localhost:6379 |
| MF_THINGS_CACHE_PASS | Cache database password | |
| MF_THINGS_CACHE_DB | Cache instance that should be used | 0 |
| MF_THINGS_HTTP_PORT | Things service HTTP port | 8180 |
| MF_THINGS_GRPC_PORT | Things service gRPC port | 8181 |
| MF_THINGS_SERVER_CERT | Path to server certificate in pem format | 8181 |
| MF_THINGS_SERVER_KEY | Path to server key in pem format | 8181 |
| MF_USERS_URL | Users service URL | localhost:8181 |
## Deployment
@ -56,6 +57,7 @@ services:
MF_THINGS_DB_USER: [Database user]
MF_THINGS_DB_PASS: [Database password]
MF_THINGS_DB: [Name of the database used by the service]
MF_THINGS_DB_SSL_MODE: [SSL mode to connect to the database with]
MF_THINGS_CA_CERTS: [Path to trusted CAs in PEM format]
MF_THINGS_CACHE_URL: [Cache database URL]
MF_THINGS_CACHE_PASS: [Cache database password]
@ -83,7 +85,7 @@ make things
make install
# set the environment variables and run the service
MF_THINGS_LOG_LEVEL=[Things log level] MF_THINGS_DB_HOST=[Database host address] MF_THINGS_DB_PORT=[Database host port] MF_THINGS_DB_USER=[Database user] MF_THINGS_DB_PASS=[Database password] MF_THINGS_DB=[Name of the database used by the service] MF_HTTP_ADAPTER_CA_CERTS=[Path to trusted CAs in PEM format] MF_THINGS_CACHE_URL=[Cache database URL] MF_THINGS_CACHE_PASS=[Cache database password] MF_THINGS_CACHE_DB=[Cache instance that should be used] MF_THINGS_HTTP_PORT=[Service HTTP port] MF_THINGS_GRPC_PORT=[Service gRPC port] MF_USERS_URL=[Users service URL] MF_THINGS_SERVER_CERT=[Path to server certificate] MF_THINGS_SERVER_KEY=[Path to server key] $GOBIN/mainflux-things
MF_THINGS_LOG_LEVEL=[Things log level] MF_THINGS_DB_HOST=[Database host address] MF_THINGS_DB_PORT=[Database host port] MF_THINGS_DB_USER=[Database user] MF_THINGS_DB_PASS=[Database password] MF_THINGS_DB=[Name of the database used by the service] MF_THINGS_DB_SSL_MODE=[SSL mode to connect to the database with] MF_HTTP_ADAPTER_CA_CERTS=[Path to trusted CAs in PEM format] MF_THINGS_CACHE_URL=[Cache database URL] MF_THINGS_CACHE_PASS=[Cache database password] MF_THINGS_CACHE_DB=[Cache instance that should be used] MF_THINGS_HTTP_PORT=[Service HTTP port] MF_THINGS_GRPC_PORT=[Service gRPC port] MF_USERS_URL=[Users service URL] MF_THINGS_SERVER_CERT=[Path to server certificate] MF_THINGS_SERVER_KEY=[Path to server key] $GOBIN/mainflux-things
```
Setting `MF_THINGS_CA_CERTS` expects a file in PEM format of trusted CAs. This will enable TLS against the Users gRPC endpoint trusting only those CAs that are provided.

View File

@ -18,8 +18,8 @@ import (
// Connect creates a connection to the PostgreSQL instance and applies any
// unapplied database migrations. A non-nil error is returned to indicate
// failure.
func Connect(host, port, name, user, pass string) (*sql.DB, error) {
url := fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=%s sslmode=disable", host, port, user, name, pass)
func Connect(host, port, name, user, pass, sslMode string) (*sql.DB, error) {
url := fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=%s sslmode=%s", host, port, user, name, pass, sslMode)
db, err := sql.Open("postgres", url)
if err != nil {

View File

@ -60,7 +60,7 @@ func TestMain(m *testing.M) {
log.Fatalf("Could not connect to docker: %s", err)
}
if db, err = postgres.Connect("localhost", port, "test", "test", "test"); err != nil {
if db, err = postgres.Connect("localhost", port, "test", "test", "test", "disable"); err != nil {
log.Fatalf("Could not setup test DB connection: %s", err)
}
defer db.Close()

View File

@ -16,19 +16,20 @@ The service is configured using the environment variables presented in the
following table. Note that any unset variables will be replaced with their
default values.
| Variable | Description | Default |
|----------------------|-------------------------------------------------|--------------|
| MF_USERS_LOG_LEVEL | Log level for Users (debug, info, warn, error) | error |
| MF_USERS_DB_HOST | Database host address | localhost |
| MF_USERS_DB_PORT | Database host port | 5432 |
| MF_USERS_DB_USER | Database user | mainflux |
| MF_USERS_DB_PASSWORD | Database password | mainflux |
| MF_USERS_DB | Name of the database used by the service | users |
| MF_USERS_HTTP_PORT | Users service HTTP port | 8180 |
| MF_USERS_GRPC_PORT | Users service gRPC port | 8181 |
| MF_USERS_SERVER_CERT | Path to server certificate in pem format | |
| MF_USERS_SERVER_KEY | Path to server key in pem format | |
| MF_USERS_SECRET | String used for signing tokens | users |
| Variable | Description | Default |
|----------------------|--------------------------------------------------|--------------|
| MF_USERS_LOG_LEVEL | Log level for Users (debug, info, warn, error) | error |
| MF_USERS_DB_HOST | Database host address | localhost |
| MF_USERS_DB_PORT | Database host port | 5432 |
| MF_USERS_DB_USER | Database user | mainflux |
| MF_USERS_DB_PASSWORD | Database password | mainflux |
| MF_USERS_DB | Name of the database used by the service | users |
| MF_USERS_DB_SSL_MODE | Database connection SSL mode (disable or require)| disable |
| MF_USERS_HTTP_PORT | Users service HTTP port | 8180 |
| MF_USERS_GRPC_PORT | Users service gRPC port | 8181 |
| MF_USERS_SERVER_CERT | Path to server certificate in pem format | |
| MF_USERS_SERVER_KEY | Path to server key in pem format | |
| MF_USERS_SECRET | String used for signing tokens | users |
## Deployment
@ -51,6 +52,7 @@ services:
MF_USERS_DB_USER: [Database user]
MF_USERS_DB_PASS: [Database password]
MF_USERS_DB: [Name of the database used by the service]
MF_USERS_DB_SSL_MODE: [SSL mode to connect to the database with]
MF_USERS_HTTP_PORT: [Service HTTP port]
MF_USERS_GRPC_PORT: [Service gRPC port]
MF_USERS_SECRET: [String used for signing tokens]
@ -73,7 +75,7 @@ make users
make install
# set the environment variables and run the service
MF_USERS_LOG_LEVEL=[Users log level] MF_USERS_DB_HOST=[Database host address] MF_USERS_DB_PORT=[Database host port] MF_USERS_DB_USER=[Database user] MF_USERS_DB_PASS=[Database password] MF_USERS_DB=[Name of the database used by the service] MF_USERS_HTTP_PORT=[Service HTTP port] MF_USERS_GRPC_PORT=[Service gRPC port] MF_USERS_SECRET=[String used for signing tokens] MF_USERS_SERVER_CERT=[Path to server certificate] MF_USERS_SERVER_KEY=[Path to server key] $GOBIN/mainflux-users
MF_USERS_LOG_LEVEL=[Users log level] MF_USERS_DB_HOST=[Database host address] MF_USERS_DB_PORT=[Database host port] MF_USERS_DB_USER=[Database user] MF_USERS_DB_PASS=[Database password] MF_USERS_DB=[Name of the database used by the service] MF_USERS_DB_SSL_MODE=[SSL mode to connect to the database with] MF_USERS_HTTP_PORT=[Service HTTP port] MF_USERS_GRPC_PORT=[Service gRPC port] MF_USERS_SECRET=[String used for signing tokens] MF_USERS_SERVER_CERT=[Path to server certificate] MF_USERS_SERVER_KEY=[Path to server key] $GOBIN/mainflux-users
```
## Usage

View File

@ -18,9 +18,8 @@ import (
// Connect creates a connection to the PostgreSQL instance and applies any
// unapplied database migrations. A non-nil error is returned to indicate
// failure.
func Connect(host, port, name, user, pass string) (*sql.DB, error) {
t := "host=%s port=%s user=%s dbname=%s password=%s sslmode=disable"
url := fmt.Sprintf(t, host, port, user, name, pass)
func Connect(host, port, name, user, pass, sslMode string) (*sql.DB, error) {
url := fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=%s sslmode=%s", host, port, user, name, pass, sslMode)
db, err := sql.Open("postgres", url)
if err != nil {

View File

@ -53,7 +53,7 @@ func TestMain(m *testing.M) {
log.Fatalf("Could not connect to docker: %s", err)
}
if db, err = postgres.Connect("localhost", port, "test", "test", "test"); err != nil {
if db, err = postgres.Connect("localhost", port, "test", "test", "test", "disable"); err != nil {
log.Fatalf("Could not setup test DB connection: %s", err)
}
defer db.Close()