Compare commits

...

195 commits

Author SHA1 Message Date
5489eeeb7a
Use correct output filename 2025-03-31 17:29:35 +02:00
39e1db9c32
Add basic firewall setup for l4lb namespace
Also teach sunet-l4lb-namespace to load the nft ruleset if it exists.
While here modify the script so instead of running "once per netns
config file" we merge the interface config from each json file into the
same dict per namespace. Without this we would attempt to load the nft
ruleset twice (once per file that mentioned the namespace) or warn twice
if the file did not exist etc.
2025-03-31 17:19:29 +02:00
f7dd464ed7
l4lb: install conntrack
Useful for veryfing what traffic is creating state.
2025-03-30 08:39:16 +02:00
db2b4ca409
Update sunet-l4lb-namespace
Make it able to delete addresses that are no longer in the netns config.
Also make it read one netns-base.json for hardware config which is
managed by puppet but also make it look for netns-sunet-cdn-agent.json
which is not created by puppet. This file will be generated by
sunet-cdn-agent and will include the configuration for dummy0.
2025-03-19 12:35:21 +01:00
f638e4c6f4
Update to latest sunet-cdnp 2025-03-17 22:36:55 +01:00
c386349271
cdn db init: secure schema usage
Trying to run goose for creating database contents failed:
```
2024/11/14 11:59:13 goose run: failed to ensure DB version: ERROR: permission denied for schema public (SQLSTATE 42501)
```

This seems to be because PostgreSQL 15 removed the default CREATE
permission in the public schema for users other than the database owner.

Instead we create a user-specific schema owned by that same user and
leave the public schema unused.
2024-11-14 13:01:06 +01:00
29c81d13a0
Expose postgres at standard port 2024-11-14 12:14:18 +01:00
cb46a3b6fb
Expose postgres port 2024-11-14 12:12:50 +01:00
58dc985e12
Update cdn password 2024-11-13 16:06:13 +01:00
dc7bf71dd9
No need to escape single quites in here-doc 2024-11-13 16:04:17 +01:00
f1b4d5ad07
Fix path typo 2024-11-13 14:59:59 +01:00
7a91f6df19
Properly ensure files 2024-11-13 14:54:33 +01:00
206e450c99
Add init script for setting up cdn database 2024-11-13 14:52:17 +01:00
3cc1b602fd
Add cdn user password 2024-11-13 14:35:18 +01:00
61f47320a7
Use named volume for persistence 2024-11-13 13:52:26 +01:00
b121790b77
Fix password variable 2024-11-13 13:39:42 +01:00
17219fd226
Install dockerhost2 on db machine 2024-11-13 13:35:15 +01:00
728ed4126f
Fix naming for db compose file 2024-11-13 13:33:18 +01:00
c82df547ee
Merge remote-tracking branch 'multiverse/main' 2024-11-13 13:31:39 +01:00
85afb706ed
Add initial support for handling a DB server
Used to store varnish config etc
2024-11-13 13:27:58 +01:00
78894e7500
internal-sto3-test-db-1.cdn.sunet.se added 2024-11-12 17:14:20 +01:00
e7efc59870
Update cdnp to v0.0.6 2024-11-12 16:59:08 +01:00
f27eb9c07d
Update cdnp to v0.0.5 2024-11-12 16:47:17 +01:00
0447b7b106
Restart sunet-cdnp if extracting new version 2024-11-12 16:31:29 +01:00
56b16a6d44
Update cdnp to v0.0.4 2024-11-12 16:28:52 +01:00
da099a5e53
Make sure cdnp is running 2024-11-12 10:31:23 +01:00
6d6f1b632d
Add "," 2024-11-12 10:19:11 +01:00
2e49e12c70
Start creating sunet-cdnp unit file 2024-11-12 10:11:03 +01:00
dba0e2e107
Test firewall config 2024-11-11 15:37:59 +01:00
0a61c8ad28
Update sunet-cdnp to v0.0.3 2024-11-08 09:41:14 +01:00
91fe726b61
Update sunet-cdnp to v0.0.2 2024-11-08 08:45:53 +01:00
f0eed8e804
Revert "Test updated certbot sync script"
This reverts commit 57b1700759.
2024-11-07 12:42:44 +01:00
9a73d8bdfe
Improve comment 2024-11-07 12:41:43 +01:00
1164b59747
Install tool for managing ACME provisioner 2024-11-07 12:41:14 +01:00
f07e6708e3
Another update of certbot-sync dir 2024-11-05 15:37:05 +01:00
8cd801bd64
Replace cp+chown with install 2024-11-05 14:45:37 +01:00
0461a8f0b8
mqtt: fix certfile usage
Use fullchain.pem instead of cert.pem which fixes "certificate signed by
unknown authority" problems.
Also point cafile to correct root cert.
2024-11-05 14:39:13 +01:00
a858a1973f
Sync dc and hostname 2024-11-04 12:34:38 +01:00
80df8d10ff
Add real client contents to mqtt server 2024-11-04 12:02:25 +01:00
3413446ce4
Less stuttering in variable naming 2024-11-04 11:58:15 +01:00
efa269ab33
Add back $clients
Should not have been removed in last commit
2024-11-04 11:56:00 +01:00
a71a8f5639
mqtt: open local firewall for any clients 2024-11-04 11:52:31 +01:00
9cee243af6
Allow ACME validation from step-ca to cache 2024-11-04 09:39:02 +01:00
e5a23593bf
Apply IP-specific certbot command to cache instead 2024-11-04 09:31:50 +01:00
6f2dd2df0f
Revert "Only bind certbot to machine-specific IP"
Incorrectly applied to MQTT class, was supposed to be done for cache servers.

This reverts commit b4261094a7.
2024-11-04 09:30:39 +01:00
b4261094a7
Only bind certbot to machine-specific IP
Because there will be haproxy instances running next to this service we
can only listen to the machine-local address not the default of "all addreses":

