From 02a20979550c6fc4b119f4bed6e2a77a031fac62 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Fri, 5 Jul 2024 22:52:10 +1000 Subject: [PATCH 1/6] feat: paramatise use_default_location - allow the use of location blocks for simpleproxy - add way to add locations in simpleproxy --- site/profiles/manifests/nginx/simpleproxy.pp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/site/profiles/manifests/nginx/simpleproxy.pp b/site/profiles/manifests/nginx/simpleproxy.pp index 28d6c1e..7a497ae 100644 --- a/site/profiles/manifests/nginx/simpleproxy.pp +++ b/site/profiles/manifests/nginx/simpleproxy.pp @@ -12,6 +12,8 @@ class profiles::nginx::simpleproxy ( Stdlib::Port $proxy_port = 80, Stdlib::Host $proxy_host = $facts['networking']['ip'], String $proxy_path = '/', + Boolean $use_default_location = true, + Hash $locations = {}, ) { # if nginx_version isnt set, install nginx @@ -83,7 +85,7 @@ class profiles::nginx::simpleproxy ( $defaults = { 'listen_port' => $listen_port, 'server_name' => $server_names, - 'use_default_location' => true, + 'use_default_location' => $use_default_location, 'access_log' => "/var/log/nginx/${nginx_vhost}_access.log", 'error_log' => "/var/log/nginx/${nginx_vhost}_error.log", 'autoindex' => 'on', @@ -103,6 +105,11 @@ class profiles::nginx::simpleproxy ( # create the nginx vhost with the merged parameters create_resources('nginx::resource::server', { $nginx_vhost => $nginx_parameters }) + # create nginx locations + if $use_default_location == false { + create_resources('nginx::resource::location', $locations) + } + # manage selinux if $::facts['os']['selinux']['config_mode'] == 'enforcing' { -- 2.47.3 From cbded220bb0d5a1f8f4adf959716fc3846694c20 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Fri, 5 Jul 2024 23:15:06 +1000 Subject: [PATCH 2/6] feat: add sonarr locations - add authproxy - add api and web - add /consul/health for unauth access from consul - update sonarr/consul check to use /consul/health - change client body side to 20mb --- hieradata/roles/apps/media/sonarr.eyaml | 1 + hieradata/roles/apps/media/sonarr.yaml | 84 ++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/hieradata/roles/apps/media/sonarr.eyaml b/hieradata/roles/apps/media/sonarr.eyaml index 18be20a..79f024e 100644 --- a/hieradata/roles/apps/media/sonarr.eyaml +++ b/hieradata/roles/apps/media/sonarr.eyaml @@ -1 +1,2 @@ sonarr::api_key: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEANhwc0Vk0htkacwqGA/ZEVR7hpC1V2+nyP3lxyqkVNWERdcIsoMjlfwp2QNoLVirALY10Kon1wKXiRLT+QOqF9aTapS2Vb2YH3ZujR5yT6T1z4e0o4EA3IlNJZemVIziIqrK8+8zZzVafYdOYwMwpbc5EzoJPBtdqNHbDaQu4bRTCp2yMISTOzFjZpOoEJlRyC8YrffNU2xzA5mh5Cw+00MdIfPd8enrCnA4b1ddqP/IsfEYRt91ANQBULwKC5wenKdJAN5qKSKW6KU9TUM5YvGvUPgTvcYgXNf3/INL6G3/HwISTE5A7S6lqwYLyRTT1fMHtgDIqS936DPqCdAZtzjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBZ4e3jAM0zvV43IrCzQOGIgDBwOWgm+wJG+jAU8r1awWDvzQXgF3h65nAKfoOuGEztsjeBEruU4EmZy6llLbfSSb8=] +ldap_bindpass: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAF5/sP43SJX/FB6cAS0GPqxC78JS7jSNKoUqWB/IXkv8uXYiClqk+Xw4nFx8EtknNn628DHBY3vCLQ59Xk89p0fyimP70m3BM6or5iRGdCqEAOzL399GbYX8WFHjyQRBmGdaLR5h2r5UnmjuPpDtV+fgsqxo4gNpXnuQ+46ZZPQce/dzHzux+4aEK4Q6UbD/ZZSQklD6zEUV+Agj6E9cQlJPBiHtTyUdXOYHYlJN1HhFPXu3C6KIz63YioVCah1n6T/rJtPQ07pVUfizIaJiPpzcUN91+ZWyyjUPo0bRGZtYKVs/uCAYXht4F5ttKQDaGa3wd4a5IdtacmEWQWFqk3TBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDtB/68xkjxK3nrNh0MilACgDDt85aBvSp/Oj9EY67eNPr+JcnQ7WfyuqAYAnmYqfbQI8MDtYAx7br0+inJXvQ1BvI=] diff --git a/hieradata/roles/apps/media/sonarr.yaml b/hieradata/roles/apps/media/sonarr.yaml index 09ab30c..3bca555 100644 --- a/hieradata/roles/apps/media/sonarr.yaml +++ b/hieradata/roles/apps/media/sonarr.yaml @@ -2,6 +2,7 @@ hiera_include: - sonarr - profiles::nginx::simpleproxy + - profiles::nginx::ldapauth # manage sonarr sonarr::params::user: sonarr @@ -27,9 +28,88 @@ profiles::nginx::simpleproxy::nginx_aliases: profiles::nginx::simpleproxy::proxy_port: 8000 profiles::nginx::simpleproxy::proxy_host: 127.0.0.1 profiles::nginx::simpleproxy::proxy_path: '/' +profiles::nginx::simpleproxy::use_default_location: false +nginx::client_max_body_size: 20M + +ldap_host: 'ldap.service.consul' +ldap_basedn: 'dc=main,dc=unkin,dc=net' +ldap_binddn: 'cn=svc_sonarr,ou=services,ou=users,dc=main,dc=unkin,dc=net' +ldap_template: '(memberOf=ou=sonarr_access,ou=groups,dc=main,dc=unkin,dc=net)' + +profiles::nginx::simpleproxy::locations: + # authentication proxy + authproxy: + ensure: 'present' + server: "%{lookup('profiles::nginx::simpleproxy::nginx_vhost')}" + ssl_only: true + internal: true + location: '= /auth-proxy' + proxy: "http://%{lookup('profiles::nginx::simpleproxy::proxy_host')}:8888" + proxy_set_header: + - 'Content-Length ""' + - "X-Ldap-URL ldap://%{lookup('ldap_host')}" + - 'X-Ldap-Starttls "false"' + - "X-Ldap-BaseDN %{lookup('ldap_basedn')}" + - "X-Ldap-BindDN %{lookup('ldap_binddn')}" + - "X-Ldap-BindPass %{lookup('ldap_bindpass')}" + - 'X-CookieName "nginxauth"' + - 'Cookie nginxauth=$cookie_nginxauth' + - "X-Ldap-Template %{lookup('ldap_template')}" + - 'X-Ldap-Realm "Restricted"' + proxy_cache: 'cache' + proxy_cache_valid: '200 10m' + proxy_cache_key: '"$http_authorization$cookie_nginxauth"' + location_cfg_append: + proxy_pass_request_body: 'off' + # sonarr health checks by consul + sonarr_web_consul: + ensure: 'present' + server: "%{lookup('profiles::nginx::simpleproxy::nginx_vhost')}" + ssl_only: true + location: '/consul/health' + proxy: "http://%{lookup('profiles::nginx::simpleproxy::proxy_host')}:%{lookup('profiles::nginx::simpleproxy::proxy_port')}" + proxy_set_header: + - 'Host $host' + - 'X-Forwarded-For $proxy_add_x_forwarded_for' + - 'X-Forwarded-Host $host' + - 'X-Forwarded-Proto $scheme' + - 'Upgrade $http_upgrade' + - 'Connection $http_connection' + proxy_redirect: 'off' + proxy_http_version: '1.1' + location_allow: + - 127.0.0.1 + - "%{facts.networking.ip}" + location_deny: + - all + # authorised sonarr access from external + sonarr_web_external: + ensure: 'present' + server: "%{lookup('profiles::nginx::simpleproxy::nginx_vhost')}" + ssl_only: true + location: '/' + auth_request: '/auth-proxy' + proxy: "http://%{lookup('profiles::nginx::simpleproxy::proxy_host')}:%{lookup('profiles::nginx::simpleproxy::proxy_port')}" + proxy_set_header: + - 'Host $host' + - 'X-Forwarded-For $proxy_add_x_forwarded_for' + - 'X-Forwarded-Host $host' + - 'X-Forwarded-Proto $scheme' + - 'Upgrade $http_upgrade' + - 'Connection $http_connection' + proxy_redirect: 'off' + proxy_http_version: '1.1' + # location for sonarr api, which should be accessible without authentication + sonarr_api: + ensure: 'present' + server: "%{lookup('profiles::nginx::simpleproxy::nginx_vhost')}" + ssl_only: true + location: '~ /api' + proxy: "http://%{lookup('profiles::nginx::simpleproxy::proxy_host')}:%{lookup('profiles::nginx::simpleproxy::proxy_port')}" + location_cfg_append: + client_max_body_size: '10m' # configure consul service -nginx::client_max_body_size: 10M consul::services: sonarr: service_name: 'sonarr' @@ -41,7 +121,7 @@ consul::services: checks: - id: 'sonarr_http_check' name: 'Sonarr HTTP Check' - http: "https://%{facts.networking.fqdn}:443" + http: "https://%{facts.networking.fqdn}:443/consul/health" method: 'GET' tls_skip_verify: true interval: '10s' -- 2.47.3 From 354e561380b1473bfef1e79589d11f982b149f6c Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 6 Jul 2024 17:32:44 +1000 Subject: [PATCH 3/6] feat: add ldapauth for nginx - add service, defaults and script --- site/profiles/manifests/nginx/ldapauth.pp | 72 ++++ .../ldapauth/nginx-ldap-auth-daemon.py.erb | 351 ++++++++++++++++++ .../ldapauth/nginx-ldap-auth.default.erb | 18 + .../ldapauth/nginx-ldap-auth.service.erb | 17 + 4 files changed, 458 insertions(+) create mode 100644 site/profiles/manifests/nginx/ldapauth.pp create mode 100644 site/profiles/templates/ldapauth/nginx-ldap-auth-daemon.py.erb create mode 100644 site/profiles/templates/ldapauth/nginx-ldap-auth.default.erb create mode 100644 site/profiles/templates/ldapauth/nginx-ldap-auth.service.erb diff --git a/site/profiles/manifests/nginx/ldapauth.pp b/site/profiles/manifests/nginx/ldapauth.pp new file mode 100644 index 0000000..afb1f81 --- /dev/null +++ b/site/profiles/manifests/nginx/ldapauth.pp @@ -0,0 +1,72 @@ +class profiles::nginx::ldapauth ( + Stdlib::AbsolutePath $bin_path = '/usr/local/bin/nginx-ldap-auth', + Stdlib::AbsolutePath $env_path = '/etc/default/nginx-ldap-auth', + String $user = 'nginx-ldap-auth', + String $group = 'nginx-ldap-auth', + Boolean $systempkgs = false, + String $version = 'system', + Hash $packages = { + 'python3.11-ldap' => { ensure => 'present' } + } +){ + + + if $::facts['python3_version'] { + + $python_version = $version ? { + 'system' => $::facts['python3_version'], + default => $version, + } + + ensure_resources('package', $packages) + + # Deploy the default configuration file using a template + file { $env_path: + ensure => file, + content => template('profiles/ldapauth/nginx-ldap-auth.default.erb'), + } + + # Deploy the daemon script using a template + file { $bin_path: + ensure => file, + content => template('profiles/ldapauth/nginx-ldap-auth-daemon.py.erb'), + mode => '0755', + } + + # Manage user and group + group { $group: + ensure => present, + system => true, + } + + user { $user: + ensure => present, + comment => 'nginx-ldap-auth helper', + gid => $group, + shell => '/sbin/nologin', + system => true, + require => Group[$group], + } + + # Create log directory for nginx-ldap-auth + file { '/var/log/nginx-ldap-auth': + ensure => directory, + owner => $user, + group => $group, + mode => '0755', + require => User[$user], + } + + # Ensure the systemd service is enabled and started + systemd::unit_file { 'nginx-ldap-auth.service': + content => template('profiles/ldapauth/nginx-ldap-auth.service.erb'), + enable => true, + active => true, + require => [ + File[$bin_path], + File[$env_path], + User[$user], + ], + } + } +} diff --git a/site/profiles/templates/ldapauth/nginx-ldap-auth-daemon.py.erb b/site/profiles/templates/ldapauth/nginx-ldap-auth-daemon.py.erb new file mode 100644 index 0000000..56f546d --- /dev/null +++ b/site/profiles/templates/ldapauth/nginx-ldap-auth-daemon.py.erb @@ -0,0 +1,351 @@ +#!/bin/sh +''''[ -z $LOG ] && export LOG=/dev/stdout # ''' +''''which python3.11 >/dev/null && exec python3.11 -u "$0" "$@" >> $LOG 2>&1 # ''' +# Copyright (C) 2014-2022 Nginx, Inc. + +import sys +import os +import signal +import base64 +import ldap +from ldap.filter import escape_filter_chars +import argparse + +if sys.version_info.major == 2: + from Cookie import BaseCookie + from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +elif sys.version_info.major == 3: + from http.cookies import BaseCookie + from http.server import HTTPServer, BaseHTTPRequestHandler + +if not hasattr(__builtins__, "basestring"): basestring = (str, bytes) + +#Listen = ('localhost', 8888) +#Listen = "/tmp/auth.sock" # Also uncomment lines in 'Requests are + # processed with UNIX sockets' section below + +# ----------------------------------------------------------------------------- +# Different request processing models: select one +# ----------------------------------------------------------------------------- +# Requests are processed in separate thread +import threading + +if sys.version_info.major == 2: + from SocketServer import ThreadingMixIn +elif sys.version_info.major == 3: + from socketserver import ThreadingMixIn + +class AuthHTTPServer(ThreadingMixIn, HTTPServer): + pass +# ----------------------------------------------------------------------------- +# Requests are processed in separate process +#from SocketServer import ForkingMixIn +#class AuthHTTPServer(ForkingMixIn, HTTPServer): +# pass +# ----------------------------------------------------------------------------- +# Requests are processed with UNIX sockets +#import threading +#from SocketServer import ThreadingUnixStreamServer +#class AuthHTTPServer(ThreadingUnixStreamServer, HTTPServer): +# pass +# ----------------------------------------------------------------------------- + +class AuthHandler(BaseHTTPRequestHandler): + + # Return True if request is processed and response sent, otherwise False + # Set ctx['user'] and ctx['pass'] for authentication + def do_GET(self): + + ctx = self.ctx + + ctx['action'] = 'input parameters check' + for k, v in self.get_params().items(): + ctx[k] = self.headers.get(v[0], v[1]) + if ctx[k] == None: + self.auth_failed(ctx, 'required "%s" header was not passed' % k) + return True + + ctx['action'] = 'performing authorization' + auth_header = self.headers.get('Authorization') + auth_cookie = self.get_cookie(ctx['cookiename']) + + if auth_cookie != None and auth_cookie != '': + auth_header = "Basic " + auth_cookie + self.log_message("using username/password from cookie %s" % + ctx['cookiename']) + else: + self.log_message("using username/password from authorization header") + + if auth_header is None or not auth_header.lower().startswith('basic '): + + self.send_response(401) + self.send_header('WWW-Authenticate', 'Basic realm="' + ctx['realm'] + '"') + self.send_header('Cache-Control', 'no-cache') + self.end_headers() + + return True + + ctx['action'] = 'decoding credentials' + + try: + auth_decoded = base64.b64decode(auth_header[6:]) + if sys.version_info.major == 3: auth_decoded = auth_decoded.decode("utf-8") + user, passwd = auth_decoded.split(':', 1) + + except: + self.auth_failed(ctx) + return True + + ctx['pass'] = passwd + ctx['user'] = ldap.filter.escape_filter_chars(user) + + # Continue request processing + return False + + def get_cookie(self, name): + cookies = self.headers.get('Cookie') + if cookies: + authcookie = BaseCookie(cookies).get(name) + if authcookie: + return authcookie.value + else: + return None + else: + return None + + + # Log the error and complete the request with appropriate status + def auth_failed(self, ctx, errmsg = None): + + msg = 'Error while ' + ctx['action'] + if errmsg: + msg += ': ' + errmsg + + ex, value, trace = sys.exc_info() + + if ex != None: + msg += ": " + str(value) + + if ctx.get('url'): + msg += ', server="%s"' % ctx['url'] + + if ctx.get('user'): + msg += ', login="%s"' % ctx['user'] + + self.log_error(msg) + self.send_response(401) + self.send_header('WWW-Authenticate', 'Basic realm="' + ctx['realm'] + '"') + self.send_header('Cache-Control', 'no-cache') + self.end_headers() + + def get_params(self): + return {} + + def log_message(self, format, *args): + if len(self.client_address) > 0: + addr = BaseHTTPRequestHandler.address_string(self) + else: + addr = "-" + + if not hasattr(self, 'ctx'): + user = '-' + else: + user = self.ctx['user'] + + sys.stdout.write("%s - %s [%s] %s\n" % (addr, user, + self.log_date_time_string(), format % args)) + + def log_error(self, format, *args): + self.log_message(format, *args) + + +# Verify username/password against LDAP server +class LDAPAuthHandler(AuthHandler): + # Parameters to put into self.ctx from the HTTP header of auth request + params = { + # parameter header default + 'realm': ('X-Ldap-Realm', 'Restricted'), + 'url': ('X-Ldap-URL', None), + 'starttls': ('X-Ldap-Starttls', 'false'), + 'disable_referrals': ('X-Ldap-DisableReferrals', 'false'), + 'basedn': ('X-Ldap-BaseDN', None), + 'template': ('X-Ldap-Template', '(cn=%(username)s)'), + 'binddn': ('X-Ldap-BindDN', ''), + 'bindpasswd': ('X-Ldap-BindPass', ''), + 'cookiename': ('X-CookieName', '') + } + + @classmethod + def set_params(cls, params): + cls.params = params + + def get_params(self): + return self.params + + # GET handler for the authentication request + def do_GET(self): + + ctx = dict() + self.ctx = ctx + + ctx['action'] = 'initializing basic auth handler' + ctx['user'] = '-' + + if AuthHandler.do_GET(self): + # request already processed + return + + ctx['action'] = 'empty password check' + if not ctx['pass']: + self.auth_failed(ctx, 'attempt to use empty password') + return + + try: + # check that uri and baseDn are set + # either from cli or a request + if not ctx['url']: + self.log_message('LDAP URL is not set!') + return + if not ctx['basedn']: + self.log_message('LDAP baseDN is not set!') + return + + ctx['action'] = 'initializing LDAP connection' + ldap_obj = ldap.initialize(ctx['url']); + + # Python-ldap module documentation advises to always + # explicitely set the LDAP version to use after running + # initialize() and recommends using LDAPv3. (LDAPv2 is + # deprecated since 2003 as per RFC3494) + # + # Also, the STARTTLS extension requires the + # use of LDAPv3 (RFC2830). + ldap_obj.protocol_version=ldap.VERSION3 + + # Establish a STARTTLS connection if required by the + # headers. + if ctx['starttls'] == 'true': + ldap_obj.start_tls_s() + + # See https://www.python-ldap.org/en/latest/faq.html + if ctx['disable_referrals'] == 'true': + ldap_obj.set_option(ldap.OPT_REFERRALS, 0) + + ctx['action'] = 'binding as search user' + ldap_obj.bind_s(ctx['binddn'], ctx['bindpasswd'], ldap.AUTH_SIMPLE) + + ctx['action'] = 'preparing search filter' + searchfilter = ctx['template'] % {'username': ctx['user']} + + self.log_message(('searching on server "%s" with base dn ' + \ + '"%s" with filter "%s"') % + (ctx['url'], ctx['basedn'], searchfilter)) + + ctx['action'] = 'running search query' + results = ldap_obj.search_s(ctx['basedn'], ldap.SCOPE_SUBTREE, + searchfilter, ['objectclass'], 1) + + ctx['action'] = 'verifying search query results' + + nres = len(results) + + if nres < 1: + self.auth_failed(ctx, 'no objects found') + return + + if nres > 1: + self.log_message("note: filter match multiple objects: %d, using first" % nres) + + user_entry = results[0] + ldap_dn = user_entry[0] + + if ldap_dn == None: + self.auth_failed(ctx, 'matched object has no dn') + return + + self.log_message('attempting to bind using dn "%s"' % (ldap_dn)) + + ctx['action'] = 'binding as an existing user "%s"' % ldap_dn + + ldap_obj.bind_s(ldap_dn, ctx['pass'], ldap.AUTH_SIMPLE) + + self.log_message('Auth OK for user "%s"' % (ctx['user'])) + + # Successfully authenticated user + self.send_response(200) + self.end_headers() + + except: + self.auth_failed(ctx) + +def exit_handler(signal, frame): + global Listen + + if isinstance(Listen, basestring): + try: + os.unlink(Listen) + except: + ex, value, trace = sys.exc_info() + sys.stderr.write('Failed to remove socket "%s": %s\n' % + (Listen, str(value))) + sys.stderr.flush() + sys.exit(0) + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Simple Nginx LDAP authentication helper.""") + # Group for listen options: + group = parser.add_argument_group("Listen options") + group.add_argument('--host', metavar="hostname", + default="localhost", help="host to bind (Default: localhost)") + group.add_argument('-p', '--port', metavar="port", type=int, + default=8888, help="port to bind (Default: 8888)") + # ldap options: + group = parser.add_argument_group(title="LDAP options") + group.add_argument('-u', '--url', metavar="URL", + default="ldap://localhost:389", + help=("LDAP URI to query (Default: ldap://localhost:389)")) + group.add_argument('-s', '--starttls', metavar="starttls", + default="false", + help=("Establish a STARTTLS protected session (Default: false)")) + group.add_argument('--disable-referrals', metavar="disable_referrals", + default="false", + help=("Sets ldap.OPT_REFERRALS to zero (Default: false)")) + group.add_argument('-b', metavar="baseDn", dest="basedn", default='', + help="LDAP base dn (Default: unset)") + group.add_argument('-D', metavar="bindDn", dest="binddn", default='', + help="LDAP bind DN (Default: anonymous)") + group.add_argument('-w', metavar="passwd", dest="bindpw", default='', + help="LDAP password for the bind DN (Default: unset)") + group.add_argument('-f', '--filter', metavar='filter', + default='(cn=%(username)s)', + help="LDAP filter (Default: cn=%%(username)s)") + # http options: + group = parser.add_argument_group(title="HTTP options") + group.add_argument('-R', '--realm', metavar='"Restricted Area"', + default="Restricted", help='HTTP auth realm (Default: "Restricted")') + group.add_argument('-c', '--cookie', metavar="cookiename", + default="", help="HTTP cookie name to set in (Default: unset)") + + args = parser.parse_args() + global Listen + Listen = (args.host, args.port) + auth_params = { + 'realm': ('X-Ldap-Realm', args.realm), + 'url': ('X-Ldap-URL', args.url), + 'starttls': ('X-Ldap-Starttls', args.starttls), + 'disable_referrals': ('X-Ldap-DisableReferrals', args.disable_referrals), + 'basedn': ('X-Ldap-BaseDN', args.basedn), + 'template': ('X-Ldap-Template', args.filter), + 'binddn': ('X-Ldap-BindDN', args.binddn), + 'bindpasswd': ('X-Ldap-BindPass', args.bindpw), + 'cookiename': ('X-CookieName', args.cookie) + } + LDAPAuthHandler.set_params(auth_params) + server = AuthHTTPServer(Listen, LDAPAuthHandler) + signal.signal(signal.SIGINT, exit_handler) + signal.signal(signal.SIGTERM, exit_handler) + + sys.stdout.write("Start listening on %s:%d...\n" % Listen) + sys.stdout.flush() + server.serve_forever() diff --git a/site/profiles/templates/ldapauth/nginx-ldap-auth.default.erb b/site/profiles/templates/ldapauth/nginx-ldap-auth.default.erb new file mode 100644 index 0000000..c3b80ab --- /dev/null +++ b/site/profiles/templates/ldapauth/nginx-ldap-auth.default.erb @@ -0,0 +1,18 @@ +# +# these are used with systemd too +# so please keep options names inside variables +# +#URL="--url ldap://example.com:389" +#BASE="-b dc=nodomain" +#BIND_DN="-D cn=admin,dc=nodomain" +#BIND_PASS="-w secret" +#COOKIE="-c nginxauth" +#FILTER="-f (cn=%(username)s)" +#REALM="-R 'Restricted Area'" + +# these are used with init scripts only +LOG=/var/log/nginx-ldap-auth/daemon.log +RUNDIR=/var/run/nginx-ldap-auth/ +PIDFILE=/var/run/nginx-ldap-auth/nginx-ldap-auth.pid +USER=<%= @user %> +GROUP=<%= @group %> diff --git a/site/profiles/templates/ldapauth/nginx-ldap-auth.service.erb b/site/profiles/templates/ldapauth/nginx-ldap-auth.service.erb new file mode 100644 index 0000000..afdf2c0 --- /dev/null +++ b/site/profiles/templates/ldapauth/nginx-ldap-auth.service.erb @@ -0,0 +1,17 @@ +[Unit] +Description=LDAP authentication helper for Nginx +After=network.target network-online.target + +[Service] +Type=simple +User=<%= @user %> +Group=<%= @group %> +WorkingDirectory=/var/run +EnvironmentFile=<%= @env_path %> +ExecStart=<%= @bin_path %> $URL $BASE $BIND_DN $BIND_PASS $COOKIE $FILTER $REALM +KillMode=process +KillSignal=SIGINT +Restart=on-failure + +[Install] +WantedBy=multi-user.target -- 2.47.3 From d1dd12a091d44c2dc5465142e45bd3b0599676d9 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 6 Jul 2024 17:59:38 +1000 Subject: [PATCH 4/6] feat: add cache to simpleproxy --- site/profiles/manifests/nginx/simpleproxy.pp | 28 ++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/site/profiles/manifests/nginx/simpleproxy.pp b/site/profiles/manifests/nginx/simpleproxy.pp index 7a497ae..29c1daf 100644 --- a/site/profiles/manifests/nginx/simpleproxy.pp +++ b/site/profiles/manifests/nginx/simpleproxy.pp @@ -99,15 +99,39 @@ class profiles::nginx::simpleproxy ( # merge the hashes conditionally $nginx_parameters = merge($defaults, $extras_hash) + ## manage cache for nginx + #file {'/var/cache/nginx/cache': + # ensure => 'directory', + # owner => 'nginx', + # group => 'root', + # mode => '0700', + #} + + #file {'/var/cache/nginx/cache_temp': + # ensure => 'directory', + # owner => 'nginx', + # group => 'root', + # mode => '0700', + #} + # manage the nginx class - include 'nginx' + class { 'nginx': + proxy_cache_path => { + '/var/cache/nginx/cache' => 'cache:128m', + }, + proxy_cache_levels => '1:2', + proxy_cache_keys_zone => 'cache:128m', + proxy_cache_max_size => '1024m', + proxy_cache_inactive => '10m', + proxy_temp_path => '/var/cache/nginx/cache_temp', + } # create the nginx vhost with the merged parameters create_resources('nginx::resource::server', { $nginx_vhost => $nginx_parameters }) # create nginx locations if $use_default_location == false { - create_resources('nginx::resource::location', $locations) + create_resources('nginx::resource::location', $locations => {'server' => $nginx_vhost}) } # manage selinux -- 2.47.3 From 8b01ddba9c2d3c2be0c1326e644351a9f123efe7 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 6 Jul 2024 22:09:16 +1000 Subject: [PATCH 5/6] fix: cleanup simpleproxy - remove commented sections - remove $server from locations --- site/profiles/manifests/nginx/simpleproxy.pp | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/site/profiles/manifests/nginx/simpleproxy.pp b/site/profiles/manifests/nginx/simpleproxy.pp index 29c1daf..c9f124e 100644 --- a/site/profiles/manifests/nginx/simpleproxy.pp +++ b/site/profiles/manifests/nginx/simpleproxy.pp @@ -99,21 +99,6 @@ class profiles::nginx::simpleproxy ( # merge the hashes conditionally $nginx_parameters = merge($defaults, $extras_hash) - ## manage cache for nginx - #file {'/var/cache/nginx/cache': - # ensure => 'directory', - # owner => 'nginx', - # group => 'root', - # mode => '0700', - #} - - #file {'/var/cache/nginx/cache_temp': - # ensure => 'directory', - # owner => 'nginx', - # group => 'root', - # mode => '0700', - #} - # manage the nginx class class { 'nginx': proxy_cache_path => { @@ -131,7 +116,7 @@ class profiles::nginx::simpleproxy ( # create nginx locations if $use_default_location == false { - create_resources('nginx::resource::location', $locations => {'server' => $nginx_vhost}) + create_resources('nginx::resource::location', $locations) } # manage selinux -- 2.47.3 From 2ab2cd1399bc3c42bc9451c89e485e5a16f914cb Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 6 Jul 2024 22:50:10 +1000 Subject: [PATCH 6/6] feat: deploy ldap-auth to all *arrs - refactor sonarr locations to generalised locations - set locations to be deep merged - updated hiera_include statements for media and media subroles - added eyaml entries for all ldap credentials --- hieradata/common.yaml | 4 ++ hieradata/roles/apps/media.yaml | 79 +++++++++++++++++++++++ hieradata/roles/apps/media/jellyfin.yaml | 1 - hieradata/roles/apps/media/lidarr.eyaml | 1 + hieradata/roles/apps/media/lidarr.yaml | 10 ++- hieradata/roles/apps/media/prowlarr.eyaml | 1 + hieradata/roles/apps/media/prowlarr.yaml | 10 ++- hieradata/roles/apps/media/radarr.eyaml | 1 + hieradata/roles/apps/media/radarr.yaml | 10 ++- hieradata/roles/apps/media/readarr.eyaml | 1 + hieradata/roles/apps/media/readarr.yaml | 10 ++- hieradata/roles/apps/media/sonarr.yaml | 76 ---------------------- 12 files changed, 115 insertions(+), 89 deletions(-) diff --git a/hieradata/common.yaml b/hieradata/common.yaml index 4a05016..17e2ae0 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -129,6 +129,10 @@ lookup_options: profiles::ceph::client::keyrings: merge: strategy: deep + profiles::nginx::simpleproxy::locations: + merge: + strategy: deep + facts_path: '/opt/puppetlabs/facter/facts.d' diff --git a/hieradata/roles/apps/media.yaml b/hieradata/roles/apps/media.yaml index 25bc31a..bfebf08 100644 --- a/hieradata/roles/apps/media.yaml +++ b/hieradata/roles/apps/media.yaml @@ -1,4 +1,7 @@ --- +hiera_include: + - profiles::nginx::simpleproxy + profiles::yum::global::repos: ceph-reef: name: ceph-reef @@ -18,3 +21,79 @@ profiles::base::groups::local: gid: 20000 allowdupe: false forcelocal: true + +ldap_host: 'ldap.service.consul' +ldap_basedn: 'dc=main,dc=unkin,dc=net' + +profiles::nginx::simpleproxy::locations: + # authentication proxy + authproxy: + ensure: 'present' + server: "%{lookup('profiles::nginx::simpleproxy::nginx_vhost')}" + ssl_only: true + internal: true + location: '= /auth-proxy' + proxy: "http://%{lookup('profiles::nginx::simpleproxy::proxy_host')}:8888" + proxy_set_header: + - 'Content-Length ""' + - "X-Ldap-URL ldap://%{lookup('ldap_host')}" + - 'X-Ldap-Starttls "false"' + - "X-Ldap-BaseDN %{lookup('ldap_basedn')}" + - "X-Ldap-BindDN %{lookup('ldap_binddn')}" + - "X-Ldap-BindPass %{lookup('ldap_bindpass')}" + - 'X-CookieName "nginxauth"' + - 'Cookie nginxauth=$cookie_nginxauth' + - "X-Ldap-Template %{lookup('ldap_template')}" + - 'X-Ldap-Realm "Restricted"' + proxy_cache: 'cache' + proxy_cache_valid: '200 10m' + proxy_cache_key: '"$http_authorization$cookie_nginxauth"' + location_cfg_append: + proxy_pass_request_body: 'off' + # health checks by consul + arrstack_web_consul: + ensure: 'present' + server: "%{lookup('profiles::nginx::simpleproxy::nginx_vhost')}" + ssl_only: true + location: '/consul/health' + proxy: "http://%{lookup('profiles::nginx::simpleproxy::proxy_host')}:%{lookup('profiles::nginx::simpleproxy::proxy_port')}" + proxy_set_header: + - 'Host $host' + - 'X-Forwarded-For $proxy_add_x_forwarded_for' + - 'X-Forwarded-Host $host' + - 'X-Forwarded-Proto $scheme' + - 'Upgrade $http_upgrade' + - 'Connection $http_connection' + proxy_redirect: 'off' + proxy_http_version: '1.1' + location_allow: + - 127.0.0.1 + - "%{facts.networking.ip}" + location_deny: + - all + # authorised access from external + arrstack_web_external: + ensure: 'present' + server: "%{lookup('profiles::nginx::simpleproxy::nginx_vhost')}" + ssl_only: true + location: '/' + auth_request: '/auth-proxy' + proxy: "http://%{lookup('profiles::nginx::simpleproxy::proxy_host')}:%{lookup('profiles::nginx::simpleproxy::proxy_port')}" + proxy_set_header: + - 'Host $host' + - 'X-Forwarded-For $proxy_add_x_forwarded_for' + - 'X-Forwarded-Host $host' + - 'X-Forwarded-Proto $scheme' + - 'Upgrade $http_upgrade' + - 'Connection $http_connection' + proxy_redirect: 'off' + proxy_http_version: '1.1' + # location for api, which should be accessible without authentication + arrstack_api: + ensure: 'present' + server: "%{lookup('profiles::nginx::simpleproxy::nginx_vhost')}" + ssl_only: true + location: '~ /api' + proxy: "http://%{lookup('profiles::nginx::simpleproxy::proxy_host')}:%{lookup('profiles::nginx::simpleproxy::proxy_port')}" + location_cfg_append: + client_max_body_size: '20m' diff --git a/hieradata/roles/apps/media/jellyfin.yaml b/hieradata/roles/apps/media/jellyfin.yaml index 8a761bd..01bd9b6 100644 --- a/hieradata/roles/apps/media/jellyfin.yaml +++ b/hieradata/roles/apps/media/jellyfin.yaml @@ -1,7 +1,6 @@ --- hiera_include: - jellyfin - - profiles::nginx::simpleproxy # manage jellyfin jellyfin::params::service_enable: true diff --git a/hieradata/roles/apps/media/lidarr.eyaml b/hieradata/roles/apps/media/lidarr.eyaml index f42cfb5..19b5bee 100644 --- a/hieradata/roles/apps/media/lidarr.eyaml +++ b/hieradata/roles/apps/media/lidarr.eyaml @@ -1,2 +1,3 @@ --- lidarr::api_key: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAeIT5i5yJ/KCmEBEgF8r36dl2RK/0/LQWPl6bgth7KOdtfNynhH4bCxembrJwzXasT1KBrPWYmTc2IObBz2tqu7BIHoioI2y+GVs2ulhx63lrfeDI/I4QFs5EOh9fIoyOxlIkvKm+p0WVfaegKOKM63XHHvG2TmBwTypEHB1IXaCMVl87tY+3xmMEaiqVPik3llqLCog1rmRLbIQx+whAFPtlhHur0ozfdYLKiM57YHAsQpGgASYkAAjvZuKabOrRZsIhhsHCb4JQ/evvIrhkviK7nP4xHdeqRSJgdEDmIldr2FW3uHCzuq033K3T7HNc3HbUM/5lC0ygP8sZnnM8rDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAyfQkaBPJJWVsc2FGiyCyMgDAYuYDAwBBAJzfVZ4RFrQyi48VZeS8MTjf2HNAXBYoYgTtdZAk9i+pIV22p9ee+KsU=] +ldap_bindpass: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAEDEyk6fBBnrjZvfK8MnUVOTWxhFGtgY34/2CuIq55MoVLsk2ZgVrL7Kt+94bqFhwEB67kuNpMGXqTgW5ose2yWs5iVSJLECsf9C+tvGBGwaV35LNwP5S3aQmFagyTpZZz9QlGKC7818jlXz7vZWDtiUhy5TGMHeyS0fdjCveavtZR28A+ZrvWjJeLdN47mmvYwYfFnQBs3kSgkl5KyMVhFWSFOSLeHsuEzCVXHoQ1jQG+2TV5m18wV0RR/sOju2E+vsulqlDgCyifgoiry4GzJeKNrNDI2bifzHCAi6yZqHL/klyqbGTnKLlA4xKoXsHF+xEwcoq4S9JDLAdWeH1SDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCdvh4yn8knozcYhinybRq3gDAwTKv8VakQG7XK/mcEplwtoiKqLnj9IIGdIUh1zPi2Sg48ET5rfZyl0p7ddIYoHjU=] diff --git a/hieradata/roles/apps/media/lidarr.yaml b/hieradata/roles/apps/media/lidarr.yaml index b2f60b7..03d3ff4 100644 --- a/hieradata/roles/apps/media/lidarr.yaml +++ b/hieradata/roles/apps/media/lidarr.yaml @@ -1,7 +1,7 @@ --- hiera_include: - lidarr - - profiles::nginx::simpleproxy + - profiles::nginx::ldapauth # manage lidarr lidarr::params::user: lidarr @@ -27,9 +27,13 @@ profiles::nginx::simpleproxy::nginx_aliases: profiles::nginx::simpleproxy::proxy_port: 8000 profiles::nginx::simpleproxy::proxy_host: 127.0.0.1 profiles::nginx::simpleproxy::proxy_path: '/' +profiles::nginx::simpleproxy::use_default_location: false +nginx::client_max_body_size: 20M + +ldap_binddn: 'cn=svc_lidarr,ou=services,ou=users,dc=main,dc=unkin,dc=net' +ldap_template: '(memberOf=ou=lidarr_access,ou=groups,dc=main,dc=unkin,dc=net)' # configure consul service -nginx::client_max_body_size: 10M consul::services: lidarr: service_name: 'lidarr' @@ -41,7 +45,7 @@ consul::services: checks: - id: 'lidarr_http_check' name: 'Lidarr HTTP Check' - http: "https://%{facts.networking.fqdn}:443" + http: "https://%{facts.networking.fqdn}:443/consul/health" method: 'GET' tls_skip_verify: true interval: '10s' diff --git a/hieradata/roles/apps/media/prowlarr.eyaml b/hieradata/roles/apps/media/prowlarr.eyaml index 05b8389..2b908f1 100644 --- a/hieradata/roles/apps/media/prowlarr.eyaml +++ b/hieradata/roles/apps/media/prowlarr.eyaml @@ -1,2 +1,3 @@ --- prowlarr::api_key: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAdAzvi5Z2cX7KWdMlMfR5N+Jz9Pmh3k9yvPgM1JnTM8ZODs5VyQf/d3goWJ5Fn+jcjVqQ+aBga2CHfbdjgg5dGC19Jr8CmxVkYpMVb+e6Md4LEglUD6g70LK8JHB1FAM0fqW82/zqBL73KFKcu71Hpbf9YylJD4LXCr/k4D7hPX3tgEOzFn1iGl/DqxJFWnorj0btk3/2AmA3AMjvFy4r39PwbMfr2jNFSmAdJa7j7W+ESyE08Cc795VORIa/lbrT0ZfBMGXqzNTIpcdJ7uabcrH0qHNM8FPh4eHBzGMqLvIba487bs2TUb8eIivwT2EAwmGDWX1QkG2o6lGyO8PyqzBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBO8BQpHvHYOA2tjyxpjGw4gDATwt1wP0aPFPnbRoqPdwClfOzbWmtbT/rCBmCQH0HkyA8sqr2I2qlOsuJukCjBDHo=] +ldap_bindpass: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAhduPAqoZuq/xeRs4f/KX4r88evPMogQX79yofLAB5Qqdr48s2X0BAa1iiw0vMdL6Tf0uc794WJN5MP2Yp365Vk1yhwgqH92rt5hKPI+wBN5uak2iLgLzLWsp0HOx7d1ukDWBbj0lI6G5LiofsL3KJbbTnkovn06L4PRJXgn44+ynfywiCl2tPy2294DhfooeM6/Cy+t9lA6blzHLCOHtt/rBKmk1GT2y3YBCPhRfOumWXQWnv4Q+f6KkQkvpfPyAFYNiQxQYBv5bGwLnwiDk3xQnPM4FfcutVuAOKjsoeMa+K1KShDFyEfBxIER8JSpigj2/khstyihcVW0Xrod3uDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCRqqRwMThwn1F/6byFhTWxgDAfucfkFhmqxBv/u5H+wWnjvK5EH7eU/fECrajYPBW/cmsYjLgXlwrAzFGqWze3AZc=] diff --git a/hieradata/roles/apps/media/prowlarr.yaml b/hieradata/roles/apps/media/prowlarr.yaml index 8279455..b4a2fc8 100644 --- a/hieradata/roles/apps/media/prowlarr.yaml +++ b/hieradata/roles/apps/media/prowlarr.yaml @@ -1,7 +1,7 @@ --- hiera_include: - prowlarr - - profiles::nginx::simpleproxy + - profiles::nginx::ldapauth # manage prowlarr prowlarr::params::user: prowlarr @@ -27,9 +27,13 @@ profiles::nginx::simpleproxy::nginx_aliases: profiles::nginx::simpleproxy::proxy_port: 8000 profiles::nginx::simpleproxy::proxy_host: 127.0.0.1 profiles::nginx::simpleproxy::proxy_path: '/' +profiles::nginx::simpleproxy::use_default_location: false +nginx::client_max_body_size: 20M + +ldap_binddn: 'cn=svc_prowlarr,ou=services,ou=users,dc=main,dc=unkin,dc=net' +ldap_template: '(memberOf=ou=prowlarr_access,ou=groups,dc=main,dc=unkin,dc=net)' # configure consul service -nginx::client_max_body_size: 10M consul::services: prowlarr: service_name: 'prowlarr' @@ -41,7 +45,7 @@ consul::services: checks: - id: 'prowlarr_http_check' name: 'Prowlarr HTTP Check' - http: "https://%{facts.networking.fqdn}:443" + http: "https://%{facts.networking.fqdn}:443/consul/health" method: 'GET' tls_skip_verify: true interval: '10s' diff --git a/hieradata/roles/apps/media/radarr.eyaml b/hieradata/roles/apps/media/radarr.eyaml index 15e57af..07fe5ac 100644 --- a/hieradata/roles/apps/media/radarr.eyaml +++ b/hieradata/roles/apps/media/radarr.eyaml @@ -1,2 +1,3 @@ --- radarr::api_key: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEALtNnNr2N7DpP9zx5anmQavFmsTLIyPkpJGCkJpUTHMYFSScS/3FOUuufajk4Cmu4FbPswp/N/U1nHO8oLF6xNQ+H77+xXuKPalW/3R1IRqGoczwsAfstJ6nYF+PLjjeK2TDP+KMs3Eg2+nrXB7NOVOP88RvDLyZq93Wn9qR+1VG6Y2gLqGSJArZpNilV5ygUYRgbMeckjqfLynYBXtgDQQLYNhxDO6WGRRv+0X773nmOdrWFAUjqF6/K+Ejjk5ZbaqnGyjljMstSrhg7NWxtMRbCjeMpjUjUS4Hn/Vayg2M2Ag2s87gsE1e4QFa6KP7GVRu3swvyZ3D54Ba/xrebxzBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDD6gIEfNGPXA8zv/vysgxJgDADMi7Fx5q+aqTMeqcKLg1AukTlCnJ62zykm6RNGdS0KlpJsvTSmWF4So3v/9BsKdk=] +ldap_bindpass: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAf6LbAXy3EsJqkf4KO8xikpXfSVIVOD2obnwZLPEiCfbC0iJyZ2Uc/RbHM9NnIpg8dgEnYGgaBM9HC+kFKYFP4skLsPQ0mpqOv13WbOAHOphhyBxWc/n4Eg4HqMAiHsC4qA9Sj5j4F29tNiMmpNM0eqDXD6YIrajV5IF+SKQQzZrNSrcDrzjqENaMnJWVc2gj7Zb9kPB1LdM5ZfljpPtfQHXHhh9ShTDKuWMx46nc+UYaRcJqHEns7OExwpsEAtA1SSunD81PTijJ6Bn1Y6cAsZoBot5YgFGaWtgQ4jvEqj7EbG8gDJuHMSwa9RzA9SMsVwEh2g1pko7wYbBR/arV7jBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAhZlVaEdaLNh60gAY0KwEKgDAHPoXfFRq0I2K2J+NFgNFm/A00jYGVRfuPsX6VZfPaJ499dtMiJifrK3Kfk1oXpvk=] diff --git a/hieradata/roles/apps/media/radarr.yaml b/hieradata/roles/apps/media/radarr.yaml index bdb949d..1c18b4e 100644 --- a/hieradata/roles/apps/media/radarr.yaml +++ b/hieradata/roles/apps/media/radarr.yaml @@ -1,7 +1,7 @@ --- hiera_include: - radarr - - profiles::nginx::simpleproxy + - profiles::nginx::ldapauth # manage radarr radarr::params::user: radarr @@ -28,9 +28,13 @@ profiles::nginx::simpleproxy::nginx_aliases: profiles::nginx::simpleproxy::proxy_port: 8000 profiles::nginx::simpleproxy::proxy_host: 127.0.0.1 profiles::nginx::simpleproxy::proxy_path: '/' +profiles::nginx::simpleproxy::use_default_location: false +nginx::client_max_body_size: 20M + +ldap_binddn: 'cn=svc_radarr,ou=services,ou=users,dc=main,dc=unkin,dc=net' +ldap_template: '(memberOf=ou=radarr_access,ou=groups,dc=main,dc=unkin,dc=net)' # configure consul service -nginx::client_max_body_size: 10M consul::services: radarr: service_name: 'radarr' @@ -42,7 +46,7 @@ consul::services: checks: - id: 'radarr_http_check' name: 'radarr HTTP Check' - http: "https://%{facts.networking.fqdn}:443" + http: "https://%{facts.networking.fqdn}:443/consul/health" method: 'GET' tls_skip_verify: true interval: '10s' diff --git a/hieradata/roles/apps/media/readarr.eyaml b/hieradata/roles/apps/media/readarr.eyaml index e63bd85..d0b1c68 100644 --- a/hieradata/roles/apps/media/readarr.eyaml +++ b/hieradata/roles/apps/media/readarr.eyaml @@ -1,2 +1,3 @@ --- readarr::api_key: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAlJ5RLp6pVTGQgtbzO5cQSrHBMg80S1ImFprHDeWC3GPN2KbheM80b1FKxvN+oVUJ8/kfiV6zstLOoYPUJQfmJNa/Xe95W/5+9hH2IS/oQ0yVdfLOjRq//qp+mVvSJ7JrtOyYSIrU3HjxaD+eXTPYp4UEJKfdSmGyDr7XuCOVIZe0Lu7OHczs8VKrowN99RJZ589HoMqrqCZWPlx14l/uNFjYdK/w6VcUWoo9y/5z1jtsNIObV8kSAYQQLwSr3tmjJdEE3au4sjeMOOJDpGcd5aJRWpKp12+8oHdVR5BV5326aCb13tkp6Td0jq/W9J2Jyv05vUdpP3PnVH9mHPDh6TBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDA+2mMNGwfYM+mRoVTQiZMgDBanhVFmpYe42vZgMBKpNcNRjTnoCl27RpxD3KnjYwkE1zw/NeEOLoSZ1Try3GrlaA=] +ldap_bindpass: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAcOegaqGEsivQAlhSYvaiVUij4QJ/kterSg+wX/7P/oWjSN1oSNAFfco6lg5fYUsR7HDKZ4IwYuO1Q/q8hOxYkqzYrH/MIAhZatfQxyxriKuekxqOMuXgwrWCzAexQL0Fb4s5gcHQ4fwy5OxsM1CxFXnSSm1eYNXl5IERd//c0dFoIcshiGlOCFsj8Ne9mookFTJQDZrxM4VMXaVb+Fl9mOyy1ppDBKHTP/1ise/6LIUi+9YngamAWLIrsur5KvR45kvRoxDNLfJZasAqhD/5QLceDdSxqKBDur57QzmoPo2lFdT4WlzphKOdyHZtYOYr7BPdbtCqkXTWdkXvqFlRxjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCXhYe6zoRW7/OxVrZnAEoTgDDPFTz5S4nZWiwzjdT7Yd88Ii6I/v6ckaKTx0gd0pZKsVZkFYQBBhIfqFS2ho0UG3Y=] diff --git a/hieradata/roles/apps/media/readarr.yaml b/hieradata/roles/apps/media/readarr.yaml index d7785c8..060f509 100644 --- a/hieradata/roles/apps/media/readarr.yaml +++ b/hieradata/roles/apps/media/readarr.yaml @@ -1,7 +1,7 @@ --- hiera_include: - readarr - - profiles::nginx::simpleproxy + - profiles::nginx::ldapauth # manage readarr readarr::params::user: readarr @@ -27,9 +27,13 @@ profiles::nginx::simpleproxy::nginx_aliases: profiles::nginx::simpleproxy::proxy_port: 8000 profiles::nginx::simpleproxy::proxy_host: 127.0.0.1 profiles::nginx::simpleproxy::proxy_path: '/' +profiles::nginx::simpleproxy::use_default_location: false +nginx::client_max_body_size: 20M + +ldap_binddn: 'cn=svc_readarr,ou=services,ou=users,dc=main,dc=unkin,dc=net' +ldap_template: '(memberOf=ou=readarr_access,ou=groups,dc=main,dc=unkin,dc=net)' # configure consul service -nginx::client_max_body_size: 10M consul::services: readarr: service_name: 'readarr' @@ -41,7 +45,7 @@ consul::services: checks: - id: 'readarr_http_check' name: 'Readarr HTTP Check' - http: "https://%{facts.networking.fqdn}:443" + http: "https://%{facts.networking.fqdn}:443/consul/health" method: 'GET' tls_skip_verify: true interval: '10s' diff --git a/hieradata/roles/apps/media/sonarr.yaml b/hieradata/roles/apps/media/sonarr.yaml index 3bca555..9724726 100644 --- a/hieradata/roles/apps/media/sonarr.yaml +++ b/hieradata/roles/apps/media/sonarr.yaml @@ -1,7 +1,6 @@ --- hiera_include: - sonarr - - profiles::nginx::simpleproxy - profiles::nginx::ldapauth # manage sonarr @@ -31,84 +30,9 @@ profiles::nginx::simpleproxy::proxy_path: '/' profiles::nginx::simpleproxy::use_default_location: false nginx::client_max_body_size: 20M -ldap_host: 'ldap.service.consul' -ldap_basedn: 'dc=main,dc=unkin,dc=net' ldap_binddn: 'cn=svc_sonarr,ou=services,ou=users,dc=main,dc=unkin,dc=net' ldap_template: '(memberOf=ou=sonarr_access,ou=groups,dc=main,dc=unkin,dc=net)' -profiles::nginx::simpleproxy::locations: - # authentication proxy - authproxy: - ensure: 'present' - server: "%{lookup('profiles::nginx::simpleproxy::nginx_vhost')}" - ssl_only: true - internal: true - location: '= /auth-proxy' - proxy: "http://%{lookup('profiles::nginx::simpleproxy::proxy_host')}:8888" - proxy_set_header: - - 'Content-Length ""' - - "X-Ldap-URL ldap://%{lookup('ldap_host')}" - - 'X-Ldap-Starttls "false"' - - "X-Ldap-BaseDN %{lookup('ldap_basedn')}" - - "X-Ldap-BindDN %{lookup('ldap_binddn')}" - - "X-Ldap-BindPass %{lookup('ldap_bindpass')}" - - 'X-CookieName "nginxauth"' - - 'Cookie nginxauth=$cookie_nginxauth' - - "X-Ldap-Template %{lookup('ldap_template')}" - - 'X-Ldap-Realm "Restricted"' - proxy_cache: 'cache' - proxy_cache_valid: '200 10m' - proxy_cache_key: '"$http_authorization$cookie_nginxauth"' - location_cfg_append: - proxy_pass_request_body: 'off' - # sonarr health checks by consul - sonarr_web_consul: - ensure: 'present' - server: "%{lookup('profiles::nginx::simpleproxy::nginx_vhost')}" - ssl_only: true - location: '/consul/health' - proxy: "http://%{lookup('profiles::nginx::simpleproxy::proxy_host')}:%{lookup('profiles::nginx::simpleproxy::proxy_port')}" - proxy_set_header: - - 'Host $host' - - 'X-Forwarded-For $proxy_add_x_forwarded_for' - - 'X-Forwarded-Host $host' - - 'X-Forwarded-Proto $scheme' - - 'Upgrade $http_upgrade' - - 'Connection $http_connection' - proxy_redirect: 'off' - proxy_http_version: '1.1' - location_allow: - - 127.0.0.1 - - "%{facts.networking.ip}" - location_deny: - - all - # authorised sonarr access from external - sonarr_web_external: - ensure: 'present' - server: "%{lookup('profiles::nginx::simpleproxy::nginx_vhost')}" - ssl_only: true - location: '/' - auth_request: '/auth-proxy' - proxy: "http://%{lookup('profiles::nginx::simpleproxy::proxy_host')}:%{lookup('profiles::nginx::simpleproxy::proxy_port')}" - proxy_set_header: - - 'Host $host' - - 'X-Forwarded-For $proxy_add_x_forwarded_for' - - 'X-Forwarded-Host $host' - - 'X-Forwarded-Proto $scheme' - - 'Upgrade $http_upgrade' - - 'Connection $http_connection' - proxy_redirect: 'off' - proxy_http_version: '1.1' - # location for sonarr api, which should be accessible without authentication - sonarr_api: - ensure: 'present' - server: "%{lookup('profiles::nginx::simpleproxy::nginx_vhost')}" - ssl_only: true - location: '~ /api' - proxy: "http://%{lookup('profiles::nginx::simpleproxy::proxy_host')}:%{lookup('profiles::nginx::simpleproxy::proxy_port')}" - location_cfg_append: - client_max_body_size: '10m' - # configure consul service consul::services: sonarr: -- 2.47.3