Appearance
Frequently Asked Questions
How do I [Insert Question Here]?
Quick Q&A for common problems/questions about the DP-SALA/D Stack
How do I add a new application to my stack?
You have two options:
You can check SWAG's proxy confs folder for the application you are trying to add in it's configuration folder.
- You will use the following command:
mv /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf.sample /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf - Install the application into your docker network (keep track of the internal port that it uses)
- Then nano into the .conf
nano /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf
- If you are using a subdomain configuration:
- You can change the server_name directive to the path you want to use as a subdomain (make sure you leave the .*)
- The $upstream_app should match the docker container name
- The $upstream_port should match the docker internal port
- Everything else can be left unchanged
- If you are using a subfolder configuration:
- The $location directive can be changed after the / to the path you want to use as a subfolder (make sure to leave the ^~)
- The $upstream_app should match the docker container name
- The $upstream_port should match the docker internal port
- You will use the following command:
TIP
If you have the auto-reload docker mod, SWAG will automatically reload the changes, and display them. Otherwise, SWAG will have to be manually reloaded to see the changes.
- If there isn't a premade template, you can DIY your own using the
_template.sub[domain/folder].conf.sample.
You will use the following command:
cp /home/[USER]/appdata/swag/nginx/proxy-confs/_template.sub[domain/folder].conf.sample /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].confInstall the application into your docker network (keep track of the internal port that it uses)
Then nano into the .conf
nano /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf- If you are using a subdomain template:
- You'll want to modify anything with <> make sure to remove the <> when you are done.
- If you are using a subfolder template:
- You'll want to modify anything with <> make sure to remove the <> when you are done.
- If you are using a subdomain template:
Which ever way you decide to do, once you have made the changes, save and exit.
THIS IS IMPORTANT!!!
You'll want to verify that the $upstream_app, $port and $protocal are correct, otherwise you will keep getting 502 errors when trying to visit them. The web path/container_name doesn't really matter, you can name it whatever.
TIP
Most of the time, the template will work out-of-the-box with all of the changes. However, you may run into an application that requrires more configuration to run behind a reverse proxy. You will have to consult the application's documentation to find settings that will let it run behind a reverse proxy. SWAG uses NGINX as it's base, so most NGINX configurations can be used to have it run behind a reverse proxy.
WARNING
If you decide to proxy something externally to docker, this comes with the caveat that the $upstream_app must be an IP address (preferably static), and the $upstream_port must be an external port that the application is listening on. Failing to do so, will result in a 502 Bad Gateway error.
How do I add LLDAP Authentication to [SERVICE]?
First, check to see if LDAP authentication is supported by the application that you are trying to add. Some services/applications either don't support LDAP auth out of the box, or there is some plugin/addon to add for LDAP auth to function. Do a quick Google search to see if LDAP auth is supported, and if it requires a secure connection. Canvas in particular requires LDAPS (LDAP over SSL) and will not function unless configured correctly.
Second, if the app supports LDAP Auth, it usually requires a dedicated user to manage the application, usually called a "Bind User" which you will setup in LLDAP. Try to pick a username that will be descriptive for the service it will bind to. The password that is used should be lengthy and mixtures of characters. The next required parts are the "configuration" parts, which are detailed below:
- User DN/Bind User/User: "cn=[USER],ou=people,dc=[DOMAIN],dc=[TLD]"
- Base/User Search Base: "ou=people,dc=[DOMAIN],dc=[TLD]"
- User Filter(no grouping, UID access): (&(uid={username})(objectClass=person)(ou=people,dc=[DOMAIN],dc=[TLD]))
- User Filter(group access, UID or Email access): (&(objectClass=person)(memberof=cn=[GROUP NAME],ou=groups,dc=[DOMAIN],dc=[TLD])(|(uid={username})(mail={username})))
- User Filter(group access, UID access): (&(objectClass=person)(memberof=cn=[GROUP NAME],ou=groups,dc=[DOMAIN],dc=[TLD]))
- Admin Filter(group access): (memberof=cn=[GROUP NAME]_administrator,ou=groups,dc=[DOMAIN],dc=[TLD])
These are some typical settings, however, depending on the service or app, there may be an example configuration out there, for example, Authelia for LLDAP has an example config: https://github.com/lldap/lldap/blob/main/example_configs/authelia_config.yml
yml
###############################################################
# Authelia configuration #
###############################################################
# This is just the LDAP part of the Authelia configuration!
authentication_backend:
# Password reset through authelia works normally.
password_reset:
disable: false
# How often authelia should check if there is an user update in LDAP
refresh_interval: 1m
ldap:
implementation: custom
# Pattern is ldap://HOSTNAME-OR-IP:PORT
# Normal ldap port is 389, standard in LLDAP is 3890
url: ldap://lldap:3890
# The dial timeout for LDAP.
timeout: 5s
# Use StartTLS with the LDAP connection, TLS not supported right now
start_tls: false
#tls:
# skip_verify: false
# minimum_version: TLS1.2
# Set base dn, like dc=google,dc.com
base_dn: dc=example,dc=com
username_attribute: uid
# You need to set this to ou=people, because all users are stored in this ou!
additional_users_dn: ou=people
# To allow sign in both with username and email, one can use a filter like
# (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))
users_filter: "(&({username_attribute}={input})(objectClass=person))"
# Set this to ou=groups, because all groups are stored in this ou
additional_groups_dn: ou=groups
# The groups are not displayed in the UI, but this filter works.
groups_filter: "(member={dn})"
# The attribute holding the name of the group.
group_name_attribute: cn
# Email attribute
mail_attribute: mail
# The attribute holding the display name of the user. This will be used to greet an authenticated user.
display_name_attribute: displayName
# The username and password of the bind user.
# "bind_user" should be the username you created for authentication with the "lldap_strict_readonly" permission. It is not recommended to use an actual admin account here.
# If you are configuring Authelia to change user passwords, then the account used here needs the "lldap_password_manager" permission instead.
user: uid=bind_user,ou=people,dc=example,dc=com
# Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
password: 'REPLACE_ME'Here is a list of the attributes that you can use: uid (username), mail (email address), cn (this could be a username, or a full name be careful), and displayName (usually the full name of the user).
Not all of these are good for use cases, however, the most commonly used ones are going to be uid and email.
If this didn't cover what was needed for adding LDAP auth connectivity to your service, consult Google, or the LLDAP GitHub Example Configs, linked here: https://github.com/lldap/lldap/tree/main/example_configs which should give you a good starting point to see how to configure the LDAP authentication for your service.
Here is my recommendation to how user management works:
- Setup dedicated groups that match the application/service name, add all users who use that to the group.
- Filter the user based on the group, if they are in that group, they have permission to access the application.
How do I handle user creation?
Once the stack is all setup, you may want to add users . I outline my way of handling user creation and management, but you may do this anyway you like, I've done it this way given the constraints of how I host, and handle having users access some or all of my services that I host.
User Creation:
- Ask for the user's email address, full name, and if they would like something different for their display name.
- Using their full name, I create a username. Say if the user was named: Alice Example, their username would be aexa. If I already had a duplicate of the username, I'd append a number, starting at 0.
- I would create a temporary password for the user, and then have them go to auth.domain.tld to then "Forgot Password" so that they can setup a password themselves, and have it conform to my password standards I have set.
- I then go to the user page, and add them to their respective groups to let them have access to the services.
- I'd let the user know that some apps will take a bit to pull their information, while some create their profile on sign in. This is completely normal, and give it up to 24 hours for changes to fully propagate through the system.
This is one way of doing it, but I do have a standard, which I hold to the highest degree. This is important, as it does make finding the user just a little easier when trying to figure out what goes wrong.