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

sentry-ldap-auth for Active Directory #22

Open
Piknik1990 opened this issue Sep 4, 2017 · 7 comments
Open

sentry-ldap-auth for Active Directory #22

Piknik1990 opened this issue Sep 4, 2017 · 7 comments

Comments

@Piknik1990
Copy link

Hello!

I need to set up AD-authorization on Sentry. In the Internet on this theme I found this topic only: https://forum.sentry.io/t/how-to-set-up-to-auth-via-ms-active-directory-or-ldap/1880/5

But settings of this topic leads or not work AD-auth, or full non-work sentry (He not accept options "LOGGING").

I have next AD-server

IP 10.10.10.10
Domain: test.comp.com
Users: test.comp.com/Users
Groups: test.comp.com/Groups

Test User: test.comp.com/Users/user
Test Groups: test.comp.com/Groups/adminsupport (full right)
test.comp.com/Groups/support (read only)

Now my conf-file have follow parameters:

sentry.conf.py

from sentry.conf.server import *
 
import os.path
 
CONF_ROOT = os.path.dirname(__file__)
 
DATABASES = {
    'default': {
        'ENGINE': 'sentry.db.postgres',
        'NAME': 'sentry',
        'USER': 'sentry',
        'PASSWORD': '123',
        'HOST': '127.0.0.1',
        'PORT': '5432',
        'AUTOCOMMIT': True,
        'ATOMIC_REQUESTS': False,
    }
}
 
SENTRY_USE_BIG_INTS = True
SENTRY_SINGLE_ORGANIZATION = True
DEBUG = False
SENTRY_CACHE = 'sentry.cache.redis.RedisCache'
BROKER_URL = 'redis://localhost:6379'
SENTRY_RATELIMITER = 'sentry.ratelimits.redis.RedisRateLimiter'
SENTRY_BUFFER = 'sentry.buffer.redis.RedisBuffer'
SENTRY_QUOTAS = 'sentry.quotas.redis.RedisQuota'
SENTRY_TSDB = 'sentry.tsdb.redis.RedisTSDB'
SENTRY_DIGESTS = 'sentry.digests.backends.redis.RedisBackend'
# FORCE_SCRIPT_NAME = '/sentry'
SENTRY_WEB_HOST = '0.0.0.0'
SENTRY_WEB_PORT = 9000
SENTRY_WEB_OPTIONS = {
    # 'workers': 3,  # the number of web workers
    # 'protocol': 'uwsgi',  # Enable uwsgi protocol instead of http
}
 

import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfUniqueNamesType

AUTH_LDAP_SERVER_URI = 'ldap://10.10.10.10.'
AUTH_LDAP_BIND_DN = 'CN=User,CN=Users,DC=test,DC=comp,DC=com'
AUTH_LDAP_BIND_PASSWORD = '123'

AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_DEBUG_LEVEL: 0,
ldap.OPT_REFERRALS: 0,
}

AUTH_LDAP_USER_SEARCH = LDAPSearch(
    'dc=test,dc=comp,dc=com',
    ldap.SCOPE_SUBTREE,
    'member={1}',
)

AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
    'dc=test,dc=comp,dc=comp',
    ldap.SCOPE_SUBTREE,
    'objectClass=group'
)

AUTH_LDAP_GROUP_TYPE = GroupOfUniqueNamesType()
AUTH_LDAP_REQUIRE_GROUP = None
AUTH_LDAP_DENY_GROUP = None

AUTH_LDAP_USER_ATTR_MAP = {
    'name': 'cn',
    'email': 'mail'
}

AUTH_LDAP_FIND_GROUP_PERMS = False
AUTH_LDAP_CACHE_GROUPS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600

AUTH_LDAP_DEFAULT_SENTRY_ORGANIZATION = u'TEST COMP COM'
AUTH_LDAP_SENTRY_ORGANIZATION_ROLE_TYPE = 'member'
AUTH_LDAP_SENTRY_ORGANIZATION_GLOBAL_ACCESS = True

AUTHENTICATION_BACKENDS = AUTHENTICATION_BACKENDS + (
    'sentry_ldap_auth.backend.SentryLdapBackend',
)

import logging
logger = logging.getLogger('django_auth_ldap')
logger.addHandler(logging.StreamHandler())
logger.addHandler(logging.FileHandler(r"/tmp/ldap2.log"))
logger.setLevel('DEBUG')

