-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add option to specify TLS config for mongodb database plugin #5632
Changes from 6 commits
29ea465
b262c3f
a246997
f6cc885
1857a79
eb23b18
58af47f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,8 @@ package mongodb | |
import ( | ||
"context" | ||
"crypto/tls" | ||
"crypto/x509" | ||
"io/ioutil" | ||
"encoding/base64" | ||
"encoding/json" | ||
"errors" | ||
|
@@ -29,6 +31,9 @@ type mongoDBConnectionProducer struct { | |
WriteConcern string `json:"write_concern" structs:"write_concern" mapstructure:"write_concern"` | ||
Username string `json:"username" structs:"username" mapstructure:"username"` | ||
Password string `json:"password" structs:"password" mapstructure:"password"` | ||
SSLCert string `json:"ssl_cert" structs:"ssl_cert" mapstructure:"ssl_cert"` | ||
SSLKey string `json:"ssl_key" structs:"ssl_key" mapstructure:"ssl_key"` | ||
SSLCA string `json:"ssl_ca" structs:"ssl_ca" mapstructure:"ssl_ca"` | ||
|
||
Initialized bool | ||
RawConfig map[string]interface{} | ||
|
@@ -119,7 +124,7 @@ func (c *mongoDBConnectionProducer) Connection(_ context.Context) (interface{}, | |
c.session.Close() | ||
} | ||
|
||
dialInfo, err := parseMongoURL(c.ConnectionURL) | ||
dialInfo, err := parseMongoURL(c.ConnectionURL, c.SSLCert, c.SSLKey, c.SSLCA) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
@@ -153,7 +158,7 @@ func (c *mongoDBConnectionProducer) Close() error { | |
return nil | ||
} | ||
|
||
func parseMongoURL(rawURL string) (*mgo.DialInfo, error) { | ||
func parseMongoURL(rawURL string, sslCert string, sslKey string, sslCA string) (*mgo.DialInfo, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If all variable are the same type, you can just repeat the variable names and put the type at the end. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great advice, thanks |
||
url, err := url.Parse(rawURL) | ||
if err != nil { | ||
return nil, err | ||
|
@@ -201,7 +206,37 @@ func parseMongoURL(rawURL string) (*mgo.DialInfo, error) { | |
} | ||
if ssl { | ||
info.DialServer = func(addr *mgo.ServerAddr) (net.Conn, error) { | ||
return tls.Dial("tcp", addr.String(), &tls.Config{}) | ||
tlsConfig := &tls.Config{} | ||
if sslCert != "" && sslKey != "" && sslCA != "" { | ||
clientCertPEM, err := ioutil.ReadFile(sslCert); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The API server will not have access to local resources. You must consume the PEM encoded string directly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, I totally forgot about that. I have changed the code to consume as strings instead |
||
if err != nil { | ||
return nil, errors.New("could not read file: " + sslCert) | ||
} | ||
clientKeyPEM, err := ioutil.ReadFile(sslKey); | ||
if err != nil { | ||
return nil, errors.New("could not read file: " + sslKey) | ||
} | ||
caPEM, err := ioutil.ReadFile(sslCA); | ||
if err != nil { | ||
return nil, errors.New("could not read file: " + sslCA) | ||
} | ||
caCerts := x509.NewCertPool() | ||
ok := caCerts.AppendCertsFromPEM([]byte(caPEM)) | ||
if !ok { | ||
return nil, errors.New("failed to parse root certificate " + sslCA) | ||
} | ||
clientCert, err := tls.X509KeyPair(clientCertPEM, clientKeyPEM) | ||
clientCert.Leaf, err = x509.ParseCertificate(clientCert.Certificate[0]) | ||
if err != nil { | ||
return nil, errors.New("failed parsing ssl options") | ||
} | ||
tlsConfig = &tls.Config{ | ||
Certificates: []tls.Certificate{clientCert}, | ||
RootCAs: caCerts, | ||
InsecureSkipVerify: false, | ||
} | ||
} | ||
return tls.Dial("tcp", addr.String(), tlsConfig) | ||
} | ||
} | ||
case "connect": | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,16 +26,19 @@ has a number of parameters to further configure a connection. | |
### Parameters | ||
|
||
- `connection_url` `(string: <required>)` – Specifies the MongoDB standard | ||
connection string (URI). This field can be templated and supports passing the | ||
username and password parameters in the following format {{field_name}}. A | ||
connection string (URI). This field can be templated and supports passing the | ||
username and password parameters in the following format {{field_name}}. A | ||
templated connection URL is required when using root credential rotation. | ||
- `write_concern` `(string: "")` - Specifies the MongoDB [write | ||
concern][mongodb-write-concern]. This is set for the entirety of the session, | ||
maintained for the lifecycle of the plugin process. Must be a serialized JSON | ||
object, or a base64-encoded serialized JSON object. The JSON payload values | ||
map to the values in the [Safe][mgo-safe] struct from the mgo driver. | ||
- `username` `(string: "")` - The root credential username used in the connection URL. | ||
- `password` `(string: "")` - The root credential password used in the connection URL. | ||
- `username` `(string: "")` - The root credential username used in the connection URL. | ||
- `password` `(string: "")` - The root credential password used in the connection URL. | ||
- `ssl_cert` `(string: "")` - Path to a PEM-encoded client certificate. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Path is an incorrect description since this is this is an API endpoint not a local resource. |
||
- `ssl_key` `(string: "")` - Path to the private key of the client certificate. | ||
- `ssl_ca` `(string: "")` - Path to a PEM-encoded CA certificate to verify the server against. | ||
|
||
### Sample Payload | ||
|
||
|
@@ -46,7 +49,10 @@ has a number of parameters to further configure a connection. | |
"connection_url": "mongodb://{{username}}:{{password}}@mongodb.acme.com:27017/admin?ssl=true", | ||
"write_concern": "{ \"wmode\": \"majority\", \"wtimeout\": 5000 }", | ||
"username": "admin", | ||
"password": "Password!" | ||
"password": "Password!", | ||
"ssl_cert": "/path/to/ssl/cert", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These parameters would not be paths. They should be PEM encoded certs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right |
||
"ssl_key": "/path/to/ssl/key", | ||
"ssl_ca": "/path/to/ssl/ca" | ||
} | ||
``` | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should all be labeled TLS instead of SSL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch