From dc5350c20fb39fec554cf2d72222690d2016d33b Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 23 Mar 2024 18:03:08 +0100 Subject: [PATCH] fickit: Handle secrets more seriously --- admin/main.go | 32 ++++++++++++++++++++++++++++++++ fickit-backend.yml | 45 ++++++++++++++++++++++++++++++++++++++------- libfic/db.go | 11 +++++++++++ 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/admin/main.go b/admin/main.go index 38231285..d6977913 100644 --- a/admin/main.go +++ b/admin/main.go @@ -3,6 +3,7 @@ package main import ( "flag" "io/fs" + "io/ioutil" "log" "net/http" "os" @@ -10,6 +11,7 @@ import ( "path" "path/filepath" "strconv" + "strings" "syscall" "srs.epita.fr/fic-server/admin/api" @@ -39,9 +41,29 @@ func main() { } if v, exists := os.LookupEnv("FICOIDC_SECRET"); exists { api.OidcSecret = v + } else if v, exists := os.LookupEnv("FICOIDC_SECRET_FILE"); exists { + fd, err := os.Open(v) + if err != nil { + log.Fatal("Unable to open FICOIDC_SECRET_FILE:", err) + } + + b, _ := ioutil.ReadAll(fd) + api.OidcSecret = strings.TrimSpace(string(b)) + + fd.Close() } if v, exists := os.LookupEnv("FICCA_PASS"); exists { pki.SetCAPassword(v) + } else if v, exists := os.LookupEnv("FICCA_PASS_FILE"); exists { + fd, err := os.Open(v) + if err != nil { + log.Fatal("Unable to open FICCA_PASS_FILE:", err) + } + + b, _ := ioutil.ReadAll(fd) + pki.SetCAPassword(strings.TrimSpace(string(b))) + + fd.Close() } else { log.Println("WARNING: no password defined for the CA, will use empty password to secure CA private key") log.Println("WARNING: PLEASE DEFINE ENVIRONMENT VARIABLE: FICCA_PASS") @@ -54,6 +76,16 @@ func main() { } if v, exists := os.LookupEnv("FICCLOUD_PASS"); exists { cloudPassword = v + } else if v, exists := os.LookupEnv("FICCLOUD_PASS_FILE"); exists { + fd, err := os.Open(v) + if err != nil { + log.Fatal("Unable to open FICCLOUD_PASS_FILE:", err) + } + + b, _ := ioutil.ReadAll(fd) + cloudPassword = strings.TrimSpace(string(b)) + + fd.Close() } if v, exists := os.LookupEnv("FIC_BASEURL"); exists { baseURL = v diff --git a/fickit-backend.yml b/fickit-backend.yml index 5eeeb105..017377d4 100644 --- a/fickit-backend.yml +++ b/fickit-backend.yml @@ -143,6 +143,16 @@ onboot: - /etc/iptables/rules.v6:/etc/iptables/rules.v6:ro net: /run/netns/fic-admin + - name: create-secrets + image: alpine:3.19 + command: ["/bin/init_secrets.sh"] + binds: + - /bin/init_secrets.sh:/bin/init_secrets.sh:ro + - /var/lib/fic/secrets:/var/lib/fic/secrets + runtime: + mkdir: + - /var/lib/fic/secrets + services: # - name: getty # image: linuxkit/getty:5d86a2ce2d890c14ab66b13638dcadf74f29218b @@ -165,12 +175,13 @@ services: env: - MYSQL_DATABASE=fic - MYSQL_USER=fic - - MYSQL_PASSWORD=fic + - MYSQL_PASSWORD_FILE=/run/secrets/mysql_password - MYSQL_RANDOM_ROOT_PASSWORD=yes binds: - /etc/hosts:/etc/hosts:ro - /etc/mysql/conf.d:/etc/mysql/conf.d:ro - /var/lib/fic/mysql:/var/lib/mysql + - /var/lib/fic/secrets/mysql_password:/run/secrets/mysql_password:ro net: /run/netns/db pid: new ipc: new @@ -185,11 +196,12 @@ services: - MYSQL_HOST=db - MYSQL_DATABASE=fic - MYSQL_USER=fic - - MYSQL_PASSWORD=fic + - MYSQL_PASSWORD_FILE=/run/secrets/mysql_password binds: - /etc/hosts:/etc/hosts:ro - /root/mysql_backup.sh:/root/mysql_backup.sh:ro - /var/lib/fic/backups/:/var/lib/fic/backups/ + - /var/lib/fic/secrets/mysql_password:/run/secrets/mysql_password:ro net: /run/netns/db runtime: mkdir: @@ -200,11 +212,15 @@ services: env: - PATH=/usr/sbin:/usr/bin:/sbin:/bin - MYSQL_HOST=db - - FICCA_PASS=jee8AhloAith1aesCeQu5ahgIegaeM4K + - MYSQL_PASSWORD_FILE=/run/secrets/mysql_password + - FICCA_PASS_FILE=/run/secrets/fic_ca_pass - FICOIDC_ISSUER=live.fic.srs.epita.fr - - FICOIDC_SECRET=N4n7AXzK9kpXt3TmSn8wAgtxqxhGORgcubLaE2g + - FICOIDC_SECRET_FILE=/run/secrets/fic_oidc_secret binds: - /etc/hosts:/etc/hosts:ro + - /var/lib/fic/secrets/fic_ca_pass:/run/secrets/fic_ca_pass:ro + - /var/lib/fic/secrets/fic_oidc_secret:/run/secrets/fic_oidc_secret:ro + - /var/lib/fic/secrets/mysql_password:/run/secrets/mysql_password:ro - /var/lib/fic/raw_files:/mnt/fic - /var/lib/fic/dashboard:/srv/DASHBOARD - /var/lib/fic/files:/srv/FILES @@ -248,11 +264,12 @@ services: image: nemunaire/fic-checker:latest env: - MYSQL_HOST=db - - MYSQL_PASSWORD=fic + - MYSQL_PASSWORD_FILE=/run/secrets/mysql_password binds: - /etc/hosts:/etc/hosts:ro - /var/lib/fic/generator:/srv/GENERATOR:ro - /var/lib/fic/teams:/srv/TEAMS:ro + - /var/lib/fic/secrets/mysql_password:/run/secrets/mysql_password:ro - /var/lib/fic/settingsdist:/srv/SETTINGSDIST:ro - /var/lib/fic/submissions:/srv/submissions net: /run/netns/fic-checker @@ -288,11 +305,12 @@ services: command: ["/srv/generator", "-bind=/srv/GENERATOR/generator.socket"] env: - MYSQL_HOST=db - - MYSQL_PASSWORD=fic + - MYSQL_PASSWORD_FILE=/run/secrets/mysql_password binds: - /etc/hosts:/etc/hosts:ro - /var/lib/fic/generator:/srv/GENERATOR - /var/lib/fic/teams:/srv/TEAMS + - /var/lib/fic/secrets/mysql_password:/run/secrets/mysql_password:ro - /var/lib/fic/settingsdist:/srv/SETTINGSDIST:ro net: /run/netns/fic-generator pid: new @@ -308,10 +326,11 @@ services: command: ["/srv/qa", "--bind=:8083", "-baseurl=/qa"] env: - MYSQL_HOST=db - - MYSQL_PASSWORD=fic + - MYSQL_PASSWORD_FILE=/run/secrets/mysql_password binds: - /etc/hosts:/etc/hosts:ro - /var/lib/fic/teams:/srv/TEAMS:ro + - /var/lib/fic/secrets/mysql_password:/run/secrets/mysql_password:ro - /var/lib/fic/settingsdist:/srv/SETTINGSDIST:ro net: /run/netns/fic-qa pid: new @@ -383,6 +402,18 @@ files: /bin/hostname deimos mode: "0555" + - path: bin/init_secrets.sh + contents: | + #!/bin/sh + + SECRETS_DIR="/var/lib/fic/secrets" + + [ -f "${SECRETS_DIR}/mysql_password" ] || tr -d -c "a-zA-Z0-9" < /dev/urandom | fold -w31 | head -n 1 > "${SECRETS_DIR}/mysql_password" + + [ -f "${SECRETS_DIR}/fic_ca_pass" ] || tr -d -c "a-zA-Z0-9" < /dev/urandom | fold -w31 | head -n 1 > "${SECRETS_DIR}/fic_ca_pass" + [ -f "${SECRETS_DIR}/fic_oidc_secret" ] || tr -d -c "a-zA-Z0-9" < /dev/urandom | fold -w31 | head -n 1 > "${SECRETS_DIR}/fic_oidc_secret" + mode: "0755" + - path: etc/profile.d/color_prompt.sh contents: | PS1='\[\e[1;33m\]'$PS1'\[\e[0m\]' diff --git a/libfic/db.go b/libfic/db.go index 3d169006..ae6826ae 100644 --- a/libfic/db.go +++ b/libfic/db.go @@ -4,6 +4,7 @@ import ( "database/sql" "errors" "fmt" + "io/ioutil" "log" "os" "strings" @@ -36,6 +37,16 @@ func DSNGenerator() string { } if v, exists := os.LookupEnv("MYSQL_PASSWORD"); exists { db_password = v + } else if v, exists := os.LookupEnv("MYSQL_PASSWORD_FILE"); exists { + fd, err := os.Open(v) + if err != nil { + log.Fatal("Unable to open MYSQL_PASSWORD_FILE:", err) + } + + b, _ := ioutil.ReadAll(fd) + db_password = strings.TrimSpace(string(b)) + + fd.Close() } else if v, exists := os.LookupEnv("MYSQL_ROOT_PASSWORD"); exists { db_user = "root" db_password = v