#LOGGING[‘overridable’] = [‘sentry’, ‘django_auth_ldap’ ]
#LOGGING[‘loggers’][‘django_auth_ldap’] = {
#‘handlers’: [‘console’],
#‘level’: ‘DEBUG’
#}

Tell me, do you have AD-like config file for Sentry for example?

@barronhagerman
Copy link
Contributor

After just a quick look at your configuration, it doesn't look like your AUTH_LDAP_USER_SEARCH is correct. The LDAP query (parameter 3 for LDAPSearch()) should be something like (uid=%(user)s)

@Piknik1990
Copy link
Author

Piknik1990 commented Sep 8, 2017

Slightly differently explain.

I experimented several days and now I have this:

Active Directory on Windows 2008R2

  1. domain test.comp.com
  2. User: user in catalog test.comp.com/Users/
  3. IP 10.10.10.1

Sentry on CentOS 7

  1. SELinux and Firewalld disable
  2. IP 10.10.10.10
  3. Installed:
    pip install redis==2.10.5
    pip install sentry pyyaml
    sentry upgrade --noinput
    sentry createuser --email [email protected] --password '123' --superuser --no-input
    yum -y install openldap-devel openldap-clients
    pip install python-ldap django-auth-ldap sentry-ldap-auth
    sentry run worker
    sentry run web
    sentry run cron
  4. If enter command "ldapsearch -x -h 10.10.10.1 -D "[email protected]" -W -b "cn=users,dc=test,dc=comp,dc=com" -s sub "(&(objectClass=user)(objectClass=person))" cn mail" and password I see username and email. Wherein in Windows logging massage of successful/failed authorization.
  5. If I try authorization via Sentry interface I get failed auth, but in the Windows not no one messages of successful/failed authorization. No one. Such sensation, that at all does not try to unite with AD.

My sentry.conf.py:

...
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfUniqueNamesType

AUTH_LDAP_SERVER_URI = 'ldap://10.10.10.1'
AUTH_LDAP_BIND_DN = 'user'
AUTH_LDAP_BIND_PASSWORD = '1qaz@WSX'

AUTH_LDAP_USER_SEARCH = LDAPSearch(
    'cn=Users,dc=test,dc=comp,dc=com',
    ldap.SCOPE_SUBTREE,
    '(&(objectClass=user)(objectClass=person))',
)

AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
    'cn=Groups,dc=test,dc=comp,dc=com',
    ldap.SCOPE_SUBTREE,
    '(objectClass=groupOfUniqueNames)'
)

AUTH_LDAP_GROUP_TYPE = GroupOfUniqueNamesType()
AUTH_LDAP_REQUIRE_GROUP = None
AUTH_LDAP_DENY_GROUP = None

AUTH_LDAP_USER_ATTR_MAP = {
    'name': 'cn',
    'email': 'mail'
}

AUTH_LDAP_FIND_GROUP_PERMS = False
AUTH_LDAP_CACHE_GROUPS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600

AUTH_LDAP_DEFAULT_SENTRY_ORGANIZATION = u'TEST Company'
AUTH_LDAP_SENTRY_ORGANIZATION_ROLE_TYPE = 'member'
AUTH_LDAP_SENTRY_ORGANIZATION_GLOBAL_ACCESS = True

AUTHENTICATION_BACKENDS = AUTHENTICATION_BACKENDS + (
    'sentry_ldap_auth.backend.SentryLdapBackend',
)

import logging
logger = logging.getLogger('django_auth_ldap')
logger.addHandler(logging.StreamHandler())
logger.setLevel('DEBUG')

I tried change ldap.SCOPE_SUBTREE:
In the ldapsearch work (&(objectClass=user)(objectClass=person)) and (cn=*), not work (uid=%(user)s) (ldap_search_ext: Bad search filter (-7))
In the Sentry not work nothing.

Also I tried this config with diverse "dap.SCOPE_SUBTREE" and this not work too:

#########################
## LDAP Authentication ##
#########################

import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType

# Baseline configuration.
AUTH_LDAP_SERVER_URI = "ldap://10.10.10.1"