Error seen:
```
Could not bind TCP port 80 because it is already in use by another process on this system (such as a web server). Please stop the program in question and then try again.
```
2024-11-04 09:26:42 +01:00
d4f938770a
Get internal cert for hostname
Used for client cert auth to MQTT server
2024-11-04 09:14:42 +01:00
101f11fdad
Use new synced certbot dir 2024-11-01 14:38:04 +01:00
57b1700759
Test updated certbot sync script 2024-11-01 14:21:29 +01:00
a9fd90efb7
Add cache-2 ipv6 address to cert sync server 2024-11-01 14:07:41 +01:00
a39f5cdbae
Remove "command" and fix indent 2024-10-31 15:39:11 +01:00
ca94d62c62
Make sure root owns sunet-cdnp binary 2024-10-31 15:38:17 +01:00
740c5d29c1
Missing "," 2024-10-31 15:35:44 +01:00
48d9866a7c
Call tar from command to make notify simpler 2024-10-31 15:33:48 +01:00
0ad91d34d1
Missing "," 2024-10-31 15:30:36 +01:00
e15225d1b5
Extract sunet-cdnp and create symlink in PATH
Store files in /var/lib/sunet-cdnp instead of /root
2024-10-31 15:26:08 +01:00
19aa10dc05
Missing "," 2024-10-31 12:56:33 +01:00
395e67c918
Download CDN purger to cache 2024-10-31 12:55:07 +01:00
196c1403e6
Allow decapsulated ip6ip6 packets 2024-10-30 09:25:12 +01:00
41298df063
Setup interface for ip6ip6 tunneling
Running into systemd-networkd bugs, don't be fooled by "Local=::1" and
"Remote=::1". This still results in the equivalent of setting them to
'any' or '::' because we are using the default interface name.
2024-10-29 17:01:46 +01:00
2ad7073858
Fix name 2024-10-29 14:23:34 +01:00
0b3e9c48ff
Add nftables rule for ip6tnl packets 2024-10-29 14:21:34 +01:00
bd055b1ac8
Run puppet-lint 2024-10-29 08:30:49 +01:00
c4b9bef3c5
Set net.ipv4.vs.sloppy_tcp=1
Needed if taking over packets for a connection that was established via
another node.
2024-10-29 08:29:21 +01:00
c93846d03b
Use @ 2024-10-28 13:35:55 +01:00
c7b74c27fc
Use fact that exists 2024-10-28 13:34:59 +01:00
6a8671fa3e
Add import filters for bgp 2024-10-28 13:26:13 +01:00
7dc787cb68
Less indentation 2024-10-28 13:22:53 +01:00
af96f5e985
Manage bird.conf on l4lb machines
Currently just add basic template
2024-10-28 13:18:59 +01:00
fb956e4198
Add basic dummy0 interface 2024-10-25 15:28:03 +02:00
5d60c2dd02
Move template to correct location 2024-10-25 15:23:49 +02:00
e2d550bf29
Start managing bird2
Also give dummy-interface support to sunet-l4lb-namespace tool, used
to hold IPv4/IPv6 service addresses that should be announced via BGP.
2024-10-25 15:19:21 +02:00
d632aaca5c
Update script to use new conf path 2024-10-22 17:12:56 +02:00
4856be3f06
Rework dir layout to match other hosts 2024-10-22 17:11:58 +02:00
f588078b75
Add namespace management files 2024-10-22 17:06:29 +02:00
74c0bf76a1
Fix type name 2024-10-22 15:23:03 +02:00
1ddf93c330
Disable cilium by default
We will go for IPVS for now which can deal with the l4lb hosts being
multihomed.
2024-10-22 15:20:09 +02:00
272be292ad
Revert "Test chrony branch"
This reverts commit c15070dd28.
2024-10-22 14:22:39 +02:00
57dcae2cdf
Merge pull request #57 from SUNET/patlu-no-ntp
Do not install ntp with cosmos script
2024-10-21 08:23:46 +02:00
19c864cb77
Manage ntp with sunet::server again 2024-10-18 15:23:26 +02:00
c15070dd28
Test chrony branch 2024-10-18 15:21:48 +02:00
f537508bee
Do not install ntp with cosmos script
This is handled with sunet::server
2024-10-17 16:36:45 +02:00
7286dec3ff
Make sure X-Forwarded-Proto is set
Needed to cache http and https responses separately via Vary header
2024-10-15 16:29:31 +02:00
ad66745a90
Missing " 2024-10-13 14:32:42 +02:00
4f2428575c
Fix name 2024-10-13 14:31:23 +02:00
b018c81f81
cache: initial rules to allow traffic from l4lb 2024-10-13 14:28:50 +02:00
4bf6b2d79b
Enable certbot sync for cache-2 2024-10-13 11:28:00 +02:00
dad7f50195
Add secrets for cache-2 2024-10-13 11:12:52 +02:00
0aae7f3504
internal-sto3-test-cache-2.cdn.sunet.se added 2024-10-13 11:02:39 +02:00
37ad05ca6b
Missing [ 2024-10-11 22:12:05 +02:00
ca7fbbe945
Combine networkctl reload command 2024-10-11 22:10:50 +02:00
d289ffa656
Add config for ipip interface
Supplying an empty .network file is weird but without it the tunl0
interface is left in a DOWN state even with Independent=true.

Maybe this is related to "tunl0" being automatically created when the
"ipip" kernel module is loaded.
2024-10-11 22:05:11 +02:00
cb50714f4f
Rename remaining file 2024-10-11 22:00:37 +02:00
44c73b78ae
Prefix files with numbers as recommended by docs
See "systemd.netdev" docs.
2024-10-11 21:57:59 +02:00
382214ef2b
Make puppet-lint happy 2024-10-11 20:04:13 +02:00
3e393a62f9
Add '' 2024-10-11 19:05:29 +02:00
a82798ead5
Add network reload support 2024-10-11 19:04:17 +02:00
fe428a9e74
Also include cidr suffix 2024-10-11 18:57:10 +02:00
b5d9682e01
This is a hash 2024-10-11 18:55:39 +02:00
637e2ae307
Add address config for dummy interface 2024-10-11 18:52:53 +02:00
1e8cad6ea0
Add dummy0 interface
The netplan version we have is too old to do this so handle it manually.
2024-10-11 18:45:54 +02:00
eb49f13c49
Fix backend name 2024-10-11 18:14:30 +02:00
8227300a34
Enclose ipv6 addresses in [] 2024-10-11 14:00:23 +02:00
4d7283e361
Allow haproxy to bind to ports 80/443
This way we can run haproxy as an unprivileged user and still use what
is normally considered privileged ports.
2024-10-11 13:49:04 +02:00
1247c7f0be
Use hiera data for ip4/ip6 2024-10-11 12:03:24 +02:00
498ee6d2f1
Add ip4 and ip6 addresses for service config 2024-10-11 12:00:36 +02:00
7402f8cfc1
More tweaks 2024-10-11 11:51:36 +02:00
5185b62431
Syntax fixes 2024-10-11 11:47:44 +02:00
31d7a3c93a
puppet-lint fixes 2024-10-11 11:46:06 +02:00
ca9f7fbe50
Replace "." with ","
While here fix some variable usage and puppet-lint complaints
2024-10-11 11:42:12 +02:00
88e3771f6e
Install certificate files 2024-10-11 11:38:58 +02:00
3df9990cdc
Fix option string 2024-10-11 10:52:59 +02:00
50b0865434
Point out sync server 2024-10-11 10:37:13 +02:00
b635ce3793
Move keys from eyaml to yaml
Also inclide ip list
2024-10-11 09:54:58 +02:00
4fd59a194b
Add sync server config for cache-1 2024-10-11 09:48:25 +02:00
4e276ed613
Add pubkey for cert sync 2024-10-11 09:45:31 +02:00
d2c61200db
Add certbot_sync_client_ssh_key 2024-10-11 09:41:33 +02:00
aa5788f34a
Make cache hosts a certbot sync client 2024-10-11 08:41:24 +02:00
c860812f2a
Apply certbot class to cs hosts 2024-10-11 08:38:29 +02:00
ad61c8e23c
Update host to match cert 2024-10-10 21:38:35 +02:00
894c416b22
Apply acmed class to cs hosts 2024-10-10 21:33:30 +02:00
8b487ecdab
Use cert name in cdn subdomain 2024-10-10 21:27:42 +02:00
c9525d6200
Add cert entry 2024-10-10 21:26:18 +02:00
43aa005c26
internal-sto3-test-cs-1.cdn.sunet.se added 2024-10-10 21:14:58 +02:00
747059cd92
Missing " 2024-10-10 20:44:23 +02:00
ff6376b68d
Add basic varnish VCL for testing 2024-10-10 20:39:35 +02:00
efa9455fe9
Add key 2024-10-10 20:34:10 +02:00
33bebd7627
Add host key 2024-10-10 20:32:10 +02:00
802e9a1389
Fix erb iteration 2024-10-10 15:45:58 +02:00
bacdb2c90a
Make sure customer conf dir is created 2024-10-10 15:31:54 +02:00
170bdbc154
Missing $ 2024-10-10 15:29:50 +02:00
26f583c41a
Fix manifest name 2024-10-10 15:28:23 +02:00
4b1f93c08a
Add missing $ 2024-10-10 15:27:06 +02:00
cf51469fae
Apply cdn::cache to cache nodes 2024-10-10 15:25:12 +02:00
d0a19691aa
Initial cdn::cache manifest 2024-10-10 15:22:11 +02:00
b2de8d246b
Start installing docker on cache machines 2024-10-10 11:01:28 +02:00
feae7e8e26
internal-sto3-test-cache-1.cdn.sunet.se added 2024-10-10 10:53:52 +02:00
254a3f107e
Quote some variables to make shellcheck happy 2024-10-10 10:38:45 +02:00
7001a3fab6
Remove trailing "/" in dir path 2024-10-10 10:36:00 +02:00
d38ef1b1ce
Remove bridges for now 2024-10-10 10:27:41 +02:00
5d05e596c0
Cleanup ":" 2024-10-10 10:24:31 +02:00
563886294b
Fix template 2024-10-10 10:23:55 +02:00
d78d8c22b1
Make sure we trust internal cdn CA 2024-10-10 10:19:00 +02:00
b44fb5ce43
Update key paths to reflect internal CA 2024-10-10 10:17:39 +02:00
65fc0590b4
Add certbot deploy script for mosquitto 2024-10-10 10:13:04 +02:00
b9266ec0e7
Start requesting ACME certs from internal CA 2024-10-09 12:13:30 +02:00
8f8c360c69
Use environment instead of instance 2024-10-09 11:59:51 +02:00
c09f81afbf
Fix type declaration
```
Error: Evaluation Error: Error while evaluating a Resource Statement, Class[Cdn::Ca_trust]:
  parameter 'ca_root_fp' entry 'test' entry 'url' expects a Hash value, got String
  parameter 'ca_root_fp' entry 'test' entry 'fp' expects a Hash value, got String on node internal-sto3-test-mqtt-1.cdn.sunet.se
```

Also rename variable now that it contains more than fingerprint
2024-10-09 11:53:52 +02:00
1ef179cad2
Fix broken file declaration
While here make puppet-lint happy
2024-10-09 11:50:34 +02:00
1dcc58d991
Apply trust class to mqtt 2024-10-09 11:47:53 +02:00
ab3c08c5e1
Add class for setting up trust of internal CA 2024-10-09 11:46:28 +02:00
d1b0694e44
Also set --admin-provisioner=admin
Without this the commands will hang for input to select a provisioner.
This is needed now that we have enabled a second (the ACME) provisioner
on init.
2024-10-08 21:45:17 +02:00
22a2029cf9
Enable ACME provisioner at init 2024-10-08 16:50:46 +02:00
6354f6faaa
Test opening port 80 for certbot operation 2024-10-08 16:38:11 +02:00
fe04d862e3
Move script to correct location 2024-10-08 14:12:48 +02:00
8d4d1841c4
Bootstrap step client 2024-10-08 14:09:44 +02:00
44001514de
Missing "," 2024-10-08 13:42:14 +02:00
a4a5a44647
Install step-cli from deb 2024-10-08 13:40:54 +02:00
1cfbc3e908
Make puppet-lint happy with indent 2024-10-08 13:36:21 +02:00
49ff235bc4
Download step client deb file 2024-10-08 13:33:32 +02:00
aca8dd1b22
Add file to correct location 2024-10-08 13:12:54 +02:00
d9db9fee72
Add init script for setting provisioner file
This is to deal with the problem that it makes sense to have a separate
passsword for encryption keys and the admin provisioner. It is currently
not possible to control this via the docker env flags so add this
workaround for now.
2024-10-08 12:35:41 +02:00
d1c863c7cb
Expose the step-ca port 2024-10-08 10:09:20 +02:00
d46d54a6a6
Enable compose file 2024-10-08 10:04:32 +02:00
1803d1c69a
Add initial compose file for step-ca 2024-10-08 10:02:48 +02:00
828f9a899d
Fix templates for passwords 2024-10-08 09:51:08 +02:00
fa484c7d2f
Add ca secrets 2024-10-08 09:47:51 +02:00
f247388664
Trust maria
Copied from cnaas-ops
2024-10-08 09:41:09 +02:00
9379ba58e2
Handle undef ca_secrets more gracefully 2024-10-08 09:39:09 +02:00
61a4ec13e3
Start setting up step-ca files 2024-10-08 09:36:04 +02:00
e02160a311
Initial cdn::ca class 2024-10-07 08:35:00 +02:00
9f05f40714
Install docker on ca machines 2024-10-06 15:37:33 +02:00
49106049ff
Start using cdn.conf template 2024-10-06 14:51:55 +02:00
e5ce5dd1cd
Start managing cdn.conf 2024-10-06 14:50:07 +02:00
40036c3c32
Fix variable usage 2024-10-06 14:44:32 +02:00
52469c754d
Correct path 2024-10-06 14:32:17 +02:00
4b90469531
Missing $ 2024-10-06 14:30:51 +02:00
0c5e2604b6
Add missing clients parameter 2024-10-06 14:29:48 +02:00
7352a20143
Start managing mqtt ACL
Include sample comsos-rules entry for testing out template
2024-10-06 14:26:10 +02:00
6664c9c356
internal-sto3-test-ca-1.cdn.sunet.se added 2024-10-06 08:32:52 +02:00
2099c4d691
Fix class name 2024-10-04 17:43:31 +02:00
c638772941
Apply mqtt class 2024-10-04 17:41:59 +02:00
152179a5c1
Initial commit for mqtt management 2024-10-04 17:33:49 +02:00
895264bc4f
Trust kano
Copied from platform-ops
2024-10-04 17:18:09 +02:00
febde032ee
Update to new key standard 2024-10-04 17:16:23 +02:00
ca3e6b211d
internal-sto3-test-mqtt-1.cdn.sunet.se added 2024-10-04 17:07:50 +02:00
571af24060
Make seccomp file readable by runner 2024-10-04 09:22:05 +02:00
05ee26e7c2
Make docker_certs available to runner 2024-10-03 21:04:17 +02:00
48d3b890d0
Use owner/group matching runner compose file 2024-10-03 20:57:28 +02:00
284bc65dbe
Update secret 2024-10-03 20:48:20 +02:00
d1d72ad80a
Try to access map correctly 2024-10-03 20:42:39 +02:00
25a18fd58b
Remove extra dot 2024-10-03 20:15:39 +02:00
Patrik Holmqvist
028ba3d608
Merge pull request #56 from SUNET/pahol-fix-noble-eyaml
patch for broken eyaml in ubuntu24.04.
2024-09-10 13:16:19 +02:00
7941e3f970
Merge the 2 patch functions to 1. 2024-09-09 17:29:31 +02:00
fac9a556ba
Patch for broken eyaml in ubuntu24.04. 2024-09-09 16:52:38 +02:00
67 changed files with 2862 additions and 91 deletions

View file

@ -67,6 +67,39 @@ function patch_broken_eyaml {
next if @@plugins.include? spec
dependency = spec.dependencies.find { |d| d.name == "hiera-eyaml" }
EOF
fi
fi
fi
#
# Ubuntu 24.04 (noble) has a hiera-eyaml version that is incompatible with ruby 3.2+ (default in ubuntu24).
# This is fixed in hiera-eyaml version 3.3.0: https://github.com/voxpupuli/hiera-eyaml/pull/340/files
# https://github.com/voxpupuli/hiera-eyaml/blob/master/CHANGELOG.md
# But there is no modern version of hiera-eyaml packaged in debian or ubuntu.
# https://github.com/puppetlabs/puppet/wiki/Puppet-8-Compatibility#filedirexists-removed
#
. /etc/os-release
if [ "${VERSION_CODENAME}" == "noble" ]; then
plugins_file="/usr/share/rubygems-integration/all/gems/hiera-eyaml-3.3.0/lib/hiera/backend/eyaml/subcommands/edit.rb"
if [ -f $plugins_file ]; then
# We only want to try patching the file if it is the known broken version
bad_sum="59c6eb910ab2eb44f8c75aeaa79bff097038feb673b5c6bdccde23d9b2a393e2"
sum=$(sha256sum $plugins_file | awk '{print $1}')
if [ "$sum" == "$bad_sum" ]; then
patch --fuzz=0 --directory=/ --strip=0 <<'EOF'
--- /usr/share/rubygems-integration/all/gems/hiera-eyaml-3.3.0/lib/hiera/backend/eyaml/subcommands/edit.rb.orig 2022-06-11 16:30:10.000000000 +0000
+++ /usr/share/rubygems-integration/all/gems/hiera-eyaml-3.3.0/lib/hiera/backend/eyaml/subcommands/edit.rb 2024-09-09 14:13:19.306342025 +0000
@@ -59,7 +59,7 @@
Optimist::die "You must specify an eyaml file" if ARGV.empty?
options[:source] = :eyaml
options[:eyaml] = ARGV.shift
- if File.exists? options[:eyaml]
+ if File.exist? options[:eyaml]
begin
options[:input_data] = File.read options[:eyaml]
rescue
EOF
fi
fi

View file

@ -1,75 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
mhxC7iIM
=w3OF
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -0,0 +1,86 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=GNcK
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -0,0 +1,105 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=wtzC
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -6,12 +6,38 @@
disable_ipv6_privacy: true
disable_all_local_users: true
install_scriptherder: true
ntpd_config: false
ntpd_config: true
'^cdn-prod-l4lb-[0-9]+.sunet.se$':
sunet::dockerhost2:
cdn::l4lb:
'^internal-.+-test-runner-[0-9]+.\.cdn\.sunet\.se$':
'^internal-.+-test-runner-[0-9]+\.cdn\.sunet\.se$':
sunet::dockerhost2:
cdn::runner:
'^internal-.+-test-mqtt-[0-9]+\.cdn\.sunet\.se$':
cdn::ca_trust:
cdn::mqtt:
dc: sto3
clients:
- internal-sto3-test-cache-2.cdn.sunet.se
client_ips:
- 192.36.171.94 # internal-sto3-test-cache-2.cdn.sunet.se
'^internal-.+-test-ca-[0-9]+\.cdn\.sunet\.se$':
sunet::dockerhost2:
cdn::ca:
'^internal-.+-test-cache-[0-9]+\.cdn\.sunet\.se$':
sunet::dockerhost2:
cdn::cache:
sunet::certbot::sync::client:
'^internal-.+-test-cs-[0-9]+\.cdn\.sunet\.se$':
sunet::certbot::acmed:
sunet::certbot::sync::server:
'^internal-.+-test-db-[0-9]+\.cdn\.sunet\.se$':
sunet::dockerhost2:
cdn::db:

View file

@ -0,0 +1,5 @@
#!/bin/bash
# Create /root/.step, executed by puppet
CA_FINGERPRINT=$(step certificate fingerprint /opt/step-ca/data/certs/root_ca.crt)
step ca bootstrap --ca-url https://localhost:9000 --fingerprint "$CA_FINGERPRINT"

View file

@ -0,0 +1,17 @@
#!/bin/bash
# When initializing step-ca with the docker flag DOCKER_STEPCA_INIT_ACME
# a basic ACME provisioner is enabled. This script runs commands to modify the
# default configuration.
# Enable forceCN if not set.
# This is needed because certbot does not include a
# Subject CN field in the CSR:
# https://github.com/certbot/certbot/issues/9633#issuecomment-1484988078
# ... and the Mosquitto MQTT server uses the Subject CN in ACL filters.
#
# Ideally Mosquitto would learn to look at the SAN field instead:
# https://github.com/eclipse-mosquitto/mosquitto/issues/2511
if [ "$(step ca provisioner list | jq -r '.[] | select (.name == "acme") | .forceCN')" = "null" ]; then
step ca provisioner update acme --force-cn --admin-subject=step --admin-provisioner=admin --admin-password-file=/opt/step-ca/init/secrets/provisioner-password
fi

View file

@ -0,0 +1,36 @@
#!/bin/bash
# When initializing step-ca with the docker flag
# DOCKER_STEPCA_INIT_PASSWORD_FILE the password will be used both for key
# encryption as well as the admin "step" provisioner. If not using that flag a
# separate password will be generated for each usage. This seems better as you
# are not typing the encryption password any other time, while the provisioner
# password is used anytime you are managing things.
#
# This script is used on first setup of step-ca to modify the provisioner to
# use its own password instead. Pending
# https://github.com/smallstep/cli/pull/1294 you need to supply the new
# password by hand, see below for the commented out command.
# If we detect that the key-password is still valid for the provisioner change it.
if step ca admin list --admin-subject=step --admin-provisioner=admin --admin-password-file=/opt/step-ca/init/secrets/key-password > /dev/null 2>&1; then
echo "admin provisioner still using encryption key password, changing it"
# Change the provisioner password
# https://smallstep.com/docs/step-ca/provisioners/#changing-a-jwk-provisioner-password
OLD_ENCRYPTED_KEY=$(step ca provisioner list | jq -r '.[] | select(.name == "admin").encryptedKey')
# Unfortunately not possible to supply --password-file to "crypto jwe encrypt" yet, pending https://github.com/smallstep/cli/pull/1294
#ENCRYPTED_KEY=$(echo $OLD_ENCRYPTED_KEY | step crypto jwe decrypt --password-file /opt/step-ca/init/secrets/key-password | step crypto jwe encrypt --alg PBES2-HS256+A128KW --password-file /opt/step-ca/init/secrets/provisioner-password | step crypto jose format)
ENCRYPTED_KEY=$(echo "$OLD_ENCRYPTED_KEY" | step crypto jwe decrypt --password-file /opt/step-ca/init/secrets/key-password | step crypto jwe encrypt --alg PBES2-HS256+A128KW | step crypto jose format)
step ca provisioner update admin --private-key=<(echo -n "$ENCRYPTED_KEY") --admin-subject=step --admin-provisioner=admin --admin-password-file=/opt/step-ca/init/secrets/key-password
# Now verify that we can use the expected password for the admin provisioner
if ! step ca admin list --admin-subject=step --admin-provisioner=admin --admin-password-file=/opt/step-ca/init/secrets/provisioner-password > /dev/null 2>&1; then
echo "tried updating provisioner password but it does not work!"
exit 1
fi
else
echo "admin provisioner not using encryption key password, doing nothing"
fi

View file

@ -0,0 +1,43 @@
#!/bin/bash
set -eu
step_ca_url=$1
#step_ca_url='https://internal-sto3-test-ca-1.cdn.sunet.se:9000'
expected_root_fp=$2
root_ca_url="$step_ca_url/root/$expected_root_fp"
root_ca_name='step_ca_root.crt'
root_ca_path="/usr/local/share/ca-certificates/$root_ca_name"
current_root_fp=''
if [ -f "$root_ca_path" ]; then
current_root_fp=$(openssl x509 -in $root_ca_path -fingerprint -sha256 -noout | awk -F= '{print $2}' | sed 's/://g' | tr '[:upper:]' '[:lower:]')
fi
if [ -n "$current_root_fp" ] && [ "$current_root_fp" = "$expected_root_fp" ]; then
echo "$root_ca_path: correct fingerprint"
exit 0
fi
tmp_dir=$(mktemp -d)
tmp_root_path=$tmp_dir/$root_ca_name
# We are deliberatly running curl with -k here. We can not trust the
# connection before we have the root cert, and the goal is to fetch that root
# cert. Security is attained by validating the fingerprint of the downloaded
# cert prior to installing it.
curl -ks $root_ca_url | jq -j .ca > $tmp_root_path
tmp_fp=$(openssl x509 -in $tmp_root_path -fingerprint -sha256 -noout | awk -F= '{print $2}' | sed 's/://g' | tr '[:upper:]' '[:lower:]')
if [ "$tmp_fp" = "$expected_root_fp" ]; then
echo "$root_ca_path: installing validated file"
mv -v $tmp_root_path $root_ca_path
# Make OS pick up the new cert
update-ca-certificates
fi
# We expect the directory to be empty at this point so rmdir is safer than rm -rf
rmdir -v $tmp_dir

View file

@ -0,0 +1,25 @@
#!/bin/bash
set -e
# shellcheck source=/dev/null
. /conf/init-cdn-db.conf
# Create database named after user, then create a schema named the same as the
# user which is also owned by that user. Because search_path (SHOW
# search_path;) starts with "$user" by default this means any tables will be
# created in that user-specific SCHEMA by default instead of falling back to
# "public". This follows the "secure schema usage pattern" summarized as
# "Constrain ordinary users to user-private schemas" from
# https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATTERNS
#
# "In PostgreSQL 15 and later, the default configuration supports this usage
# pattern. In prior versions, or when using a database that has been upgraded
# from a prior version, you will need to remove the public CREATE privilege
# from the public schema"
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER cdn WITH PASSWORD '${cdn_password:?}';
CREATE DATABASE cdn;
GRANT ALL PRIVILEGES ON DATABASE cdn TO cdn;
\c cdn;
CREATE SCHEMA cdn AUTHORIZATION cdn;
EOSQL

View file

@ -0,0 +1,209 @@
#!/usr/bin/env python3
# pylint:disable=invalid-name
# pylint:enable=invalid-name
# pylint:disable=invalid-name
# pylint:enable=invalid-name
"""
netplan does not have network namespace support so configure by hand
Tools used before committing code:
black sunet-l4lb-namespace
isort sunet-l4lb-namespace
pylint sunet-l4lb-namespace
mypy --strict sunet-l4lb-namespace
"""
import ipaddress
import json
import os
import shlex
import subprocess
import sys
def run_command(cmd: str) -> subprocess.CompletedProcess[str]:
"""Execute subprocess command"""
print(f"{cmd}")
args = shlex.split(cmd)
try:
proc = subprocess.run(args, capture_output=True, check=True, encoding="utf-8")
except subprocess.CalledProcessError as exc:
stderr_str = exc.stderr.rstrip()
print(
f"command failed: cmd='{cmd}', rc={exc.returncode}, stderr='{stderr_str}'",
file=sys.stderr,
)
sys.exit(1)
return proc
def configure_interfaces( # pylint: disable=too-many-locals,too-many-branches
namespace: str, if_data: dict[str, dict[str, list[str]]]
) -> None:
"""Configure interfaces"""
proc = run_command(f"ip netns exec {namespace} ip -j addr show")
namespace_ifs = json.loads(proc.stdout)
ipv4_key = "ipv4"
ipv6_key = "ipv6"
for if_name, data in if_data.items():
if_exists = next(
(True for interface in namespace_ifs if interface["ifname"] == if_name),
False,
)
if not if_exists:
if if_name.startswith("dummy"):
run_command(
f"ip netns exec {namespace} ip link add {if_name} type dummy"
)
else:
run_command(f"ip link set {if_name} netns {namespace}")
run_command(f"ip netns exec {namespace} ip link set {if_name} up")
proc = run_command(f"ip netns exec {namespace} ip -j addr show dev {if_name}")
if_conf = json.loads(proc.stdout)
# Add missing addresses from config
if ipv4_key in data:
for configured_ipv4_cidr in data[ipv4_key]:
ip4, prefix = configured_ipv4_cidr.split("/")
v4_addr_exists = next(
(
True
for addr in if_conf[0]["addr_info"]
if addr["local"] == ip4 and addr["prefixlen"] == int(prefix)
),
False,
)
if not v4_addr_exists:
run_command(
f"ip netns exec {namespace} ip addr add {configured_ipv4_cidr} dev {if_name}" # pylint: disable=line-too-long
)
if ipv6_key in data:
for ipv6_cidr in data[ipv6_key]:
ip6, prefix = ipv6_cidr.split("/")
v6_addr_exists = next(
(
True
for addr in if_conf[0]["addr_info"]
if addr["local"] == ip6 and addr["prefixlen"] == int(prefix)
),
False,
)
if not v6_addr_exists:
run_command(
f"ip netns exec {namespace} ip addr add {ipv6_cidr} dev {if_name}"
)
# Remove no longer configured addresseses
for addr_info in if_conf[0]["addr_info"]:
# Ignore addresses like fe80
if addr_info["scope"] != "global":
continue
cidr = "/".join((addr_info["local"], str(addr_info["prefixlen"])))
# We need strict=False because otherwise ip_network() gets angry if
# there are host bits set in the address (which of course there is
# because we are parsing actual interface configs, not pure
# "networks")
cidr_net = ipaddress.ip_network(cidr, strict=False)
needs_removal = False
if cidr_net.version == 4:
if ipv4_key not in data or cidr not in data[ipv4_key]:
needs_removal = True
elif cidr_net.version == 6:
if ipv6_key not in data or cidr not in data[ipv6_key]:
needs_removal = True
else:
raise ValueError(
f"Expected IPv4 or IPv6, got something else: {cidr_net.version}"
)
if needs_removal:
run_command(
f"ip netns exec {namespace} ip addr del {cidr} dev {if_name}"
)
def setup_namespaces(netns_data: dict[str, dict[str, dict[str, list[str]]]]) -> None:
"""Setup network namespaces"""
proc = run_command("ip -j netns list")
existing_netns = json.loads(proc.stdout)
for namespace, if_data in netns_data.items():
netns_exists = next(
(True for netns in existing_netns if netns["name"] == namespace), False
)
if not netns_exists:
run_command(f"ip netns add {namespace}")
# Make localhost available
run_command(f"ip netns exec {namespace} ip link set lo up")
# (Re)load the nft ruleset for the given namespace
nft_ruleset = f"/opt/sunet-cdn/l4lb/conf/nft-{namespace}.conf"
if os.path.isfile(nft_ruleset):
run_command(f"ip netns exec {namespace} nft -f {nft_ruleset}")
else:
print(
f"WARNING: no nft ruleset found for namespace '{namespace}' ({nft_ruleset}), the namespace will not be firewalled" # pylint: disable=line-too-long
)
configure_interfaces(namespace, if_data)
def main() -> None:
"""Starting point of the program"""
# JSON file format:
# {
# "namespace1": {
# "interface1": {
# "ipv4": [
# "192.168.10.1/31"
# ],
# "ipv6": [
# "2001:db8:1337:74::1/127"
# ]
# },
# "interface2": {
# "ipv4": [
# "192.168.10.3/31"
# ],
# "ipv6": [
# "2001:db8:1338:75::1/127"
# ]
# }
# }
# }
input_files = [
"/opt/sunet-cdn/l4lb/conf/netns-base.json",
"/opt/sunet-cdn/l4lb/conf/netns-sunet-cdn-agent.json",
]
merged_netns_data: dict[str, dict[str, dict[str, list[str]]]] = {}
for input_file in input_files:
try:
with open(input_file, encoding="utf-8") as f:
netns_data = json.load(f)
# Combine interface config from multiple files belonging to the same namespace
for ns, ns_data in netns_data.items():
if ns in merged_netns_data:
merged_netns_data[ns].update(ns_data)
else:
merged_netns_data[ns] = ns_data
except FileNotFoundError:
print(f"skipping nonexistant file '{input_file}'")
continue
setup_namespaces(merged_netns_data)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,21 @@
#!/bin/bash
# Mosquitto is running with a user that is not privileged enough to read files
# directly from the certbot dirs, so copy files to where mosquitto expects
# them.
set -eu
le_dir="/etc/letsencrypt/live/$(hostname -f)"
mosquitto_dir="/etc/mosquitto"
le_fullchain="$le_dir/fullchain.pem"
mosquitto_fullchain="$mosquitto_dir/certs/fullchain.pem"
install -m 644 -o mosquitto -g root "$le_fullchain" "$mosquitto_fullchain"
le_key="$le_dir/privkey.pem"
mosquitto_key="$mosquitto_dir/certs/privkey.pem"
install -m 600 -o mosquitto -g root "$le_key" "$mosquitto_key"
# Tell mosquitto to reload certs
pkill -x -HUP mosquitto

View file

@ -0,0 +1,127 @@
# Configure a SUNET CDN CA server
class cdn::ca(
String $step_ca_version = '0.27.4',
)
{
$ca_secrets = lookup({ 'name' => 'cdn::ca-secrets', 'default_value' => undef })
file { '/opt/step-ca':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
# The owner/group matches the 'step' user in the step-ca container
file { '/opt/step-ca/data':
ensure => directory,
owner => '1000',
group => '1000',
mode => '0750',
}
# Files used for initial install of step-ca
file { '/opt/step-ca/init':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
file { '/opt/step-ca/init/secrets':
ensure => directory,
owner => '1000',
group => '1000',
mode => '0750',
}
file { '/opt/step-ca/init/scripts':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
file { '/opt/step-ca/init/scripts/set-provisioner-pw':
ensure => file,
owner => 'root',
group => 'root',
mode => '0755',
content => file('cdn/ca/set-provisioner-pw'),
}
file { '/opt/step-ca/init/scripts/bootstrap-client':
ensure => file,
owner => 'root',
group => 'root',
mode => '0755',
content => file('cdn/ca/bootstrap-client'),
}
file { '/opt/step-ca/init/scripts/configure-acme':
ensure => file,
owner => 'root',
group => 'root',
mode => '0755',
content => file('cdn/ca/configure-acme'),
}
file { '/opt/step-ca/init/deb':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
exec { 'curl -LO https://dl.smallstep.com/gh-release/cli/gh-release-header/v0.27.4/step-cli_0.27.4-1_amd64.deb':
cwd => '/opt/step-ca/init/deb',
creates => '/opt/step-ca/init/deb/step-cli_0.27.4-1_amd64.deb',
}
package {'step-cli':
ensure => present,
source => '/opt/step-ca/init/deb/step-cli_0.27.4-1_amd64.deb',
}
if $ca_secrets {
if $ca_secrets['key_password'] {
file { '/opt/step-ca/init/secrets/key-password':
ensure => file,
owner => '1000',
group => '1000',
mode => '0640',
content => template('cdn/ca/key-password.erb'),
}
}
if $ca_secrets['provisioner_password'] {
file { '/opt/step-ca/init/secrets/provisioner-password':
ensure => file,
owner => '1000',
group => '1000',
mode => '0640',
content => template('cdn/ca/provisioner-password.erb'),
}
}
}
sunet::nftables::docker_expose { 'expose step-ca' :
allow_clients => 'any',
port => 9000,
iif => $facts['networking']['primary'],
}
sunet::docker_compose { 'sunet-cdn-ca':
content => template('cdn/ca/docker-compose.yml.erb'),
service_name => 'cdn-ca',
compose_dir => '/opt/sunet-cdn/compose',
compose_filename => 'docker-compose.yml',
description => 'SUNET CDN CA',
}
exec { '/opt/step-ca/init/scripts/bootstrap-client':
creates => '/root/.step/config/defaults.json',
onlyif => 'test -f /opt/step-ca/data/certs/root_ca.crt'
}
}

View file

@ -0,0 +1,43 @@
# Configure a SUNET CDN CA server
class cdn::ca_trust(
Hash[String, Hash[String, String]] $ca_root = {
test => {
url => 'https://internal-sto3-test-ca-1.cdn.sunet.se:9000',
fp => '9c7cb4b835ad1ee2d63f903032208b245c82c38823b02a05c66a5b93c1d5e32d',
},
}
)
{
# Files for trusting internal CA
file { '/opt/cdn-ca-trust':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
file { '/opt/cdn-ca-trust/scripts':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
file { '/opt/cdn-ca-trust/scripts/trust-step-ca':
ensure => file,
owner => 'root',
group => 'root',
mode => '0755',
content => file('cdn/ca_trust/trust-step-ca'),
}
# 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,'[-]')
$environment = $dash_split[2]
exec { "/opt/cdn-ca-trust/scripts/trust-step-ca ${ca_root[$environment]['url']} ${ca_root[$environment]['fp']}":
}
}

View file

@ -0,0 +1,292 @@
# Configure a SUNET CDN CA server
class cdn::cache(
Hash[String, Integer] $customers = {
customer1 => 1000000000,
},
String $sunet_cdnp_version = '0.0.7',
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,
notify => Service['sunet-cdnp'],
}
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}",
}
}
}
}
}

View file

@ -0,0 +1,76 @@
# Configure a SUNET CDN DB server
class cdn::db(
String $postgres_version = '17.0-bookworm',
)
{
$db_secrets = lookup({ 'name' => 'cdn::db-secrets', 'default_value' => undef })
if $db_secrets {
file { '/opt/sunet-cdn':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
file { '/opt/sunet-cdn/compose':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0750',
}
file { '/opt/sunet-cdn/db':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0750',
}
# User/group 999 matches postgres user in container
file { '/opt/sunet-cdn/db/conf':
ensure => directory,
owner => '999',
group => '999',
mode => '0750',
}
file { '/opt/sunet-cdn/db/docker-entrypoint-initdb.d':
ensure => directory,
owner => '999',
group => '999',
mode => '0750',
}
file { '/opt/sunet-cdn/db/conf/init-cdn-db.conf':
ensure => file,
owner => '999',
group => '999',
mode => '0640',
content => template('cdn/db/init-cdn-db.conf.erb'),
}
file { '/opt/sunet-cdn/db/docker-entrypoint-initdb.d/init-cdn-db.sh':
ensure => file,
owner => '999',
group => '999',
mode => '0750',
content => file('cdn/db/init-cdn-db.sh'),
}
sunet::nftables::docker_expose { 'postgres-db' :
allow_clients => '127.0.0.1',
port => 5432,
iif => $facts['networking']['primary'],
}
sunet::docker_compose { 'sunet-cdn-db':
content => template('cdn/db/docker-compose.yml.erb'),
service_name => 'cdn-db',
compose_dir => '/opt/sunet-cdn/compose',
compose_filename => 'docker-compose.yml',
description => 'SUNET CDN DB',
}
}
}

View file

@ -1,14 +1,120 @@
# Configure the SUNET CDN l4lb service
class cdn::l4lb(
Boolean $cilium_enabled = false,
String $cilium_version = 'v1.16.1',
String $cilium_devices = 'enp129s0f1np1',
)
{
sunet::docker_compose { 'sunet-cdn-l4lb':
content => template('cdn/l4lb/docker-compose.yml.erb'),
service_name => 'cdn-l4lb',
compose_dir => '/opt/sunet-cdn/compose/l4lb',
compose_filename => 'docker-compose.yml',
description => 'SUNET CDN l4lb',
if $cilium_enabled {
sunet::docker_compose { 'sunet-cdn-l4lb':
content => template('cdn/l4lb/docker-compose.yml.erb'),
service_name => 'cdn-l4lb',
compose_dir => '/opt/sunet-cdn/compose/l4lb',
compose_filename => 'docker-compose.yml',
description => 'SUNET CDN l4lb',
}
}
include sunet::systemd_reload
package {'conntrack': ensure => installed }
package {'bird2': ensure => installed }
file { '/opt/sunet-cdn':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0640',
}
$sysctl_file = '/etc/sysctl.d/99-cdn-l4lb.conf'
file { $sysctl_file:
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
content => template('cdn/l4lb/sysctl.erb'),
}
# Load the sysctl file if it has changed
exec { "sysctl -p ${sysctl_file}":
subscribe => File[$sysctl_file],
refreshonly => true,
}
file { '/opt/sunet-cdn/l4lb':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0640',
}
file { '/opt/sunet-cdn/l4lb/conf':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0640',
}
file { '/opt/sunet-cdn/l4lb/conf/netns-base.json':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
content => template('cdn/l4lb/netns-base.json.erb'),
}
file { '/opt/sunet-cdn/l4lb/conf/nft-l4lb.conf':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
content => template('cdn/l4lb/nft-l4lb.conf.erb'),
}
file { '/usr/local/bin/sunet-l4lb-namespace':
ensure => file,
owner => 'root',
group => 'root',
mode => '0755',
content => file('cdn/l4lb/sunet-l4lb-namespace'),
}
file { '/etc/systemd/system/sunet-l4lb-namespace.service':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
content => template('cdn/l4lb/sunet-l4lb-namespace.service.erb'),
}
file { '/etc/systemd/system/bird.service.d':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
file { '/etc/systemd/system/bird.service.d/override.conf':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
content => template('cdn/l4lb/bird-override.conf.erb'),
notify => [Class['sunet::systemd_reload']]
}
file { '/etc/bird/bird.conf':
ensure => file,
owner => 'bird',
group => 'bird',
mode => '0640',
content => template('cdn/l4lb/bird.conf.erb'),
notify => Service['bird'],
}
service { 'bird':
ensure => 'running',
enable => true,
}
}

View file

@ -0,0 +1,65 @@
# Configure a SUNET CDN mqtt server
class cdn::mqtt(
String $dc = '',
Array[String] $clients = [],
Array[String] $client_ips = [],
Hash[String, Hash] $bridges = {},
Hash[String, String] $acme_url = {
test => 'https://internal-sto3-test-ca-1.cdn.sunet.se:9000/acme/acme/directory'
}
)
{
include sunet::packages::certbot
include cdn::ca_trust
package {'mosquitto': ensure => installed }
file { '/etc/mosquitto/aclfile':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
content => template('cdn/mqtt/aclfile.erb'),
}
file { '/etc/mosquitto/conf.d/cdn.conf':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
content => template('cdn/mqtt/cdn.conf.erb'),
}
sunet::nftables::allow { 'allow-step-ca-acme':
from => 'any',
port => 80,
proto => 'tcp',
}
$client_ips.each | String $client_ip | {
sunet::nftables::allow { "allow-acme-client-${client_ip}":
from => $client_ip,
port => 8883,
proto => 'tcp',
}
}
# 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,'[-]')
$environment = $dash_split[2]
file { '/etc/letsencrypt/renewal-hooks/deploy/sunet-cdn-mqtt':
ensure => file,
owner => 'root',
group => 'root',
mode => '0755',
content => file('cdn/mqtt/sunet-cdn-mqtt'),
}
exec { "certbot certonly -n --email patlu@sunet.se --no-eff-email --agree-tos --standalone -d ${my_fqdn} --server ${acme_url[$environment]}":
creates => "/etc/letsencrypt/live/${my_fqdn}/fullchain.pem"
}
}

View file

@ -13,17 +13,18 @@ class cdn::runner(
mode => '0750',
}
# The owner/group matches 'user' in compose file for runner
file { '/opt/forgejo-runner/data':
ensure => directory,
owner => 'root',
group => 'root',
owner => '1001',
group => '1001',
mode => '0750',
}
file { '/opt/forgejo-runner/data/seccomp.json':
ensure => file,
owner => 'root',
group => 'root',
group => '1001',
mode => '0640',
content => template('cdn/runner/seccomp.json.erb'),
}
@ -31,7 +32,7 @@ class cdn::runner(
file { '/opt/forgejo-runner/docker_certs':
ensure => directory,
owner => 'root',
group => 'root',
group => '1001',
mode => '0750',
}

View file

@ -0,0 +1,14 @@
services:
ca:
image: "smallstep/step-ca:<%= @step_ca_version %>"
volumes:
- /opt/step-ca/data:/home/step
- /opt/step-ca/init/secrets:/init-secrets
ports:
- 9000:9000
environment:
- DOCKER_STEPCA_INIT_NAME=sunet-cdn-ca
- DOCKER_STEPCA_INIT_DNS_NAMES=localhost,<%= @networking['fqdn'] %>
- DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=true
- DOCKER_STEPCA_INIT_PASSWORD_FILE=/init-secrets/key-password
- DOCKER_STEPCA_INIT_ACME=true

View file

@ -0,0 +1 @@
<%= @ca_secrets['key_password'] %>

View file

@ -0,0 +1 @@
<%= @ca_secrets['provisioner_password'] %>

View file

@ -0,0 +1,3 @@
[NetDev]
Name=dummy0
Kind=dummy

View file

@ -0,0 +1,10 @@
[Match]
Name=dummy0
[Network]
<% @cache_secrets['customers'].each do |customer, customer_settings| -%>
# <%= customer %>
Address=<%= customer_settings['ip4'] %>/32
Address=<%= customer_settings['ip6'] %>/128
<% end -%>

View file

@ -0,0 +1,16 @@
[NetDev]
Name=ip6tnl0
Kind=ip6tnl
[Tunnel]
Independent=true
# Local and Remote should be 'any' or '::' but right now it does not work.
# However, by using the name "ip6tnl0" that matches the name of the interface
# automatically created when the kernel module is loaded it seems we can set
# anything "non-zero" here and the config will be accepted but still leaving
# "::" as both Local and Remote on the interface. This then results in the
# wanted configuration for now. One bug cancelling out another bug?
# https://github.com/systemd/systemd/issues/34930
Local=::1
Remote=::1
Mode=ip6ip6

View file

@ -0,0 +1,2 @@
[Match]
Name=ip6tnl0

View file

@ -0,0 +1,8 @@
[NetDev]
Name=tunl0
Kind=ipip
[Tunnel]
Independent=true
Local=0.0.0.0
Remote=0.0.0.0

View file

@ -0,0 +1,2 @@
[Match]
Name=tunl0

View file

@ -0,0 +1,79 @@
version: "3.9"
services:
haproxy:
# This is the official haproxy-supported container.
image: "docker.io/haproxytech/haproxy-debian:2.9.6"
volumes:
- /opt/sunet-cdn/customers/<%= @customer %>/conf/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
- /opt/sunet-cdn/customers/<%= @customer %>/shared:/shared
- /opt/sunet-cdn/customers/<%= @customer %>/certs:/certs:ro
- /opt/sunet-cdn/customers/<%= @customer %>/certs-private:/certs-private:ro
# The general (outdated?) advice is never to start haproxy as an
# unprivileged user for production purposes:
# https://docs.haproxy.org/2.9/management.html
# ... but looking at https://hub.docker.com/_/haproxy it states:
# ===
# Note: the 2.4+ versions of the container will run as USER haproxy by
# default (hence the --sysctl net.ipv4.ip_unprivileged_port_start=0 above),
# but older versions still default to root for compatibility reasons; use
# --user haproxy (or any other UID) if you want to run as non-root in older
# versions.
# ===
# ... So it seems reasonable to use a custom user even for haproxy. The
# very large uid/gid is used to have a reasonable guarantee that nothing in
# the normal system will ever collide with it, and is inspired by what
# the OpenShift kubernetes system does:
# https://www.redhat.com/en/blog/a-guide-to-openshift-and-uids#
user: <%= @customer_uid %>:<%= @customer_uid %>
# Setting network_mode is done to not involve overhead of NAT, the
# idea is that it is one less state table to take care of in case of
# handling DDoS traffic, and it also means we will see real client IP
# addresses in haproxy for setting headers etc.
network_mode: "host"
# The following can not be used with network_mode: host so needs to be set
# in the global OS sysctl instead:
# ===
#sysctls:
# - net.ipv4.ip_unprivileged_port_start=80
# ===
varnish:
# We build our own varnish with the slash vmod present. We use the slash
# "fellow" storage backend to be able to persist cached content to disk, so
# it is retained in case of a restart of the container or machine.
image: "platform.sunet.se/sunet-cdn/cdn-varnish:af7f7d11e61acf9f6113811615d1baa46daf3bd1"
# Use the same custom user as is used for haproxy.
user: <%= @customer_uid %>:<%= @customer_uid %>
volumes:
- /opt/sunet-cdn/customers/<%= @customer %>/conf/varnish.vcl:/etc/varnish/varnish.vcl:ro
- /opt/sunet-cdn/customers/<%= @customer %>/shared:/shared
- /opt/sunet-cdn/customers/<%= @customer %>/cache:/cache
# From https://www.varnish-software.com/developers/tutorials/running-varnish-docker/:
# ===
# The /var/lib/varnish folder is frequently accessed by the varnishd
# program. Loading this folder into memory and accessing it through tmpfs
# would accelerate access to this folder.
# ===
# Using the subfolder "varnishd" is an updated expectation, see
# https://github.com/varnish/docker-varnish/issues/51
tmpfs:
- /var/lib/varnish/varnishd:exec,uid=<%= @customer_uid %>
# Varnish does not need to listen to any network ports as all communication
# between it and haproxy happens over a UNIX socket.
command: [
"-E",
"/usr/lib/varnish/vmods/libvmod_slash.so",
"-a",
"/shared/varnish.sock,PROXY,mode=600",
"-f",
"/etc/varnish/varnish.vcl",
"-p",
"feature=+http2",
"-s",
"fellow=fellow,/cache/fellow-storage,512MB,512MB,10MB",
]
# Allow io_uring operations expected by slash fellow.
security_opt:
- seccomp:/opt/sunet-cdn/conf/varnish-slash-seccomp.json
# Fix error log: "varnish-1 | Info: Child (29) said fellow_io_uring_register_buffers: fellow_io_uring_register_buffers Cannot allocate memory (12)"
ulimits:
memlock: -1

View file

@ -0,0 +1,63 @@
global
log stdout format raw local0 debug
stats socket /shared/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode http
option httplog
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /usr/local/etc/haproxy/errors/400.http
errorfile 403 /usr/local/etc/haproxy/errors/403.http
errorfile 408 /usr/local/etc/haproxy/errors/408.http
errorfile 500 /usr/local/etc/haproxy/errors/500.http
errorfile 502 /usr/local/etc/haproxy/errors/502.http
errorfile 503 /usr/local/etc/haproxy/errors/503.http
errorfile 504 /usr/local/etc/haproxy/errors/504.http
frontend customer
bind <%= @cache_secrets['customers'][@customer]['ip4'] %>:80
bind [<%= @cache_secrets['customers'][@customer]['ip6'] %>]:80
bind <%= @cache_secrets['customers'][@customer]['ip4'] %>:443 ssl crt /certs-private/combined.pem
bind [<%= @cache_secrets['customers'][@customer]['ip6'] %>]:443 ssl crt /certs-private/combined.pem
default_backend varnish
backend varnish
server varnish /shared/varnish.sock send-proxy-v2 proxy-v2-options ssl
# https://varnish-cache.org/docs/trunk/users-guide/vcl-backends.html#connecting-through-a-proxy
listen haproxy_https
mode tcp
option tcplog
maxconn 1000
bind /shared/haproxy_https accept-proxy mode 640
stick-table type ip size 100
stick on dst
<% @cache_secrets['customers'][@customer]['origins'].each_with_index do |origin, index| -%>
server s<%= index %> <%= origin %>:443 ssl ca-file /etc/ssl/certs/ca-certificates.crt alpn http/1.1 sni fc_pp_authority
<% end -%>
# While varnish could recach out to HTTP backends itself, lets stick to one
# place (haproxy) for dealing with loadbalancing etc.
listen haproxy_http
mode tcp
option tcplog
maxconn 1000
bind /shared/haproxy_http accept-proxy mode 640
stick-table type ip size 100
stick on dst
<% @cache_secrets['customers'][@customer]['origins'].each_with_index do |origin, index| -%>
server s<%= index %> <%= origin %>:80
<% end -%>

View file

@ -0,0 +1,16 @@
# This service file is generated by Puppet. Do not edit.
[Unit]
Description=SUNET CDN Purger
Wants=docker.service
After=docker.service
[Service]
Type=simple
ExecStart=/usr/local/bin/sunet-cdnp \
-mqtt-ca-file /usr/local/share/ca-certificates/step_ca_root.crt \
-mqtt-client-key-file /etc/letsencrypt/live/<%= @networking['fqdn'] %>/privkey.pem \
-mqtt-client-cert-file /etc/letsencrypt/live/<%= @networking['fqdn'] %>/fullchain.pem \
-mqtt-server <%= @mqtt_url[@location][@environment] %>
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,2 @@
# Allow haproxy to bind to port 80 and 443 when running as unprivileged user
net.ipv4.ip_unprivileged_port_start=80

View file

@ -0,0 +1,841 @@
{
"defaultAction": "SCMP_ACT_ERRNO",
"defaultErrnoRet": 1,
"archMap": [
{
"architecture": "SCMP_ARCH_X86_64",
"subArchitectures": [
"SCMP_ARCH_X86",
"SCMP_ARCH_X32"
]
},
{
"architecture": "SCMP_ARCH_AARCH64",
"subArchitectures": [
"SCMP_ARCH_ARM"
]
},
{
"architecture": "SCMP_ARCH_MIPS64",
"subArchitectures": [
"SCMP_ARCH_MIPS",
"SCMP_ARCH_MIPS64N32"
]
},
{
"architecture": "SCMP_ARCH_MIPS64N32",
"subArchitectures": [
"SCMP_ARCH_MIPS",
"SCMP_ARCH_MIPS64"
]
},
{
"architecture": "SCMP_ARCH_MIPSEL64",
"subArchitectures": [
"SCMP_ARCH_MIPSEL",
"SCMP_ARCH_MIPSEL64N32"
]
},
{
"architecture": "SCMP_ARCH_MIPSEL64N32",
"subArchitectures": [
"SCMP_ARCH_MIPSEL",
"SCMP_ARCH_MIPSEL64"
]
},
{
"architecture": "SCMP_ARCH_S390X",
"subArchitectures": [
"SCMP_ARCH_S390"
]
},
{
"architecture": "SCMP_ARCH_RISCV64",
"subArchitectures": null
}
],
"syscalls": [
{
"names": [
"accept",
"accept4",
"access",
"adjtimex",
"alarm",
"bind",
"brk",
"cachestat",
"capget",
"capset",
"chdir",
"chmod",
"chown",
"chown32",
"clock_adjtime",
"clock_adjtime64",
"clock_getres",
"clock_getres_time64",
"clock_gettime",
"clock_gettime64",
"clock_nanosleep",
"clock_nanosleep_time64",
"close",
"close_range",
"connect",
"copy_file_range",
"creat",
"dup",
"dup2",
"dup3",
"epoll_create",
"epoll_create1",
"epoll_ctl",
"epoll_ctl_old",
"epoll_pwait",
"epoll_pwait2",
"epoll_wait",
"epoll_wait_old",
"eventfd",
"eventfd2",
"execve",
"execveat",
"exit",
"exit_group",
"faccessat",
"faccessat2",
"fadvise64",
"fadvise64_64",
"fallocate",
"fanotify_mark",
"fchdir",
"fchmod",
"fchmodat",
"fchmodat2",
"fchown",
"fchown32",
"fchownat",
"fcntl",
"fcntl64",
"fdatasync",
"fgetxattr",
"flistxattr",
"flock",
"fork",
"fremovexattr",
"fsetxattr",
"fstat",
"fstat64",
"fstatat64",
"fstatfs",
"fstatfs64",
"fsync",
"ftruncate",
"ftruncate64",
"futex",
"futex_requeue",
"futex_time64",
"futex_wait",
"futex_waitv",
"futex_wake",
"futimesat",
"getcpu",
"getcwd",
"getdents",
"getdents64",
"getegid",
"getegid32",
"geteuid",
"geteuid32",
"getgid",
"getgid32",
"getgroups",
"getgroups32",
"getitimer",
"getpeername",
"getpgid",
"getpgrp",
"getpid",
"getppid",
"getpriority",
"getrandom",
"getresgid",
"getresgid32",
"getresuid",
"getresuid32",
"getrlimit",
"get_robust_list",
"getrusage",
"getsid",
"getsockname",
"getsockopt",
"get_thread_area",
"gettid",
"gettimeofday",
"getuid",
"getuid32",
"getxattr",
"inotify_add_watch",
"inotify_init",
"inotify_init1",
"inotify_rm_watch",
"io_cancel",
"ioctl",
"io_destroy",
"io_getevents",
"io_pgetevents",
"io_pgetevents_time64",
"ioprio_get",
"ioprio_set",
"io_setup",
"io_submit",
"ipc",
"kill",
"landlock_add_rule",
"landlock_create_ruleset",
"landlock_restrict_self",
"lchown",
"lchown32",
"lgetxattr",
"link",
"linkat",
"listen",
"listxattr",
"llistxattr",
"_llseek",
"lremovexattr",
"lseek",
"lsetxattr",
"lstat",
"lstat64",
"madvise",
"map_shadow_stack",
"membarrier",
"memfd_create",
"memfd_secret",
"mincore",
"mkdir",
"mkdirat",
"mknod",
"mknodat",
"mlock",
"mlock2",
"mlockall",
"mmap",
"mmap2",
"mprotect",
"mq_getsetattr",
"mq_notify",
"mq_open",
"mq_timedreceive",
"mq_timedreceive_time64",
"mq_timedsend",
"mq_timedsend_time64",
"mq_unlink",
"mremap",
"msgctl",
"msgget",
"msgrcv",
"msgsnd",
"msync",
"munlock",
"munlockall",
"munmap",
"name_to_handle_at",
"nanosleep",
"newfstatat",
"_newselect",
"open",
"openat",
"openat2",
"pause",
"pidfd_open",
"pidfd_send_signal",
"pipe",
"pipe2",
"pkey_alloc",
"pkey_free",
"pkey_mprotect",
"poll",
"ppoll",
"ppoll_time64",
"prctl",
"pread64",
"preadv",
"preadv2",
"prlimit64",
"process_mrelease",
"pselect6",
"pselect6_time64",
"pwrite64",
"pwritev",
"pwritev2",
"read",
"readahead",
"readlink",
"readlinkat",
"readv",
"recv",
"recvfrom",
"recvmmsg",
"recvmmsg_time64",
"recvmsg",
"remap_file_pages",
"removexattr",
"rename",
"renameat",
"renameat2",
"restart_syscall",
"rmdir",
"rseq",
"rt_sigaction",
"rt_sigpending",
"rt_sigprocmask",
"rt_sigqueueinfo",
"rt_sigreturn",
"rt_sigsuspend",
"rt_sigtimedwait",
"rt_sigtimedwait_time64",
"rt_tgsigqueueinfo",
"sched_getaffinity",
"sched_getattr",
"sched_getparam",
"sched_get_priority_max",
"sched_get_priority_min",
"sched_getscheduler",
"sched_rr_get_interval",
"sched_rr_get_interval_time64",
"sched_setaffinity",
"sched_setattr",
"sched_setparam",
"sched_setscheduler",
"sched_yield",
"seccomp",
"select",
"semctl",
"semget",
"semop",
"semtimedop",
"semtimedop_time64",
"send",
"sendfile",
"sendfile64",
"sendmmsg",
"sendmsg",
"sendto",
"setfsgid",
"setfsgid32",
"setfsuid",
"setfsuid32",
"setgid",
"setgid32",
"setgroups",
"setgroups32",
"setitimer",
"setpgid",
"setpriority",
"setregid",
"setregid32",
"setresgid",
"setresgid32",
"setresuid",
"setresuid32",
"setreuid",
"setreuid32",
"setrlimit",
"set_robust_list",
"setsid",
"setsockopt",
"set_thread_area",
"set_tid_address",
"setuid",
"setuid32",
"setxattr",
"shmat",
"shmctl",
"shmdt",
"shmget",
"shutdown",
"sigaltstack",
"signalfd",
"signalfd4",
"sigprocmask",
"sigreturn",
"socketcall",
"socketpair",
"splice",
"stat",
"stat64",
"statfs",
"statfs64",
"statx",
"symlink",
"symlinkat",
"sync",
"sync_file_range",
"syncfs",
"sysinfo",
"tee",
"tgkill",
"time",
"timer_create",
"timer_delete",
"timer_getoverrun",
"timer_gettime",
"timer_gettime64",
"timer_settime",
"timer_settime64",
"timerfd_create",
"timerfd_gettime",
"timerfd_gettime64",
"timerfd_settime",
"timerfd_settime64",
"times",
"tkill",
"truncate",
"truncate64",
"ugetrlimit",
"umask",
"uname",
"unlink",
"unlinkat",
"utime",
"utimensat",
"utimensat_time64",
"utimes",
"vfork",
"vmsplice",
"wait4",
"waitid",
"waitpid",
"write",
"writev"
],
"action": "SCMP_ACT_ALLOW"
},
{
"names": [
"process_vm_readv",
"process_vm_writev",
"ptrace"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"minKernel": "4.8"
}
},
{
"names": [
"socket"
],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 0,
"value": 40,
"op": "SCMP_CMP_NE"
}
]
},
{
"names": [
"personality"
],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 0,
"value": 0,
"op": "SCMP_CMP_EQ"
}
]
},
{
"names": [
"personality"
],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 0,
"value": 8,
"op": "SCMP_CMP_EQ"
}
]
},
{
"names": [
"personality"
],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 0,
"value": 131072,
"op": "SCMP_CMP_EQ"
}
]
},
{
"names": [
"personality"
],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 0,
"value": 131080,
"op": "SCMP_CMP_EQ"
}
]
},
{
"names": [
"personality"
],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 0,
"value": 4294967295,
"op": "SCMP_CMP_EQ"
}
]
},
{
"names": [
"sync_file_range2",
"swapcontext"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"arches": [
"ppc64le"
]
}
},
{
"names": [
"arm_fadvise64_64",
"arm_sync_file_range",
"sync_file_range2",
"breakpoint",
"cacheflush",
"set_tls"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"arches": [
"arm",
"arm64"
]
}
},
{
"names": [
"arch_prctl"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"arches": [
"amd64",
"x32"
]
}
},
{
"names": [
"modify_ldt"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"arches": [
"amd64",
"x32",
"x86"
]
}
},
{
"names": [
"s390_pci_mmio_read",
"s390_pci_mmio_write",
"s390_runtime_instr"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"arches": [
"s390",
"s390x"
]
}
},
{
"names": [
"riscv_flush_icache"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"arches": [
"riscv64"
]
}
},
{
"names": [
"open_by_handle_at"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_DAC_READ_SEARCH"
]
}
},
{
"names": [
"bpf",
"clone",
"clone3",
"fanotify_init",
"fsconfig",
"fsmount",
"fsopen",
"fspick",
"lookup_dcookie",
"mount",
"mount_setattr",
"move_mount",
"open_tree",
"perf_event_open",
"quotactl",
"quotactl_fd",
"setdomainname",
"sethostname",
"setns",
"syslog",
"umount",
"umount2",
"unshare"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_SYS_ADMIN"
]
}
},
{
"names": [
"clone"
],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 0,
"value": 2114060288,
"op": "SCMP_CMP_MASKED_EQ"
}
],
"excludes": {
"caps": [
"CAP_SYS_ADMIN"
],
"arches": [
"s390",
"s390x"
]
}
},
{
"names": [
"clone"
],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 1,
"value": 2114060288,
"op": "SCMP_CMP_MASKED_EQ"
}
],
"comment": "s390 parameter ordering for clone is different",
"includes": {
"arches": [
"s390",
"s390x"
]
},
"excludes": {
"caps": [
"CAP_SYS_ADMIN"
]
}
},
{
"names": [
"clone3"
],
"action": "SCMP_ACT_ERRNO",
"errnoRet": 38,
"excludes": {
"caps": [
"CAP_SYS_ADMIN"
]
}
},
{
"names": [
"reboot"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_SYS_BOOT"
]
}
},
{
"names": [
"chroot"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_SYS_CHROOT"
]
}
},
{
"names": [
"delete_module",
"init_module",
"finit_module"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_SYS_MODULE"
]
}
},
{
"names": [
"acct"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_SYS_PACCT"
]
}
},
{
"names": [
"kcmp",
"pidfd_getfd",
"process_madvise",
"process_vm_readv",
"process_vm_writev",
"ptrace"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_SYS_PTRACE"
]
}
},
{
"names": [
"iopl",
"ioperm"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_SYS_RAWIO"
]
}
},
{
"names": [
"settimeofday",
"stime",
"clock_settime",
"clock_settime64"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_SYS_TIME"
]
}
},
{
"names": [
"vhangup"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_SYS_TTY_CONFIG"
]
}
},
{
"names": [
"get_mempolicy",
"mbind",
"set_mempolicy",
"set_mempolicy_home_node"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_SYS_NICE"
]
}
},
{
"names": [
"syslog"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_SYSLOG"
]
}
},
{
"names": [
"bpf"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_BPF"
]
}
},
{
"names": [
"perf_event_open"
],
"action": "SCMP_ACT_ALLOW",
"includes": {
"caps": [
"CAP_PERFMON"
]
}
},
{
"names": [
"io_uring_enter",
"io_uring_register",
"io_uring_setup"
],
"action": "SCMP_ACT_ALLOW"
}
]
}

