add sso login

This commit is contained in:
Elizabeth Hunt 2024-01-04 01:40:27 -05:00
parent e67eff6acc
commit fdd85fb735
19 changed files with 223 additions and 59 deletions

2
.env.sample Normal file
View File

@ -0,0 +1,2 @@
HEADSCALE_PREAUTH_KEY=
HEADSCALE_OIDC_SECRET=

7
README.md Normal file
View File

@ -0,0 +1,7 @@
order:
- common.yml
- deploy-nameservers.yml
- deploy-webservers.yml
- deploy-authelia.yml
- deploy-vpn.yml
- deploy-vpn-tags.yml

4
deploy-authelia.yml Normal file
View File

@ -0,0 +1,4 @@
- name: authelia setup
hosts: authelia
roles:
- authelia

23
deploy-vpn-tags.yml Normal file
View File

@ -0,0 +1,23 @@
- name: prod headscale tags
hosts: prod
tasks:
- name: add prod tags to prod servers
include_role:
name: artis3n.tailscale
vars:
tailscale_args: "--login-server='https://headscale.simponic.xyz'"
tailscale_authkey: "{{ lookup('env', 'HEADSCALE_PREAUTH_KEY') }}"
tailscale_tags:
- "prod"
- name: private headscale tags
hosts: private
tasks:
- name: add private tags to private servers
include_role:
name: artis3n.tailscale
vars:
tailscale_args: "--login-server='https://headscale.simponic.xyz'"
tailscale_authkey: "{{ lookup('env', 'HEADSCALE_PREAUTH_KEY') }}"
tailscale_tags:
- "private"

View File

@ -1,2 +1,4 @@
--- ---
headscale_users: ['simponic'] headscale_oidc_secret: "{{ lookup('env', 'HEADSCALE_OIDC_SECRET') }}"
headscale_allowed_users:
- "elizabeth.hunt@simponic.xyz"

View File

@ -25,6 +25,9 @@ nijika ansible_user=root ansible_connection=ssh
[vpn] [vpn]
nijika ansible_user=root ansible_connection=ssh nijika ansible_user=root ansible_connection=ssh
[authelia]
nijika ansible_user=root ansible_connection=ssh
[dnsinternal] [dnsinternal]
johan ansible_user=root ansible_connection=ssh johan ansible_user=root ansible_connection=ssh

View File

@ -0,0 +1,2 @@
users_database.yml
configuration.yml

View File

@ -0,0 +1,30 @@
---
- name: ensure authelia docker/compose exist
file:
path: /etc/docker/compose/authelia
state: directory
owner: root
group: root
mode: 0700
- name: copy authelia config
copy:
src: ../files/authelia
dest: /etc/docker/compose/authelia/
owner: root
group: root
mode: u=rw,g=r,o=r
- name: build authelia docker-compose.yml.j2
template:
src: ../templates/docker-compose.yml.j2
dest: /etc/docker/compose/authelia/docker-compose.yml
owner: root
group: root
mode: u=rw,g=r,o=r
- name: daemon-reload and enable authelia
ansible.builtin.systemd_service:
state: restarted
enabled: true
name: docker-compose@authelia

View File

@ -0,0 +1,17 @@
version: '3.3'
services:
authelia:
image: authelia/authelia
container_name: authelia
volumes:
- ./authelia:/config
ports:
- 9091:9091
restart: unless-stopped
redis:
image: redis:alpine
container_name: redis
volumes:
- ./redis:/data
restart: unless-stopped

View File

@ -1,5 +1,11 @@
--- ---
# set hostname
- name: Set a hostname specifying strategy
ansible.builtin.hostname:
name: "{{ inventory_hostname }}"
use: systemd
# docker # docker
- name: install dependencies - name: install dependencies
apt: apt:

View File

@ -39,7 +39,8 @@
- name: flush dns cache on replicas - name: flush dns cache on replicas
file: path={{ item }} state=absent file: path={{ item }} state=absent
with_fileglob: /var/cache/bind/db.* with_fileglob: "/var/cache/bind/db.*"
when: inventory_hostname in groups['dnsreplica']
- name: restart bind9 - name: restart bind9
service: service:

