Ta strona wygląda najlepiej z włączoną obsługą JavaScript
Bezpieczne zarządzanie sekretami - Korzystanie z HashiCorp Vault z GitLab CI/CD
· ☕ 11 min czytania
· 🐧 sysadmin
Oto film instruktażowy
Wstęp
Poniżej przedstawiam zintegrowany tutorial obejmujący instalację HashiCorp Vault na osobnym serwerze oraz jego integrację z GitLab Runnerami. Dzięki temu zapewnimy bezpieczne przechowywanie sekretów i ich wykorzystanie w pipeline’ach GitLab CI/CD.
Błąd “tls: failed to verify certificate: x509: cannot validate certificate for 10.10.0.150 because it doesn’t contain any IP SANs” oznacza, że certyfikat SSL używany przez Vault nie zawiera informacji o IP w polu Subject Alternative Name (SAN). Zalecane jest wygenerowanie poprawnego certyfikatu SSL z odpowiednim polem SAN. Po wykonaniu tych kroków, Vault powinien poprawnie zaakceptować połączenia HTTPS i pozwolić na dalszą konfigurację oraz inicjalizację.
2a. Stwórz plik konfiguracyjny OpenSSL dla certyfikatu z IP SAN
Musisz wygenerować nowy certyfikat, który zawiera IP adres jako SAN.
Gdy uruchamiasz polecenie sudo journalctl -u vault.service, widzisz ostrzeżenie:
1
WARN[0000]log.go:244 gosnowflake.(*defaultLogger).Warn DBUS_SESSION_BUS_ADDRESS envvar looks to be not set, this can lead to runaway dbus-daemon processes. To avoid this, set envvar DBUS_SESSION_BUS_ADDRESS=$XDG_RUNTIME_DIR/bus (if it exists) or DBUS_SESSION_BUS_ADDRESS=/dev/null.
Ostrzeżenie DBUS_SESSION_BUS_ADDRESS envvar looks to be not set, this can lead to runaway dbus-daemon processes wskazuje, że zmienna środowiskowa DBUS_SESSION_BUS_ADDRESS nie jest ustawiona. Może to prowadzić do niekontrolowanych procesów dbus-daemon, co może powodować problemy z zasobami.
Aby rozwiązać ten problem, należy ustawić zmienną środowiskową DBUS_SESSION_BUS_ADDRESS w pliku .bashrc.
Zdefiniuj zmienne środowiskowe w ustawieniach CI/CD projektu::
VAULT_ADDR = https://<vault_server_ip>:8200
VAULT_TOKEN = <vault_token>
Jeśli dodasz zmienne środowiskowe VAULT_TOKEN i VAULT_ADDR w ustawieniach CI/CD projektu w GitLab, nie musisz deklarować ich ponownie w pliku .gitlab-ci.yml. GitLab automatycznie przekaże te zmienne do wszystkich zadań w pipeline.
Dodaj certyfikat Vault w GitLab runners
Pobierz certyfikat SSL z Vault:
Najpierw pobierz certyfikat SSL używany przez Vault:
variables:# Definiuje URL repozytoriumREPO_URL:'git@gitlab.sysadmin.homes:developers/taiko.git'# Definiuje gałąź do użyciaBRANCH:'main'# Ścieżka do przechowywania raportówREPORT_PATH:'/workspace'# Nazwa raportuREPORT_NAME:'TAIKO_AUTOMATED_TESTS'# Obraz Docker do użyciaDOCKER_IMAGE:"taiko"# Strategia Git do użyciaGIT_STRATEGY:clone# Pomija pobieranie Chromium dla TaikoTAIKO_SKIP_CHROMIUM_DOWNLOAD:"true"stages:# Definiuje etapy dla potoku CI/CD- clean- build_and_test- cleanupbefore_script:# Sprawdza, czy ssh-agent jest zainstalowany, jeśli nie, instaluje openssh-client- 'which ssh-agent || ( apk update && apk add openssh-client )'# Uruchamia ssh-agent w tle- eval $(ssh-agent -s)# Tworzy katalog .ssh, jeśli nie istnieje- mkdir -p ~/.ssh# Ustawia uprawnienia katalogu .ssh na 700- chmod 700 ~/.ssh# Tworzy pusty plik known_hosts, jeśli nie istnieje- touch ~/.ssh/known_hosts# Ustawia uprawnienia pliku known_hosts na 644- chmod 644 ~/.ssh/known_hosts# Dodaje klucz prywatny z zmiennej środowiskowej do pliku i usuwa znaki powrotu karetki - echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_ed25519# Ustawia uprawnienia pliku klucza prywatnego na 400- chmod 400 ~/.ssh/id_ed25519# Dodaje klucz prywatny do ssh-agent- ssh-add ~/.ssh/id_ed25519# Tworzy plik konfiguracyjny SSH z ustawieniami dla hosta GitLab- echo -e "Host gitlab.sysadmin.homes\n\tUser git\n\tHostname gitlab.sysadmin.homes\n\tIdentityFile ~/.ssh/id_ed25519\n\tIdentitiesOnly yes\n\tStrictHostKeyChecking no" > ~/.ssh/config# Dodaje adres IP serwera GitLab do /etc/hosts- echo "10.10.0.119 gitlab.sysadmin.homes" >> /etc/hosts# Instaluje OpenSSL, jq i curl, jeśli nie są już zainstalowane- apk add --no-cache openssl jq curl# Pobiera certyfikat SSL z serwera GitLab i zapisuje go do pliku- echo -n | openssl s_client -connect gitlab.sysadmin.homes:443 -servername gitlab.sysadmin.homes | openssl x509 > gitlab.crt# Kopiuje pobrany certyfikat do katalogu zaufanych certyfikatów- cp gitlab.crt /usr/local/share/ca-certificates/gitlab.crt# Pobiera certyfikat SSL z serwera HashiCorp Vault i zapisuje go do pliku- echo -n | openssl s_client -connect 10.10.0.150:8200 -servername 10.10.0.150 | openssl x509 > vault.crt# Kopiuje pobrany certyfikat do katalogu zaufanych certyfikatów- cp vault.crt /usr/local/share/ca-certificates/vault.crt# Aktualizuje listę zaufanych certyfikatów- update-ca-certificates# Eksportuje poświadczenia AWX z HashiCorp Vault- | export AWX_SECRET=$(curl --silent --header "X-Vault-Token: $VAULT_TOKEN" $VAULT_ADDR/v1/secret/data/gitlab/awx)
export AWX_USERNAME=$(echo $AWX_SECRET | jq -r '.data.data.login')
export AWX_PASSWORD=$(echo $AWX_SECRET | jq -r '.data.data.password')# Eksportuje poświadczenia ArgoCD z HashiCorp Vault- | export ARGOCD_SECRET=$(curl --silent --header "X-Vault-Token: $VAULT_TOKEN" $VAULT_ADDR/v1/secret/data/gitlab/argocd)
export ARGOCD_USERNAME=$(echo $ARGOCD_SECRET | jq -r '.data.data.login')
export ARGOCD_PASSWORD=$(echo $ARGOCD_SECRET | jq -r '.data.data.password')# Zmienne NPM_USER i NPM_PASS nie są poprawnie przekazywane do Dockerfile, gdy są eksportowane w sekcji before_script. # Docker buduje obraz przed uruchomieniem skryptów before_script, więc zmienne te nie są dostępne w czasie budowania obrazu Docker. # Aby rozwiązać ten problem, zmienne NPM_USER i NPM_PASS powinny być zdefiniowane jako zmienne CI/CD na poziomie projektu w GitLab, # a następnie przekazywane jako argumenty podczas budowania obrazu Docker.build_and_test_awx:stage:build_and_testtags:# Użyj runnera z tagiem 'docker1'- docker1image:docker:latestservices:# Użyj usługi Docker-in-Docker- name:docker:dindvariables:# Użyj sterownika overlay2 dla DockerDOCKER_DRIVER:overlay2# Ustaw hosta DockerDOCKER_HOST:"tcp://docker:2375"# Wyłącz katalog certyfikatów TLS dla DockerDOCKER_TLS_CERTDIR:""script:# Klonuje repozytorium- git clone --single-branch --branch $BRANCH $REPO_URL# Buduje obraz Docker z poświadczeniami NPM- docker build --build-arg NPM_USER="${NPM_USER}" --build-arg NPM_PASS="${NPM_PASS}" -t $DOCKER_IMAGE -f Dockerfile .# Uruchamia testy wewnątrz kontenera Docker- | docker run --rm -v ${CI_PROJECT_DIR}:/workspace $DOCKER_IMAGE bash -c '
server_address="awx.sysadmin.homes"
username="${AWX_USERNAME}"
password="${AWX_PASSWORD}"
rm -rf /workspace/node_modules
rm -rf /lib/node_modules
ln -s /usr/local/lib/node_modules/ /workspace/node_modules
ln -s /usr/local/lib/node_modules/ /lib/node_modules
rm -f *.tar downloaded//*
rm -rf reports .gauge logs
gauge run /workspace/specs/test-awx.spec
'# Archiwizuje raporty, jeśli istnieją- if [ -d "${CI_PROJECT_DIR}/reports/" ]; thenformattedDate=$(date +"%d_%m_%Y_%H_%M");filename="PASS_${REPORT_NAME}_${formattedDate}_AWX.tar";tar -cf ${filename} ${CI_PROJECT_DIR}/reports/ ${CI_PROJECT_DIR}/logs/;mv ${filename} ${CI_PROJECT_DIR}/;fi# Czyści system Docker- docker system prune -af# Czyści woluminy Docker- docker volume prune -fartifacts:# Definiuje ścieżki do artefaktówpaths:- "${CI_PROJECT_DIR}/*.tar"build_and_test_argocd:stage:build_and_testtags:# Użyj runnera z tagiem 'docker2'- docker2image:docker:latestservices:# Użyj usługi Docker-in-Docker- name:docker:dindvariables:# Użyj sterownika overlay2 dla DockerDOCKER_DRIVER:overlay2# Ustaw hosta DockerDOCKER_HOST:"tcp://docker:2375"# Wyłącz katalog certyfikatów TLS dla DockerDOCKER_TLS_CERTDIR:""script:# Klonuje repozytorium- git clone --single-branch --branch $BRANCH $REPO_URL# Buduje obraz Docker z poświadczeniami NPM- docker build --build-arg NPM_USER="${NPM_USER}" --build-arg NPM_PASS="${NPM_PASS}" -t $DOCKER_IMAGE -f Dockerfile .# Uruchamia testy wewnątrz kontenera Docker- | docker run --rm -v ${CI_PROJECT_DIR}:/workspace $DOCKER_IMAGE bash -c '
server_address="argocd.sysadmin.homes"
username="${ARGOCD_USERNAME}"
password="${ARGOCD_PASSWORD}"
rm -rf /workspace/node_modules
rm -rf /lib/node_modules
ln -s /usr/local/lib/node_modules/ /workspace/node_modules
ln -s /usr/local/lib/node_modules/ /lib/node_modules
rm -f *.tar downloaded//*
rm -rf reports .gauge logs
gauge run /workspace/specs/test-argocd.spec
'# Archiwizuje raporty, jeśli istnieją- if [ -d "${CI_PROJECT_DIR}/reports/" ]; thenformattedDate=$(date +"%d_%m_%Y_%H_%M");filename="PASS_${REPORT_NAME}_${formattedDate}_ArgoCD.tar";tar -cf ${filename} ${CI_PROJECT_DIR}/reports/ ${CI_PROJECT_DIR}/logs/;mv ${filename} ${CI_PROJECT_DIR}/;fi# Czyści system Docker- docker system prune -af# Czyści woluminy Docker- docker volume prune -fartifacts:# Definiuje ścieżki do artefaktówpaths:- "${CI_PROJECT_DIR}/*.tar"clean_workspace:stage:cleanupparallel:matrix:# Użyj runnerów z tagiem 'docker1' i 'docker2'- RUNNER:docker1- RUNNER:docker2tags:- ${RUNNER}script:# Czyści katalog workspace- rm -rf $CI_PROJECT_DIR/*
Podsumowanie
Zainstalowanie Vault na osobnym serwerze zapewnia większą elastyczność i skalowalność w zarządzaniu sekretami. Dzięki powyższemu tutorialowi skonfigurowałeś Vault, aby bezpiecznie przechowywał i zarządzał sekretami, oraz zintegrowałeś go z GitLab, umożliwiając bezpieczne korzystanie z tych sekretów w pipeline’ach CI/CD. Upewnij się, że konfiguracja sieci i zabezpieczenia są odpowiednio skonfigurowane, aby umożliwić bezpieczne połączenia między GitLab runnerami a Vault.