View file

@ -0,0 +1,92 @@
# The builtin VCL is called when there is no explicit
# return statement.
#
# See the VCL chapters in the Users Guide for a comprehensive documentation
# at https://www.varnish-cache.org/docs/.
# Marker to tell the VCL compiler that this VCL has been written with the
# 4.0 or 4.1 syntax.
vcl 4.1;
import std;
# https://www.varnish-software.com/developers/tutorials/avoid-http-to-https-redirect-loops-varnish/#create-cache-variations-based-on-the-x-forwarded-proto-header
import proxy;
# https://varnish-cache.org/docs/trunk/users-guide/vcl-backends.html#connecting-through-a-proxy
backend haproxy_https {
.path = "/shared/haproxy_https";
}
backend haproxy_http {
.path = "/shared/haproxy_http";
}
backend destination_http {
.host = "<%= @cache_secrets['customers'][@customer]['host'] %>";
.port = "80";
.via = haproxy_http;
}
backend destination_https {
.host = "<%= @cache_secrets['customers'][@customer]['host'] %>";
.port = "443";
.via = haproxy_https;
}
sub vcl_recv {
# Happens before we check if we have this in cache already.
#
# Typically you clean up the request here, removing cookies you don't need,
# rewriting the request, etc.
#
# The usage of the proxy module is possible because haproxy is configured
# to set PROXY SSL headers for us.
if (proxy.is_ssl()) {
set req.http.X-Forwarded-Proto = "https";
std.syslog(180, "RECV: this is https");
if (req.http.host == "<%= @cache_secrets['customers'][@customer]['host'] %>") {
set req.backend_hint = destination_https;
}
} else {
set req.http.X-Forwarded-Proto = "http";
std.syslog(180, "RECV: this is http");
if (req.http.host == "<%= @cache_secrets['customers'][@customer]['host'] %>") {
set req.backend_hint = destination_http;
}
}
if (req.method == "PURGE") {
if (req.http.x-sunet-cdn-key == "<%= @cache_secrets['customers'][@customer]['key'] %>") {
return (purge);
}
return(synth(405,"Not allowed."));
}
}
sub vcl_backend_response {
# Happens after we have read the response headers from the backend.
#
# Here you clean the response headers, removing silly Set-Cookie headers
# and other mistakes your backend does.
# Use slash/fellow for storage
set beresp.storage = storage.fellow;
# Hold stale objects (where TTL has expired) for a longer time
set beresp.grace = 30m;
# https://www.varnish-software.com/developers/tutorials/avoid-http-to-https-redirect-loops-varnish/#create-cache-variations-based-on-the-x-forwarded-proto-header
if(beresp.http.Vary) {
set beresp.http.Vary = beresp.http.Vary + ", X-Forwarded-Proto";
} else {
set beresp.http.Vary = "X-Forwarded-Proto";
}
}
sub vcl_deliver {
# Happens when we have all the pieces we need, and are about to send the
# response to the client.
#
# You can do accounting or modifying the final object here.
unset resp.http.Vary;
}

