Terraform: WinRM with domain accounts does not work

Created on 2 Sep 2017  ยท  6Comments  ยท  Source: hashicorp/terraform

Hi,

Unless I'm missing something. Terraform is currently unable to use a WinRM connection if the account is a domain user. Local accounts work fine provided WinRM has been correctly configured on the target server. This seems to be because Terraform uses basic authentication to connect, and WinRM will not allow domain accounts using basic authentication. See: https://stackoverflow.com/questions/11153692/wsman-and-basic-authorization

I've noticed that Chef solve this by switching to Negotiate authentication when a domain account is detected. Negotiate will allow domain accounts.

Example Terraform code:

connection {
  type     = "winrm"
  user     = "[email protected]"
  password = "myplaintextpassword"
  host     = "host"
  https    = "true"
  port     = "5986"
  insecure = "true"
}

The error in Terraform:
remote-exec-provisioner (internal) 2017/09/02 18:58:14 connection error: http error: 401 -

We can demonstrate that WinRM is configured correctly using Test-WSMan with a local account and basic authentication:

$myLocalAccount = New-Object System.Management.Automation.PSCredential("Administrator",$secPasword)
Test-WSMan -ComputerName host -Authentication Basic -Credential $myLocalAccount -UseSSL -Port 5986


wsmid           : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor   : Microsoft Corporation
ProductVersion  : OS: 10.0.14393 SP: 0.0 Stack: 3.0

We can then change to a domain account and try again using basic authentication, which is not allowed:

$myDomainAccount = New-Object System.Management.Automation.PSCredential("[email protected]",$secPasword)
Test-WSMan -ComputerName host -Authentication Basic -Credential $myDomainAccount -UseSSL -Port 5986
Test-WSMan : <f:WSManFault xmlns:f="http://schemas.microsoft.com/wbem/wsman/1/wsmanfault" Code="5" Machine="MY-COMPUTER"><f:Message>Access is 
denied. </f:Message></f:WSManFault>

But if we switch to negotiate authentication the domain account is now allowed:

$myDomainAccount = New-Object System.Management.Automation.PSCredential("[email protected]",$secPasword)
Test-WSMan -ComputerName host -Authentication Negotiate -Credential $myDomainAccount -UseSSL -Port 5986


wsmid           : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor   : Microsoft Corporation
ProductVersion  : OS: 10.0.14393 SP: 0.0 Stack: 3.0

Is support for negotiate authentication something that can be added, or am I missing something?

Thanks.

bug provisionewinrm

Most helpful comment

This is the same issue as here, I believe:
https://github.com/hashicorp/terraform/issues/7397

I have been looking into this and believe Terraform should be able to support it, maybe by adding a "negotiate" optional parameter to the WinRM connection provider. Then if negotiate is enabled NTLM can be enabled for that connection using code similar to here:
https://gist.github.com/tintoy/5aacf6c4de3cbf31082985f5ff8b38f7/

I have created a Gist with the patch, if someone from Hashicorp wants to take a look. I have been unable to test it, though.

All 6 comments

+1

This is the same issue as here, I believe:
https://github.com/hashicorp/terraform/issues/7397

I have been looking into this and believe Terraform should be able to support it, maybe by adding a "negotiate" optional parameter to the WinRM connection provider. Then if negotiate is enabled NTLM can be enabled for that connection using code similar to here:
https://gist.github.com/tintoy/5aacf6c4de3cbf31082985f5ff8b38f7/

I have created a Gist with the patch, if someone from Hashicorp wants to take a look. I have been unable to test it, though.

Negotiate will probably not help in a windows domain. My experience with pywinrm in a Windows Domain is that only Kerberos authentication is allowed for domain accounts.

BTW, i tried changing the code to use Negotiate and it didn't work, but maybe i didn't do it right.
Sorry for the misformatted markdown, can't fix it.

diff --git a/communicator/winrm/communicator.go b/communicator/winrm/communicator.go
index 729e6eb..a467b9b 100644
\-\-\- a/communicator/winrm/communicator.go
\+\+\+ b/communicator/winrm/communicator.go
@@ -5,11 +5,13 @@ import (
        "io"
        "log"
        "math/rand"
\+       //      "net/http"
        "strconv"
        "strings"
        "sync"
        "time"

\+       //      ntlmssp "github.com/Azure/go-ntlmssp"
        "github.com/hashicorp/terraform/communicator/remote"
        "github.com/hashicorp/terraform/terraform"
        "github.com/masterzen/winrm"
@@ -62,6 +64,15 @@ func (c *Communicator) Connect(o terraform.UIOutput) error {

        params := winrm.DefaultParameters
        params.Timeout = formatDuration(c.Timeout())
\+       if c.connInfo.AuthType == "Negotiate" {
\+               params.TransportDecorator = func() winrm.Transporter { return &winrm.ClientNTLM{} }
\+               /*              params.TransportDecorator = func(transport *http.Transport) http.RoundTripper {
\+                                       return &ntlmssp.Negotiator{
\+                                               RoundTripper: transport,
\+                                       }
\+                               }
\+               */
\+       }

        client, err := winrm.NewClientWithParameters(
                c.endpoint, c.connInfo.User, c.connInfo.Password, params)
diff --git a/communicator/winrm/provisioner.go b/communicator/winrm/provisioner.go
index 1482042..2340cba 100644
\-\-\- a/communicator/winrm/provisioner.go
\+\+\+ b/communicator/winrm/provisioner.go
@@ -37,6 +37,7 @@ type connectionInfo struct {
        Port       int
        HTTPS      bool
        Insecure   bool
\+       AuthType   string \`mapstructure:"auth_type"\`
        CACert     string \`mapstructure:"cacert"\`
        Timeout    string
        ScriptPath string        \`mapstructure:"script_path"\`
diff --git a/terraform/eval_validate.go b/terraform/eval_validate.go
index 478aa64..a02f117 100644
\-\-\- a/terraform/eval_validate.go
\+\+\+ b/terraform/eval_validate.go
@@ -154,6 +154,7 @@ func (n *EvalValidateProvisioner) validateConnConfig(connConfig *ResourceConfig)
                // For type=winrm only (enforced in winrm communicator)
                HTTPS    interface{} \`mapstructure:"https"\`
                Insecure interface{} \`mapstructure:"insecure"\`
\+               AuthType interface{} \`mapstructure:"auth_type"\`
                CACert   interface{} \`mapstructure:"cacert"\`
        }
`

`  connection {
    type = "winrm"
    host = "windowshost.mydomain"
    user = "DOMAIN\user"
    auth_type= "Negotiate"
    password = "${chomp(file("secrets/user-pass.txt"))}"
  }

Hello! :robot:

This issue relates to an older version of Terraform that is no longer in active development, and because the area of Terraform it relates to has changed significantly since the issue was opened we suspect that the issue is either fixed or that the circumstances around it have changed enough that we'd need an updated issue report in order to reproduce and address it.

If you're still seeing this or a similar issue in the latest version of Terraform, please do feel free to open a new bug report! Please be sure to include all of the information requested in the template, even if it might seem redundant with the information already shared in _this_ issue, because the internal details relating to this problem are likely to be different in the current version of Terraform.

Thanks!

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rnowosielski picture rnowosielski  ยท  3Comments

rjinski picture rjinski  ยท  3Comments

sprokopiak picture sprokopiak  ยท  3Comments

c4milo picture c4milo  ยท  3Comments

rkulagowski picture rkulagowski  ยท  3Comments