# Configure a SUNET CDN CA server class cdn::cache( Hash[String, Integer] $customers = { customer1 => 1000000000, }, String $sunet_cdnp_version = '0.0.4', Hash[String, String] $acme_url = { test => 'https://internal-sto3-test-ca-1.cdn.sunet.se:9000/acme/acme/directory' }, Hash[String, Hash[String, String]] $mqtt_url = { sto3 => { test => 'tls://internal-sto3-test-mqtt-1.cdn.sunet.se:8883', }, }, ) { include sunet::systemd_reload include sunet::packages::certbot include cdn::ca_trust $cache_secrets = lookup({ 'name' => 'cdn::cache-secrets', 'default_value' => undef }) file { '/opt/sunet-cdn': ensure => directory, owner => 'root', group => 'root', mode => '0755', } file { '/opt/sunet-cdn/customers': ensure => directory, owner => 'root', group => 'root', mode => '0755', } file { '/opt/sunet-cdn/conf': ensure => directory, owner => 'root', group => 'root', mode => '0755', } file { '/opt/sunet-cdn/conf/varnish-slash-seccomp.json': ensure => file, owner => 'root', group => 'root', mode => '0644', content => template('cdn/cache/varnish-slash-seccomp.json.erb'), } file { '/etc/systemd/network/10-cdn-dummy.netdev': ensure => file, owner => 'root', group => 'root', mode => '0644', content => template('cdn/cache/10-cdn-dummy.netdev.erb'), } file { '/etc/systemd/network/10-cdn-dummy.network': ensure => file, owner => 'root', group => 'root', mode => '0644', content => template('cdn/cache/10-cdn-dummy.network.erb'), } file { '/etc/systemd/network/10-cdn-ipip.netdev': ensure => file, owner => 'root', group => 'root', mode => '0644', content => template('cdn/cache/10-cdn-ipip.netdev.erb'), } file { '/etc/systemd/network/10-cdn-ipip.network': ensure => file, owner => 'root', group => 'root', mode => '0644', content => template('cdn/cache/10-cdn-ipip.network.erb'), } file { '/etc/systemd/network/10-cdn-ip6tunl.netdev.erb': ensure => file, owner => 'root', group => 'root', mode => '0644', content => template('cdn/cache/10-cdn-ip6tunl.netdev.erb'), } file { '/etc/systemd/network/10-cdn-ip6tunl.network.erb': ensure => file, owner => 'root', group => 'root', mode => '0644', content => template('cdn/cache/10-cdn-ip6tunl.network.erb'), } # Reload the network config if it has changed exec { 'networkctl reload': subscribe => [File['/etc/systemd/network/10-cdn-dummy.network'], File['/etc/systemd/network/10-cdn-ipip.network']], refreshonly => true, } $sysctl_file = '/etc/sysctl.d/99-cdn-cache.conf' file { $sysctl_file: ensure => file, owner => 'root', group => 'root', mode => '0644', content => template('cdn/cache/sysctl.erb'), } # Load the sysctl file if it has changed exec { "sysctl -p ${sysctl_file}": subscribe => File[$sysctl_file], refreshonly => true, } # Allow IPv4 tunnel packets arriving from l4lb nodes sunet::nftables::rule { 'sunet_cdn_tunnel4': rule => 'add rule inet filter input ip saddr { 130.242.64.233, 130.242.64.235 } ip protocol ipencap counter accept comment "sunet-cdn-tunnel4"' } # Allow IPv6 tunnel packets arriving from l4lb nodes sunet::nftables::rule { 'sunet_cdn_tunnel6': rule => 'add rule inet filter input ip6 saddr { 2001:6b0:2006:74::1, 2001:6b0:2006:75::1 } ip6 nexthdr ipv6 counter accept comment "sunet-cdn-tunnel6"' } # Allow decapsulated tunnel packets targeting the service IP range to reach # local service ports sunet::nftables::rule { 'sunet_cdn_service4': rule => 'add rule inet filter input meta iifname tunl0 ip daddr 188.240.152.0/24 tcp dport { 80, 443 } counter accept comment "sunet-cdn-service4"' } sunet::nftables::rule { 'sunet_cdn_service6': rule => 'add rule inet filter input meta iifname ip6tnl0 ip6 daddr 2001:6b0:2100::/48 tcp dport { 80, 443 } counter accept comment "sunet-cdn-service6"' } # From https://wiki.sunet.se/display/sunetops/Platform+naming+standards $my_fqdn = $facts['networking']['fqdn'] $dot_split = split($my_fqdn, '[.]') $my_hostname = $dot_split[0] $dash_split = split($my_hostname,'[-]') $location = $dash_split[1] $environment = $dash_split[2] sunet::nftables::allow { 'allow-step-ca-acme': from => '89.45.237.248', # internal-sto3-test-ca-1.cdn.sunet.se port => 80, proto => 'tcp', } # Get client cert for connecting to MQTT bus exec { "certbot certonly -n --email patlu@sunet.se --no-eff-email --agree-tos --standalone -d ${my_fqdn} --server ${acme_url[$environment]} --http-01-address ${facts['networking']['ip']}": creates => "/etc/letsencrypt/live/${my_fqdn}/fullchain.pem" } $sunet_cdnp_dir = '/var/lib/sunet-cdnp' $sunet_cdnp_file = "sunet-cdnp_${sunet_cdnp_version}_linux_${facts[os][architecture]}.tar.gz" $sunet_cdnp_url = "https://github.com/SUNET/sunet-cdnp/releases/download/v${sunet_cdnp_version}/${sunet_cdnp_file}" # Create directory for managing CDP purger file { $sunet_cdnp_dir: ensure => directory, owner => 'root', group => 'root', mode => '0755', } exec { "curl -LO ${sunet_cdnp_url}": creates => "${sunet_cdnp_dir}/${sunet_cdnp_file}", cwd => $sunet_cdnp_dir, notify => Exec['extract sunet-cdnp'], } exec { 'extract sunet-cdnp': command => "tar -xzf ${sunet_cdnp_file} sunet-cdnp", cwd => $sunet_cdnp_dir, refreshonly => true, } file { "${sunet_cdnp_dir}/sunet-cdnp": owner => 'root', group => 'root', mode => '0755', } file { '/usr/local/bin/sunet-cdnp': ensure => link, target => "${sunet_cdnp_dir}/sunet-cdnp", } file { '/etc/systemd/system/sunet-cdnp.service': ensure => file, owner => 'root', group => 'root', mode => '0644', content => template('cdn/cache/sunet-cdnp.service.erb'), notify => [Class['sunet::systemd_reload']], } service { 'sunet-cdnp': ensure => 'running', enable => true, } if $cache_secrets { $customers.each |String $customer, Integer $customer_uid| { if $cache_secrets['customers'][$customer] { file { "/opt/sunet-cdn/customers/${customer}": ensure => directory, owner => $customer_uid, group => $customer_uid, mode => '0750', } file { "/opt/sunet-cdn/customers/${customer}/conf": ensure => directory, owner => $customer_uid, group => $customer_uid, mode => '0750', } file { "/opt/sunet-cdn/customers/${customer}/shared": ensure => directory, owner => $customer_uid, group => $customer_uid, mode => '0750', } file { "/opt/sunet-cdn/customers/${customer}/cache": ensure => directory, owner => $customer_uid, group => $customer_uid, mode => '0750', } file { "/opt/sunet-cdn/customers/${customer}/certs-private": ensure => directory, owner => $customer_uid, group => $customer_uid, mode => '0750', } $combined_pem = "/opt/sunet-cdn/customers/${customer}/certs-private/combined.pem" concat { $combined_pem: ensure => present, owner => $customer_uid, group => $customer_uid, mode => '0640', } concat::fragment { "${customer}-fullchain-${cache_secrets['customers'][$customer]['host']}": target => $combined_pem, source => "/opt/certbot-sync/letsencrypt/live/${cache_secrets['customers'][$customer]['host']}/fullchain.pem", order => '01', } concat::fragment { "${customer}-privkey-${cache_secrets['customers'][$customer]['host']}": target => $combined_pem, source => "/opt/certbot-sync/letsencrypt/live/${cache_secrets['customers'][$customer]['host']}/privkey.pem", order => '02', } file { "/opt/sunet-cdn/customers/${customer}/conf/haproxy.cfg": ensure => file, owner => $customer_uid, group => $customer_uid, mode => '0440', content => template('cdn/cache/haproxy.cfg.erb'), } file { "/opt/sunet-cdn/customers/${customer}/conf/varnish.vcl": ensure => file, owner => $customer_uid, group => $customer_uid, mode => '0440', content => template('cdn/cache/varnish.vcl.erb'), } sunet::docker_compose { "sunet-cdn-cache-${customer}": content => template('cdn/cache/docker-compose.yml.erb'), service_name => "cdn-cache-${customer}", compose_dir => "/opt/sunet-cdn/compose/${customer}", compose_filename => 'docker-compose.yml', description => "SUNET CDN CA ${customer}", } } } } }