View file

@ -0,0 +1,13 @@
services:
db:
image: "postgres:<%= @postgres_version %>"
environment:
- POSTGRES_PASSWORD=<%= @db_secrets['postgres_password'] %>
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- /opt/sunet-cdn/db/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
- /opt/sunet-cdn/db/conf:/conf
volumes:
postgres_data:

View file

@ -0,0 +1,2 @@
# File sourced by init-cdn-db.sh
cdn_password="<%= @db_secrets['cdn_password'] %>"

View file

@ -0,0 +1,4 @@
[Service]
NetworkNamespacePath=/var/run/netns/l4lb
Wants=sunet-l4lb-namespace.service
After=sunet-l4lb-namespace.service

View file

@ -0,0 +1,115 @@
# Configure logging
log syslog all;
# Set router ID. It is a unique identification of your router, usually one of
# IPv4 addresses of the router. It is recommended to configure it explicitly.
router id <%= @facts['networking']['ip'] %>;
# The Device protocol is not a real routing protocol. It does not generate any
# routes and it only serves as a module for getting information about network
# interfaces from the kernel. It is necessary in almost any configuration.
protocol device {
}
# The direct protocol is not a real routing protocol. It automatically generates
# direct routes to all network interfaces. Can exist in as many instances as you
# wish if you want to populate multiple routing tables with direct routes.
protocol direct {
ipv4;
ipv6;
interface "dummy0";
}
# The Kernel protocol is not a real routing protocol. Instead of communicating
# with other routers in the network, it performs synchronization of BIRD
# routing tables with the OS kernel. One instance per table.
protocol kernel {
ipv4 {
import none;
export filter { if source = RTS_DEVICE then { reject; } accept; };
};
# Create ECMP routes in kernel table from multiple paths
merge paths;
}
protocol kernel {
ipv6 {
import none;
export filter { if source = RTS_DEVICE then { reject; } accept; };
};
# Create ECMP routes in kernel table from multiple paths
merge paths;
}
protocol bgp tug_r11_v4 {
description "tug-r11-v4";
local 130.242.64.233 as 65443;
neighbor 130.242.64.232 as 1653;
hold time 90;
ipv4 {
import filter {
if net ~ [ 0.0.0.0/0 ] then
accept; else reject;
};
export filter {
if net ~ [ 188.240.152.0/24{32,32} ] then
accept; else reject;
};
};
}
protocol bgp tug_r11_v6 {
description "tug-r12-v6";
local 2001:6b0:2006:74::1 as 65443;
neighbor 2001:6b0:2006:74:: as 1653;
hold time 90;
ipv6 {
import filter {
if net ~ [ ::/0 ] then
accept; else reject;
};
export filter {
if net ~ [ 2001:6b0:2100::/48{128,128} ] then
accept; else reject;
};
};
}
protocol bgp tug_r12_v4 {
description "tug-r12-v4";
local 130.242.64.235 as 65443;
neighbor 130.242.64.234 as 1653;
hold time 90;
ipv4 {
import filter {
if net ~ [ 0.0.0.0/0 ] then
accept; else reject;
};
export filter {
if net ~ [ 188.240.152.0/24{32,32} ] then
accept; else reject;
};
};
}
protocol bgp tug_r12_v6 {
description "tug-r12-v6";
local 2001:6b0:2006:75::1 as 65443;
neighbor 2001:6b0:2006:75:: as 1653;
hold time 90;
ipv6 {
import filter {
if net ~ [ ::/0 ] then
accept; else reject;
};
export filter {
if net ~ [ 2001:6b0:2100::/48{128,128} ] then
accept; else reject;
};
};
}

