Compare commits

...

25 commits

Author SHA1 Message Date
Quentin fa510688d7
update guichet 2024-06-24 13:52:18 +02:00
Baptiste Jonglez fc83048b02 staging: move bottin and guichet to docker, sync with prod config 2024-06-23 22:29:14 +02:00
Jill 86026c5642
cluster(prod/cryptpad): Update cryptpad image on Nomad cluster 2024-06-23 11:55:16 +02:00
Baptiste Jonglez 87464506ce staging: Passage garage en mode docker 2024-06-23 11:34:36 +02:00
baptiste 2f8b2c74f4 Merge pull request 'Upgrade cryptpad from 2024.3.0 to 2024.3.1' (#27) from KokaKiwi/nixcfg:update-cryptpad-2024.3.1 into main
Reviewed-on: Deuxfleurs/nixcfg#27
Reviewed-by: maximilien <me@mricher.fr>
2024-06-23 09:05:41 +00:00
Baptiste Jonglez 7e88a88e04 prod: garage: Enable on-demand-tls check for *.garage S3 endpoint
We were hitting Let's Encrypt rate limits because we were generating
thousands of non-sense certificates like "foo.bar.baz.garage.deuxfleurs.fr"

See https://crt.sh

Subdomains of garage.deuxfleurs.fr only make sense when accessing buckets
through S3 with vhost-style, so let's enable the on-demand-tls check to
make sure that the bucket exists in Garage.

In the long term, we might want to have a wildcard certificate for this
usage, or simply stop supporting vhost-style S3 access.
2024-06-08 17:14:48 +02:00
Baptiste Jonglez 9fc22d72d4 garage: harmonize staging and prod (checks, services) 2024-06-08 16:43:18 +02:00
Baptiste Jonglez cbb0093f2c staging: garage: Handle *.garage.staging for vhost-style S3 and add on-demand TLS checks 2024-06-08 16:35:35 +02:00
Baptiste Jonglez d4fb14347d staging: Upgrade tricot for on-demand TLS checks 2024-06-08 16:34:16 +02:00
Baptiste Jonglez 67794c53a3 Disable DHCPv6 and DHCPv6-PD in all cases 2024-06-02 21:35:36 +02:00
Baptiste Jonglez ba37244447 Add common terminfo for more terminal support 2024-06-02 21:35:22 +02:00
Baptiste Jonglez 8d475b2ee6 Fix nixos deprecation warning 2024-06-02 21:35:08 +02:00
Baptiste Jonglez 7aa220a2e1 Add small script to gather system information from machines 2024-05-31 11:35:00 +02:00
Baptiste Jonglez 1924f2f4ab sshtool: improve usage message 2024-05-31 11:34:38 +02:00
Baptiste Jonglez bdc7376df4 staging: make tricot config closer to prod 2024-05-30 23:47:38 +02:00
Baptiste Jonglez 22dba1f35c staging: enable IPv4 diplonat (UPnP) for corrin site 2024-05-30 23:42:48 +02:00
Baptiste Jonglez 7c174d6746 Revert "staging: disable allocation of grafana on piranha"
piranha is accessible on a more reliable network now.
2024-05-30 21:33:32 +02:00
Baptiste Jonglez 02bdc5a0c0 Move piranha to new network 2024-05-30 10:12:48 +02:00
maximilien 726f4b2f32 Merge pull request 'cluster(prod): Add dathomir site' (#25) from KokaKiwi/nixcfg:add-dathomir into main
Reviewed-on: Deuxfleurs/nixcfg#25
Reviewed-by: maximilien <me@mricher.fr>
2024-05-26 21:04:01 +00:00
Jill 37a2f781eb
prod(cluster/dathomir): Open more SSH ports 2024-05-26 23:00:39 +02:00
Jill 435cbeebfb
cluster(prod): Add oseille 2024-05-26 18:24:28 +02:00
Jill 3776734e50
style: Fix spacetab in cluster/prod/ssh_config 2024-05-26 17:04:33 +02:00
Jill 57628b508e
cluster(prod): Add io 2024-05-26 17:04:18 +02:00
Armaël Guéneau ef91461210 doc/architecture.md: ajout de la ligne de commande utile pour lancer la CLI garage 2024-05-26 12:43:03 +02:00
Jill a513690004
cluster(prod): Add dathomir site and onion node 2024-05-15 11:50:49 +02:00
34 changed files with 470 additions and 299 deletions

View file

@ -3,3 +3,7 @@ type = 'user'
description = 'LDAP base DN for everything'
example = 'dc=example,dc=com'
[secrets."d53/gandi_api_key"]
type = 'user'
description = 'Gandi API key'

View file

@ -26,7 +26,7 @@ job "cryptpad" {
}
config {
image = "kokakiwi/cryptpad:2024.3.0"
image = "kokakiwi/cryptpad:2024.3.1"
ports = [ "http" ]
volumes = [

View file

@ -80,9 +80,9 @@ job "garage" {
#### Configuration for service ports: admin port (internal use only)
service {
name = "garage-admin"
port = "admin"
address_mode = "host"
name = "garage-admin"
# Check that Garage is alive and answering TCP connections
check {
type = "tcp"
@ -96,18 +96,19 @@ job "garage" {
}
}
#### Configuration for service ports: externally available ports (API, web)
#### Configuration for service ports: externally available ports (S3 API, K2V, web)
service {
name = "garage-api"
tags = [
"garage_api",
"tricot garage.deuxfleurs.fr",
"tricot *.garage.deuxfleurs.fr",
"tricot-on-demand-tls-ask http://garage-admin.service.prod.consul:3903/check",
"tricot-site-lb",
]
port = "s3"
address_mode = "host"
name = "garage-api"
# Check 1: Garage is alive and answering TCP connections
check {
name = "garage-api-live"
@ -132,6 +133,39 @@ job "garage" {
}
service {
name = "garage-k2v"
tags = [
"garage_k2v",
"tricot k2v.deuxfleurs.fr",
"tricot-site-lb",
]
port = "k2v"
address_mode = "host"
# Check 1: Garage is alive and answering TCP connections
check {
name = "garage-k2v-live"
type = "tcp"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
# Check 2: Garage is in a healthy state and requests should be routed here
check {
name = "garage-k2v-healthy"
port = "admin"
type = "http"
path = "/health"
interval = "60s"
timeout = "5s"
}
}
service {
name = "garage-web"
tags = [
"garage-web",
"tricot * 1",
@ -144,7 +178,6 @@ job "garage" {
]
port = "web"
address_mode = "host"
name = "garage-web"
# Check 1: Garage is alive and answering TCP connections
check {
name = "garage-web-live"
@ -183,39 +216,6 @@ job "garage" {
port = "web"
on_update = "ignore"
}
service {
tags = [
"garage_k2v",
"tricot k2v.deuxfleurs.fr",
"tricot-site-lb",
]
port = "k2v"
address_mode = "host"
name = "garage-k2v"
# Check 1: Garage is alive and answering TCP connections
check {
name = "garage-k2v-live"
type = "tcp"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
# Check 2: Garage is in a healthy state and requests should be routed here
check {
name = "garage-k2v-healthy"
port = "admin"
type = "http"
path = "/health"
interval = "60s"
timeout = "5s"
}
}
}
}
}

View file

@ -13,8 +13,8 @@ job "guichet" {
task "guichet" {
driver = "docker"
config {
image = "dxflrs/guichet:m1gzk1r00xp0kz566fwbpc87z7haq7xj"
args = [ "server", "-config", "/etc/config.json" ]
image = "dxflrs/guichet:0x4y7bj1qb8w8hckvpbzlgyxh63j66ij"
args = [ "server", "-config", "/etc/config.json" ]
readonly_rootfs = true
ports = [ "web_port" ]
volumes = [

View file

@ -75,6 +75,24 @@
address = "10.83.4.2";
endpoint = "82.65.41.110:33742";
};
"onion" = {
siteName = "dathomir";
publicKey = "gpeqalqAUaYlMuebv3glQeZyE64+OpkyIHFhfStJQA4=";
address = "10.83.5.1";
endpoint = "82.64.238.84:33740";
};
"oseille" = {
siteName = "dathomir";
publicKey = "T87GzAQt02i00iOMbEm7McA/VL9OBrG/kCrgoNh5MmY=";
address = "10.83.5.2";
endpoint = "82.64.238.84:33741";
};
"io" = {
siteName = "dathomir";
publicKey = "3+VvWJtABOAd6zUCMROhqGbNtkQRtoIkVmYn0M81jQw=";
address = "10.83.5.3";
endpoint = "82.64.238.84:33742";
};
};
# Pin Nomad version

View file

@ -9,3 +9,6 @@ concombre.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL3N0QOFNGkC
courgette.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPCXJeo6yeQeTN7D7OZwLd8zbyU1jWywlhQ29yyk7x+G
abricot.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPhHUQtc5lukPMFkiWf/sTgaUpwNFXHCJoQKu4ooRFy+
ananas.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHs0zAyBy70oyV56qaMaMAKR7VjEDnsm5LEyZJbM95BL
onion.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINjBQ67fxwuDDzRPveTko/Sgf0cev3tIvlr3CfAmhF0C
oseille.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAgQdQ5UVFFn+DXN90ut9+V7NtEopQJnES3r8soKTZW4
io.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIvgCJ7Jew7ou1RZuaT41Sd+ucZAgxUwtdieqNqoC3+T

11
cluster/prod/node/io.nix Normal file
View file

@ -0,0 +1,11 @@
{ ... }:
{
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sda";
services.openssh.ports = [ 22 33603 ];
deuxfleurs.hostName = "io";
deuxfleurs.staticIPv4.address = "192.168.1.36";
deuxfleurs.staticIPv6.address = "2a01:e0a:5e4:1d0:52e5:49ff:fe5c:5f35";
}

View file

@ -0,0 +1 @@
../site/dathomir.nix

View file

@ -0,0 +1,12 @@
{ ... }:
{
boot.loader.systemd-boot.enable = true;
boot.loader.timeout = 20;
boot.loader.efi.canTouchEfiVariables = true;
services.openssh.ports = [ 22 33601 ];
deuxfleurs.hostName = "onion";
deuxfleurs.staticIPv4.address = "192.168.1.34";
deuxfleurs.staticIPv6.address = "2a01:e0a:5e4:1d0:223:24ff:feb0:e866";
}

View file

@ -0,0 +1 @@
../site/dathomir.nix

View file

@ -0,0 +1,12 @@
{ ... }:
{
boot.loader.systemd-boot.enable = true;
boot.loader.timeout = 20;
boot.loader.efi.canTouchEfiVariables = true;
services.openssh.ports = [ 22 33602 ];
deuxfleurs.hostName = "oseille";
deuxfleurs.staticIPv4.address = "192.168.1.35";
deuxfleurs.staticIPv6.address = "2a01:e0a:5e4:1d0:223:24ff:feaf:f90b";
}

View file

@ -0,0 +1 @@
../site/dathomir.nix

View file

@ -0,0 +1,7 @@
{ ... }:
{
deuxfleurs.siteName = "dathomir";
deuxfleurs.cnameTarget = "dathomir.site.deuxfleurs.fr";
deuxfleurs.publicIPv4 = "82.64.238.84";
deuxfleurs.staticIPv4.defaultGateway = "192.168.1.1";
}

View file

@ -1,35 +1,43 @@
UserKnownHostsFile ./cluster/prod/known_hosts
Host concombre
HostName concombre.machine.deuxfleurs.fr
HostName concombre.machine.deuxfleurs.fr
Host courgette
HostName courgette.machine.deuxfleurs.fr
HostName courgette.machine.deuxfleurs.fr
Host celeri
HostName celeri.machine.deuxfleurs.fr
HostName celeri.machine.deuxfleurs.fr
Host dahlia
HostName dahlia.machine.deuxfleurs.fr
HostName dahlia.machine.deuxfleurs.fr
Host diplotaxis
HostName diplotaxis.machine.deuxfleurs.fr
HostName diplotaxis.machine.deuxfleurs.fr
Host doradille
HostName doradille.machine.deuxfleurs.fr
HostName doradille.machine.deuxfleurs.fr
Host df-ykl
HostName df-ykl.machine.deuxfleurs.fr
HostName df-ykl.machine.deuxfleurs.fr
Host df-ymf
HostName df-ymf.machine.deuxfleurs.fr
HostName df-ymf.machine.deuxfleurs.fr
Host df-ymk
HostName df-ymk.machine.deuxfleurs.fr
HostName df-ymk.machine.deuxfleurs.fr
Host abricot
HostName abricot.machine.deuxfleurs.fr
HostName abricot.machine.deuxfleurs.fr
Host ananas
HostName ananas.machine.deuxfleurs.fr
HostName ananas.machine.deuxfleurs.fr
Host onion
HostName onion.machine.deuxfleurs.fr
Host oseille
HostName oseille.machine.deuxfleurs.fr
Host io
HostName io.machine.deuxfleurs.fr

View file

@ -0,0 +1,100 @@
job "core-bottin" {
datacenters = ["neptune", "jupiter", "corrin", "bespin"]
type = "system"
priority = 90
update {
max_parallel = 1
stagger = "1m"
}
group "bottin" {
constraint {
distinct_property = "${meta.site}"
value = "1"
}
network {
port "ldap_port" {
static = 389
to = 389
}
}
task "bottin" {
driver = "docker"
config {
image = "dxflrs/bottin:7h18i30cckckaahv87d3c86pn4a7q41z"
network_mode = "host"
readonly_rootfs = true
ports = [ "ldap_port" ]
volumes = [
"secrets/config.json:/config.json",
"secrets:/etc/bottin",
]
}
restart {
interval = "5m"
attempts = 10
delay = "15s"
mode = "delay"
}
resources {
memory = 100
memory_max = 200
}
template {
data = file("../config/bottin/config.json.tpl")
destination = "secrets/config.json"
}
template {
data = "{{ key \"secrets/consul/consul.crt\" }}"
destination = "secrets/consul.crt"
}
template {
data = "{{ key \"secrets/consul/consul-client.crt\" }}"
destination = "secrets/consul-client.crt"
}
template {
data = "{{ key \"secrets/consul/consul-client.key\" }}"
destination = "secrets/consul-client.key"
}
template {
data = <<EOH
CONSUL_HTTP_ADDR=https://consul.service.staging.consul:8501
CONSUL_HTTP_SSL=true
CONSUL_CACERT=/etc/bottin/consul.crt
CONSUL_CLIENT_CERT=/etc/bottin/consul-client.crt
CONSUL_CLIENT_KEY=/etc/bottin/consul-client.key
EOH
destination = "secrets/env"
env = true
}
service {
tags = [ "${meta.site}" ]
port = "ldap_port"
address_mode = "host"
name = "bottin"
check {
type = "tcp"
port = "ldap_port"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
}
}
}
}

View file

@ -54,7 +54,7 @@ job "core-diplonat" {
data = <<EOH
DIPLONAT_REFRESH_TIME=60
DIPLONAT_EXPIRATION_TIME=300
DIPLONAT_IPV6_ONLY=true
DIPLONAT_IPV6_ONLY={{ $site := env "meta.site" }}{{ if eq $site "corrin" }}false{{ else }}true{{ end }}
DIPLONAT_CONSUL_NODE_NAME={{ env "attr.unique.hostname" }}
DIPLONAT_CONSUL_URL=https://localhost:8501
DIPLONAT_CONSUL_CA_CERT=/etc/diplonat/consul-ca.crt

View file

@ -25,7 +25,7 @@ job "core-tricot" {
config {
packages = [
"git+https://git.deuxfleurs.fr/Deuxfleurs/tricot.git?ref=redirect&rev=b76b6dcbcc47ebc61848389a6b0d5d4e8d8cde48"
"git+https://git.deuxfleurs.fr/Deuxfleurs/tricot.git?ref=main&rev=9bb505d977cb8bafd8039159241788ff25510d69"
]
command = "tricot"
# cap_add = [ "net_bind_service" ] # this doesn't work for whatever reason, so we need to put user = "root" instead
@ -71,6 +71,7 @@ TRICOT_CONSUL_CLIENT_KEY=/etc/tricot/consul-client.key
TRICOT_HTTP_BIND_ADDR=[::]:80
TRICOT_HTTPS_BIND_ADDR=[::]:443
TRICOT_METRICS_BIND_ADDR=[::]:9334
TRICOT_WARMUP_CERT_MEMORY_STORE=true
RUST_LOG=tricot=debug
RUST_BACKTRACE=1
EOH
@ -82,9 +83,6 @@ EOH
name = "tricot-http"
port = "http_port"
tags = [
"d53-aaaa ${attr.unique.hostname}.machine.staging.deuxfleurs.org",
"d53-aaaa ${meta.site}.site.staging.deuxfleurs.org",
"d53-aaaa staging.deuxfleurs.org",
"(diplonat (tcp_port 80))"
]
address_mode = "host"
@ -94,7 +92,10 @@ EOH
name = "tricot-https"
port = "https_port"
tags = [
"(diplonat (tcp_port 443))"
"(diplonat (tcp_port 443))",
"d53-aaaa ${attr.unique.hostname}.machine.staging.deuxfleurs.org",
"d53-aaaa ${meta.site}.site.staging.deuxfleurs.org",
"d53-aaaa staging.deuxfleurs.org"
]
address_mode = "host"
}

View file

@ -1,3 +1,8 @@
[secrets."directory/ldap_base_dn"]
type = 'user'
description = 'LDAP base DN for everything'
example = 'dc=example,dc=com'
[secrets."d53/gandi_api_key"]
type = 'user'
description = 'Gandi API key'

View file

@ -1,133 +0,0 @@
job "directory" {
datacenters = ["neptune", "jupiter", "corrin", "bespin"]
type = "service"
priority = 90
constraint {
attribute = "${attr.cpu.arch}"
value = "amd64"
}
group "bottin" {
count = 1
network {
port "ldap_port" {
static = 389
}
}
task "bottin" {
driver = "nix2"
config {
packages = [
"git+https://git.deuxfleurs.fr/Deuxfleurs/bottin.git?ref=main&rev=9cab98d2cee386ece54b000bbdf2346da8b55eed"
]
command = "bottin"
}
user = "root" # needed to bind port 389
resources {
memory = 100
}
template {
data = file("../config/bottin/config.json.tpl")
destination = "config.json"
}
template {
data = "{{ key \"secrets/consul/consul-ca.crt\" }}"
destination = "etc/bottin/consul-ca.crt"
}
template {
data = "{{ key \"secrets/consul/consul-client.crt\" }}"
destination = "etc/bottin/consul-client.crt"
}
template {
data = "{{ key \"secrets/consul/consul-client.key\" }}"
destination = "etc/bottin/consul-client.key"
}
template {
data = <<EOH
CONSUL_HTTP_ADDR=https://localhost:8501
CONSUL_HTTP_SSL=true
CONSUL_CACERT=/etc/bottin/consul-ca.crt
CONSUL_CLIENT_CERT=/etc/bottin/consul-client.crt
CONSUL_CLIENT_KEY=/etc/bottin/consul-client.key
EOH
destination = "secrets/env"
env = true
}
service {
tags = ["bottin"]
port = "ldap_port"
name = "bottin"
check {
type = "tcp"
port = "ldap_port"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
}
}
}
group "guichet" {
count = 1
network {
port "web_port" { static = 9991 }
}
task "guichet" {
driver = "nix2"
config {
packages = [
"git+https://git.deuxfleurs.fr/Deuxfleurs/guichet.git?ref=main&rev=10bdee10cf6947ec6dd0ba5040d7274d6c3316a7"
]
command = "guichet"
}
template {
data = file("../config/guichet/config.json.tpl")
destination = "config.json"
}
resources {
memory = 200
}
service {
name = "guichet"
tags = [
"guichet",
"tricot guichet.staging.deuxfleurs.org",
"d53-cname guichet.staging.deuxfleurs.org",
]
port = "web_port"
check {
type = "tcp"
port = "web_port"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
}
}
}
}

View file

@ -25,6 +25,7 @@ tls_skip_verify = true
[s3_api]
s3_region = "garage-staging"
api_bind_addr = "0.0.0.0:3990"
root_domain = ".garage.staging.deuxfleurs.org"
[k2v_api]
api_bind_addr = "0.0.0.0:3993"

View file

@ -1,13 +1,12 @@
job "garage-staging" {
datacenters = [ "neptune", "jupiter", "corrin", "bespin" ]
type = "system"
priority = 90
datacenters = [ "neptune", "jupiter", "corrin", "bespin" ]
update {
max_parallel = 1
stagger = "1m"
min_healthy_time = "10s"
max_parallel = 2
min_healthy_time = "60s"
}
group "garage-staging" {
@ -19,21 +18,27 @@ job "garage-staging" {
port "admin" { static = 3909 }
}
task "server" {
driver = "nix2"
update {
max_parallel = 10
min_healthy_time = "30s"
healthy_deadline = "5m"
}
task "server" {
driver = "docker"
config {
packages = [
"#bash", # so that we can enter a shell inside container
"#coreutils",
# garage v1.0.0-rc1 as of 2024-03-28
"git+https://git.deuxfleurs.fr/Deuxfleurs/garage.git?ref=next-0.10&rev=afad62939e071621666ca7255f7164f92c4475bb"
]
command = "garage"
image = "superboum/garage:v1.0.0-rc1-hotfix-red-ftr-wquorum"
command = "/garage"
args = [ "server" ]
bind = {
"/mnt/storage/garage-staging/data" = "/data",
"/mnt/ssd/garage-staging/meta" = "/meta",
network_mode = "host"
volumes = [
"/mnt/storage/garage-staging/data:/data",
"/mnt/ssd/garage-staging/meta:/meta",
"secrets/garage.toml:/etc/garage.toml",
"secrets:/etc/garage",
]
logging {
type = "journald"
}
}
@ -41,27 +46,24 @@ job "garage-staging" {
RUST_LOG = "garage=info,garage_api=debug",
}
# files currently owned by root, we don't want to chown everything
user = "root"
template {
data = file("../config/garage.toml")
destination = "etc/garage.toml"
destination = "secrets/garage.toml"
}
template {
data = "{{ key \"secrets/consul/consul-ca.crt\" }}"
destination = "etc/garage/consul-ca.crt"
destination = "secrets/consul-ca.crt"
}
template {
data = "{{ key \"secrets/consul/consul-client.crt\" }}"
destination = "etc/garage/consul-client.crt"
destination = "secrets/consul-client.crt"
}
template {
data = "{{ key \"secrets/consul/consul-client.key\" }}"
destination = "etc/garage/consul-client.key"
destination = "secrets/consul-client.key"
}
resources {
@ -73,22 +75,68 @@ job "garage-staging" {
kill_signal = "SIGINT"
kill_timeout = "20s"
restart {
interval = "5m"
attempts = 10
delay = "1m"
mode = "delay"
}
service {
name = "garage-staging-rpc"
tags = ["garage-staging-rpc"]
port = "rpc"
}
#### Configuration for service ports: admin port (internal use only)
service {
name = "garage-staging-admin"
tags = [
"garage-staging-admin",
]
port = "admin"
check {
name = "garage-tcp-liveness-check"
type = "tcp"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
}
#### Configuration for service ports: externally available ports (S3 API, K2V, web)
service {
name = "garage-staging-s3-api"
tags = [
"garage-staging-api",
"tricot garage.staging.deuxfleurs.org",
"tricot *.garage.staging.deuxfleurs.org",
"tricot-add-header Access-Control-Allow-Origin *",
"tricot-on-demand-tls-ask http://garage-staging-admin.service.staging.consul:3909/check",
"tricot-site-lb",
]
port = "s3"
# Check 1: Garage is alive and answering TCP connections
check {
name = "garage-staging-api-live"
type = "tcp"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
# Check 2: Garage is in a healthy state and requests should be routed here
check {
name = "garage-staging-api-healthy"
port = "admin"
type = "http"
path = "/health"
@ -106,7 +154,21 @@ job "garage-staging" {
"tricot-site-lb",
]
port = "k2v"
# Check 1: Garage is alive and answering TCP connections
check {
name = "garage-staging-k2v-live"
type = "tcp"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
# Check 2: Garage is in a healthy state and requests should be routed here
check {
name = "garage-staging-k2v-healthy"
port = "admin"
type = "http"
path = "/health"
@ -119,14 +181,34 @@ job "garage-staging" {
name = "garage-staging-web"
tags = [
"garage-staging-web",
"tricot * 1",
"tricot *.web.staging.deuxfleurs.org",
"tricot staging.deuxfleurs.org",
"tricot matrix.home.adnab.me/.well-known/matrix/server",
"tricot-add-header Strict-Transport-Security max-age=63072000; includeSubDomains; preload",
"tricot-add-header X-Frame-Options SAMEORIGIN",
"tricot-add-header X-XSS-Protection 1; mode=block",
"tricot-add-header X-Content-Type-Options nosniff",
"tricot-add-header Access-Control-Allow-Origin *",
"tricot-on-demand-tls-ask http://garage-staging-admin.service.staging.consul:3909/check",
"tricot-site-lb",
]
port = "web"
# Check 1: Garage is alive and answering TCP connections
check {
name = "garage-staging-web-live"
type = "tcp"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
# Check 2: Garage is in a healthy state and requests should be routed here
check {
name = "garage-staging-web-healthy"
port = "admin"
type = "http"
path = "/health"
@ -134,44 +216,6 @@ job "garage-staging" {
timeout = "5s"
}
}
service {
name = "garage-staging-admin"
tags = [
"garage-staging-admin",
]
port = "admin"
check {
name = "garage-admin-health-check"
type = "http"
path = "/health"
interval = "60s"
timeout = "5s"
check_restart {
limit = 10
grace = "90s"
ignore_warnings = true
}
}
check {
name = "garage-tcp-liveness-check"
type = "tcp"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = true
}
}
}
restart {
interval = "5m"
attempts = 10
delay = "1m"
mode = "delay"
}
}
}
}

View file

@ -1,12 +1,15 @@
{
"http_bind_addr": ":9991",
"ldap_server_addr": "ldap://bottin.service.staging.consul:389",
"ldap_server_addr": "ldap://{{ env "meta.site" }}.bottin.service.staging.consul:389",
"base_dn": "{{ key "secrets/directory/ldap_base_dn" }}",
"user_base_dn": "ou=users,{{ key "secrets/directory/ldap_base_dn" }}",
"user_name_attr": "cn",
"group_base_dn": "ou=groups,{{ key "secrets/directory/ldap_base_dn" }}",
"group_name_attr": "cn",
"mailing_list_base_dn": "ou=mailing_lists,ou=groups,{{ key "secrets/directory/ldap_base_dn" }}",
"mailing_list_name_attr": "cn",
"mailing_list_guest_user_base_dn": "ou=guests,ou=users,{{ key "secrets/directory/ldap_base_dn" }}",
"invitation_base_dn": "ou=invitations,{{ key "secrets/directory/ldap_base_dn" }}",
"invitation_name_attr": "cn",

View file

@ -0,0 +1,58 @@
job "guichet" {
datacenters = ["neptune", "jupiter", "corrin", "bespin"]
type = "service"
priority = 90
group "guichet" {
count = 1
network {
port "web_port" { to = 9991 }
}
task "guichet" {
driver = "docker"
config {
image = "dxflrs/guichet:m1gzk1r00xp0kz566fwbpc87z7haq7xj"
args = [ "server", "-config", "/etc/config.json" ]
readonly_rootfs = true
ports = [ "web_port" ]
volumes = [
"secrets/config.json:/etc/config.json"
]
}
template {
data = file("../config/guichet/config.json.tpl")
destination = "secrets/config.json"
}
resources {
memory = 200
}
service {
name = "guichet"
tags = [
"guichet",
"tricot guichet.staging.deuxfleurs.org",
"d53-cname guichet.staging.deuxfleurs.org",
]
port = "web_port"
address_mode = "host"
check {
type = "tcp"
port = "web_port"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
}
}
}
}

View file

@ -1,51 +1,51 @@
[secrets."directory/ldap_base_dn"]
# General configuration
[secrets."directory/guichet/web_hostname"]
type = 'user'
description = 'LDAP base DN for everything'
example = 'dc=example,dc=com'
description = 'Public hostname from which Guichet is accessible via HTTP (e.g. guichet.example.com)'
# Mailing configuration
[secrets."directory/guichet/smtp_user"]
type = 'user'
description = 'SMTP username'
[secrets."directory/guichet/s3_access_key"]
type = 'user'
description = 'Garage access key for Guichet profile pictures'
[secrets."directory/guichet/s3_endpoint"]
type = 'user'
description = 'S3 endpoint URL'
[secrets."directory/guichet/s3_region"]
type = 'user'
description = 'S3 region'
[secrets."directory/guichet/smtp_pass"]
type = 'user'
description = 'SMTP password'
[secrets."directory/guichet/web_hostname"]
type = 'user'
description = 'Public hostname from which Guichet is accessible via HTTP'
example = 'guichet.example.com'
[secrets."directory/guichet/s3_bucket"]
type = 'user'
description = 'S3 bucket in which to store data files (such as profile pictures)'
[secrets."directory/guichet/smtp_server"]
type = 'user'
description = 'SMTP server address (hostname:port)'
[secrets."directory/guichet/s3_secret_key"]
type = 'user'
description = 'Garage secret key for Guichet profile pictures'
[secrets."directory/guichet/mail_from"]
type = 'user'
description = 'E-mail address from which to send welcome emails to new users'
[secrets."directory/guichet/mail_domain"]
type = 'user'
description = 'E-mail domain for new users'
example = 'example.com'
description = 'E-mail domain for new users (e.g. example.com)'
# S3 configuration
[secrets."directory/guichet/s3_endpoint"]
type = 'user'
description = 'S3 endpoint URL'
[secrets."directory/guichet/s3_bucket"]
type = 'user'
description = 'S3 bucket in which to store data files (such as profile pictures)'
[secrets."directory/guichet/s3_region"]
type = 'user'
description = 'S3 region'
[secrets."directory/guichet/s3_access_key"]
type = 'user'
description = 'Garage access key for Guichet profile pictures'
[secrets."directory/guichet/s3_secret_key"]
type = 'user'
description = 'Garage secret key for Guichet profile pictures'

View file

@ -79,12 +79,6 @@ job "telemetry-service" {
group "grafana" {
count = 1
constraint {
attribute = "${attr.unique.hostname}"
operator = "!="
value = "piranha"
}
network {
port "grafana" {
static = 3719

View file

@ -9,8 +9,8 @@
boot.loader.efi.canTouchEfiVariables = true;
deuxfleurs.hostName = "piranha";
deuxfleurs.staticIPv4.address = "192.168.1.25";
deuxfleurs.staticIPv6.address = "2a01:cb05:911e:ec00:223:24ff:feb0:ea82";
deuxfleurs.staticIPv4.address = "192.168.5.25";
deuxfleurs.staticIPv6.address = "2001:912:1ac0:2200::25";
system.stateVersion = "22.11";
}

View file

@ -2,7 +2,7 @@
{
deuxfleurs.siteName = "corrin";
deuxfleurs.staticIPv4.defaultGateway = "192.168.1.1";
deuxfleurs.staticIPv4.defaultGateway = "192.168.5.1";
deuxfleurs.cnameTarget = "corrin.site.staging.deuxfleurs.org.";
deuxfleurs.publicIPv4 = "109.222.162.50";
deuxfleurs.publicIPv4 = "45.81.62.36";
}

View file

@ -9,11 +9,6 @@ Host origan
HostName origan.machine.staging.deuxfleurs.org
Host piranha
HostName %h.machine.staging.deuxfleurs.org
#HostName piranha.polyno.me
#OR
#ProxyJump caribou.machine.deuxfleurs.fr
#HostName 10.14.3.1
HostName piranha.machine.staging.deuxfleurs.org
Host df-pw5

View file

@ -175,3 +175,12 @@ Then, other stuff can be started in any order, e.g.:
- `app/cryptpad`
- `app/drone-ci`
## Operating garage
Garage is operated using its command-line interface, which can be accessed using
any node of the cluster running garage:
```
docker ps # to find the identifier of the container running garage
docker exec -ti <id> /garage <cli args...>
```

6
gather_facts Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env ./sshtool
cmd lsblk -o name,size,type,mountpoint,rota,fstype,fsused,fsuse%
cmd "lscpu | grep 'Model name'"
cmd lscpu -e=cpu,minmhz,maxmhz,mhz
cmd lsmem --summary

View file

@ -65,6 +65,9 @@ SystemMaxUse=1G
wireguard-tools
];
# Enable support for all terminal emulators such as urxvt
environment.enableAllTerminfo = true;
programs.vim.defaultEditor = true;
# Enable network time
@ -73,7 +76,7 @@ SystemMaxUse=1G
# Enable the OpenSSH daemon and disable password login.
services.openssh.enable = true;
services.openssh.passwordAuthentication = false;
services.openssh.settings.PasswordAuthentication = false;
virtualisation.docker = {
enable = true;

View file

@ -204,6 +204,13 @@ in
# link-local addresses
networkConfig.IPv6AcceptRA = mkIf noRA false;
networkConfig.LinkLocalAddressing = mkIf noRA "no";
# By default, systemd-networkd may try to use DHCPv6 depending on RA flags.
# Disable DHCPv6 client and IPv6 Prefix Delegation in all cases.
ipv6AcceptRAConfig.DHCPv6Client = false;
dhcpV6Config.UseAddress = false;
dhcpV6Config.UseDelegatedPrefix = false;
};
# Configure Unbound as a central DNS server for everything

View file

@ -13,7 +13,7 @@ CMDFILE=./$(basename $CMDFILE)
CLUSTER="$1"
if [ -z "$CLUSTER" ] || [ ! -d "cluster/$CLUSTER" ]; then
echo "Usage: $CMDFILE <cluster name>"
echo "Usage: $CMDFILE <cluster name> [host1] [host2] [...]"
echo "The cluster name must be the name of a subdirectory of cluster/"
exit 1
fi