Monogramm / taiga-contrib-ldap-auth-ext

:snake: :alembic: Extended Taiga plugin for LDAP authentication
http://taiga.io
GNU Affero General Public License v3.0
45 stars 15 forks source link

Add a step-by-step installation guide for Taiga6 recommended docker installation #43

Closed nuokh closed 2 years ago

nuokh commented 3 years ago

I am pretty sure most of us on premise folks have tons of experience with virtualization solutions like VMWare but are total docker noobs.

I am struggling to install this plugin to Taiga6 recommended docker deployment. I know that I am struggling through a lot of problems that are basically solved with basic docker knowledge and installing the community plugin in your docker installation is probably easy for a dev with a lot of Docker experience but for us old and gnarly sysadmins it's just super confusing and we have to make sure every deployment checks certain boxes like “can we test backups, updates, restores” and “can we plug it into our LDAP to manage our 300 users that constantly forget passwords”.

Thanks for the great work overall!

nuokh commented 3 years ago

Okay here is my take on it using an online ldap test server as an example. I guess there is still some mistake in this approach because I won't get it to work, but maybe it helps as a starting point:

Install and run a fresh Taiga6 docker installation according to this guide. Then go into the backend container:

sudo docker exec -it taiga-docker_taiga-back_1 /bin/bash

Get an editor: apt update apt install vim

Edit the common.py config file:

vim settings/common.py

Paste the following configuration between the "#TELEMETRY" and "# NOTE: DON'T INSERT ANYTHING AFTER THIS BLOCK"-block:

INSTALLED_APPS += ["taiga_contrib_ldap_auth_ext"]

# TODO https://github.com/Monogramm/taiga-contrib-ldap-auth-ext/issues/16
LDAP_SERVER = 'ldap://ldap.forumsys.com'
LDAP_PORT = 389

# Flag to enable LDAP with STARTTLS before bind
LDAP_START_TLS = False

# Support of alternative LDAP ciphersuites
#from ldap3 import Tls
#import ssl

#LDAP_TLS_CERTS = Tls(validate=ssl.CERT_NONE, version=ssl.PROTOCOL_TLSv1, ciphers='RSA+3DES')

# Full DN of the service account use to connect to LDAP server and search for login user's account entry
# If LDAP_BIND_DN is not specified, or is blank, then an anonymous bind is attempated
LDAP_BIND_DN = 'cn=read-only-admin,dc=example,dc=com'
LDAP_BIND_PASSWORD = 'password'

# Starting point within LDAP structure to search for login user
LDAP_SEARCH_BASE = 'ou=mathematicians,dc=example,dc=com'

# Additional search criteria to the filter (will be ANDed)
#LDAP_SEARCH_FILTER_ADDITIONAL = '(mail=*)'

# Names of attributes to get username, e-mail and full name values from
# These fields need to have a value in LDAP 
LDAP_USERNAME_ATTRIBUTE = 'uid'
LDAP_EMAIL_ATTRIBUTE = 'mail'
LDAP_FULL_NAME_ATTRIBUTE = 'displayName'

# Option to not store the passwords in the local db
#LDAP_SAVE_LOGIN_PASSWORD = False

# TODO https://github.com/Monogramm/taiga-contrib-ldap-auth-ext/issues/15
# Group search filter where $1 is the project slug and $2 is the role slug
#LDAP_GROUP_SEARCH_FILTER = 'CN=$2,OU=$1,OU=Groups,DC=example,DC=net'

# TODO https://github.com/Monogramm/taiga-contrib-ldap-auth-ext/issues/15
# Use an attribute in the user entry for membership
#LDAP_USER_MEMBER_ATTRIBUTE = 'memberof,primaryGroupID'

# TODO https://github.com/Monogramm/taiga-contrib-ldap-auth-ext/issues/15
# Starting point within LDAP structure to search for login group
#LDAP_GROUP_SEARCH_BASE = 'OU=Groups,DC=example,DC=net'
# Group classes filter
#LDAP_GROUP_FILTER = '(|(objectclass=group)(objectclass=groupofnames)(objectclass=groupofuniquenames))'
# Group member attribute
#LDAP_GROUP_MEMBER_ATTRIBUTE = 'memberof,primaryGroupID'

# TODO https://github.com/Monogramm/taiga-contrib-ldap-auth-ext/issues/17
# Taiga super users group id
#LDAP_GROUP_ADMIN = 'OU=TaigaAdmin,DC=example,DC=net'

# Fallback on normal authentication method if LDAP auth fails. Uncomment to disable and only allow LDAP login.
#LDAP_FALLBACK = ""

# Function to map LDAP username to local DB user unique identifier.
# Upon successful LDAP bind, will override returned username attribute
# value. May result in unexpected failures if changed after the database
# has been populated.
# 
def _ldap_slugify(uid: str) -> str:
    # example: force lower-case
    #uid = uid.lower()
    return uid

# To enable the function above, uncomment the line below to store the function in the variable
#LDAP_MAP_USERNAME_TO_UID = _ldap_slugify

# Similarly, you can apply filters to the email and name by defining functions and specifying them here in the same way
#LDAP_MAP_EMAIL = _ldap_map_email
#LDAP_MAP_NAME = _ldap_map_name

Save and quit common.py.

Install the plugin:

source /opt/venv/bin/activate (venv) pip install taiga-contrib-ldap-auth-ext

Leave the Python venv by typing: deactivate

Exit the taiga-back container: exit

Enter the taiga-front container: sudo docker exec -it taiga-docker_taiga-front_1 /bin/bash

Open conf.json:

vi usr/share/nginx/html/conf.json

Add

