209 lines
5.5 KiB
Puppet
209 lines
5.5 KiB
Puppet
#
|
|
# General SSO documentation: https://wiki.sunet.se/x/sZGLBg
|
|
#
|
|
# @param hostname FQDN of the host this is running on.
|
|
#
|
|
# @param email Support email used in error messages etc.
|
|
#
|
|
# @param service_endpoint Location of service to reverse proxy for.
|
|
#
|
|
# @param groups
|
|
# List of user groups from sso_groups in global/overlay/etc/hiera/data/common.yaml. The
|
|
# default is a non-existing placeholder group, added to make the Apache config valid.
|
|
#
|
|
# @param passthrough List of paths to disable SAML protection for, e.g. API paths.
|
|
#
|
|
# @param x_remote_user
|
|
# If true, EPPN is put in the HTTP header X-Remote-User instead of REMOTE_USER.
|
|
#
|
|
# @param single_user
|
|
# If true, EPPN is discarded and X-Remote-User is set to "soc-user". This is useful in
|
|
# cases where the service we reverse proxy for can't create new accounts automatically.
|
|
# We use this only for Graylog at the time of writing.
|
|
#
|
|
/ @param swamid_testing Set this to true if your SP is registered in swamid-testing.
|
|
#
|
|
# @param front_clients
|
|
# Hiera field, defined at common.yaml, with the the frontend IP prefixes that require access
|
|
# to port 443. Defaults to empty string.
|
|
#
|
|
class soc::sso(
|
|
$hostname,
|
|
$email,
|
|
$service_endpoint,
|
|
$groups = ['PLACEHOLDER'],
|
|
$passthrough = [],
|
|
$x_remote_user = false,
|
|
$swamid_testing = false,
|
|
$single_user = false,
|
|
$front_clients = '',
|
|
$satosa = true,
|
|
$satosa_certbot = true,
|
|
$translog = 'INFO',
|
|
$proxy = 'https://shared-sso-proxy1.cert.sunet.se/idp',
|
|
$norpan = false,
|
|
) {
|
|
|
|
file { '/opt/sso':
|
|
ensure => directory,
|
|
}
|
|
|
|
#
|
|
# Apache files
|
|
#
|
|
|
|
file { '/opt/sso/apache':
|
|
ensure => directory,
|
|
}
|
|
|
|
file { '/opt/sso/apache/site.conf':
|
|
ensure => file,
|
|
content => template('soc/sso/apache-site.conf.erb'),
|
|
}
|
|
|
|
# SSL defaults copied from certbot:
|
|
# https://github.com/certbot/certbot/blob/master/certbot-apache/certbot_apache/_internal/tls_configs/current-options-ssl-apache.conf
|
|
file { '/opt/sso/apache/ssl.conf':
|
|
ensure => file,
|
|
content => file('soc/sso/apache-ssl.conf'),
|
|
}
|
|
|
|
file { '/opt/sso/apache/groups.txt':
|
|
ensure => file,
|
|
content => template('soc/sso/apache-groups.txt.erb')
|
|
}
|
|
|
|
#
|
|
# Shibboleth files
|
|
#
|
|
|
|
file { '/opt/sso/shibboleth':
|
|
ensure => directory,
|
|
}
|
|
|
|
file { '/opt/sso/shibboleth/shibboleth2.xml':
|
|
ensure => file,
|
|
content => template('soc/sso/shibboleth2.xml.erb'),
|
|
}
|
|
|
|
file { '/opt/sso/shibboleth/shibd.logger':
|
|
ensure => file,
|
|
content => template('soc/sso/shibd.logger.erb'),
|
|
}
|
|
|
|
file { '/opt/sso/shibboleth/attribute-map.xml':
|
|
ensure => file,
|
|
content => file('soc/sso/attribute-map.xml'),
|
|
}
|
|
|
|
file { '/opt/sso/shibboleth/md-signer2.crt':
|
|
ensure => file,
|
|
content => file('soc/sso/md-signer2.crt'),
|
|
}
|
|
if $satosa {
|
|
if $norpan {
|
|
file { '/opt/sso/shibboleth/frontend.xml':
|
|
ensure => file,
|
|
content => file('soc/sso/frontend_norpan.xml'),
|
|
}
|
|
} else {
|
|
file { '/opt/sso/shibboleth/frontend.xml':
|
|
ensure => file,
|
|
content => file('soc/sso/frontend.xml'),
|
|
}
|
|
}
|
|
|
|
file { '/opt/sso/shibboleth/attribute-policy.xml':
|
|
ensure => file,
|
|
content => file('soc/sso/attribute-policy.xml'),
|
|
}
|
|
|
|
if lookup('sso_sp_key', undef, undef, undef) != undef {
|
|
sunet::snippets::secret_file { '/opt/sso/shibboleth/sp-key.pem':
|
|
hiera_key => 'sso_sp_key'
|
|
}
|
|
} else {
|
|
sunet::snippets::keygen {'shib_cert':
|
|
key_file => '/opt/sso/shibboleth/sp-key.pem',
|
|
cert_file => '/opt/sso/shibboleth/sp-cert.pem'
|
|
}
|
|
}
|
|
|
|
} else {
|
|
sunet::snippets::secret_file { '/opt/sso/shibboleth/sp-key.pem':
|
|
hiera_key => 'sso_sp_key'
|
|
}
|
|
}
|
|
|
|
#
|
|
# Certbot
|
|
#
|
|
|
|
if $satosa_certbot {
|
|
package { ['certbot', 'python3-requests']:
|
|
ensure => 'latest',
|
|
}
|
|
|
|
file { '/etc/letsencrypt/acme-dns-auth.py':
|
|
ensure => file,
|
|
content => file('soc/sso/acme-dns-auth.py'),
|
|
mode => '0744',
|
|
}
|
|
|
|
file { '/etc/letsencrypt/renewal-hooks/deploy/soc-sso-reload':
|
|
ensure => file,
|
|
mode => '0700',
|
|
content => "#!/bin/sh -eu\ndocker exec sso service apache2 reload",
|
|
}
|
|
|
|
sunet::scriptherder::cronjob { 'le_renew':
|
|
cmd => '/bin/echo "Keeping this cronjob, but disabled to avoid scriptherder complainign about unknown check"',
|
|
special => 'daily',
|
|
}
|
|
}
|
|
|
|
#
|
|
# Docker
|
|
#
|
|
|
|
exec {"Create Docker network \"sso\" to talk to service":
|
|
# We OR with true to ignore errors, since the network often already exists.
|
|
# We specify a subnet so that services which have the option/requirement can
|
|
# specify this subnet as source of trusted proxies. This is used in Graylog,
|
|
# for example; see setting "trusted_proxies".
|
|
command => 'docker network create sso --subnet 172.29.0.0/24 || true'
|
|
}
|
|
|
|
file { '/opt/sso/docker-compose.yml':
|
|
ensure => file,
|
|
mode => '0600',
|
|
content => template('soc/sso/docker-compose.yml.erb'),
|
|
}
|
|
|
|
sunet::docker_compose_service { 'sso':
|
|
description => '',
|
|
compose_file => '/opt/sso/docker-compose.yml',
|
|
}
|
|
|
|
#
|
|
# NFT Rules
|
|
#
|
|
|
|
if 'wg0' in $facts['networking']['interfaces'].keys {
|
|
if $front_clients != '' {
|
|
$front_clients_exposed = hiera_array($front_clients,[])
|
|
sunet::nftables::docker_expose { 'clients_https' :
|
|
allow_clients => $front_clients_exposed,
|
|
port => 443,
|
|
iif => 'wg0',
|
|
}
|
|
}
|
|
}
|
|
|
|
sunet::nftables::docker_expose { 'apache_sso_https' :
|
|
allow_clients => ['0.0.0.0/0'],
|
|
port => 443,
|
|
iif => 'ens3',
|
|
}
|
|
|
|
}
|