Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GSSAPI support #115

Closed
styleex opened this issue Jun 12, 2017 · 15 comments
Closed

GSSAPI support #115

styleex opened this issue Jun 12, 2017 · 15 comments

Comments

@styleex
Copy link

styleex commented Jun 12, 2017

In my application i have a /etc/krb.conf and /etc/krb5.keytab (configured by adcli join). It would be great if this ldap library could authenticate with this credentials as python ldap3 library.

@styleex
Copy link
Author

styleex commented Oct 1, 2017

Do you have any thoughts about the task? Or a workaround?

@johnweldon
Copy link
Member

I'm not familiar with using GSSAPI. If you're able to provide some more details on what an implementation might look like, it may increase the possibility of someone adding support.

@liggitt
Copy link
Contributor

liggitt commented Oct 3, 2017

Typically it requires building with cgo against c-bindings to a native library. I wouldn't expect it to be built into this library, but I'd consider an interface that allowed injecting a GSSAPI provider impl.

@styleex
Copy link
Author

styleex commented Oct 6, 2017

@vm86 describe, please, the integration of gssapi and ldap.

@liggitt Yes, I understand that you do not want to depend on cgo. In my opinion, the interface for implementing its authorization methods is the best option.

@vm86
Copy link

vm86 commented Oct 18, 2017

Hello, for the work of authorization it is necessary to implement the SASL
https://tools.ietf.org/html/rfc4513#section-5.2
after that this is RFC for GSSAPI ( kerberos )
https://tools.ietf.org/html/rfc4752

if necessary, I can write more details for GSSAPI. but first need a working SASL.

@subcon42
Copy link

subcon42 commented May 8, 2018

Correct, SASL needs to be implemented or linked in some fashion. There are a few Go libraries out there but I am unfamiliar with them and hesitate to recommend a specific one. The only deep, hands-on SASL+LDAP experience I have (dev-wise) would be via Perl's Net::LDAP suite coupled with Authen::SASL. I offer this as a comparative reference only ... maybe you'll find it helpful, maybe not ...

In addition to the SASL/GSSAPI (Kerberos5) mechanism, I recommend the SASL/EXTERNAL mechanism be implemented (possibly even first). This is used for PKI-based Mutual Auth against a DSA, just to name a practical use-case that is common in the world.

Simple Binds (a.k.a binding cleartext using a DN and password) are considered deprecated by just about every major directory service provider. This fact does not change whether or not one uses SSL/TLS (some believe it does, so I'm going to squash that myth here and now) 😄

It is true, Simple Bind support is necessary in many environments, but this should not be the only authentication choice in a nice library such as this.

Out of all modern SASL authentication mechanisms, at least in the LDAP world, SASL/EXTERNAL is the least painless to use and administer IMHO (having done it for years). I suspect that would be a far-less challenging SASL authentication mechanism to start implementing. There's far less to it than SASL/GSSAPI, both in the development sense and in the user-effort sense.

Lastly, and this is subjective I admit, but PKI Mutual Auth is a far smarter and more sustainable way to authenticate clients securely than Kerberos -- far, far fewer things are likely to go wrong with a PKI Issuance Chain than a Single Sign-On service.

@simmel
Copy link

simmel commented Aug 21, 2018

https://github.com/apcera/gssapi might help? ⛽️ 🔥 😜

@johnweldon
Copy link
Member

Feel free to propose an interface to expose for third party implementations

@simmel
Copy link

simmel commented Oct 23, 2018

As I'm not-really-a-Go-programmer what does that mean?

@johnweldon
Copy link
Member

@simmel - my suggestion wasn't directed at your proposal directly - just more generally. The big picture response is that to practically implement GSSAPI would probably mean using C bindings, which we're not willing to do now. If someone wants to build a third party library that wraps this one and adds GSSAPI, then we can discuss what interface/code changes are needed (if any) in this library to facilitate that.

@29x10
Copy link

29x10 commented Dec 20, 2018

@johnweldon

https://sourcegraph.com/github.com/python-ldap/python-ldap/-/blob/Modules/LDAPObject.c#L797:13

It would be great if you cold take a look how to translate that into golang

Here is the actual openldap method in c

https://github.com/openldap/openldap/blob/master/libraries/libldap/sasl.c#L506

@johnweldon
Copy link
Member

Interesting @29x10 - I'll reopen this as an enhancement request and with a call for volunteer help.

@johnweldon johnweldon reopened this Dec 20, 2018
@lukeo3o1
Copy link

I got the same problem, can't use Simple bind authentication

got error:
LDAP Result Code 8 "Strong Auth Required"

Found a third party library:
https://github.com/jcmturner/gokrb5

Maybe it will help?

@TobiasKarnat
Copy link

I need this as well for enterprise use: I wrote a program to synchronize ldap-group members with local linux group users.
As sssd with krb5 is already used, I would not need a technical user to authorize with the active directory server, but could you the computer account to authorize?!

dequbed added a commit to dequbed/go-ldap that referenced this issue Sep 7, 2021
This adds a new Mechanism for SASL Binds using GSSAPI. It does *not*
implement security layers. It does *not* implement any of the newer GS2
mechanism. It does *not* implement the KERBEROSV5 mechanism.
It also due to implementing GSSAPI specifically, not allow for channel
bindings.

Use this with caution.

Closes go-ldap#115.
dequbed added a commit to dequbed/go-ldap that referenced this issue Sep 7, 2021
This adds a new Mechanism for SASL Binds using GSSAPI. It does *not*
implement security layers. It does *not* implement any of the newer GS2
mechanism. It does *not* implement the KERBEROSV5 mechanism.
It also due to implementing GSSAPI specifically, not allow for channel
bindings.

Use this with caution.

Closes go-ldap#115.
dequbed added a commit to dequbed/go-ldap that referenced this issue Sep 7, 2021
This adds a new Mechanism for SASL Binds using GSSAPI. It does *not*
implement security layers. It does *not* implement any of the newer GS2
mechanism. It does *not* implement the KERBEROSV5 mechanism.
It also due to implementing GSSAPI specifically, not allow for channel
bindings.

Use this with caution.

Closes go-ldap#115.
Adphi pushed a commit to linka-cloud/ldap that referenced this issue Sep 9, 2021
This adds a new Mechanism for SASL Binds using GSSAPI. It does *not*
implement security layers. It does *not* implement any of the newer GS2
mechanism. It does *not* implement the KERBEROSV5 mechanism.
It also due to implementing GSSAPI specifically, not allow for channel
bindings.

Use this with caution.

Closes go-ldap#115.
Adphi pushed a commit to linka-cloud/ldap that referenced this issue Sep 10, 2021
This adds a new Mechanism for SASL Binds using GSSAPI. It does *not*
implement security layers. It does *not* implement any of the newer GS2
mechanism. It does *not* implement the KERBEROSV5 mechanism.
It also due to implementing GSSAPI specifically, not allow for channel
bindings.

Use this with caution.

Closes go-ldap#115.
@patryk4815
Copy link

Ticket can be closed.

Keytab and other are supported now ;)
Ref: #449

