When a Microsoft SQL Database is being configured in Vault, it's important to set the the expected syntax for the documented parameters below that are part of the API /database/config/:name
:
connection_url
username
password
Database Administrators may inadvertently use syntax that's typically supported in CLI applications such as: mssql-cli or as ADO / ODBC type parameters which are not supported in Vault and may result in a panic and or other unexpected behaviour.
In the example below a bad configuration is made with the password parameter missing and instead incorrectly set in connection_url
which will not work and will result in visible panic within the Vault operational logs.
vault secrets enable -path=dbs database ;
# Success! Enabled the database secrets engine at: dbs/
vault write dbs/config/msql1 plugin_name=mssql-database-plugin \
verify_connection=true allowed_roles="*" \
connection_url="user id=SA;password=p455;" username="SA" ;
# Success! Data written to: dbs/config/msql1
vault write -f dbs/rotate-root/msql1 ;
# Error writing data to dbs/rotate-root/msql1: Put "https://…:8200/v1/dbs/rotate-root/msql1": EOF
# OR:
# Error writing data to dbs/rotate-root/msql1: Put "https://…:8200/v1/dbs/rotate-root/msql1": stream error: stream ID 1; INTERNAL_ERROR
The Vault operational logs (journalctl -u vault
) may then include panics outputs similar to that below that correlate to the corresponding dbs/rotate-root/msql1
request:
… [DEBUG] secrets.database.database_ea2c0d9e: created database object: name=mydb plugin_name=mssql-database-plugin
… [TRACE] secrets.database.database_ea2c0d9e.mssql-database-plugin: close: transport=builtin status=started
… [TRACE] secrets.database.database_ea2c0d9e.mssql-database-plugin: close: transport=builtin status=finished err=<nil> took="64.614µs"
… [INFO] http: panic serving 127.0.0.1:56714: interface conversion: interface {} is nil, not string
goroutine 4922 [running]:
net/http.(*conn).serve.func1()
/usr/local/Cellar/go/1.19.4/libexec/src/net/http/server.go:1850 +0xbf
panic({0x595f160, 0xc0012f3f20})
/usr/local/Cellar/go/1.19.4/libexec/src/runtime/panic.go:890 +0x262
github.com/hashicorp/vault/builtin/logical/database.(*databaseBackend).pathRotateRootCredentialsUpdate.func1({0x77568b8, 0xc001019e00}, 0xc00184c300, 0x0?)
/private/tmp/vault-20221211-8467-17qdo62/builtin/logical/database/path_rotate_credentials.go:104 +0xdd5
github.com/hashicorp/vault/sdk/framework.(*Backend).HandleRequest(0xc000b6d260, {0x77568b8, 0xc001019e00}, 0xc00184c300)
/private/tmp/vault-20221211-8467-17qdo62/sdk/framework/backend.go:291 +0xa82
github.com/hashicorp/vault/vault.(*Router).routeCommon(0xc00061a1e0, {0x77568b8, 0xc001019e00}, 0xc00184c300, 0x0)
/private/tmp/vault-20221211-8467-17qdo62/vault/router.go:727 +0x160b
github.com/hashicorp/vault/vault.(*Router).Route(...)
/private/tmp/vault-20221211-8467-17qdo62/vault/router.go:507
github.com/hashicorp/vault/vault.(*Core).doRouting(0xc001080000?, {0x77568b8?, 0xc001019e00?}, 0x0?)
/private/tmp/vault-20221211-8467-17qdo62/vault/request_handling.go:817 +0x2c
github.com/hashicorp/vault/vault.(*Core).handleRequest(0xc001080000, {0x77568b8, 0xc001019e00}, 0xc00184c300)
/private/tmp/vault-20221211-8467-17qdo62/vault/request_handling.go:1008 +0x11da
github.com/hashicorp/vault/vault.(*Core).handleCancelableRequest(0xc001080000, {0x77568b8, 0xc001019aa0}, 0xc00184c300)
/private/tmp/vault-20221211-8467-17qdo62/vault/request_handling.go:665 +0x1545
github.com/hashicorp/vault/vault.(*Core).switchedLockHandleRequest(0xc001080000, {0x77568b8, 0xc0016c5dd0}, 0xc00184c300, 0xe0?)
/private/tmp/vault-20221211-8467-17qdo62/vault/request_handling.go:472 +0x539
github.com/hashicorp/vault/vault.(*Core).HandleRequest(...)
/private/tmp/vault-20221211-8467-17qdo62/vault/request_handling.go:433
github.com/hashicorp/vault/http.request(0x5e44ae0?, {0x7745550, 0xc0016c5ce0}, 0xc000637800, 0xc00184c300?)
/private/tmp/vault-20221211-8467-17qdo62/http/handler.go:910 +0x86
github.com/hashicorp/vault/http.handleLogicalInternal.func1({0x7745550, 0xc0016c5ce0}, 0xc000637800)
/private/tmp/vault-20221211-8467-17qdo62/http/logical.go:354 +0xb6
net/http.HandlerFunc.ServeHTTP(0xc001746f94?, {0x7745550?, 0xc0016c5ce0?}, 0xc00102bb40?)
/usr/local/Cellar/go/1.19.4/libexec/src/net/http/server.go:2109 +0x2f
github.com/hashicorp/vault/http.handleRequestForwarding.func1({0x7745550, 0xc0016c5ce0}, 0xc000637800)
/private/tmp/vault-20221211-8467-17qdo62/http/handler.go:835 +0x39d
net/http.HandlerFunc.ServeHTTP(0xc0018b7398?, {0x7745550?, 0xc0016c5ce0?}, 0x0?)
/usr/local/Cellar/go/1.19.4/libexec/src/net/http/server.go:2109 +0x2f
net/http.(*ServeMux).ServeHTTP(0x10?, {0x7745550, 0xc0016c5ce0}, 0xc000637800)
/usr/local/Cellar/go/1.19.4/libexec/src/net/http/server.go:2487 +0x149
github.com/hashicorp/vault/http.wrapHelpHandler.func1({0x7745550, 0xc0016c5ce0}, 0xc000637800)
/private/tmp/vault-20221211-8467-17qdo62/http/help.go:25 +0x129
net/http.HandlerFunc.ServeHTTP(0xc000d69d00?, {0x7745550?, 0xc0016c5ce0?}, 0x252c640?)
/usr/local/Cellar/go/1.19.4/libexec/src/net/http/server.go:2109 +0x2f
github.com/hashicorp/vault/http.wrapCORSHandler.func1({0x7745550?, 0xc0016c5ce0?}, 0xc0018b7510?)
/private/tmp/vault-20221211-8467-17qdo62/http/cors.go:29 +0x1e5
net/http.HandlerFunc.ServeHTTP(0xc001080000?, {0x7745550?, 0xc0016c5ce0?}, 0xc000a11ec0?)
/usr/local/Cellar/go/1.19.4/libexec/src/net/http/server.go:2109 +0x2f
github.com/hashicorp/vault/http.rateLimitQuotaWrapping.func1({0x7745550, 0xc0016c5ce0}, 0xc000637800)
/private/tmp/vault-20221211-8467-17qdo62/http/util.go:110 +0xc30
net/http.HandlerFunc.ServeHTTP(0xc00173ffb0?, {0x7745550?, 0xc0016c5ce0?}, 0xc001825470?)
/usr/local/Cellar/go/1.19.4/libexec/src/net/http/server.go:2109 +0x2f
github.com/hashicorp/vault/http.wrapGenericHandler.func1({0x7753e90?, 0xc0001a0fc0}, 0xc000637400)
/private/tmp/vault-20221211-8467-17qdo62/http/handler.go:422 +0xdb3
net/http.HandlerFunc.ServeHTTP(0xc001746f94?, {0x7753e90?, 0xc0001a0fc0?}, 0xa5bd5a0?)
/usr/local/Cellar/go/1.19.4/libexec/src/net/http/server.go:2109 +0x2f
github.com/hashicorp/go-cleanhttp.PrintablePathCheckHandler.func1({0x7753e90, 0xc0001a0fc0}, 0xc000637400)
/Users/brew/Library/Caches/Homebrew/go_mod_cache/pkg/mod/github.com/hashicorp/go-cleanhttp@v0.5.2/handlers.go:42 +0x93
net/http.HandlerFunc.ServeHTTP(0x0?, {0x7753e90?, 0xc0001a0fc0?}, 0x1319f54?)
/usr/local/Cellar/go/1.19.4/libexec/src/net/http/server.go:2109 +0x2f
net/http.serverHandler.ServeHTTP({0x773daa8?}, {0x7753e90, 0xc0001a0fc0}, 0xc000637400)
/usr/local/Cellar/go/1.19.4/libexec/src/net/http/server.go:2947 +0x30c
net/http.(*conn).serve(0xc000bf8320, {0x77568b8, 0xc0006760c0})
/usr/local/Cellar/go/1.19.4/libexec/src/net/http/server.go:1991 +0x607
created by net/http.(*Server).Serve
/usr/local/Cellar/go/1.19.4/libexec/src/net/http/server.go:3102 +0x4db
The correct way to have defined the /database/config/:name
is to include the parameters username
& password
as per what's outlined in the Vault documentation- like for example:
vault write dbs/config/msql1 plugin_name=mssql-database-plugin \
verify_connection=true allowed_roles="*" \
username="SA" password="p455" \
connection_url="sqlserver://{{username}}:{{password}}@localhost" ;
# Success! Data written to: dbs/config/msql1
vault write -f dbs/rotate-root/msql1
# Success! Data written to: dbs/rotate-root/msql1