View File

@ -30,7 +30,7 @@ www.simponic.xyz. 1 IN CNAME simponic.xyz.
s1._domainkey.simponic.xyz. 1 IN CNAME s1.domainkey.u25709709.wl210.sendgrid.net. s1._domainkey.simponic.xyz. 1 IN CNAME s1.domainkey.u25709709.wl210.sendgrid.net.
s2._domainkey.simponic.xyz. 1 IN CNAME s2.domainkey.u25709709.wl210.sendgrid.net. s2._domainkey.simponic.xyz. 1 IN CNAME s2.domainkey.u25709709.wl210.sendgrid.net.
headscale.simponic.xyz. 1 IN CNAME nijika.simponic.xyz. headscale.simponic.xyz. 1 IN CNAME nijika.simponic.xyz.
authentik.simponic.xyz. 1 IN CNAME nijika.simponic.xyz. authelia.simponic.xyz. 1 IN CNAME nijika.simponic.xyz.
;; MX Records ;; MX Records
simponic.xyz. 1 IN MX 10 mail.simponic.xyz. simponic.xyz. 1 IN MX 10 mail.simponic.xyz.

View File

@ -23,6 +23,14 @@
group: root group: root
mode: u=rw,g=r,o=r mode: u=rw,g=r,o=r
- name: build headscale config template
template:
src: ../templates/config.yml.j2
dest: /etc/docker/compose/headscale/config.yml
owner: root
group: root
mode: u=rw,g=r,o=r
- name: ensure headscale data volume exist - name: ensure headscale data volume exist
file: file:
path: /etc/docker/compose/headscale/data path: /etc/docker/compose/headscale/data
@ -31,12 +39,6 @@
group: root group: root
mode: 0700 mode: 0700
- name: ensure headscale users
shell: |
docker exec headscale headscale user create "{{ item }}"
with_items:
- "{{ headscale_users }}"
- name: daemon-reload and enable headscale - name: daemon-reload and enable headscale
ansible.builtin.systemd_service: ansible.builtin.systemd_service:
state: restarted state: restarted

View File

@ -234,52 +234,44 @@ unix_socket_permission: "0770"
# it is still being tested and might have some bugs, please # it is still being tested and might have some bugs, please
# help us test it. # help us test it.
# OpenID Connect # OpenID Connect
# oidc: oidc:
# only_start_if_oidc_is_available: true # Block further startup until the OIDC provider is healthy and available
# issuer: "https://your-oidc.issuer.com/path" only_start_if_oidc_is_available: true
# client_id: "your-oidc-client-id" # Specified by your OIDC provider
# client_secret: "your-oidc-client-secret" issuer: "https://authelia.simponic.xyz"
# # Alternatively, set `client_secret_path` to read the secret from the file. # Specified/generated by your OIDC provider
# # It resolves environment variables, making integration to systemd's client_id: "simponicheadscale"
# # `LoadCredential` straightforward: client_secret: "{{ headscale_oidc_secret }}"
# client_secret_path: "${CREDENTIALS_DIRECTORY}/oidc_client_secret" # alternatively, set `client_secret_path` to read the secret from the file.
# # client_secret and client_secret_path are mutually exclusive. # It resolves environment variables, making integration to systemd's
# # `LoadCredential` straightforward:
# # The amount of time from a node is authenticated with OpenID until it #client_secret_path: "${CREDENTIALS_DIRECTORY}/oidc_client_secret"
# # expires and needs to reauthenticate.
# # Setting the value to "0" will mean no expiry. # Customize the scopes used in the OIDC flow, defaults to "openid", "profile" and "email" and add custom query
# expiry: 180d # parameters to the Authorize Endpoint request. Scopes default to "openid", "profile" and "email".
# scope: ["openid", "profile", "email"]
# # Use the expiry from the token received from OpenID when the user logged # Optional: Passed on to the browser login request used to tweak behaviour for the OIDC provider
# # in, this will typically lead to frequent need to reauthenticate and should extra_params:
# # only been enabled if you know what you are doing. domain_hint: simponic.xyz
# # Note: enabling this will cause `oidc.expiry` to be ignored.
# use_expiry_from_token: false # Optional: List allowed principal domains and/or users. If an authenticated user's domain is not in this list,
# # the authentication request will be rejected.
# # Customize the scopes used in the OIDC flow, defaults to "openid", "profile" and "email" and add custom query allowed_domains:
# # parameters to the Authorize Endpoint request. Scopes default to "openid", "profile" and "email". - simponic.xyz
# # Optional. Note that groups from Keycloak have a leading '/'.
# scope: ["openid", "profile", "email", "custom"] # allowed_groups:
# extra_params: # - /admins
# domain_hint: example.com # - admins
# # - people
# # List allowed principal domains and/or users. If an authenticated user's domain is not in this list, the # Optional.
# # authentication request will be rejected. allowed_users:
# - "{{ headscale_allowed_users }}"
# allowed_domains:
# - example.com # If `strip_email_domain` is set to `true`, the domain part of the username email address will be removed.
# # Note: Groups from keycloak have a leading '/' # This will transform `first-name.last-name@example.com` to the user `first-name.last-name`
# allowed_groups: # If `strip_email_domain` is set to `false` the domain part will NOT be removed resulting to the following
# - /headscale # user: `first-name.last-name.example.com`
# allowed_users: strip_email_domain: true
# - alice@example.com
#
# # If `strip_email_domain` is set to `true`, the domain part of the username email address will be removed.
# # This will transform `first-name.last-name@example.com` to the user `first-name.last-name`
# # If `strip_email_domain` is set to `false` the domain part will NOT be removed resulting to the following
# user: `first-name.last-name.example.com`
#
# strip_email_domain: true
# Logtail configuration # Logtail configuration
# Logtail is Tailscales logging and auditing infrastructure, it allows the control panel # Logtail is Tailscales logging and auditing infrastructure, it allows the control panel

