Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
selfhost:sso [2024/08/27 13:03] – willy | selfhost:sso [2025/03/13 09:29] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Authentication ===== | + | ====== G) SSO Authentication |
- | Having a strong layer of authentication is mandatory for self-hosted services that are exposed to the internet. | + | Having a strong layer of authentication is mandatory for self-hosted services that are exposed to the internet. |
- | + | ||
- | A few assumptions: | + | |
+ | I also assume that the focus is **home services access**, which means a very limiter number of users (spouse, kids, maybe grandparents, | ||
+ | |||
There are a few key points that i want to stress on authentication: | There are a few key points that i want to stress on authentication: | ||
- | * 2FA (Two Factor Authentication) will not be considered | ||
- | * You want to create users only once, as much as possible. | ||
- | * Only selected services will need to differentiate between users | ||
- | * Most services will not need to know who is accessing them | ||
* From outside, **all** services must require authentication | * From outside, **all** services must require authentication | ||
* From inside, authentication is required only where a specific user makes a difference | * From inside, authentication is required only where a specific user makes a difference | ||
- | * Avoid double authentication | + | |
+ | | ||
+ | * 2FA (Two Factor Authentication) will not be considered (left as an exercise to the reader) | ||
+ | * SSO should be enabled everywhere, but in reality most of services do not support any kind of SSO, so... YMMV. | ||
For example, a //media server// will need to know who is connecting to show your preferred shows and your " | For example, a //media server// will need to know who is connecting to show your preferred shows and your " | ||
- | Authentication will be required when connecting from // | ||
- | The most simple and effective approach is to enable the PAM Authentication plugin of NGINX and connect your reverse-proxy authentication to your server user management. So that by adding a new user to your server, that will be automagically added to your services, or at least the ones that can link to reverse-proxy authentication. | + | ===== The concept behind SSO ===== |
- | You have the following combinations: | + | The idea is that you have a dedicated service |
- | * Services | + | |
- | * Services that needs to know who is connecting, and **can** get this info from the reverse-proxy | + | |
- | * Services that needs to know who is connecting, | + | |
- | You will be able to play with the PAM authentication | + | The key point is that the SSO happens __before__ the user even reach the service, thus providing an additional layer of security |
- | The general rule is as follow: | + | The second key point should be that you add users to a single database, instead of creating the same user for different services each time. |
- | ^ Service | + | |
- | | do not require authentication | + | |
- | | Require auth, can use reverse-proxy auth | use PAM auth | use PAM auth | | + | |
- | | Require auth, cannot use reverse-proxy auth | use service auth | use service auth | | + | |
- | Using PAM Auth on services | + | Unfortunately, |
- | Please note that for services that cannot use reverse-proxy auth you will need to create users. | + | ==== Different SSO solutions ==== |
- | There is a more complex solution | + | The most simple SSO possible |
+ | A more advanced SSO approach is to use a dedicated gateway like [[https:// | ||
- | ===== NGINX pam_auth ===== | + | As a side note, a few words on server login capability. Should the user be allowed also access to the server via SSH / console? An answer to this question is not so simple because of the use of services like NFS or Samba, and wether some users might need to login phisically on the server. I leave these considerations to your use case. |
- | I think it's nice that with NGINX you can authenticate your users directly with your home server users. This means you don't need to add a second set of users, and that the users will only need one password, and no sync is required between HTTP users and server | + | So, the NGINX PAM Auth approach: |
+ | * Requires the users to be able to also login via SSH / local console on the server | ||
+ | * Shows a somewhat ugly (and non-customizable) login popup on the browser | ||
+ | | ||
+ | | ||
+ | | ||
+ | * Easier | ||
- | Create | + | Instead, |
- | <file - nginx> | + | |
- | auth required pam_unix.so | + | |
- | account | + | |
- | </ | + | |
+ | * More flexible, can support OAuth and such | ||
+ | * Easier to integrate with some services (there will still be services that cannot use it) | ||
+ | * Can simoultaneously use also __basic authentication__, | ||
+ | Overall, it's a mess. At least you can fully replace NGINX auth with Authelia, leveraging the support for basic auth where needed, but still lots of services have an hard time integrating with an SSO or any kind. While i am slowing trying to migrate everything to Authelia, it's a long game that often requires tickets on GitHub for each service and lots of patience. | ||
+ | This also means that it is impossible to really have only **one** login for everything. You will have to create the user on the server, then add it to Authelia, then add it to any specific services that cannot use either. Sorry, that's life at this point. | ||
- | server { | + | ==== SSO approach matrix ==== |
- | server_name 10.0.0.1 mydomain.com; | + | |
- | listen 8443 ssl; | + | |
- | access_log / | + | |
- | error_log / | + | |
- | root / | + | |
- | auth_pam " | + | |
- | auth_pam_service_name " | + | |
- | include " | + | |
- | include com.mydomain/ | + | |
- | } | + | |
+ | You have the following combinations: | ||
+ | * Services that do not require to differentiate the user | ||
+ | * Services that needs to know who is connecting, and **can** get this info from the SSO | ||
+ | * Services that needs to know who is connecting, and **cannot** get this info from the SSO | ||
+ | The general rule is as follow: | ||
+ | ^ Service | ||
+ | | do not require authentication | ||
+ | | Require auth, can use reverse-proxy auth | use SSO auth | use SSO auth | | ||
+ | | Require auth, cannot use reverse-proxy auth | use service auth | use service auth | | ||
- | https://www.authelia.com/ | + | Using SSO on services that cannot understand SSO auth is, in theory, a great way to increase security as others will not even be able to reach your service, but will require the users to perform the authentication twice and will cause some mobile apps to fail, so i do not recommend it. |
- | https:// | ||
- | useradd -m authelia | + | ===== Authelia SSO ===== |
- | su - authelia | + | First of all, follow [[services:authelia|this page]] to install the service itself. |
+ | In order to use WebDAV, CardDAV or CalDAV, you will need to enable also basic auth on Authelia, at least for specific subdomains and locations. | ||
- | wget https:// | + | Authelia works by using the auth_request module of NGINX. The reverse proxy will first send any request to Authelia which will validate the user login. If login is successful, NGINX will then redirect the user to the correct destination page. This process is transparent once the user is logged and very fast. |
- | mkdir bin | + | The entire process is described [[https://www.authelia.com/ |
- | cd bin | + | |
- | tar xvf ../authelia-v4.38.10-linux-amd64.tar.gz | + | |
- | cd .. | + | |
- | creare file configuration.yml (vedi esempio) | + | In order to use Authelia you need to include a few different snippets of NGINX configuration |
+ | * the **authelia_location** and **authelia_location-basic** | ||
+ | * the **authelia_authrequest** and **authelia_authrequest-basic** | ||
+ | * the **authelia_proxy** | ||
- | mkdir config db logs | + | The **authelia_location** will create, in your domain, a specific entry point (/ |
- | lancia authelia | + | The **authelia_authrequest** injects in your location the redirection to the above defined entry point, and this enables the Authelia authentication for the specific location. This can be added aither to a specific location, or can be addedd at server level to have it enabled for __all__ locations within the domain. |
+ | The last snippet, **authelia_proxy**, | ||
- | NGINX auth_request | + | ==== Example configuration ==== |
- | www-servers/nginx NGINX_MODULES_HTTP: | + | This is my **home.mydomain.com** NGINX configuration file with Authelia configured: |
+ | < | ||
+ | server { | ||
+ | server_name home.mydomain.com; | ||
+ | # This listen only when accessed from outside the home network | ||
+ | listen 8443 ssl; | ||
+ | http2 on; | ||
+ | # Authelia auth entry point | ||
+ | include " | ||
+ | # Enable Authelia login for the entire subdomain | ||
+ | include " | ||
+ | include " | ||
+ | # Include all the services under the subdomain | ||
+ | include " | ||
+ | } | ||
+ | </ | ||
- | crea file org.gardiol/ | ||
- | crea file org.gardiol/ | ||
- | crea org.gardiol/ | ||
- | crea org.gardiol/ | ||
- | configura ogni subdomain auth | + | ===== NGINX PAM SSO ===== |
+ | This is achieved by using the **pam_auth** module on Linux. You have already built nginx with pam_auth support, but you need to configure it. | ||
- | Creazione passwords: | + | First of all configure PAM, create the file **/ |
- | ./authelia-linux-amd64 crypto hash generate --help | + | <file - nginx> |
+ | auth required pam_unix.so | ||
+ | account required pam_unix.so | ||
+ | </file> | ||
+ | Now add the following lines to any service you want behind PAM authentication in NGINX: | ||
+ | < | ||
+ | auth_pam " | ||
+ | auth_pam_service_name " | ||
+ | </ | ||
+ | You can add them to the **location** section, but also directly in the **server** section. In this case, you can disable PAM auth for specific location with: | ||
+ | < | ||
+ | auth_pam off; | ||
+ | </ | ||
- | <file - authelia> | + | So for example: |
- | #!/sbin/openrc-run | + | <code> |
- | # Copyright 1999-2021 Gentoo Authors | + | server { |
- | # Distributed under the terms of the GNU General Public License v2 | + | server_name 10.0.0.1 mydomain.com; |
+ | listen 8443 ssl; | ||
+ | access_log | ||
+ | | ||
+ | root / | ||
+ | auth_pam " | ||
+ | auth_pam_service_name " | ||
+ | include " | ||
+ | include com.mydomain/ | ||
+ | } | ||
+ | </ | ||
- | description=" | + | Restart your NGINX and you are done! |
- | pidfile="/ | + | |
- | command_background=true | + | |
- | command="/ | + | |
- | command_args=" | + | |
- | command_user=" | + | |
- | depend() { | ||
- | need net | ||
- | } | ||
- | </ | ||
+ | |||
+ | ===== Specific services configuration ===== | ||
+ | |||
+ | See each service page, i wll write there any service specific details. |