"loginFormType": "ldap" and a , to the end of the line above.

The final conf.json should look like this

{
    "api": "http://yourhost.com:9000/api/v1/",
    "eventsUrl": "ws://yourhost.com:9000/events",
    "eventsMaxMissedHeartbeats": 5,
    "eventsHeartbeatIntervalTime": 60000,
    "eventsReconnectTryInterval": 10000,
    "debug": false,
    "debugInfo": false,
    "defaultLanguage": "en",
    "themes": ["taiga"],
    "defaultTheme": "taiga",
    "defaultLoginEnabled": true,
    "publicRegisterEnabled": false,
    "feedbackEnabled": true,
    "supportUrl": "https://resources.taiga.io",
    "privacyPolicyUrl": null,
    "termsOfServiceUrl": null,
    "maxUploadFileSize": null,
    "contribPlugins": [],
    "gitHubClientId": "",
    "gitLabClientId": "",
    "gitLabUrl": "",
    "tagManager": { "accountId": null },
    "tribeHost": null,
    "enableAsanaImporter": false,
    "enableGithubImporter": false,
    "enableJiraImporter": false,
    "enableTrelloImporter": false,
    "gravatar": false,
    "rtlLanguages": ["fa"],
    "loginFormType": "ldap"
}

Save and quit. Exit the taiga-front container.

exit

Restart the containers to apply the changes:

docker-compose restart

Now, ldap login using the username "euler" and password "password" should work. Sadly, it doesn't and I am a little bit lost on why. Hope this helps creating a step by step guide.

DraakBZH commented 3 years ago

I just followed what you wrote and everything is working fine for me (except for my LDAP authentication, I am using an anonymous login)

ZheniaSteger commented 3 years ago

nuokh I did everything you did with the settings.py and conf.py but additionally I extended the image with this Dockerfile

FROM taigaio/taiga-back:latest

RUN pip install taiga-contrib-ldap-auth-ext

Then built it with docker build . -t taigaio/taiga-back:withldap

Then in taigas docker-compose.yml and docker-compose-inits.yml I replaced image: taigaio/taiga-back:withldap

I have also added some print statements to the connector.py in that ldap auth plugin to see what's going on. It does appear to be using the ldap plugin however the error I am getting is this: Error connecting to LDAP server: automatic start_tls befored bind not successful

I think my particular issue might be with TLS and trying to use ldaps. Anyway hope that helps. Ill try to update here if I get it working.

karezza commented 3 years ago

Use Case: set this up in a windows ad environment, not permitting an ad account to log in yet - using config as shown above with dc specified, the settings work via an AWX setup I have and can use the account to search for a user via an ldapsearch command so I know the account works. The setup here is essentially identical to what I'm using over in AWX, so not sure why it isn't working here. continuing to work on this

Once I get this working will probably switch to a customized docker image and use a pipeline to spin up a taiga server with this module ready to go. Just need to get it working initially ...

Notes:

Updates:

karezza commented 3 years ago

So... has anyone got it to work with taiga6 & the docker install? I'm out of troubleshooting ideas. I can watch via Wireshark with TLS turned off and I can see the initial lookup to find the user was successful, and the later bindRequest & bindReponse was also successful. Seems ldap is working to lookup the user and log them in but taiga isn't getting the message that everything worked.

I'm seeing the 'success' as mentioned in this article How to Troubleshoot an LDAP Connection with Wireshark.

I could have swore I saw a note that this worked with taiga6. But, upon second check of this repository and the taiga resources page it doesn't actually say 6 anywhere.

I'm not seeing any error messages when using: docker logs -f taiga-docker_taiga-back_1

Any next steps with troubleshooting anyone might have? Anyone got this to work with an on prem Windows AD?

karezza commented 3 years ago
taiga-db_1               | 2021-06-24 22:50:47.503 UTC [51] ERROR:  duplicate key value violates unique constraint "users_user_email_243f6e77_uniq"
taiga-db_1               | 2021-06-24 22:50:47.503 UTC [51] DETAIL:  Key (email)=(karezza@domain) already exists.
taiga-db_1               | 2021-06-24 22:50:47.503 UTC [51] STATEMENT:  INSERT INTO "users_user" ("password", "last_login", "is_superuser", "uuid", "username", "email", "is_active", "is_staff", "full_name", "color", "bio", "photo", "date_joined", "accepted_terms", "read_new_terms", "lang", "theme", "timezone", "colorize_tags", "token", "email_token", "new_email", "verified_email", "is_system", "max_private_projects", "max_public_projects", "max_memberships_private_projects", "max_memberships_public_projects") VALUES ('', NULL, false, 'asdfasdfasdfasdfasdfasdfasdfasdf', 'karezza', 'karezza@domain', true, false, 'fname lname', '#4f0dda', '', '', '2021-06-24T22:50:47.501808+00:00'::timestamptz, true, false, '', '', '', false, NULL, NULL, NULL, true, false, NULL, NULL, NULL, NULL) RETURNING "users_user"."id"
taiga-gateway_1          | 172.25.0.1 - - [24/Jun/2021:22:50:47 +0000] "POST /api/v1/auth HTTP/1.1" 500 141 "http://localhost:9000/login?next=%252Fdiscover" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" "-"
karezza commented 3 years ago

Note, I've got keycloak installed and working, using it to sync w/ ldap. There is a plugin for taiga which says it will work with taiga6 & keycloak. Maybe could work as an alternative for someone while effort continues to get this one to work.

evandroteixeira1710 commented 3 years ago

What would be the best way to map the change made after ldap? Because if the server happens to restart, it loses all ldap configuration and simply some services do not start again.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.