View file

@ -0,0 +1,20 @@
{
"l4lb": {
"enp129s0f1np1": {
"ipv4": [
"130.242.64.233/31"
],
"ipv6": [
"2001:6b0:2006:74::1/127"
]
},
"enp129s0f0np0": {
"ipv4": [
"130.242.64.235/31"
],
"ipv6": [
"2001:6b0:2006:75::1/127"
]
}
}
}

View file

@ -0,0 +1,40 @@
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# accept any localhost traffic
iif lo counter accept
# accept icmp
ip protocol icmp counter accept
ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded,
parameter-problem, echo-request, mld-listener-query,
nd-router-solicit, nd-router-advert, nd-neighbor-solicit,
nd-neighbor-advert } counter accept
# accept traffic originated from us
ct state established counter accept
# silently drop invalid packets
ct state invalid counter drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0;
}
}
# HTTP and HTTPS
add rule inet filter input tcp dport 80 counter accept comment "l4lb HTTP"
add rule inet filter input tcp dport 443 counter accept comment "l4lb HTTPS"
# BGP
add rule inet filter input ip saddr { 130.242.64.232 } tcp dport 179 counter accept comment "tug-r11-v4"
add rule inet filter input ip saddr { 130.242.64.234 } tcp dport 179 counter accept comment "tug-r12-v4"
add rule inet filter input ip6 saddr { 2001:6b0:2006:74:: } tcp dport 179 counter accept comment "tug-r11-v6"
add rule inet filter input ip6 saddr { 2001:6b0:2006:75:: } tcp dport 179 counter accept comment "tug-r12-v6"

View file

@ -0,0 +1,11 @@
[Unit]
Description=Setup l4lb namespace used for all service traffic
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/sunet-l4lb-namespace
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,5 @@
# Allow non-SYN packets to be accepted for a IPVS service.
# Needed if another l4lb has been taken down and routers are now sending us
# packets for existing connections that was previously handled by the other
# node.
net.ipv4.vs.sloppy_tcp=1

View file

@ -0,0 +1,15 @@
# Clients in the local datacenter
<% @clients.each do |client| -%>
user <%= client %>
topic readwrite cdn/<%= @dc %>/purge
topic read cdn/+/purge
<% end -%>
# Bridge queues to other datacenters
<% @bridges.each do |remote_dc, bridge_config| -%>
user <%= bridge_config['address'] %>
topic readwrite cdn/<%= @remote_dc %>/purge
<% end -%>
# This affects all clients.
pattern write $SYS/broker/connection/%c/state

View file

@ -0,0 +1,19 @@
listener 8883
cafile /usr/local/share/ca-certificates/step_ca_root.crt
certfile /etc/mosquitto/certs/fullchain.pem
keyfile /etc/mosquitto/certs/privkey.pem
require_certificate true
use_identity_as_username true
acl_file /etc/mosquitto/aclfile
log_type all
<% @bridges.each do |remote_dc, bridge_config| -%>
connection <%= @dc %>-to-<%= remote_dc %>
address <%= bridge_config['address'] %>:<%= bridge_config['port'] %>
topic cdn/<%= @dc %>/purge out 1
bridge_cafile /usr/local/share/ca-certificates/step_ca_root.crt
bridge_certfile /etc/mosquitto/certs/cert.pem
bridge_keyfile /etc/mosquitto/certs/privkey.pem
<% end -%>

View file

@ -31,7 +31,7 @@ services:
bash -ec '
while : ; do
if [ -f .runner ]; then echo "runner already registered, exiting"; exit; fi
forgejo-runner register --no-interactive --name <%= @networking.fqdn %> --instance https://platform.sunet.se --token <%= @runner_token %> --labels docker:docker://node:20-bookworm,ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04 && break;
forgejo-runner register --no-interactive --name <%= @networking['fqdn'] %> --instance https://platform.sunet.se --token <%= @runner_token %> --labels docker:docker://node:20-bookworm,ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04 && break;
sleep 1 ;
done ;
forgejo-runner generate-config > config.yml ;

View file

