Skip to content
This repository has been archived by the owner on Nov 24, 2021. It is now read-only.

Kerberos Login #22

Closed
reindoat opened this issue May 9, 2019 · 6 comments
Closed

Kerberos Login #22

reindoat opened this issue May 9, 2019 · 6 comments

Comments

@reindoat
Copy link

reindoat commented May 9, 2019

When I try to login via SPNEGO I got following error:

{"errors":["SPNEGO OID of MechToken is not of type KRB5"]}

When I look via WireShark in my request there are 4 mechTypes:

MechType: 1.3.6.1.4.1.311.2.2.10 (NTLMSSP - Microsoft NTLM Security Support Provider)
MechType: 1.2.840.48018.1.2.2 (MS KRB5 - Microsoft Kerberos 5)
MechType: 1.2.840.113554.1.2.2 (KRB5 - Kerberos 5)
MechType: 1.3.6.1.4.1.311.2.2.30 (NEGOEX - SPNEGO Extended Negotiation Security Mechanism)

Seems like only the first one is checked.

@alexrait
Copy link

alexrait commented Jun 2, 2019

I got this error when using httpclient, like this:

var httpClientHandler = new HttpClientHandler(); httpClientHandler.UseDefaultCredentials = true; HttpClient httpClient = new HttpClient(httpClientHandler); var res = await httpClient.PostAsync($"http://WIN-IFC99HHBD1M:8200/v1/auth/kerberos/login", new StringContent(""));

After fixing the MechType check as was described above, I still get an error:
SPNEGO error unmarshaling MechToken: error unmarshalling MechToken OID: asn1: structure error: explicitly tagged member didn't match

@tyrannosaurus-becks
Copy link
Contributor

I am also encountering this issue.

Steps to Reproduce

vault server \
    -config=/home/tbex/Documents/vault_configs/dev-with-debug.hcl \
    -dev -dev-root-token-id=root \
    -dev-plugin-dir=/home/tbex/go/src/github.com/wintoncode/vault-plugin-auth-kerberos/bin

The contents of dev-with-debug.hcl are:

storage "inmem" {}
disable_mlock = true
ui = true
api_addr = "http://127.0.0.1:8200"
log_level = "debug"
  • Configure the Kerberos plugin:
vault auth enable \
    -passthrough-request-headers=Authorization \
    -allowed-response-headers=www-authenticate \
    -path=kerberos \
    vault-plugin-auth-kerberos
vault write auth/kerberos/config \
    keytab=@vault.keytab.base64 \
    service_account="my_service_account"
vault write auth/kerberos/config/ldap {....some config that's never reached during login....}
vault write auth/kerberos/groups/test-role policies=default
  • Run ngrok in front of Vault so it's reachable from the docker containers: ngrok http 8200
  • Enter the service docker container and set it up.
docker exec -it krb5-service-example-com bash
pip install requests
apt install gcc
apt install libkrb5-dev
pip install kerberos
useradd bob
su bob
kinit # bob’s password is “bob”
klist
  • Drop into Python and try to authenticate:
import kerberos
import requests
service = "host"
rc, vc = kerberos.authGSSClientInit(service=service, mech_oid=kerberos.GSS_MECH_OID_SPNEGO)
kerberos.authGSSClientStep(vc, "")
kerberos_token = kerberos.authGSSClientResponse(vc)
ngrok_url = "http://e7f7969a.ngrok.io" # may vary
r = requests.post(ngrok_url + "/v1/auth/kerberos/login", json={'authorization': 'Negotiate ' + kerberos_token})
print('Vault token:', r.json()['auth']['client_token'])
  • With that, I get the same error as above, so I try updating the mech_oid to be KRB5 to match the Go code's check:
import kerberos
import requests
service = "host"
rc, vc = kerberos.authGSSClientInit(service=service, mech_oid=kerberos.GSS_MECH_OID_KRB5)
kerberos.authGSSClientStep(vc, "")
kerberos_token = kerberos.authGSSClientResponse(vc)
ngrok_url = "http://e7f7969a.ngrok.io" # may vary
r = requests.post(ngrok_url + "/v1/auth/kerberos/login", json={'authorization': 'Negotiate ' + kerberos_token})
print('Vault token:', r.json()['auth']['client_token'])
  • I now receive the following error:
>>> r.content
'{"errors":["SPNEGO negotiation token is not a NegTokenInit: OID 1.2.840.113554.1.2.2 does not match SPNEGO OID 1.3.6.1.5.5.2"]}\n'

I'm a noob to Kerberos, so I'm sure I'm doing something incorrectly, but I don't know what... :-) Any tips appreciated. I'll keep poking at it and post or PR if I make any headway.

@optiz0r
Copy link

optiz0r commented Jul 9, 2019

Seeing the same using requests-kerberos and the newer requests-gssapi (on CentOS 7.x so the versions are a little outdated, though I also see the same in a virtualenv with the latest versions)

