Compare commits

..

No commits in common. "main" and "update-cryptpad-2024.3.1" have entirely different histories.

47 changed files with 322 additions and 535 deletions

View file

@ -3,7 +3,3 @@ type = 'user'
description = 'LDAP base DN for everything' description = 'LDAP base DN for everything'
example = 'dc=example,dc=com' 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 { config {
image = "kokakiwi/cryptpad:2024.3.1" image = "kokakiwi/cryptpad:2024.3.0"
ports = [ "http" ] ports = [ "http" ]
volumes = [ volumes = [

View file

@ -80,9 +80,9 @@ job "garage" {
#### Configuration for service ports: admin port (internal use only) #### Configuration for service ports: admin port (internal use only)
service { service {
name = "garage-admin"
port = "admin" port = "admin"
address_mode = "host" address_mode = "host"
name = "garage-admin"
# Check that Garage is alive and answering TCP connections # Check that Garage is alive and answering TCP connections
check { check {
type = "tcp" type = "tcp"
@ -96,19 +96,18 @@ job "garage" {
} }
} }
#### Configuration for service ports: externally available ports (S3 API, K2V, web) #### Configuration for service ports: externally available ports (API, web)
service { service {
name = "garage-api"
tags = [ tags = [
"garage_api", "garage_api",
"tricot garage.deuxfleurs.fr", "tricot garage.deuxfleurs.fr",
"tricot *.garage.deuxfleurs.fr", "tricot *.garage.deuxfleurs.fr",
"tricot-on-demand-tls-ask http://garage-admin.service.prod.consul:3903/check",
"tricot-site-lb", "tricot-site-lb",
] ]
port = "s3" port = "s3"
address_mode = "host" address_mode = "host"
name = "garage-api"
# Check 1: Garage is alive and answering TCP connections # Check 1: Garage is alive and answering TCP connections
check { check {
name = "garage-api-live" name = "garage-api-live"
@ -133,39 +132,6 @@ job "garage" {
} }
service { 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 = [ tags = [
"garage-web", "garage-web",
"tricot * 1", "tricot * 1",
@ -178,6 +144,7 @@ job "garage" {
] ]
port = "web" port = "web"
address_mode = "host" address_mode = "host"
name = "garage-web"
# Check 1: Garage is alive and answering TCP connections # Check 1: Garage is alive and answering TCP connections
check { check {
name = "garage-web-live" name = "garage-web-live"
@ -216,6 +183,39 @@ job "garage" {
port = "web" port = "web"
on_update = "ignore" 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,7 +13,7 @@ job "guichet" {
task "guichet" { task "guichet" {
driver = "docker" driver = "docker"
config { config {
image = "dxflrs/guichet:0x4y7bj1qb8w8hckvpbzlgyxh63j66ij" image = "dxflrs/guichet:m1gzk1r00xp0kz566fwbpc87z7haq7xj"
args = [ "server", "-config", "/etc/config.json" ] args = [ "server", "-config", "/etc/config.json" ]
readonly_rootfs = true readonly_rootfs = true
ports = [ "web_port" ] ports = [ "web_port" ]

View file

@ -369,7 +369,7 @@ var config = {
// Message to show the users. Example: 'The service will be down for // Message to show the users. Example: 'The service will be down for
// maintenance at 01:00 AM GMT, // maintenance at 01:00 AM GMT,
// Does only support plaintext. No line skip. // Does only support plaintext. No line skip.
noticeMessage: "Suite à une utilisation contraire à nos CGU, Deuxfleurs surveille activement cette instance Jitsi et enverra tout contenu illégal à la police. Pour toute question, commentaire ou suggestion, contactez moderation@deuxfleurs.fr . Following usage breaching our TOS, Deuxfleurs actively monitors this Jitsi instance and will send any illegal behavior to the Police. For any question, remark or suggestion, reach moderation@deuxfleurs.fr", // noticeMessage: "Suite à une utilisation contraire à nos CGU, Deuxfleurs surveille activement cette instance Jitsi et enverra tout contenu illégal à la police. Pour toute question, commentaire ou suggestion, contactez moderation@deuxfleurs.fr . Following usage breaching our TOS, Deuxfleurs actively monitors this Jitsi instance and will send any illegal behavior to the Police. For any question, remark or suggestion, reach moderation@deuxfleurs.fr",
// Enables calendar integration, depends on googleApiApplicationClientID // Enables calendar integration, depends on googleApiApplicationClientID
// and microsoftApiApplicationClientID // and microsoftApiApplicationClientID

View file

@ -81,12 +81,6 @@ http {
alias /srv/jitsi-meet/$1/$2; alias /srv/jitsi-meet/$1/$2;
} }
# Disallow robots indexation
location = /robots.txt {
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /\n";
}
# not used yet VVV # not used yet VVV
# colibri (JVB) websockets # colibri (JVB) websockets
#location ~ ^/colibri-ws/([a-zA-Z0-9-\.]+)/(.*) { #location ~ ^/colibri-ws/([a-zA-Z0-9-\.]+)/(.*) {
@ -98,12 +92,12 @@ http {
#} #}
location ~* {{ key "secrets/jitsi/blacklist_regex" }} { location ~ "2daut2wank2|2duat2wank|2duat2wank0|2duat2wank1|2duat2wank2|2duat2wank3|2duatr2wank|2duatr2wank0|2duatr2wank1|2duatr2wank2|2wank2daut2|daut1|duat2wank|duat2wank2|duatr2wank2|prettypanties|slutgfs|wabk2daugther|wank2daugther|wank2daut|wank2daut2|wank2daut3|wankwatch" {
return 302 https://www.service-public.fr/particuliers/vosdroits/R17674; return 302 https://www.service-public.fr/particuliers/vosdroits/R17674;
} }
location = /http-bind { location = /http-bind {
if ($args ~* {{ key "secrets/jitsi/blacklist_regex" }}) { if ($args ~ "2daut2wank2|2duat2wank|2duat2wank0|2duat2wank1|2duat2wank2|2duat2wank3|2duatr2wank|2duatr2wank0|2duatr2wank1|2duatr2wank2|2wank2daut2|daut1|duat2wank|duat2wank2|duatr2wank2|prettypanties|slutgfs|wabk2daugther|wank2daugther|wank2daut|wank2daut2|wank2daut3|wankwatch") {
return 403 'forbidden'; return 403 'forbidden';
} }

View file

@ -75,30 +75,6 @@
address = "10.83.4.2"; address = "10.83.4.2";
endpoint = "82.65.41.110:33742"; 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";
};
"ortie" = {
siteName = "dathomir";
publicKey = "tbx2mvt3TN3Xd+ermwwZ6it80VWT5949cKH9BRFgvzE=";
address = "10.83.5.4";
endpoint = "82.64.238.84:33743";
};
}; };
# Pin Nomad version # Pin Nomad version

View file

@ -9,7 +9,3 @@ concombre.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL3N0QOFNGkC
courgette.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPCXJeo6yeQeTN7D7OZwLd8zbyU1jWywlhQ29yyk7x+G courgette.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPCXJeo6yeQeTN7D7OZwLd8zbyU1jWywlhQ29yyk7x+G
abricot.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPhHUQtc5lukPMFkiWf/sTgaUpwNFXHCJoQKu4ooRFy+ abricot.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPhHUQtc5lukPMFkiWf/sTgaUpwNFXHCJoQKu4ooRFy+
ananas.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHs0zAyBy70oyV56qaMaMAKR7VjEDnsm5LEyZJbM95BL 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
ortie.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMqtfIPLk8a5tM6Upj7GQwlIS16nBPrZYVXE2FVlO2Yn

View file

@ -1,11 +0,0 @@
{ ... }:
{
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

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

View file

@ -1,12 +0,0 @@
{ ... }:
{
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

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

View file

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

View file

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

View file

@ -1,12 +0,0 @@
{ ... }:
{
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

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

View file

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

View file

@ -33,14 +33,3 @@ Host abricot
Host ananas 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
Host ortie
HostName ortie.machine.deuxfleurs.fr

View file

@ -1,5 +1,5 @@
job "albatros" { job "albatros" {
datacenters = ["neptune", "dathomir", "corrin", "bespin"] datacenters = ["neptune", "jupiter", "corrin", "bespin"]
type = "service" type = "service"
priority = 90 priority = 90

View file

@ -2,7 +2,7 @@ job "builder" {
namespace = "ci" namespace = "ci"
type = "batch" type = "batch"
datacenters = ["neptune", "dathomir", "corrin", "bespin"] datacenters = ["neptune", "jupiter", "corrin", "bespin"]
priority = 100 priority = 100
parameterized { parameterized {

View file

@ -1,100 +0,0 @@
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

@ -1,5 +1,5 @@
job "core-d53" { job "core-d53" {
datacenters = ["neptune", "dathomir", "corrin", "bespin"] datacenters = ["neptune", "jupiter", "corrin", "bespin"]
type = "service" type = "service"
priority = 90 priority = 90

View file

@ -1,5 +1,5 @@
job "core-diplonat" { job "core-diplonat" {
datacenters = ["neptune", "dathomir", "corrin", "bespin"] datacenters = ["neptune", "jupiter", "corrin", "bespin"]
type = "system" type = "system"
priority = 90 priority = 90
@ -54,7 +54,7 @@ job "core-diplonat" {
data = <<EOH data = <<EOH
DIPLONAT_REFRESH_TIME=60 DIPLONAT_REFRESH_TIME=60
DIPLONAT_EXPIRATION_TIME=300 DIPLONAT_EXPIRATION_TIME=300
DIPLONAT_IPV6_ONLY={{ $site := env "meta.site" }}{{ if eq $site "corrin" }}false{{ else }}true{{ end }} DIPLONAT_IPV6_ONLY=true
DIPLONAT_CONSUL_NODE_NAME={{ env "attr.unique.hostname" }} DIPLONAT_CONSUL_NODE_NAME={{ env "attr.unique.hostname" }}
DIPLONAT_CONSUL_URL=https://localhost:8501 DIPLONAT_CONSUL_URL=https://localhost:8501
DIPLONAT_CONSUL_CA_CERT=/etc/diplonat/consul-ca.crt DIPLONAT_CONSUL_CA_CERT=/etc/diplonat/consul-ca.crt

View file

@ -1,5 +1,5 @@
job "core-tricot" { job "core-tricot" {
datacenters = ["neptune", "dathomir", "corrin", "bespin"] datacenters = ["neptune", "jupiter", "corrin", "bespin"]
type = "system" type = "system"
priority = 90 priority = 90
@ -25,7 +25,7 @@ job "core-tricot" {
config { config {
packages = [ packages = [
"git+https://git.deuxfleurs.fr/Deuxfleurs/tricot.git?ref=main&rev=9bb505d977cb8bafd8039159241788ff25510d69" "git+https://git.deuxfleurs.fr/Deuxfleurs/tricot.git?ref=redirect&rev=b76b6dcbcc47ebc61848389a6b0d5d4e8d8cde48"
] ]
command = "tricot" command = "tricot"
# cap_add = [ "net_bind_service" ] # this doesn't work for whatever reason, so we need to put user = "root" instead # cap_add = [ "net_bind_service" ] # this doesn't work for whatever reason, so we need to put user = "root" instead
@ -71,7 +71,6 @@ TRICOT_CONSUL_CLIENT_KEY=/etc/tricot/consul-client.key
TRICOT_HTTP_BIND_ADDR=[::]:80 TRICOT_HTTP_BIND_ADDR=[::]:80
TRICOT_HTTPS_BIND_ADDR=[::]:443 TRICOT_HTTPS_BIND_ADDR=[::]:443
TRICOT_METRICS_BIND_ADDR=[::]:9334 TRICOT_METRICS_BIND_ADDR=[::]:9334
TRICOT_WARMUP_CERT_MEMORY_STORE=true
RUST_LOG=tricot=debug RUST_LOG=tricot=debug
RUST_BACKTRACE=1 RUST_BACKTRACE=1
EOH EOH
@ -83,6 +82,9 @@ EOH
name = "tricot-http" name = "tricot-http"
port = "http_port" port = "http_port"
tags = [ 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))" "(diplonat (tcp_port 80))"
] ]
address_mode = "host" address_mode = "host"
@ -92,10 +94,7 @@ EOH
name = "tricot-https" name = "tricot-https"
port = "https_port" port = "https_port"
tags = [ 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" address_mode = "host"
} }

View file

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

View file

@ -1,15 +1,12 @@
{ {
"http_bind_addr": ":9991", "http_bind_addr": ":9991",
"ldap_server_addr": "ldap://{{ env "meta.site" }}.bottin.service.staging.consul:389", "ldap_server_addr": "ldap://bottin.service.staging.consul:389",
"base_dn": "{{ key "secrets/directory/ldap_base_dn" }}", "base_dn": "{{ key "secrets/directory/ldap_base_dn" }}",
"user_base_dn": "ou=users,{{ key "secrets/directory/ldap_base_dn" }}", "user_base_dn": "ou=users,{{ key "secrets/directory/ldap_base_dn" }}",
"user_name_attr": "cn", "user_name_attr": "cn",
"group_base_dn": "ou=groups,{{ key "secrets/directory/ldap_base_dn" }}", "group_base_dn": "ou=groups,{{ key "secrets/directory/ldap_base_dn" }}",
"group_name_attr": "cn", "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_base_dn": "ou=invitations,{{ key "secrets/directory/ldap_base_dn" }}",
"invitation_name_attr": "cn", "invitation_name_attr": "cn",

View file

@ -0,0 +1,133 @@
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

@ -1,51 +1,51 @@
# General configuration [secrets."directory/ldap_base_dn"]
[secrets."directory/guichet/web_hostname"]
type = 'user' type = 'user'
description = 'Public hostname from which Guichet is accessible via HTTP (e.g. guichet.example.com)' description = 'LDAP base DN for everything'
example = 'dc=example,dc=com'
# Mailing configuration
[secrets."directory/guichet/smtp_user"] [secrets."directory/guichet/smtp_user"]
type = 'user' type = 'user'
description = 'SMTP username' 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"] [secrets."directory/guichet/smtp_pass"]
type = 'user' type = 'user'
description = 'SMTP password' 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"] [secrets."directory/guichet/smtp_server"]
type = 'user' type = 'user'
description = 'SMTP server address (hostname:port)' 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"] [secrets."directory/guichet/mail_from"]
type = 'user' type = 'user'
description = 'E-mail address from which to send welcome emails to new users' description = 'E-mail address from which to send welcome emails to new users'
[secrets."directory/guichet/mail_domain"] [secrets."directory/guichet/mail_domain"]
type = 'user' type = 'user'
description = 'E-mail domain for new users (e.g. example.com)' description = 'E-mail domain for new users'
example = '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

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

View file

@ -1,12 +1,13 @@
job "garage-staging" { job "garage-staging" {
datacenters = [ "neptune", "dathomir", "corrin", "bespin" ]
type = "system" type = "system"
priority = 90 priority = 90
datacenters = [ "neptune", "jupiter", "corrin", "bespin" ]
update { update {
max_parallel = 2 max_parallel = 1
min_healthy_time = "60s" stagger = "1m"
min_healthy_time = "10s"
} }
group "garage-staging" { group "garage-staging" {
@ -18,27 +19,21 @@ job "garage-staging" {
port "admin" { static = 3909 } port "admin" { static = 3909 }
} }
update {
max_parallel = 10
min_healthy_time = "30s"
healthy_deadline = "5m"
}
task "server" { task "server" {
driver = "docker" driver = "nix2"
config { config {
image = "superboum/garage:v1.0.0-rc1-hotfix-red-ftr-wquorum" packages = [
command = "/garage" "#bash", # so that we can enter a shell inside container
args = [ "server" ] "#coreutils",
network_mode = "host" # garage v1.0.0-rc1 as of 2024-03-28
volumes = [ "git+https://git.deuxfleurs.fr/Deuxfleurs/garage.git?ref=next-0.10&rev=afad62939e071621666ca7255f7164f92c4475bb"
"/mnt/storage/garage-staging/data:/data",
"/mnt/ssd/garage-staging/meta:/meta",
"secrets/garage.toml:/etc/garage.toml",
"secrets:/etc/garage",
] ]
logging { command = "garage"
type = "journald" args = [ "server" ]
bind = {
"/mnt/storage/garage-staging/data" = "/data",
"/mnt/ssd/garage-staging/meta" = "/meta",
} }
} }
@ -46,24 +41,27 @@ job "garage-staging" {
RUST_LOG = "garage=info,garage_api=debug", RUST_LOG = "garage=info,garage_api=debug",
} }
# files currently owned by root, we don't want to chown everything
user = "root"
template { template {
data = file("../config/garage.toml") data = file("../config/garage.toml")
destination = "secrets/garage.toml" destination = "etc/garage.toml"
} }
template { template {
data = "{{ key \"secrets/consul/consul-ca.crt\" }}" data = "{{ key \"secrets/consul/consul-ca.crt\" }}"
destination = "secrets/consul-ca.crt" destination = "etc/garage/consul-ca.crt"
} }
template { template {
data = "{{ key \"secrets/consul/consul-client.crt\" }}" data = "{{ key \"secrets/consul/consul-client.crt\" }}"
destination = "secrets/consul-client.crt" destination = "etc/garage/consul-client.crt"
} }
template { template {
data = "{{ key \"secrets/consul/consul-client.key\" }}" data = "{{ key \"secrets/consul/consul-client.key\" }}"
destination = "secrets/consul-client.key" destination = "etc/garage/consul-client.key"
} }
resources { resources {
@ -75,68 +73,22 @@ job "garage-staging" {
kill_signal = "SIGINT" kill_signal = "SIGINT"
kill_timeout = "20s" kill_timeout = "20s"
restart {
interval = "5m"
attempts = 10
delay = "1m"
mode = "delay"
}
service { service {
name = "garage-staging-rpc" name = "garage-staging-rpc"
tags = ["garage-staging-rpc"] tags = ["garage-staging-rpc"]
port = "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 { service {
name = "garage-staging-s3-api" name = "garage-staging-s3-api"
tags = [ tags = [
"garage-staging-api", "garage-staging-api",
"tricot garage.staging.deuxfleurs.org", "tricot garage.staging.deuxfleurs.org",
"tricot *.garage.staging.deuxfleurs.org",
"tricot-add-header Access-Control-Allow-Origin *", "tricot-add-header Access-Control-Allow-Origin *",
"tricot-on-demand-tls-ask http://garage-staging-admin.service.staging.consul:3909/check",
"tricot-site-lb", "tricot-site-lb",
] ]
port = "s3" port = "s3"
# Check 1: Garage is alive and answering TCP connections
check { 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" port = "admin"
type = "http" type = "http"
path = "/health" path = "/health"
@ -154,21 +106,7 @@ job "garage-staging" {
"tricot-site-lb", "tricot-site-lb",
] ]
port = "k2v" port = "k2v"
# Check 1: Garage is alive and answering TCP connections
check { 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" port = "admin"
type = "http" type = "http"
path = "/health" path = "/health"
@ -181,34 +119,14 @@ job "garage-staging" {
name = "garage-staging-web" name = "garage-staging-web"
tags = [ tags = [
"garage-staging-web", "garage-staging-web",
"tricot * 1",
"tricot *.web.staging.deuxfleurs.org", "tricot *.web.staging.deuxfleurs.org",
"tricot staging.deuxfleurs.org", "tricot staging.deuxfleurs.org",
"tricot matrix.home.adnab.me/.well-known/matrix/server", "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-add-header Access-Control-Allow-Origin *",
"tricot-on-demand-tls-ask http://garage-staging-admin.service.staging.consul:3909/check",
"tricot-site-lb", "tricot-site-lb",
] ]
port = "web" port = "web"
# Check 1: Garage is alive and answering TCP connections
check { 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" port = "admin"
type = "http" type = "http"
path = "/health" path = "/health"
@ -216,6 +134,44 @@ job "garage-staging" {
timeout = "5s" 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,58 +0,0 @@
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,5 +1,5 @@
job "telemetry-service" { job "telemetry-service" {
datacenters = ["neptune", "dathomir", "corrin", "bespin"] datacenters = ["neptune", "jupiter", "corrin", "bespin"]
type = "service" type = "service"
group "prometheus" { group "prometheus" {
@ -79,6 +79,12 @@ job "telemetry-service" {
group "grafana" { group "grafana" {
count = 1 count = 1
constraint {
attribute = "${attr.unique.hostname}"
operator = "!="
value = "piranha"
}
network { network {
port "grafana" { port "grafana" {
static = 3719 static = 3719

View file

@ -1,5 +1,5 @@
job "telemetry-system" { job "telemetry-system" {
datacenters = ["neptune", "dathomir", "corrin", "bespin"] datacenters = ["neptune", "jupiter", "corrin", "bespin"]
type = "system" type = "system"
priority = "100" priority = "100"

View file

@ -14,7 +14,7 @@
endpoint = "77.207.15.215:33723"; endpoint = "77.207.15.215:33723";
}; };
"origan" = { "origan" = {
siteName = "dathomir"; siteName = "jupiter";
publicKey = "smBQYUS60JDkNoqkTT7TgbpqFiM43005fcrT6472llI="; publicKey = "smBQYUS60JDkNoqkTT7TgbpqFiM43005fcrT6472llI=";
address = "10.14.2.33"; address = "10.14.2.33";
endpoint = "82.64.238.84:33733"; endpoint = "82.64.238.84:33733";

View file

@ -1,4 +1,7 @@
{ ... }: # Configuration file local to this node
{ config, pkgs, ... }:
{ {
# Use the systemd-boot EFI boot loader. # Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;

View file

@ -1 +1 @@
../site/dathomir.nix ../site/jupiter.nix

View file

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

View file

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

View file

@ -1,6 +0,0 @@
{ ... }:
{
deuxfleurs.siteName = "dathomir";
deuxfleurs.staticIPv4.defaultGateway = "192.168.1.1";
deuxfleurs.cnameTarget = "dathomir.site.staging.deuxfleurs.org.";
}

View file

@ -0,0 +1,7 @@
{ config, pkgs, ... }:
{
deuxfleurs.siteName = "jupiter";
deuxfleurs.staticIPv4.defaultGateway = "192.168.1.1";
deuxfleurs.cnameTarget = "jupiter.site.staging.deuxfleurs.org.";
}

View file

@ -9,6 +9,11 @@ Host origan
HostName origan.machine.staging.deuxfleurs.org HostName origan.machine.staging.deuxfleurs.org
Host piranha 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 HostName piranha.machine.staging.deuxfleurs.org
Host df-pw5 Host df-pw5

View file

@ -175,12 +175,3 @@ Then, other stuff can be started in any order, e.g.:
- `app/cryptpad` - `app/cryptpad`
- `app/drone-ci` - `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...>
```

View file

@ -1,6 +0,0 @@
#!/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,9 +65,6 @@ SystemMaxUse=1G
wireguard-tools wireguard-tools
]; ];
# Enable support for all terminal emulators such as urxvt
environment.enableAllTerminfo = true;
programs.vim.defaultEditor = true; programs.vim.defaultEditor = true;
# Enable network time # Enable network time
@ -76,24 +73,7 @@ SystemMaxUse=1G
# Enable the OpenSSH daemon and disable password login. # Enable the OpenSSH daemon and disable password login.
services.openssh.enable = true; services.openssh.enable = true;
services.openssh.settings.PasswordAuthentication = false; services.openssh.passwordAuthentication = false;
# FIXME: Temporary patch for OpenSSH (CVE-2024-6387)
# Patches from backport PR: https://github.com/NixOS/nixpkgs/pull/323765
programs.ssh.package = pkgs.openssh.overrideAttrs(prev: {
patches = prev.patches ++ [
(pkgs.fetchpatch {
url = "https://raw.githubusercontent.com/emilazy/nixpkgs/c21c340818954576c6401ad460a9d42bab030bc4/pkgs/tools/networking/openssh/openssh-9.6_p1-CVE-2024-6387.patch";
hash = "sha256-B3Wz/eWSdOnrOcVzDv+QqzLGdFlb3jivQ8qZMC3d0Qw=";
})
(pkgs.fetchpatch {
url = "https://raw.githubusercontent.com/emilazy/nixpkgs/c21c340818954576c6401ad460a9d42bab030bc4/pkgs/tools/networking/openssh/openssh-9.6_p1-chaff-logic.patch";
hash = "sha256-lepBEFxKTAwg379iCD8KQCZVAzs3qNSSyUTOcartpK4=";
})
];
doCheck = false;
});
virtualisation.docker = { virtualisation.docker = {
enable = true; enable = true;

View file

@ -204,13 +204,6 @@ in
# link-local addresses # link-local addresses
networkConfig.IPv6AcceptRA = mkIf noRA false; networkConfig.IPv6AcceptRA = mkIf noRA false;
networkConfig.LinkLocalAddressing = mkIf noRA "no"; 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 # Configure Unbound as a central DNS server for everything

View file

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