@ -83,7 +83,7 @@ def main():
"sunet": {
"repo": "https://github.com/SUNET/puppet-sunet.git",
"upgrade": "yes",
"tag": "stable-2023v1-2*",
"tag": "patlu-dockerhost2-ipv6-nat-2*",
},
"augeas": {
"repo": "https://github.com/SUNET/puppet-augeas.git",

View file

@ -8,7 +8,7 @@ set -e
stamp="$COSMOS_BASE/stamps/common-tools-v01.stamp"
if ! test -f $stamp; then
apt-get -y install vim traceroute tcpdump molly-guard less rsync git-core unattended-upgrades ntp
apt-get -y install vim traceroute tcpdump molly-guard less rsync git-core unattended-upgrades
update-alternatives --set editor /usr/bin/vim.basic
mkdir -p `dirname $stamp`

View file

@ -0,0 +1,3 @@
The system documentation is in the docs directory of the multiverse repository.

View file

@ -0,0 +1,4 @@
---
cdn::ca-secrets:
key_password: ENC[PKCS7,MIIDCAYJKoZIhvcNAQcDoIIC+TCCAvUCAQAxggKQMIICjAIBADB0MFwxCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxLTArBgNVBAMMJGludGVybmFsLXN0bzMtdGVzdC1jYS0xLmNkbi5zdW5ldC5zZQIUWgTVsY5hzuMqS69y4xN74SYDScMwDQYJKoZIhvcNAQEBBQAEggIACjUTsEogn8lIbvYQP/pRMhBhaLjyLyaOqW0F+mRxxG+BPVTdWf5LVXJMSf5uM+xBhw6VKwSoI/9FlnKSwPEHqHMUPvyW7+fn8wWywbov9XS97WthwZasPwUHrxVkIB1d14fbcy1iBLer9Kp5R2kP02aeyNJwNdQ/LY6LhPDYR+8d2BGPl5bbhQ2d7K2iB14ZqoOvUpmI2Ye8einCjr0p98q1j6mtPk+6UXmgH13U1PqqiXkCb9vKNhoInHocprxkkC5FB3JoJxGA6tqV1zhu17UAYfA72D3b1v1hu+fVKirQrDxggmOk/j3RX1S2juKAZutdDn7LArvGipQgGp5je7TrbS+Kql7NKj9uH4rAT04OtvklP5G8gErKUmQ/YXEG2/KYctxOcYmJyhB/ggCql7JreNwHexqd714JGxCqFwx0Px+81c7Acf6v9YyQmBLtijYSOhX0+qJ6NYrYKRGJNokNCOfobWxvaJWcd7kZOi+An5pe83jeAMzPxanpuIwgTBm7IAgjdrhnBibnBDAESp8LI5CqF268itGoXgnsBeDLP5qKxFqH0391fShxjnL/sRZXkX+CpQEp3LdQoumeuzDbdeNtYbcxfTD5/5M68eAZ7wuL/QiZDyMxx2iUdswLKjIlBWl+sNeeg7RAxvUGlL9S72e64wsAnHVZb2dZb3YwXAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQGIADIyFJ/4NOhfWu5rt8N4AwYmCz2kRycfufhNZF6sifojLxE969b6QYzRXmyo/K2a0UkLbbkgO3cysbwH/QmLlA]
provisioner_password: ENC[PKCS7,MIIDCAYJKoZIhvcNAQcDoIIC+TCCAvUCAQAxggKQMIICjAIBADB0MFwxCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxLTArBgNVBAMMJGludGVybmFsLXN0bzMtdGVzdC1jYS0xLmNkbi5zdW5ldC5zZQIUWgTVsY5hzuMqS69y4xN74SYDScMwDQYJKoZIhvcNAQEBBQAEggIAA8TKNf3Lgj8qJdT9Dq4o555fq1aFTSL9HcNiIV5mc91cAwqXFf+AdeeeFcwVDV1NXkS2oRcxybYhGIsT/OBB9u+E/+HZQ1pU69m4P96n4Sb9TXEWi/9AH2fAytKB+EloHi+kqR9fQcr6cpCoqKBhI8jP8Wa1VCPwoxIkF46WfWKG1MFdjOD8JOrwPZ0vat6M2GIL70ryY4b8/4hBYayjtY3pEtzgPidteWcmMWdoTz7IOO2sw4k0cFDLg1zXBX4P0XG3Rti8YcJhg6dFTWsHlmRCVSK8C+dyiXE3p9ZX31Zua1IkNrhJJmgrNElhXdKSzQuuQLIg4/kPK4aXB9Qbi8YRZKdyyFEAJPaKGGQUPvBeIUfZdR8Kr3D2t76Tb3t/kHPbBFycN1zpOPYfQOYoYFBMtQoJ1ttqBmKu8ZHCWoR57lI2+LLmsfGUnfx9hfe0MprzXjVbqiHNIXXnc8XzWPdvobIM+a70VWlQzTOuNfLBy32TtwCbhOJ0RYg0Dfu+2rK1FgVHG8HhaI8Wx4boWWeNmD/rjOmXb2ndPa9Z9QU5U5O0T2ZJFFwcH1kffH6P6WYbXCeiy6eThEXodx7upsKZ7BGj19Wm8RklwvrtAi5fSO6yKqKlnER9k15ZnjXMWGn4RAXWdwjy412o7oXcZfvWQXKeZgGpUD4zLm3+7C0wXAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQRpXmYZH5wxL/H6pNWlYLr4AwcLrKL54DxSegwMkvYG7C2ptUfOo5HPtjHx72KjYpkJk7e9UJpfCBWvGBDCGMlsGw]

View file

@ -0,0 +1,3 @@
The system documentation is in the docs directory of the multiverse repository.

View file

@ -0,0 +1,39 @@
---
cdn::cache-secrets:
customers:
customer1:
key: ENC[PKCS7,MIIDCwYJKoZIhvcNAQcDoIIC/DCCAvgCAQAxggKTMIICjwIBADB3MF8xCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxMDAuBgNVBAMMJ2ludGVybmFsLXN0bzMtdGVzdC1jYWNoZS0xLmNkbi5zdW5ldC5zZQIUJEYAJSDlgRqHR7z1XpIgwd3vL7gwDQYJKoZIhvcNAQEBBQAEggIAhHA91YylFORnQ6q/5m10Vokw5NY+dWyF8P43p0Qr34Lr9eOqw5lMZDnZxbgZDQr7fJPsNFxQPF2pVIa1cvHiPW0an7k56VJnHoseh7TlNNa+wx10alSuiuVFEPUoNo4uSD3hjcjWUzQygckgtqqk9PBG9CnWVevLG1cpFeUCCNa+HD/cf318uajyItiJn4EzB5Lyd7b7AsqKnEdkomPnydwMXGObeV09WY2KJ4wzIXKtAUvzLj5iQ3j9sib/M7tx18JZvilKW0AOk+diQ06Lb09iIRTxBDMrPiEARzHyCsp0kGxEAoAZQllrnA/oU6z8S/FcWxo9j+loY2MLBQ7xlN/nL2sMWTjsV5XWSl8FeoKrAAcQ+1U8hDctNfvkMSgIjilah3789qY2PU9HgT1hY0XtVLnS6n9xH6ZeV82X36Je6YTFcKQSITnJvb4AH+8uowvRgYb7FyFiCRgGlGMxByEhfsr/XOjTzTgHZx+cSoJO/5P++7RGz6mU0pBP3J6/QVvJl/7DGyoetaSVkOUwOdDpeWs5N9QTGxQSVWQM9ermZCAjXJsQCG1hGg8jbr9J9pFFKbuzKNJHkpxt0euIuGs102SUW3+INLaVoiOzsJHj1nKsQWL0EE67SPt14f9RZ6vWLiom6lKnf39EIOgeFMCdEW7/MEfsNpiySyIwI5QwXAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQQlYRoAB7KwhhbDxUmCIza4AwB9NYi+5Zz8c3OM/7GPp8tXtGcfmKjoDb5z3Yd84u4E1qjm82zHLwxMTavowSRiUk]
host: ENC[PKCS7,MIIC+wYJKoZIhvcNAQcDoIIC7DCCAugCAQAxggKTMIICjwIBADB3MF8xCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxMDAuBgNVBAMMJ2ludGVybmFsLXN0bzMtdGVzdC1jYWNoZS0xLmNkbi5zdW5ldC5zZQIUJEYAJSDlgRqHR7z1XpIgwd3vL7gwDQYJKoZIhvcNAQEBBQAEggIAifVPgYnF+hjviovROhUs9DlGZM53Uf3FjcIgTLRJlQ+pVIq01OuZZfGW1q2heLtV/wHb7al1Xfbq6FH5RJFojqDqjCvn485GfTanx3tk+OMytcS1ACjTX4XOTGLtBlgKZXv888NHp0H9xUwYiyhZQ9l26EXZhlUW6OQ7O0OSM7cwBUY0B/bW1RBjq4bXqQ6cm7CXfkRhuD9V7vYVTmW4hpl09P0fbNJIAzCO6LZpI1x4n4hvLAyDvTphFtVt/wCBPORq/a8Lr7tuD3H0wTQCwHWN1G9q1qSl9PXjpknt77tA+ykHltRh71tKbl3izLT6ytYhWrlPbGjCuytnSV63+UXYKj5UjqOYBq/UR6aqTwY4DsrhRQMmMMUxlF2ibYQMd0l9ZQCliXMOT1OKzRVCigpTJQl4fnxV62+RSgJPBAboiR9uGwk9q6Z1eOroWVVPV0Qq68Tn1fvzMnU/HQ+425Mg7cH35NWsD+EIRhpi2/8F5ONd0P74DsDtTuxi7q7mJ4ZP7+n6IYUdoGRHSAnJSOaZqjyJWmlQk6ZntJTDYyC7bKamCML2Tz5D7q2pm5HjQeqcRthgX/PaIIwEi9cTuPyyD3funJsvJtoNH7BspI0ncAP4CZORHwNPBSFsVmCFw2Rv0KojysgOHWr3Uymjti4Lq6SGfEAxxMtBRFUFCaUwTAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQL2hoIWvXnGnfl9FV/rc/g4Ag5jueWu8mguigFjLXPB1SDcYv04NKYGW8addXEwEXoqA=]
ip4: ENC[PKCS7,MIIC6wYJKoZIhvcNAQcDoIIC3DCCAtgCAQAxggKTMIICjwIBADB3MF8xCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxMDAuBgNVBAMMJ2ludGVybmFsLXN0bzMtdGVzdC1jYWNoZS0xLmNkbi5zdW5ldC5zZQIUJEYAJSDlgRqHR7z1XpIgwd3vL7gwDQYJKoZIhvcNAQEBBQAEggIAuQFDR7/DHr0+W+iFLFaPHrsb/yxnl5ZjGXL+eNT8I4/JiWEw7ImL6kgNXOz/HXPt9GU9KxNc9K5wPprZ2C+0W1EMNue4nFFgoVRmZ2ZQERCkAxCbnIMD9StkTEWXaey0IUIyFRv1Z39nezzeP27Tf2opUsu44uEFhjLR+bGsHMvoAHU7ojPCfYjm8OCWwLoPab2ZoBhR9ltOp/EvEfJHEU5FF+zcRESLxm2BKG6X86LTM0KAZ7qSesmDTsxEWp+oIh0lxdexd80j2886QIpN/U6fQFLnfTZ/Z1L/6m4lMze9J/mvuv42wZdZI2IDAy0lA+ZBJgdYRyowzn0BkAe3MwWhnMrYb4G6O3eCSyQ0vz2yrXTHtRDPAj/e2YtluanfI85Y0l3rlLzMnc6FGzHxqcecj8Fv7dYuOZ7ieWynlJe0D2MBHQIQxyEPpihzp0vY9prqvsooxv2NymdQ9piqCH2QyPDdXLYPgbY8dY3HOjJaPVo+PoGXXcB64ALEFbko+OFutZgOtrfLNMYXZcLXD4/w3kC8ZdveWDscoNbrJzLbO9OoMzsh6Rc3Og7yzOYVRzoE+FfOGr9XVmmILxOSAW7v2/j1eOyJxiVNXtZeOT1EE/UpgvPJcEfx/REoRn1r3aThEr4Yrg0AHPpvyfm5hf/kQcbjVtOBxoW0ul+KwcowPAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQpnJ46bsEbyjtb8RtPt/LXYAQHd5jWNsEaGJLpqxGKEbA6w==]
ip6: ENC[PKCS7,MIIC+wYJKoZIhvcNAQcDoIIC7DCCAugCAQAxggKTMIICjwIBADB3MF8xCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxMDAuBgNVBAMMJ2ludGVybmFsLXN0bzMtdGVzdC1jYWNoZS0xLmNkbi5zdW5ldC5zZQIUJEYAJSDlgRqHR7z1XpIgwd3vL7gwDQYJKoZIhvcNAQEBBQAEggIAljd6fcqDuioxqTrln7Dq0JTkaQuGwX5RnMWjEkWebbRdI2lQy9eb/nkfMgMFGb8WXpdJ4hBXKHIscAGRcK7NDUWOgxuhkMmT1wo1C9pJjswaJscHJqdZcr2xRTVK5xB/qfI/h9daTwqFu/m9ZGDARSAWguizI3OfGTVFYpTPI29zuIElIp+wyraTLVnqzB2tM0KNwibVSyl/BBedHkjpYeRHO6ykIzJZxZK06lgGykF0Udz2v3QSZJ4vyHWCXuBdWJsN4chDQkPvl84egjzd73OL0WfQoE4LrfmcmDaZu0top4ZwkreaLZA9z3TenFd7IUlIB7xyGrSDoItwS3LZJ6vTKrQeP0DTq9y+nqcNlFeqNgs5VCGF4p6DX8zwWStFohYXSp6kgxYe5V7KUpHeVUQYZNervoajb7bySYilP6ykgK8QT3Q70dsUQBaWdsCWW9p6VdasjI027vYiPCXD/7bliKLGjDdeBGR4S/UgFNsTzGnfV/PWn7SHN4GIbRwxXgLl2ZJMeDX0TJ9YcIn4Vs7HcB4LUuGobvMcJFjgZk6nj9Mc1pdQfCMl/P7r2ZA5Qt0bqlc/jeYRVRGRXgI49xuHSvZTuFnSvwJndVqQfMFgBgcTwFKnIyX2diKESGc9z/9A3LmSNf/2duG7xH3uX/wDqx88gnmcWOo0ktnLNQswTAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQRifWemfoVp0jTnrORmuzjIAgvAw0cfOOB3AfOZMrQdJaVHaDt3yGxC/XcVk5x4L8ri4=]
origins:
- ENC[PKCS7,MIIC6wYJKoZIhvcNAQcDoIIC3DCCAtgCAQAxggKTMIICjwIBADB3MF8xCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxMDAuBgNVBAMMJ2ludGVybmFsLXN0bzMtdGVzdC1jYWNoZS0xLmNkbi5zdW5ldC5zZQIUJEYAJSDlgRqHR7z1XpIgwd3vL7gwDQYJKoZIhvcNAQEBBQAEggIAlcofAryMHgzdzYKeslCB7ekukxm30xOyYVHusJ4mwylU82xZjtXpcneoPJKydc2bSSP6LkuGGSaiziY1XdU/TLid9fhfBtSFM1S8Cc8IoAgZd25wXo0eaf2f5AfDcSJkywW+kfySEmXCGPGaCeo25k8zZDhWvI4ZrNBDgCTksuL99HWjsT6T6orC9qu2GEBWSpXcKbKu/Yv/1XbNvsJpW1XgwkGJz2EXjJSLKljhBG4P7i8tHIGHbJn/Xo6IWgsBqi8elc5sb/gK4LE5k+JSv78M7ZRs7aRaBm25LZnvNKBPCpyy9sgDEbJzGsHOTtfuyPpgra34wVy/Vt2XFOFserbg/4ZBjkCEN1pNSjb4jDh1tedlvjV1Ovf4W5EQcE1eu2UWvyfLLjjPHz0nW2OQbJB1zO6XOEdP2ot4+WnSgsZvCv9kGJPRhbbrdLVwW/5eSttbaWPo0viNavvTSgjYBiJ38LhPmpulHzhsCSFZisjq/ue6oFhoUwHb/pMklGQRJ2i2AqzPECstCTuKpSMTMrlnAgFS7u3DDXjmeYlV0UlF1SlEpGYqkGQspfWI+7DAnDomVDGAL8M6/+xpaudTNbcTvbrbPh0kwUjKR4+cP5mUAbNEho5UxI5tGnIRWRRd560+FKrAKPY/0V/Dx/tVpu7FgrgOEScdExMzAfDrTSwwPAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQz45S0wVsGWF9YXUE7fQwd4AQPn+7I2vxK/66O56enFIfQQ==]
certbot_sync_client_ssh_key: >
ENC[PKCS7,MIIEnwYJKoZIhvcNAQcDoIIEkDCCBIwCAQAxggKTMIICjwIBAD
B3MF8xCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRV
lBTUwxMDAuBgNVBAMMJ2ludGVybmFsLXN0bzMtdGVzdC1jYWNoZS0xLmNkbi
5zdW5ldC5zZQIUJEYAJSDlgRqHR7z1XpIgwd3vL7gwDQYJKoZIhvcNAQEBBQ
AEggIAWXfHKGu8/x9Hgb2AG+5+waywkR6CBxlLMEBo2NVdqhjRFCE3vPeTeJ
j4Th81KR0RSI42U9/wCZMF8Dq/SSybfTf4CiEOo3xziXdH46qNqdGjouvLx7
fA2l8YnMQo+Wwv8NNd3N7u+p4yJ6/3Dxcw3WzkcU7Igsk2xC2AZBUufu78+a
dAaMZwWtOcszOUHrSzen40BiBWBw36wk3aj+Yu8JD3X3I/wZm9SuiVp7M9ZZ
YDyX7VxhizdbrC0+/KOexla7hnLtzPfEHzrO1rOf3Yqz71LcWFjbF2H3HCOj
3cStdEJ5OeN6U4DYLXy45yxFTHSvph+X22uKtgib9aUGANb7OK21uI6WjJ6X
MN7Lg3kQNBmmNTGELbMIQ3aFKNiOmIqKPaNxAPxUwCCVA42bLJ3aNEH3AAMM
FId8+uoreTBZWxp/zw/rZe+rKgruBxeyLNKECcP+EPmMnD/CutbD6gLqDTzV
cSZoBscqWqmjZoRdXSR1w+tAvSChTDRCagsWD6Cwj3Bqs6Dbf/aFC7VON6lO
nS/yA1hiAFC6p99MtZMM/UYYgr8XGll53X2g3d/fq4kiN0RCf2DSR8xRVyNp
HVq5M8ZZUvHlB67nbYxPHPOyOxPpjeBOwT/9OpVi3frr2AaUZNZTzAM2dHKh
p0YL9q+BZptn0WKAzjdVTkbMUMhvwwggHuBgkqhkiG9w0BBwEwHQYJYIZIAW
UDBAEqBBBAz7LpDqW08uEZwSrdu0s7gIIBwKhSSSqj3Zg5OMbHp6cus2D/Ca
Y/hp+v3EVddS0CYYNR4L4I4cqk3MT1EeCpUyyUN8mUZD5+jG+BrHuJfWOZPU
SAfp6VdWES/UYRZGNi2iSbpJzuQaoENX5kqE1W0fF+V7I7yfyFUxkZRGtpE7
4TibdvUR5VycZ0O31iOUDwkXJaIGD8LYMUhc94oG2zEb3hNyAfhEleRKSHbY
NZXv/Ghc9EfbX9grnlGeudyved15rCv60aMU+NsWnVsrlX2s0W7ewBkVJDCd
8MYokAYlOFaGzn0nBazb7yYXL5aJuy+V9d3tqjmOtN1ic4KqXZaOQSa6B4xx
pWzeu/TFgGj7/fz7NfPeufSwU1eoObi2iTZ39jKKcu4jFerFLy6/0J71kyZd
89YQtbAjGOu1/PfV3R23SLV95CP2WrYIvG9Cxu+lYD/WSM23sD5BHCvAdnWH
DFwrjPGkZb75YOy3VJwz8kAbzkqqQ52V9CngFACuPMNOfHkUC/eRRFdeYHyp
JQ6GEnjPOStWZ3pAk/XqCOngh4wQEsU22goya+J0LpeBpMi+mcXsRC8h519l
Ulqr+/zsn8tIra3YpLSjAa6RqTpJ+R9Q8=]
certbot_sync_server: internal-sto3-test-cs-1.cdn.sunet.se

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICwQG6Z0+xcV2HribPifp0MXXY9GLdISS9dHF1+qUdlw root@internal-sto3-test-cache-1.cdn.sunet.se

View file

@ -0,0 +1,3 @@
The system documentation is in the docs directory of the multiverse repository.

View file

@ -0,0 +1,39 @@
---
cdn::cache-secrets:
customers:
customer1:
key: ENC[PKCS7,MIIDCwYJKoZIhvcNAQcDoIIC/DCCAvgCAQAxggKTMIICjwIBADB3MF8xCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxMDAuBgNVBAMMJ2ludGVybmFsLXN0bzMtdGVzdC1jYWNoZS0yLmNkbi5zdW5ldC5zZQIUdz1N+zcs0PBGXqzkGwE/CGSTG5MwDQYJKoZIhvcNAQEBBQAEggIAI1BuG1SsQnLmrCgY+Sy2Vl0DslfUWntWhgmy+VNiN+DsGqJM1u46LY7KHCUstssofwafq8OFaSFRc22L63VQaHgY/LYMV/6OwvNWsNb7H4h6giXKTYbqVDwU6+sSvbGA34Yk/YdodPTHmMu+fJVXNAiVIcmUJ2KvPBboiD89lLwwyREP98hFF5tjJm91EuuS4q8msatrw7hB2R/Us1SWp+Jb4Yqh2h4hvkXtVMjrzbjDzZYSdgBm/3uJAvFaEkI5f43DLcv5I9ZZS+eX/Yame7YMheR8Kcc67RfTqiAmqFCNltLQ1yMTMDHICuCay+chuah/SYVrXilbalBxqtiTtUBkJ8LW2DwvHfQXvhtcpkQ/4wMXsSIHO4qLvUbIgze/T+zreUSgJYcqOSymYJPGM66G7mfsva5FDlEfIz15Cia9+uF7LQcw6e1vJitSy7bbL+I8HHoX+KhlfGC7I21+OBTF8j7Ju+Qj11zUa4WmZYRQxdirhJCKaD1djA+oYOffqMZ3zFD8CQidJ+uxGLTCrCR5A2zs4Z4gasWvETmrRwg6Gv4wBcx3908euruHJ7scYk4pTJWCySa5INsD6uNLWBPcspfXd/PEmFgp8SjR8lCkmoGcDgzx6AkuT/wf0w9dUmdmbG6p+pBfXWR2ROhWHOHvj/C8vHZJb8XivMuHyTowXAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQN81EZkXnsIsb1Lrj4J8Hd4AwdJUyG/D8DCU8fMySPfIHTHk6f5EFMDNPYhyO71d0zeDusHXuNWF9dxBjtGhezG4k]
host: ENC[PKCS7,MIIC+wYJKoZIhvcNAQcDoIIC7DCCAugCAQAxggKTMIICjwIBADB3MF8xCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxMDAuBgNVBAMMJ2ludGVybmFsLXN0bzMtdGVzdC1jYWNoZS0yLmNkbi5zdW5ldC5zZQIUdz1N+zcs0PBGXqzkGwE/CGSTG5MwDQYJKoZIhvcNAQEBBQAEggIAn6fTKq6YOMlpahab4milaa/CYsIv9sWj2hTLeVtfRo0VaFTI2BVIu/2w/1Rk2JAYSPo3M97ToNOA09ZdmsgFnLwBXt54QeSrYQ1qzN8XLvcZrp+1FHvrmjSlB4VnKCq/Kp0Z0XzNVJ5pDLniJyXSV2efhzKqifWP9feMFvsCXgdpbJXc0+arFHBRN8CcBJvlJde6Nq5LzTWHN2NXrIOr3m8vLcPnsQEX9SFKy7tS9l6YXnxBmLmkvHciJHgFNzuIu2gfpuDfRpNjo5UGTeEhv8tMqyhYqPBNE/OtmycacGS4fd3juab4XMfT+HM7WV84khQyejJCDdhxvIIT8XM5mDYVS2z+qhnkqRugJEqo149jAtnXYQRSQgS4Cebj7oYaYFjhpxdALUrK4sPxxFqPewmpIJdtVUpmU8UjiwdZA3yQnnKGQby2hgOZN2mekbqWvzaNdxRwCakqeTESHJ/J0aedUz1fPNzaydbIJWK68oxmzHU2XQgQE1D3B1NJWldKvt4FOkzQYyouBltoyzcpRAScQUF5ty+mvfI14+omKDiecWwJMdzColjKML9X76aPdsSgbq5jw8tjjI4D+VXSGLU6xP1DCPZjLlj0TP1yhVxxOPkt+VtxO40jzM/HJ/yHDuS/BWP4z6KxOQRJnpGUFg0AFQk0tinQ1IUmG8EuDxIwTAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQ3ky0SRUp0ChVrTTCkWAKKoAgkFfDRY4ia37Jc55b18VfTvayazimefkS6sq7Pp7TlHg=]
ip4: ENC[PKCS7,MIIC6wYJKoZIhvcNAQcDoIIC3DCCAtgCAQAxggKTMIICjwIBADB3MF8xCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxMDAuBgNVBAMMJ2ludGVybmFsLXN0bzMtdGVzdC1jYWNoZS0yLmNkbi5zdW5ldC5zZQIUdz1N+zcs0PBGXqzkGwE/CGSTG5MwDQYJKoZIhvcNAQEBBQAEggIA4DpAdWaE1EvqEpHG03q+F4lc69CY5T93xZ/DGzr82aMbU2DyP0UJ9eKxkdn6Qak0wHFfIl2C1qy/RXw9T8/6YABGop4VL2Jlu74Qz+Jv+9hbiBIfLvmLYfY+s5MhkcLGtKmcdTwVKHGuki7NWPHp3iX9LFggJhWlQSdEuoJ/OFwzEiK3H5DxxitvBURPoicomgWKbRM0iAqV1iM3nNFUB/6cbTAb/WHwuA+K/AWBhTIhuB4M5lTfBqPoGBUDkHepZQJ7dXdax90y9Avgrx5rxnLtzhXcdsuJ+lPLbHYrEfOvImncf4l/Px51pT3FxkwZJpF0qgUqHgnioGb2KXpL1pIDL3ePtLTsFcM8gMSbG/d04BZ2HGHzK09e95fgF9HgTN6GZo4PHP+eWpdyR3UGNylWH6PVMuzyEA+UgrxcGMmqXNsMWgT8hjVDj5D5GUxaGmS4DnbgoWY7QKSHsKQCP2EN+h2nUDWai8AJ7jyjRs2eJ0yoKtobmgcMkrfh4osnaQpjNiBxfE/D8l/VSWCvKmv8/ETG5c7nRSztaUAtvq8ysEBNaAyPuB8g8Nu7z3s2Hr/p7hfMzM0VNZY4b7DlvGmPqs5Av0lZV+IWK/t69DMyjlWplKqNoMZ87f6t7WxtGjvbUXhHYUwGQZMXWuaLiAtmaMYxYwhqQtbLykbPIRYwPAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQ1TMTF9KdFFxqTTCw01QcuYAQz26QlHGb4gPFOaByg8YpyQ==]
ip6: ENC[PKCS7,MIIC+wYJKoZIhvcNAQcDoIIC7DCCAugCAQAxggKTMIICjwIBADB3MF8xCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxMDAuBgNVBAMMJ2ludGVybmFsLXN0bzMtdGVzdC1jYWNoZS0yLmNkbi5zdW5ldC5zZQIUdz1N+zcs0PBGXqzkGwE/CGSTG5MwDQYJKoZIhvcNAQEBBQAEggIAP2FzvJqxJUktd4ydtawRbHZmbgQ0Db9k6E09c3YC9VgSBfBd5IhUjsf7smoPRGoHywoqW8MthPZxH/QQ7iwTAZuDCLRZ6SOlyrF6lfuH4QSUltrERjn2xntdyCiZTTL8p18mdwVK4cwyYv+aG7ztpC4aP+SahJ56pCwWSl9dA/695r9MI6a2Objf6E+biu92s5l5i8fPMleZU3en39lJ8XfiqG/z1u/Vf0f3HoGrsVeOt9rRuN6jFHRPomiFnz89kx2/UypcNU1P5MoC/q0t4dO2BcoTjcmDTwHuPzNWc8ukmW1JNNgZX2AAmjuOR2XHHOU2FijPiIni5opISFPi8lc1QNu1ptPn1OqruR5deSMJiDF/jRNZSk3RSBhoG4SXpxuStW/jmmMWdUILSn1GnYIqA0sPJvXqpeGDRRsqft+crRFnh13z8Uw/QDmQY+voRVRjRrGBD2uGnyX7QE+Ju+FP20fwdhLGdCOoi0Ea9RCJxFFWfLtZVAkmkUDbUI4xUww+Mkv8ITvbr73agBEPaoCdBc5hjzmaj+e/ZatH51p+WtY6rG+IWG441kpW4B1E5et2MQWqxCSEY82IrnliQ1LBOut9jjFLfe/UuoiddmOeBmYtsiCR7vxURDn8kG+wHvmfnAr2n+EDkf+2ojWkP9N07R8pSM+yBKCB9tTrZ38wTAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQj7eyNfGf3w8lSc1fh6PG0YAgWEtO8a6fOZPuxD6o/C5XJDmQHewD7NykrK1qiF5Tjdo=]
origins:
- ENC[PKCS7,MIIC6wYJKoZIhvcNAQcDoIIC3DCCAtgCAQAxggKTMIICjwIBADB3MF8xCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxMDAuBgNVBAMMJ2ludGVybmFsLXN0bzMtdGVzdC1jYWNoZS0yLmNkbi5zdW5ldC5zZQIUdz1N+zcs0PBGXqzkGwE/CGSTG5MwDQYJKoZIhvcNAQEBBQAEggIAwrENSsgv+k4c96RjXy2Ps5p+l0qgiCouAgVMNQg3Tusrr1kbjnhsb0NpKE46Yiulm1Zw7aBpeXQzR2BVIgGo9uWu/7TF2P7CbMzZAKW5YEu53ccAwN/BRcunNlJTptxwaSRsHcv8nrO3Jo7vcfxN40pZDpWSlFcSu5xHHPwWHyKrERvjwl2wDjbBvRtDIfv8OJAx68J2kMrC1PcZ3WBK/tgO9IMJIFp+lKq+qwBx5Sbtckuyjz1L95iynIjQfetWqrF8SB0Svv80BRbdx4ONSrpgHH1hwplmWI+HlIYtMOkOZisQYdzWu39XloQHYq42fn6nt22lTx7ZTAR913ZFgH7KvUY9VRmq5zwYD10veY2QqelOhE6OE4BBmF0nRDzLRY+QZl8ancCkWNkbKlThNqtsoNzm9A6pKXlsJw/MdwDPxm0WE/m75BjXzObovisWp7yY9zLqJv2CdGtWuaXDQIXLPaCntXX8ZaEidSpcgnjXF9sfnknzvqvPibws3TQcyzTaemPYFScGX1Dp8wzQB72TJhusNUB1NyzRHApPlXB8PKLBlwR+hxogIaoq5HSmLmtkyi9wT2Gs8aC3dbvZA+OBgEdEi5Z2WcurUI4dFcyiKiSUDdRCjHWwiOii6BYvxZ7FCwifqeyRap0MvOstKGE47TsUSxwVS4zB/l3hZTswPAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQd3iYJWuQ0pbXRzv0mca4+4AQ8aZp4Ri24FUXRut6lhxkNw==]
certbot_sync_client_ssh_key: >
ENC[PKCS7,MIIEnwYJKoZIhvcNAQcDoIIEkDCCBIwCAQAxggKTMIICjwIBAD
B3MF8xCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRV
lBTUwxMDAuBgNVBAMMJ2ludGVybmFsLXN0bzMtdGVzdC1jYWNoZS0yLmNkbi
5zdW5ldC5zZQIUdz1N+zcs0PBGXqzkGwE/CGSTG5MwDQYJKoZIhvcNAQEBBQ
AEggIAINGGnOJTuI8d+uB+J/3cTogIZ8ZGmynF25X0wMHgJcxyic7ONyfHuH
c8waNdHN4Lm5uTboFbSbcc69/41EqHNTrfQfZEhEn6hLHXbPXOLtQwAhWJeZ
CLH1p6UNFA7ZBngsgwENEmOqr0ZrX3fiv/yLKQwPbmQ8QdoD+SNIOVjy65Mm
0AgXDEL1K0XRtqsZnS9Vsvr1DJc105rT4JWCGbJGEJXvVSWdk1uKfux3SdUl
XsOCwELdChPANurjSoYkkMBKcPJ8B4ucvheXTB0fqA4euxy8JVkIjmadi9KS
Ccua1NPifBePhRP57N0PCSdR7HIhHZ/vLXps8FN3NYM6mH9WNnX5+7ZzL5ad
egNjdgIRIvo3Nhzx2p7Nq3oAnF+Tqsx50/dg7o8xhVojos+V2Mp8t/f6xnmQ
xK3/WCgygdO0+5Nu6sMQX3PhWUAt2n7ZSHpzKCHhxPcBG7XnBwjbHgCvcb+4
BTXHgAzSgmWfiTpcSudh/M6ZdSyndLL/EZYGUkWUu5A8W0quBJmUOa0H47Nn
JdAbZSKGkBfzJnBwQ9Tk4D6+UteI7UXpzHsGokzkNy+XDwELIKwbAy3ko2rQ
k3B3LryMtvFNL/BUvT+TCcFHOFMa/dciPPDDtTHFxZrdJrxeNOe4ozeQiQe6
wYuFY4jrRy8q0V2V4UdumtHKz9Wr8wggHuBgkqhkiG9w0BBwEwHQYJYIZIAW
UDBAEqBBAQRjMsWP7S0C6vH6483EKUgIIBwLHsyfda1R2PTM0lrpDllyrZfH
egF6lLdS9pwUHle0yukAAB6x+cn21/WDraZVIIKXY/rKqApk7B1x2FesSOp1
XN9hIWkJVLidnZWfXVd5WB96QYAZb4VuiD9HIgAuxhas0yW34J48sUSyDPqC
9McA+lr+2S9BqwPbIc/befDC4RIEAYPDrO2D/Mlg6Xs1Ndf58zmbhGMQDcS5
OHRGouLux5WOuoKlzoq2gxmow9LVB97IGi3VSEBROEgYyNwT99tXt7RK8mD+
pEWxb8iFzgSwdSF7sW0uYXkEwIDRNyAZdBhhThjcCvor04qMJTWNhGBMb0fA
Q5j7Xm2XN5GyS0Yye6kIH09hGVV6YdDPJsaGdzZbc4bRD4hCp6LF+Wm75SE/
8xF6hYZB7PIJkwfjwKu4WvTbsNRBiYE2ChJ4KasTfYym33AHoshuLyai8B1N
hZqiWAFbb6d12Dj4H0ynpvFQAg0fy6/b0qej4r3meRpcNqxE3ZVwJJvhUe39
djZMmjpYOEqfZTRn5vFm5JRSNEAjOcZYv4ZUVvYX34Tw1w55wu7mtZmrauYG
aRTysUnzlJmYOO7uRBJQGM3IXw7vtOxAc=]
certbot_sync_server: internal-sto3-test-cs-1.cdn.sunet.se

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKa8qWdZCU7Gp4aOfhHlfER4qiCTseCmCc+d2KSqiYGa root@internal-sto3-test-cache-2.cdn.sunet.se

View file

@ -0,0 +1,3 @@
The system documentation is in the docs directory of the multiverse repository.

View file

@ -0,0 +1,8 @@
---
certbot_acmed_clients:
cdn-test-backend.cdn.sunet.se:
allowfrom: []
fulldomain: e1964cbb-2f19-41ce-b989-15714a745810.acme-d.sunet.se
password: ENC[PKCS7,MIIDCAYJKoZIhvcNAQcDoIIC+TCCAvUCAQAxggKQMIICjAIBADB0MFwxCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxLTArBgNVBAMMJGludGVybmFsLXN0bzMtdGVzdC1jcy0xLmNkbi5zdW5ldC5zZQIUJlvw/7wY1TOzXi6H8ObMJGmJvZgwDQYJKoZIhvcNAQEBBQAEggIAYl467khNDapRl/e6mNxm0fssTMqWAMBou3ggthEN1ELsaSgdCUKs5jG6pMHhctrdEu99mG9FqPg3P2NL+8zYVfD+gnu0eysPVANKPT2XZDhTpScQXH0An42cPCZ/zpK12TTvSyeOG6I9iKtYIALDNREtd/Byaw2xkH579XtYVDIxTbJrJHJSvoXOAElCdcDJ7iuC1hF2Ixz+M6Z6ePs9jFyE7Ju6SbrLq7pQY8fFVhAA5cp9/s/7rQPFL9ESzgPKNxOnjIfOclvPzIuPjA8y66aKPKMkPRjlTkH894MjuMGmAF+Db3SKF+fGWz8yFsgZit4fIMG99zSwUT4GJWbmOtMEvNxOQC7oLqK3Epr41m29Vt+dYjsRvQF8rrd5eoTpMuXwYoaCGVwvJsL+ELCPn29jBBFffqrLsRsr2f1zJlVAD9A/YdN0KLbyIFFRzCrQTztOGT5l/0zEilQ2Ru3DdcXHVWD7Sb8Cx8IH76wtgENS6las7smn8zSSIYzrJhjEr78eDpeppqqmKEQ9+QcQ4V7bVvDAfp3e0+tIHlDKMBSm/KrPnGFCnheh5Piy1F0USOxnTYUiHLJXVBXdgRFSQXnwlJvCs6JAX4nd/rpcuzK+fQaVUEu/34ikEzllZ9MU88b77c0hK14McolL0KyDFlJQCmhdk6RsNacIf0tF1oIwXAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQkE0ZZCYx797tDYM8tluLoIAwHPV4+SiGJyf6p9FRUyLLNyqZL5TDu5qqGEL+iCaE6Hy/J80zpCMuYkkB5zzh8BkX]
subdomain: e1964cbb-2f19-41ce-b989-15714a745810
username: b4d1ebe7-98d4-440d-aa3a-2c958efbdbb8

View file

@ -0,0 +1,22 @@
certbot_sync_client_ssh_keys_db:
'internal-sto3-test-cache-1.cdn.sunet.se':
key : 'AAAAC3NzaC1lZDI1NTE5AAAAICwQG6Z0+xcV2HribPifp0MXXY9GLdISS9dHF1+qUdlw'
type : 'ssh-ed25519'
name : 'internal-sto3-test-cache-1.cdn.sunet.se'
options : 'command="/usr/bin/rrsync -no-lock /etc/letsencrypt/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding'
'internal-sto3-test-cache-2.cdn.sunet.se':
key : 'AAAAC3NzaC1lZDI1NTE5AAAAIKa8qWdZCU7Gp4aOfhHlfER4qiCTseCmCc+d2KSqiYGa'
type : 'ssh-ed25519'
name : 'internal-sto3-test-cache-2.cdn.sunet.se'
options : 'command="/usr/bin/rrsync -no-lock /etc/letsencrypt/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding'
certbot_sync_client_ssh_keys_mapping:
'root':
- 'internal-sto3-test-cache-1.cdn.sunet.se'
- 'internal-sto3-test-cache-2.cdn.sunet.se'
certbot_sync_client_ips:
- 89.45.237.149 # internal-sto3-test-cache-1.cdn.sunet.se
- 2001:6b0:40::4c6 # internal-sto3-test-cache-1.cdn.sunet.se
- 192.36.171.94 # internal-sto3-test-cache-2.cdn.sunet.se
- 2001:6b0:8:7:526b:8dff:fe80:2fb5 # internal-sto3-test-cache-2.cdn.sunet.se

View file

@ -0,0 +1,3 @@
The system documentation is in the docs directory of the multiverse repository.

View file

@ -0,0 +1,4 @@
---
cdn::db-secrets:
postgres_password: ENC[PKCS7,MIIDCAYJKoZIhvcNAQcDoIIC+TCCAvUCAQAxggKQMIICjAIBADB0MFwxCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxLTArBgNVBAMMJGludGVybmFsLXN0bzMtdGVzdC1kYi0xLmNkbi5zdW5ldC5zZQIUbbUXduFvDLw3OUVWiGrIvFBkkJMwDQYJKoZIhvcNAQEBBQAEggIAGKLk12OT5zsVKd04qsLkFtawdauLYUERXUC3d9FtZNVpwCFDNMnSsruUfasOvyvdaRbm8AUk/nAGuBNjD9HJj8J45KfQUEAPstnZPHndkF51LwU1twFrZvcSnvFANvxh61MzccMz6NVQL5CXsw4IWMDNhUbkhO5cRfxc0SOVugeTZ74BWwpEww9uKVPtfPRKCgJayBq1o/fyQblGsjJbmu/dRCm32gcdZu1lqfDU0DLsnjk14GJpqpP5h6sEfSrdXyFcWzFzdjtLZLL6TfUWYNYX6CnjjRMv1zZ73877DPXt+vvi0Nvqld5CDTXM9ggDWwZKvluVGn7sTyZdwtWLvs1qK4nui7NLfENtBrUi/GOWsxoFa9tmfeeX/cticzzQcUdDNkfaDgmBa/C7lyjlkwyDGvhYdBHycSEJJ8rxncjBGKl79mpWlK0YTsppgD5eXWZSK7gC3PecRqQ7Jri3aBAWymlM7wfJYP8Z5ocEEq7+BLKSk0Z+Npj8PqJkQ0mw96QC5kNY2LfnGTPbBPpyBZRfZh3F2x1fLN+JQN+IgMpzLW2Oce5HWlPn9iTgCiZU/7mRDJKe8wI4gSg+Mf6hWqlC+NIcMOdAcrfvobzx3PVDHletTd0xgdgGEJpOvtpkYCqcdDbFX4kyEntMaMmp32XBcgsUy1b09uHMB2klzncwXAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQereGW4ZbKx3BV6f/PqkgSYAwcqDeq645K3JJOx9su/j9qDcAGxJN1CqIJjkYFBI+/2euykTaCvIqUMhljoDjeJeE]
cdn_password: ENC[PKCS7,MIIDCAYJKoZIhvcNAQcDoIIC+TCCAvUCAQAxggKQMIICjAIBADB0MFwxCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxLTArBgNVBAMMJGludGVybmFsLXN0bzMtdGVzdC1kYi0xLmNkbi5zdW5ldC5zZQIUbbUXduFvDLw3OUVWiGrIvFBkkJMwDQYJKoZIhvcNAQEBBQAEggIAC2YvfQOuluAonjkj0iM5DABoSNLXLyjlXfkltBOtAWzlFAQfQNlKd9cArL0qthcge+4AYun9edbyrmKjBAqVYIjPZXMaUjN9HXa07vBwUaHUXUP/rSxL6JYWKAvZTUCnSS+rb/nUM8BAAodk2xNnDrd0H/VN2oBQMkFvWJbCX2/NS9zejr4BpcGTTLjr1GXOuRMwORXwNTHVYZBbZzltnXMRClcdUe9oeIfC2W0BJDTlvAsqVN4DAz985hP8b5vch3uTd59Qzr7pIqpdno8hoI75zdVZ+xeH31rYw5/wqHmsvQK3gvVTtp5zmO4lSWwhiyGfICsX1w/8Fa8j/qR17dfqzkWVWJVN4DN2O/iT1muMtP4WP4j5xvWusE1viW4qGnoFlheo9YVTCP08FLMn0BMyO/7r1AZNG0oDNhTw/DcGYRc0q1bF8L6LjprJrl8Ou7fZbxWcIuQ8UMC+aJPOI0vingTip7/nKhGIBSiplxxKPH3jB2G7NXnimi4sxgAXsXwSSHGTMZH6q46Kc7YrtzT6Vur0W8onQgqFw6Hg5kgybyrdU68skxqAHIQEV3bZ68e5f3MyKY5HxSse8IIngAQdF6mOvOf6JB3zQ98m/JXDDV9FvaMLXSu4iUMGmoHJDO6xmMLaPUamJobM7SFA+0gPa3hAV7fejDdzhh6bLFYwXAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQCT1soHO5e0vaqTWVkkyhS4Awdqh/mowa1LW46di/aaHZp0wPie3eEZnaDsKrIAo4yMFi/Sd0QCXF8YjicLFt0vK5]

View file

@ -0,0 +1,3 @@
The system documentation is in the docs directory of the multiverse repository.

View file

@ -1,2 +1,2 @@
---
runner_token: ENC[PKCS7,MIIC7AYJKoZIhvcNAQcDoIIC3TCCAtkCAQAxggKUMIICkAIBADB4MGAxCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxMTAvBgNVBAMMKGludGVybmFsLXN0bzMtdGVzdC1ydW5uZXItMS5jZG4uc3VuZXQuc2UCFB8mr7Xs+11gtQ/ESDzi1+8CDVYHMA0GCSqGSIb3DQEBAQUABIICAMOCfrRasdX7b5ch7JEmc4Pb//CVwfr9eWlwnlWE4UUr4lu6WmIHj1QuTjETpcw9G4im6hGKjV+ygUN7WPRzTwxrT5qnsXj/AYM0pI4lfAfYzkejUKUDjv6kVbwfeyZpv2E6Od8OkpyqEWM4deepj2z+gUR4UTCsHsaH6rkB4+fM4YryKcV4XibUfuTwqNvoVVLXhrajwIvzuFAorGAVm0UzYUKmfuZRNzd0pgX20eKiHxEyoQkmdfFybVMO6KGmTMgTo5IXeyxCwU0F+D6LmVkr3mdAuy3XnzWusouGOL+wiCOO5f6lM6SoC7vcJryQYIyaevYIg9FhE9Y/4ZKNTUNosWL/z+zjJ7FjE+3NZOPepga5gIXV0Nngxz3ZXluhELxM70StGuikeEfAOW9XB8ldtpg36yZtkgHNIeCPCPwZpZhNJanTxj6DinFNcqaiKG0Bv928bTPq9SUzpMoFDX2HVFepId1dZZwlUn2zU9mG1NJoHS0WdX1Ex/K6lM9GgZhlAXARrfIhw4acejObU4pNnmbW7RIqI+vhdTW3kNF9RukfcrqjPPm/8QjrfOx5d51hQByUDj4NuXFt2RwX9z5V7LqQmqyVfph4pazO2EBxRSyxSn+mUgkPQeZ2pjKz2X5W2rV+bp3oLg8txe8ssewVN8Q07AzDs0m65Vhur5OCMDwGCSqGSIb3DQEHATAdBglghkgBZQMEASoEEBm7Xl7JL1MRLgIp/wHQh4CAELL4oYGSJe4mCqdYXxyIr8g=]
runner_token: ENC[PKCS7,MIIDDAYJKoZIhvcNAQcDoIIC/TCCAvkCAQAxggKUMIICkAIBADB4MGAxCzAJBgNVBAYTAlNFMQ4wDAYDVQQKDAVTVU5FVDEOMAwGA1UECwwFRVlBTUwxMTAvBgNVBAMMKGludGVybmFsLXN0bzMtdGVzdC1ydW5uZXItMS5jZG4uc3VuZXQuc2UCFB8mr7Xs+11gtQ/ESDzi1+8CDVYHMA0GCSqGSIb3DQEBAQUABIICAAS+hS99rx2LOFCVWGfCKalKqOjfevxe+PTOaDwRWjzYMpPye2ARy989CSMGzzgj4lmTw2I9Yo+NgpBlmc7BbvrzgIbXiwVzM17haymHpzhK9Qee6dsTLGLEqw0iEFjMDQJ4MOiZ4zC7zJYTZL0mBLam6rs3aolA5e5jT2XP1wA9BlC6M1ks66KxaBl0DpDWRP1wZgPAsCQQx+ktRO+cghAzAcksoSrPALgHDgCqozXqomBqhmTLCvuKqDJ/xrVL+qfXP9QnoMWflR26fj/2N2c0uqy9SkcLcJcPXVJPbA++18ri/HC+smtAAOI/tlUjzf24jVGvxMX1H+X3f+r7p84eYlmAK83JaMw22H2WaVaDDlvdDJgv0gP0cyE1ZKZYtfx/uvUBNV5mFmTvvNfEIODYGVVC5RT/FfP4STLjRZZkHoxeFOwYkRNNle+NAMyTbVYcDpDM9ytIyjwOPAfKrit2TTl/BmJa2liATbknH/PbsXjPRqEjKPqgEi72s4G3S/Vs0ZNxhn1LdUegHnCL39OgFsqP7XXw8GPBoPAvyKJdhREbumhMqrLdj/6ZC0pF06ERH0RPzFrneCzBnFAEw6Z8L2K9McD44Se5dob8TOzWhaGdklBCShqElL/irq1tVNrMbn4qFsJPSAwqzTzL8ELY9p5svYBE4YH69V0R5PVDMFwGCSqGSIb3DQEHATAdBglghkgBZQMEASoEEOVEVMVmnqlZ9q8GL1+Qg3KAMAkj6Zyc4JbHUA9SwnGZPc6Wjuohv0bDIdwaLtvgDAS8hiAyDIVQ2L03+cdsfaQisA==]