from __future__ import print_function

import gssapi
import logging
import requests

from requests_gssapi import HTTPSPNEGOAuth, DISABLED

logging.basicConfig()
logger = logging.getLogger('requests_gssapi')
logger.setLevel(logging.DEBUG)

vhost = "vault.domain"
preempt = True

target=gssapi.Name("HTTP@{0}:8200".format(vhost), gssapi.NameType.hostbased_service)
auth = HTTPSPNEGOAuth(mutual_authentication=DISABLED, opportunistic_auth=preempt, target_name=target)
r = requests.post("https://{0}:8200/v1/auth/kerberos/login".format(vhost), auth=auth, verify='/etc/pki/tls/cert.pem')

print(r.__dict__)

Gives

DEBUG:requests_gssapi.gssapi_:HTTPSPNEGOAuth: Preemptive Authorization header: Negotiate blahblah==
DEBUG:requests_gssapi.gssapi_:handle_other(): Handling: 500
DEBUG:requests_gssapi.gssapi_:handle_other(): returning <Response [500]>
DEBUG:requests_gssapi.gssapi_:handle_response(): returning <Response [500]>
{'cookies': <<class 'requests.cookies.RequestsCookieJar'>[]>, '_content': '{"errors":["SPNEGO negotiation token is not a NegTokenInit: OID 1.2.840.113554.1.2.2 does not match SPNEGO OID 1.3.6.1.5.5.2"]}\n', 'headers': {'date': 'Tue, 09 Jul 2019 21:12:03 GMT', 'content-length': '128', 'content-type': 'application/json', 'cache-control': 'no-store'}, 'url': u'https://vault.domain:8200/v1/auth/kerberos/login', 'status_code': 500, '_content_consumed': True, 'encoding': None, 'request': <PreparedRequest [POST]>, 'connection': <requests.adapters.HTTPAdapter object at 0x7f63374d5e10>, 'elapsed': datetime.timedelta(0, 0, 26666), 'raw': <requests.packages.urllib3.response.HTTPResponse object at 0x7f6337462bd0>, 'reason': 'Internal Server Error', 'history': []}

@optiz0r
Copy link

optiz0r commented Jul 12, 2019

I made some progress on this.

Summary of my research in case it helps anyone else.

  • There are two commonly used authentication schemes for kerberos; NTLM used by windows, and KRB5 used more by Unix systems. Either can be used directly as long as client and server both know which one to use. This plugin doesn't support either directly, and requires SPNEGO.
  • SPNEGO is an additional layer on top, defined in RFC2478 and later refined in RFC4178 which allows the client and server to agree on a commonly supported protocol, including NTLM or KRB5.
  • Support for RFC4178 was conveniently merged into python/gssapi just over a month ago, and has not yet been released (pythongssapi/python-gssapi@2347e3f)
  • python/requests-gssapi does not yet support enabling rfc4178 support directly, but can be patched to do so easily

This patch for requests-gssapi is just a PoC, but demonstrates SPNEGO support working when hardcoded in:

--- a/requests_gssapi/gssapi_.py
+++ b/requests_gssapi/gssapi_.py
@@ -140,7 +140,7 @@ class HTTPSPNEGOAuth(AuthBase):
                     self.target_name, gssapi.NameType.hostbased_service)
             self.context[host] = gssapi.SecurityContext(
                 usage="initiate", flags=gssflags, name=self.target_name,
-                creds=self.creds)
+                creds=self.creds, mech=gssapi.mechs.Mechanism.from_sasl_name('SPNEGO'))

             gss_stage = "stepping context"
             if is_preemptive:

And the shortest working client code for this:

from __future__ import print_function
import gssapi
import requests
from requests_gssapi import HTTPSPNEGOAuth, DISABLED

vhost = "vault.domain:8200"
auth = HTTPSPNEGOAuth(target_name=gssapi.Name("HTTP@{0}".format(vhost), gssapi.NameType.hostbased_service))
r = requests.post("https://{0}/v1/auth/kerberos/login".format(vhost), auth=auth, verify='/etc/pki/tls/cert.pem')
print(r.__dict__)

In lieu of RFC4178 changes being included in a released version of gssapi, the following also works in current versions:

spnego = gssapi.OID.from_int_seq("1.3.6.1.5.5.2")

And a PR for proper support in requests-gssapi module for passing the mech through is in pythongssapi/requests-gssapi#19.

@tomqwpl
Copy link

tomqwpl commented Mar 2, 2021

I'm also getting this issue attempting a naïve connection from Chrome running on Windows 10 to the example HTTP server.

@tyrannosaurus-becks
Copy link
Contributor

@tomqwpl please note that this repo has moved to here: https://github.com/hashicorp/vault-plugin-auth-kerberos. I also no longer maintain this repo, or the other, but I noticed your comment and wanted to point you in the right direction.

If this issue isn't open there, you may want to open it to alert the current maintainers.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants