beats
beats copied to clipboard
[Metricbeat] MSSQL module cannot parse username if domain is included within the host string
Please include configurations and logs if available.
For confirmed bugs, please report:
- Version: Metricbeat 7.3.0
- Operating System: Windows
- Discuss Forum URL:
- Steps to Reproduce:
Using a domain within the username in credentials doesn't seem to parse regardless of escaping.
Typical configuration example might look like:
------------
# Module: mssql
# Docs: https://www.elastic.co/guide/en/beats/metricbeat/7.3/metricbeat-module-mssql.html
- module: mssql
metricsets:
- "transaction_log"
- "performance"
hosts: ["sqlserver://sa@localhost"]
period: 10s
But when attempting to use an Active Domain user rather than the SA service account, there doesn't seem to be a way to specify the domain within the hosts connection string and have it work.
Examples of what doesn't work:
hosts: ["sqlserver://domain\user:password@server01"]
hosts: ["sqlserver://domain\\user:password@server01"]
hosts: ["sqlserver://domain/user:password@server01"]
hosts: ["sqlserver://domain\/user:password@server01"]
hosts: ["domain\user:password@server01"]
hosts: ["domain\\user:password@server01"]
hosts: ["domain/user:password@server01"]
hosts: ["domain\/user:password@server01"]
Example errors
When trying with domain:
2019-08-28T12:54:59.661+1200 ERROR instance/beat.go:802 Exiting: 1 error: 2 errors: host parsing failed for mssql-transaction_log: error parsing URL: parse sqlserver://mydomain\user:password@server01: net/url: invalid userinfo; host parsing failed for mssql-performance: error parsing URL: parse sqlserver://mydomain\user:password@server01: net/url: invalid userinfo
Exiting: 1 error: 2 errors: host parsing failed for mssql-transaction_log: error parsing URL: parse sqlserver://mydomain\user:password@server01: net/url: invalid userinfo; host parsing failed for mssql-performance: error parsing URL: parse sqlserver://mydomain\user:password@server01: net/url: invalid userinfo
If leaving the domain out, the error is that the native user with that name cannot log in as the user with access is the domain user with that name not a native user:
2019-08-28T12:56:25.383+1200 ERROR instance/beat.go:802 Exiting: 1 error: 2 errors: could not create connection to db: error doing ping to db: Login error: mssql: Login failed for user 'user'.; could not create connection to db: error doing ping to db: Login error: mssql: Login failed for user 'user'.
Exiting: 1 error: 2 errors: could not create connection to db: error doing ping to db: Login error: mssql: Login failed for user 'user'.; could not create connection to db: error doing ping to db: Login error: mssql: Login failed for user 'user'.
Interestingly the domain credentials can be made to work if set separately via:
metricbeat.modules:
- module: mssql
metricsets:
- "transaction_log"
- "performance"
hosts: ["sqlserver://localhost"]
username: domain\username
password: verysecurepassword
period: 10s
Related:
- https://github.com/elastic/beats/pull/13363
- https://github.com/elastic/beats/issues/13006
Pinging @elastic/integrations (Team:Integrations)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
@geekpete
Please try out the below:
hosts: ["sqlserver://domain//user:password@server01"]
and ignore the username and password in config.yml
@geekpete Any update on the above suggestion?
@geekpete Any Update here?
Sorry, I'm still working to follow up on this one.
@geekpete Any update on the suggested method?
@geekpete Any inputs so that we can proceed with the further about this?
So in the original testing for this issue it looks like we'd tried everything except the way you're suggesting:
hosts: ["sqlserver://domain\user:password@server01"]
hosts: ["sqlserver://domain\\user:password@server01"]
hosts: ["sqlserver://domain/user:password@server01"]
hosts: ["sqlserver://domain\/user:password@server01"]
but not with two forward slashes after the domain
hosts: ["sqlserver://domain//user:password@server01"]
I'll see if I can get this tested and report back.
So in the original testing for this issue it looks like we'd tried everything except the way you're suggesting:
hosts: ["sqlserver://domain\user:password@server01"] hosts: ["sqlserver://domain\\user:password@server01"] hosts: ["sqlserver://domain/user:password@server01"] hosts: ["sqlserver://domain\/user:password@server01"]but not with two forward slashes after the
domainhosts: ["sqlserver://domain//user:password@server01"]I'll see if I can get this tested and report back.
Thank you @geekpete
The issue here is that the \ character is not a valid character for userinfo. This can be worked around by percent encoding the backslash (See https://play.golang.com/p/ldyqlqiG8f7). url.PathEscape should be used on the username prior to constructing the connection URL. This looks like it can be done like this:
diff --git a/metricbeat/mb/parse/url.go b/metricbeat/mb/parse/url.go
index c0b23f421d..5c2ff19e86 100644
--- a/metricbeat/mb/parse/url.go
+++ b/metricbeat/mb/parse/url.go
@@ -71,6 +71,8 @@ func (b URLHostParserBuilder) Build() mb.HostParser {
} else {
user = b.DefaultUsername
}
+ user = url.PathEscape(user)
+
t, ok = conf["password"]
if ok {
pass, ok = t.(string)
Until the codebase is adjusted to automatically escape/encode the slash, it's also likely you can configure the string without the slash by manually passing the encoded value %5C directly instead of "\" in the domain user name.
ie for domain user: domain%5Cusername
eg: sqlserver://domain%5Cusername:pass@ip
Related issue to sanitize input in Kibana https://github.com/elastic/integrations/issues/5213