View File

@ -1,6 +1,8 @@
user www-data; user www-data;
worker_processes 4; worker_processes 4;
pid /run/nginx.pid; pid /run/nginx.pid;
load_module modules/ndk_http_module.so;
load_module modules/ngx_http_set_misc_module.so;
events { events {
worker_connections 768; worker_connections 768;

View File

@ -0,0 +1,13 @@
server {
listen 80;
server_name authelia.simponic.xyz;
location /.well-known/acme-challenge {
root /var/www/letsencrypt;
try_files $uri $uri/ =404;
}
location / {
rewrite ^ https://authelia.simponic.xyz$request_uri? permanent;
}
}

View File

@ -1,7 +1,5 @@
server_tokens off;
server { server {
listen 80 default_server; listen 80;
server_name headscale.simponic.xyz; server_name headscale.simponic.xyz;
location /.well-known/acme-challenge { location /.well-known/acme-challenge {

View File

@ -0,0 +1,57 @@
server {
listen 443 ssl;
server_name authelia.simponic.xyz;
ssl_certificate /etc/letsencrypt/live/authelia.simponic.xyz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/authelia.simponic.xyz/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/authelia.simponic.xyz/fullchain.pem;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 5m;
ssl_stapling on;
ssl_stapling_verify on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_dhparam /etc/nginx/dhparams.pem;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://127.0.0.1:9091;
client_body_buffer_size 128k;
#Timeout if the real server is dead
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
# Advanced Proxy Config
send_timeout 5m;
proxy_read_timeout 360;
proxy_send_timeout 360;
proxy_connect_timeout 360;
# Basic Proxy Config
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-Ssl on;
proxy_redirect http:// $scheme://;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
proxy_buffers 64 256k;
# If behind reverse proxy, forwards the correct IP
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.0.0.0/8;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from fc00::/7;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
}
}

View File

@ -17,6 +17,9 @@
- name: install nginx - name: install nginx
apt: name=nginx state=latest apt: name=nginx state=latest
- name: install libnginx-mod-http-set-misc
apt: name=libnginx-mod-http-set-misc state=latest
- name: install letsencrypt - name: install letsencrypt
apt: name=letsencrypt state=latest apt: name=letsencrypt state=latest