diff --git a/README.md b/README.md index 0f649f2..8d4f891 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This is a Go command-line executable to execute remote commands on Windows machines through the use of WinRM/WinRS. -_Note_: this tool doesn't support domain users (it doesn't support GSSAPI nor Kerberos). It's primary target is to execute remote commands on EC2 windows machines. +This tool support domain users via kerberos switch. You can either use a login/password combination, or an existing credential cache (obtained via "kinit") ## Contact @@ -11,10 +11,10 @@ _Note_: this tool doesn't support domain users (it doesn't support GSSAPI nor Ke ## Getting Started -WinRM is available on Windows Server 2008 and up. This project natively supports basic authentication for local accounts, see the steps in the next section on how to prepare the remote Windows machine for this scenario. The authentication model is pluggable, see below for an example on using Negotiate/NTLM authentication (e.g. for connecting to vanilla Azure VMs). +WinRM is available on Windows Server 2008 and up. This project natively supports basic authentication for local accounts, see the steps in the next section on how to prepare the remote Windows machine for this scenario. The authentication model is pluggable, see below for an example on using Negotiate/NTLM authentication (e.g. for connecting to vanilla Azure VMs) or kerberos (for domain accounts) ### Preparing the remote Windows machine for Basic authentication -This project supports only basic authentication for local accounts (domain users are not supported). The remote windows system must be prepared for winrm: +If you can not use kerberos, use basic authentication for local accounts. The remote windows system must be prepared for winrm: _For a PowerShell script to do what is described below in one go, check [Richard Downer's blog](http://www.frontiertown.co.uk/2011/12/overthere-control-windows-from-java/)_ @@ -34,6 +34,16 @@ __N.B.:__ The `MaxMemoryPerShellMB` option has no effects on some Windows 2008R2 For more information on WinRM, please refer to the online documentation at Microsoft's DevCenter. +### Preparing the remote Windows machine for Kerberos authentication +The remote windows system must be prepared: + +On the remote host, a PowerShell prompt, using the __Run as Administrator__ option and paste in the following lines: + + winrm quickconfig + y + winrm set winrm/config/service '@{AllowUnencrypted="true"}' + winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="1024"}' + ### Building the winrm-cli executable You can build winrm-cli from source: @@ -60,6 +70,20 @@ Once built, you can run remote commands like this: ./winrm -hostname remote.domain.com -username "Administrator" -password "secret" "ipconfig /all" ``` +### kerberos authentication + +Either ensure you have a ticket granting ticket before running winrm (use kinit/klist), and run it with -ccache: + +```sh +./winrm -kerberos -ccache /tmp/krb5cc_10007 -hostname remote.domain.com "ipconfig /all" +``` + +Or if you want to user login/password : + +```sh +./winrm -kerberos -username test -password s3cr3t -hostname remote.domain.com -realm DOMAIN.COM "ipconfig /all" +``` + ## Docker ### Build image diff --git a/winrm.go b/winrm.go index 2ea2bea..af21d03 100644 --- a/winrm.go +++ b/winrm.go @@ -33,25 +33,31 @@ import ( func main() { var ( - hostname string - user string - pass string - ntlm bool - cmd string - port int - encoded bool - https bool - insecure bool - cacert string - gencert bool - certsize string - timeout string + hostname string + user string + pass string + ntlm bool + kerberos bool + realm string + ccache string + cmd string + port int + encoded bool + https bool + insecure bool + cacert string + gencert bool + certsize string + timeout string ) flag.StringVar(&hostname, "hostname", "localhost", "winrm host") flag.StringVar(&user, "username", "vagrant", "winrm admin username") flag.StringVar(&pass, "password", "vagrant", "winrm admin password") flag.BoolVar(&ntlm, "ntlm", false, "use use ntlm auth") + flag.BoolVar(&kerberos, "kerberos", false, "use kerberos auth") + flag.StringVar(&realm, "realm", "", "kerberos realm") + flag.StringVar(&ccache, "ccache", "", "kerberos credential cache file, usually /tmp/krb5cc_$UID") flag.BoolVar(&encoded, "encoded", false, "use base64 encoded password") flag.IntVar(&port, "port", 5985, "winrm port") flag.BoolVar(&https, "https", false, "use https") @@ -119,6 +125,27 @@ func main() { params.TransportDecorator = func() winrm.Transporter { return &winrm.ClientNTLM{} } } + if kerberos { + proto := "http" + if https == true { + proto = "https" + } + + params.TransportDecorator = func() winrm.Transporter { + return &winrm.ClientKerberos{ + Username: user, + Password: pass, + Hostname: hostname, + Realm: realm, + Port: port, + Proto: proto, + KrbConf: "/etc/krb5.conf", + KrbCCache: ccache, + SPN: fmt.Sprintf("HTTP/%s", hostname), + } + } + } + client, err := winrm.NewClientWithParameters(endpoint, user, pass, params) check(err)