AUTH_LDAP_USER_SEARCH = LDAPSearch("cn=Users,dc=test,dc=comp,dc=com",
    ldap.SCOPE_SUBTREE, "(&(objectClass=user)(objectClass=person))")

AUTHENTICATION_BACKENDS = (
    'sentry.utils.auth.EmailAuthBackend',
    'django_auth_ldap.backend.LDAPBackend',
    'django.contrib.auth.backends.ModelBackend',
)

Main question, why Sentry does not even try connecting on AD-server?

@barronhagerman
Copy link
Contributor

@Piknik1990 Try changing the search filter to (&(objectClass=user)(objectClass=person)(cn=%(user)s).

I don't understand why you say "Sentry does not even try connecting on AD-server". You received an error Bad search filter (-7), right? Can you connect to AD with a basic LDAP client?

Also, it's been a while since I did anything with AD, but I'm not sure you can bind a user to AD using an unencrypted channel. You should be able to connect anonymously by setting AUTH_LDAP_BIND_DN = '' and AUTH_LDAP_BIND_PASSWORD = ''

@Piknik1990
Copy link
Author

Ok. I am poorly described problem.

At first
I install Windows 2008R2, create AD domain and create user in this domain.
IP: 10.10.10.1
Domain: test.comp.com

All connect to AD server (successful or unsuccessful) I see in the Event Viewer - Security log
example: https://technet.microsoft.com/en-us/library/dd277415.w2kab163_big(l=en-us).gif

Sentry server installed in Centos 7.
Now config Sentry is:

import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfUniqueNamesType

AUTH_LDAP_SERVER_URI = 'ldap://10.10.10.1'
AUTH_LDAP_BIND_DN = ''
AUTH_LDAP_BIND_PASSWORD = ''

AUTH_LDAP_USER_SEARCH = LDAPSearch(
    'cn=Users,dc=test,dc=comp,dc=com',
    ldap.SCOPE_SUBTREE,
    '(&(objectClass=user)(objectClass=person)',
)

AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
    'cn=Groups,dc=test,dc=comp,dc=com',
    ldap.SCOPE_SUBTREE,
    '(objectClass=groupOfUniqueNames)'
)

AUTH_LDAP_GROUP_TYPE = GroupOfUniqueNamesType()
AUTH_LDAP_REQUIRE_GROUP = None
AUTH_LDAP_DENY_GROUP = None

AUTH_LDAP_USER_ATTR_MAP = {
    'name': 'cn',
    'email': 'mail'
}

AUTH_LDAP_FIND_GROUP_PERMS = False
AUTH_LDAP_CACHE_GROUPS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600

AUTH_LDAP_DEFAULT_SENTRY_ORGANIZATION = u'TEST'
AUTH_LDAP_SENTRY_ORGANIZATION_ROLE_TYPE = 'member'
AUTH_LDAP_SENTRY_ORGANIZATION_GLOBAL_ACCESS = True

AUTHENTICATION_BACKENDS = AUTHENTICATION_BACKENDS + (
    'sentry_ldap_auth.backend.SentryLdapBackend',
)

import logging
logger = logging.getLogger('django_auth_ldap')
logger.addHandler(logging.StreamHandler())
logger.setLevel('DEBUG')

Besides Sentry I install openldap-clients package. He contains useful program ldapsearch

I use this program so:

# ldapsearch -x -h 10.10.10.1 -D "[email protected]" -W -b "cn=users,dc=test,dc=comp,dc=com" -s sub "(&(objectClass=user)(objectClass=person))" cn mail sn
Enter LDAP Password: 
# extended LDIF
#
# LDAPv3
# base <cn=users,dc=test,dc=comp,dc=com> with scope subtree
# filter: (&(objectClass=user)(objectClass=person))
# requesting: cn mail sn 
#
**** DATA OF AD-SERVER****
# search result
search: 2
result: 0 Success

# numResponses: 5
# numEntries: 4

Wherein in the Event Viewer Windows server writes logs about the successful entry and exit AD-user.

If I introduce incorrect password, I get follow:

# ldapsearch -x -h 10.10.10.1 -D "[email protected]" -W -b "cn=users,dc=test,dc=comp,dc=com" -s sub "(&(objectClass=user)(objectClass=person))" cn mail sn
Enter LDAP Password: 
ldap_bind: Invalid credentials (49)
	additional info: 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1