Example usage:

package main

import (
	"fmt"
	"github.com/go-ldap/ldap/v3"
	"github.com/go-ldap/ldap/v3/gssapi"
	"log"
	"os"
)

type LdapConfig struct {
	Protocol      string
	Server        string
	Realm         string
	Basedn        string
	KrbKeytabPath string
	KrbConfPath   string
	Fqdn          string
}

func DefaultLdapConfig() LdapConfig {
	fqdn, err := os.Hostname()
	if err != nil {
		log.Fatal(err)
	}
	return LdapConfig{
		Protocol: "ldaps",
		Server:   "ldap.example.com",
		Realm:    "EXAMPLE.COM",

		// in my freeipa server it is:
		Basedn: "cn=users,cn=accounts,dc=example,dc=com",

		KrbKeytabPath: "/etc/krb5.keytab",
		KrbConfPath:   "/etc/krb5.conf",
		Fqdn:          fqdn,
	}
}

func main() {
	cfg := DefaultLdapConfig()

	// search this uid in ldap
	// in your case put different
	searchForUID := "patryk4815"

	client, err := gssapi.NewClientWithKeytab(
		"host/"+cfg.Fqdn,
		cfg.Realm,
		cfg.KrbKeytabPath,
		cfg.KrbConfPath,
	)
	if err != nil {
		log.Fatal("gssapi.NewClientWithKeytab", err)
	}
	defer client.Close()

	if err := client.Login(); err != nil {
		log.Fatal("client.Login", err)
	}

	conn, err := ldap.DialURL(fmt.Sprintf("%s://%s", cfg.Protocol, cfg.Server))
	if err != nil {
		log.Fatal("ldap.DialURL", err)
	}
	defer conn.Close()

	err = conn.GSSAPIBind(client, "ldap/"+cfg.Server, "")
	if err != nil {
		log.Fatal("conn.GSSAPIBind", err)
	}

	searchRequest := ldap.NewSearchRequest(
		cfg.Basedn,
		ldap.ScopeSingleLevel,
		ldap.NeverDerefAliases,
		1,
		0,
		false,
		fmt.Sprintf("(uid=%s)", ldap.EscapeFilter(searchForUID)),
		nil,
		nil,
	)

	searchResult, err := conn.Search(searchRequest)
	if err != nil {
		log.Fatal("conn.Search", err)
	}

	searchResult.PrettyPrint(2)
}

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

Successfully merging a pull request may close this issue.