mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Add TLS for mysql
Use ssl_mode for mysql and add docs add docs for the new parameters in config Tolerate ssl_mode without client authentication Client cert is not necessary for a SSL connection. So we tolerate failure if client cert is not provided. Improve error message if missing server_cert_name and mode is not skip-verify.
This commit is contained in:
parent
3dc3d363fd
commit
ea566fff24
@ -63,9 +63,15 @@ name = grafana
|
||||
user = root
|
||||
password =
|
||||
|
||||
# For "postgres" only, either "disable", "require" or "verify-full"
|
||||
# For "postgres", use either "disable", "require" or "verify-full"
|
||||
# For "mysql", use either "true", "false", or "skip-verify".
|
||||
ssl_mode = disable
|
||||
|
||||
ca_cert_path =
|
||||
client_key_path =
|
||||
client_cert_path =
|
||||
server_cert_name =
|
||||
|
||||
# For "sqlite3" only, path relative to data_path setting
|
||||
path = grafana.db
|
||||
|
||||
|
@ -156,7 +156,24 @@ The database user's password (not applicable for `sqlite3`).
|
||||
|
||||
### ssl_mode
|
||||
|
||||
For `postgres` only, either `disable`, `require` or `verify-full`.
|
||||
For Postgres, use either `disable`, `require` or `verify-full`.
|
||||
For MySQL, use either `true`, `false`, or `skip-verify`.
|
||||
|
||||
### ca_cert_path
|
||||
|
||||
(MySQL only) The path to the CA certificate to use. On many linux systems, certs can be found in `/etc/ssl/certs`.
|
||||
|
||||
### client_key_path
|
||||
|
||||
(MySQL only) The path to the client key. Only if server requires client authentication.
|
||||
|
||||
### client_cert_path
|
||||
|
||||
(MySQL only) The path to the client cert. Only if server requires client authentication.
|
||||
|
||||
### server_cert_name
|
||||
|
||||
(MySQL only) The common name field of the certificate used by the `mysql` server. Not necessary if `ssl_mode` is set to `skip-verify`.
|
||||
|
||||
<hr />
|
||||
|
||||
|
@ -18,8 +18,17 @@ import (
|
||||
"github.com/go-xorm/xorm"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
)
|
||||
|
||||
type MySQLConfig struct {
|
||||
SslMode string
|
||||
CaCertPath string
|
||||
ClientKeyPath string
|
||||
ClientCertPath string
|
||||
ServerCertName string
|
||||
}
|
||||
|
||||
var (
|
||||
x *xorm.Engine
|
||||
dialect migrator.Dialect
|
||||
@ -30,6 +39,8 @@ var (
|
||||
Type, Host, Name, User, Pwd, Path, SslMode string
|
||||
}
|
||||
|
||||
mysqlConfig MySQLConfig
|
||||
|
||||
UseSQLite3 bool
|
||||
)
|
||||
|
||||
@ -115,6 +126,14 @@ func getEngine() (*xorm.Engine, error) {
|
||||
case "mysql":
|
||||
cnnstr = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
|
||||
DbCfg.User, DbCfg.Pwd, DbCfg.Host, DbCfg.Name)
|
||||
if mysqlConfig.SslMode == "true" || mysqlConfig.SslMode == "skip-verify" {
|
||||
tlsCert, err := makeCert("custom", mysqlConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mysql.RegisterTLSConfig("custom", tlsCert)
|
||||
cnnstr += "&tls=custom"
|
||||
}
|
||||
case "postgres":
|
||||
var host, port = "127.0.0.1", "5432"
|
||||
fields := strings.Split(DbCfg.Host, ":")
|
||||
@ -156,4 +175,12 @@ func LoadConfig() {
|
||||
}
|
||||
DbCfg.SslMode = sec.Key("ssl_mode").String()
|
||||
DbCfg.Path = sec.Key("path").MustString("data/grafana.db")
|
||||
|
||||
if DbCfg.Type == "mysql" {
|
||||
mysqlConfig.SslMode = DbCfg.SslMode
|
||||
mysqlConfig.CaCertPath = sec.Key("ca_cert_path").String()
|
||||
mysqlConfig.ClientKeyPath = sec.Key("client_key_path").String()
|
||||
mysqlConfig.ClientCertPath = sec.Key("client_cert_path").String()
|
||||
mysqlConfig.ServerCertName = sec.Key("server_cert_name").String()
|
||||
}
|
||||
}
|
||||
|
41
pkg/services/sqlstore/tls_mysql.go
Normal file
41
pkg/services/sqlstore/tls_mysql.go
Normal file
@ -0,0 +1,41 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
func makeCert(tlsPoolName string, config MySQLConfig) (*tls.Config, error) {
|
||||
rootCertPool := x509.NewCertPool()
|
||||
pem, err := ioutil.ReadFile(config.CaCertPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not read DB CA Cert path: %v", config.CaCertPath)
|
||||
}
|
||||
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
|
||||
return nil, err
|
||||
}
|
||||
clientCert := make([]tls.Certificate, 0, 1)
|
||||
if (config.ClientCertPath != "" && config.ClientKeyPath != "") {
|
||||
|
||||
certs, err := tls.LoadX509KeyPair(config.ClientCertPath, config.ClientKeyPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientCert = append(clientCert, certs)
|
||||
}
|
||||
tlsConfig := &tls.Config{
|
||||
RootCAs: rootCertPool,
|
||||
Certificates: clientCert,
|
||||
}
|
||||
tlsConfig.ServerName = config.ServerCertName
|
||||
if config.SslMode == "skip-verify" {
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
}
|
||||
// Return more meaningful error before it is too late
|
||||
if config.ServerCertName == "" && !tlsConfig.InsecureSkipVerify{
|
||||
return nil, fmt.Errorf("server_cert_name is missing. Consider using ssl_mode = skip-verify.")
|
||||
}
|
||||
return tlsConfig, nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user