... and in Event Viewer Windows server writes about unsuccessful entry.

The (&(objectClass=user)(objectClass=person)) I found in the Google and this one of two filters, which AD processes correctly (second - (cn=*) ). To all other filters I get follow error:

# ldapsearch -x -h 10.10.10.1 -D "[email protected]" -W -b "cn=users,dc=test,dc=comp,dc=com" -s sub "(uid=%(user)s)" cn mail
Enter LDAP Password: 
# extended LDIF
#
# LDAPv3
# base <cn=users,dc=test,dc=comp,dc=com> with scope subtree
# filter: (uid=%(user)s)
# requesting: cn mail 
#

ldap_search_ext: Bad search filter (-7)

And in the Event Viewer writes the successful entry.

So I'm currently using (&(objectClass=user)(objectClass=person)) in the Sentry config.

Generally, program ldapsearch makes me understand, that the LDAP-client is working fine.

Further on Sentry:

Whatever I filter and the credentials would not write to the config, nothing falls into Event Viewer when trying to enter through Web-interface.

I introduce login "user" and password "1qaz@WSX"
I introduce login "[email protected]" and password "1qaz@WSX"
I introduce login "[email protected]" and password "123" (incorrect)
But nothing not writes in the Event Viewer. As if Sentry did not try to contact with AD. Maybe I'm misusing the data in the Web-interface?

(&(objectClass=user)(objectClass=person)(cn=%(user)s) in the ldapsearch output "ldap_search_ext: Bad search filter (-7). "
Anonymously user in Sentry config does not affect the result in any way.

I do not understand why Sentry does not try to contact the AD server at all. Even if there was an incorrect filter, then the logs Event Viewer would at least have information about the wrong request or password. But he is not. Can really the whole point is that I incorrectly enter the login in the WEB interface?

@wolfbo
Copy link

wolfbo commented Dec 19, 2017

Hello Piknik1990,
have you found a solution? I have the same Problem.

@Piknik1990
Copy link
Author

No, we moved to OpenLDAP and no solved this problem more.

@CBEPX
Copy link

CBEPX commented Apr 10, 2019

Working confing for AD
Testing on sentry 8-9.1

########
# LDAP #
########

import sys
reload(sys)
sys.setdefaultencoding('utf8')
import ldap

from django_auth_ldap.config import LDAPSearch, GroupOfUniqueNamesType

AUTH_LDAP_ALWAYS_UPDATE_USER = True
AUTH_LDAP_SERVER_URI = env('SENTRY_LDAP_SERVER_URI')
AUTH_LDAP_BIND_DN = env('SENTRY_LDAP_BIND_DN')
AUTH_LDAP_BIND_PASSWORD = env('SENTRY_LDAP_BIND_PASSWORD')
AUTH_LDAP_USER_SEARCH = LDAPSearch(u"dc=domain,dc=lan",ldap.SCOPE_SUBTREE,u"(sAMAccountName=%(user)s)"
)

AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
    u'',
    ldap.SCOPE_SUBTREE,
    u'(objectClass=groupOfUniqueNames)'
)

AUTH_LDAP_GROUP_TYPE = GroupOfUniqueNamesType()
AUTH_LDAP_REQUIRE_GROUP = None
AUTH_LDAP_DENY_GROUP = None

AUTH_LDAP_USER_ATTR_MAP = {
    "username": "sAMAccountName",
    "first_name": u"givenName",
    "last_name": u"sn",
    "email": "mail",
}

AUTH_LDAP_FIND_GROUP_PERMS = False
AUTH_LDAP_CACHE_GROUPS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600

AUTH_LDAP_DEFAULT_SENTRY_ORGANIZATION = u'Sentry'
AUTH_LDAP_SENTRY_ORGANIZATION_ROLE_TYPE = 'member'
AUTH_LDAP_SENTRY_ORGANIZATION_GLOBAL_ACCESS = True
AUTH_LDAP_SENTRY_SUBSCRIBE_BY_DEFAULT = False

SENTRY_MANAGED_USER_FIELDS = ('email', 'first_name', 'last_name', 'password', )

AUTHENTICATION_BACKENDS = AUTHENTICATION_BACKENDS + (
    'sentry_ldap_auth.backend.SentryLdapBackend',
)

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

4 participants