Ok just install it

Prepare

1
2
3
4
5
6
ip addr add 127.0.0.2/8 dev lo label lo:0
ip addr add 127.0.0.3/8 dev lo label lo:1

cat /etc/hosts
127.0.0.2 vault2.tmp.local
127.0.0.3 vault3.tmp.local

Prepare Certs

Вообщем то нам полюбому надо выпить рому… точнее сгенерить сертификаты поэтому генерим сертификаты в первую очередь что бы потом не парится с этим

Gen CA cert

Генерим CA

1
openssl req -x509 -sha256 -days 1825 -newkey rsa:2048 -keyout rootCA.key -out rootCA.crt -subj "/CN=vaultca.tmp.local/C=RU/ST=Moscow/L=Moscow/O=ZAO tmp/OU=ITDepartment/"

Create certificate request

Тут надо сделать запрос csr

1
2
3
4
openssl req -newkey rsa:2048 -keyout vault.key -out vault.csr -subj "/CN=*.tmp.local/C=RU/ST=Moscow/L=Moscow/O=ZAO tmp/OU=ITDepartment/"
# OR
#openssl genrsa -out vault.key 4096
#openssl req -new -key vault.key -sha256 -out vault.csr -config cert.config

Sign CSR with our CA cert

Вообщем то тут надо бы сгенерить какие нить простенькие сертификаты… но желательно сделать их не на 10 дней потому что иначе получим ошибку типа

Error checking seal status: Get “https://127.0.0.1:8200/v1/sys/seal-status”: x509: certificate has expired or is not yet valid: current time 2023-12-18T15:48:30+03:00 is after 2023-10-27T15:41:51Z

Так же может быть такая ошибка эт потому что нам надо юзать

Error checking seal status: Get “https://vault2.tmp.local:8200/v1/sys/seal-status”: x509: certificate relies on legacy Common Name field, use SANs instead

-extfile <(printf “subjectAltName=DNS:*.tmp.local”)

1
2
3
4
5
6
7
8
openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in vault.csr -out vault.crt -days 3650 -CAcreateserial -extfile <(printf "subjectAltName=DNS:*.tmp.local")
# Or for fullname hosts
#openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in vault.csr -out vault.crt -days 3650 -CAcreateserial -extfile <(printf "subjectAltName=DNS.1:vault2.tmp.local,DNS.2:vault3.tmp.local,IP.1:127.0.0.2,IP.2:127.0.0.3")
# OR with file
#openssl x509 -req -sha256 -in vault.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out vault.crt -days 365 -extfile cert.config -extensions 'v3_req'

openssl rsa -in vault.key -out vault_nopass.key
openssl verify -verbose -CAfile rootCA.crt vault.crt

Второй командой убираем пароль из ключа. Ибо Vault не умеет пароли, и github предлагают какие то костыли…

If the key file is encrypted, you will be prompted to enter the passphrase on server startup

Что бы не было ошибки типа

Error checking seal status: Get “https://vault2.tmp.local:8200/v1/sys/seal-status”: x509: certificate signed by unknown authority

Надо закинуть CA сертификат в наш файлик с сертификатом, для этого делаем следующее + дока говорит - The primary certificate should appear first in the combined file.

1
cat rootCA.crt >> vault.crt

Node ONE

Simple config for raft

Т.к у нас первый сервер на IP 127.0.0.2 поэтому я для него конфиг назвал server-2.hcl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
storage "raft" {
  path    = "/media/data/vault2/raft"
  node_id = "oadmintst2"

  retry_join {
    leader_api_addr = "https://vault2.tmp.local:8200"
    leader_ca_cert_file = "/opt/vault/certs/withca/rootCA.crt"
    leader_client_cert_file = "/opt/vault/certs/withca/vault.crt"
    leader_client_key_file = "/opt/vault/certs/withca/vault_nopass.key"
  }
  retry_join {
    leader_api_addr = "https://vault3.tmp.local:8200"
    leader_ca_cert_file = "/opt/vault/certs/withca/rootCA.crt"
    leader_client_cert_file = "/opt/vault/certs/withca/vault.crt"
    leader_client_key_file = "/opt/vault/certs/withca/vault_nopass.key"
  }
}

listener "tcp" {
 address = "vault2.tmp.local:8200"
 cluster_address = "vault2.tmp.local:8201"
 tls_cert_file = "/opt/vault/certs/withca/vault.crt"
 tls_key_file = "/opt/vault/certs/withca/vault_nopass.key"
 tls_client_ca_file = "/opt/vault/certs/withca/rootCA.crt"
 tls_disable = 0
}

ui = true
api_addr = "https://vault2.tmp.local:8200"
cluster_addr = "https://vault2.tmp.local:8201"
cluster_name = "vault-tmp"
log_level = "INFO"
disable_mlock=true

Cluster address must be set when using raft storage

Если видим такую херню то очевидно надо забыли cluster_addr…

Run

Запускаем это чудо:

1
vault server -config=/etc/vault/conf.d/server-2.hcl

Проверяем статус

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
export VAULT_ADDR='https://vault2.tmp.local:8200'
export VAULT_CACERT=/opt/vault/certs/withca/rootCA.crt
vault status
Key                Value
---                -----
Seal Type          shamir
Initialized        false
Sealed             true
Total Shares       0
Threshold          0
Unseal Progress    0/0
Unseal Nonce       n/a
Version            1.12.0
Build Date         2022-10-10T18:14:33Z
Storage Type       raft
HA Enabled         true

Тут вообщем все намана должно быть… Но мы видимо что Initialized: false

Поэтому надо инициализовать наш новый vault

1
2
3
4
5
6
7
8
vault operator init
Unseal Key 1: XPFnXMHpFDqwXK9uCjgtNSw4wlrYkfXRY6QttU1KSsXt
Unseal Key 2: rgTtwxv/Gx84vubOqdvyls9C/IlVWw84E9nplLHe5bhe
Unseal Key 3: 8EyC1p6L701iVs+7c6U4It8P5yk0TWGHV1JJASQHU2z5
Unseal Key 4: /jzdxtVBqPtDQMXls0TcxhoigoA7s4KT/l5VR5vDWNAT
Unseal Key 5: L59iKxsnPHGYc4I83iHeuW0pjujhRN8tm4VJAwXIHFOF

Initial Root Token: hvs.AGXnkD9hJJX2Tf8yzQCp9gNO

Дальше надо рассолить это дело

1
vault operator unseal # 3раза ибо у нас treshhold 3

Тут почему то я подумал на кой хер мне вообще эит 5 ключей и решил переделать на один нах

1
2
3
4
5
6
7
8
9
vault operator rekey -init -key-threshold=1 -key-shares=1
vault operator rekey
...
#Rekey operation nonce: 939cd1b9-7b23-5bb0-a8e8-2311a1af8937
#Unseal Key (will be hidden):

#Key 1: oQY3TjGmc4OoioVDQG4n2qlgN34MXFdjyumYyezZgIM=

#Operation nonce: 939cd1b9-7b23-5bb0-a8e8-2311a1af8937

Unseal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
vault operator unseal
# insert key
vault status
Key                     Value
---                     -----
Seal Type               shamir
Initialized             true
Sealed                  false
Total Shares            1
Threshold               1
Version                 1.12.0
Build Date              2022-10-10T18:14:33Z
Storage Type            raft
Cluster Name            vault-tmp
Cluster ID              78c82cd4-5ce1-0ca6-4849-6e7c5a5822fb
HA Enabled              true
HA Cluster              https://vault2.tmp.local:8201
HA Mode                 active
Active Since            2023-12-21T06:28:31.593633502Z
Raft Committed Index    78
Raft Applied Index      78

Login + list peer

1
2
3
4
5
vault login
vault operator raft list-peers
Node          Address                  State     Voter
----          -------                  -----     -----
oadmintst2    vault2.tmp.local:8201    leader    true

Node TWO

Config

Т.к у нас второй сервер на IP 127.0.0.3 поэтому я для него конфиг назвал server-3.hcl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
storage "raft" {
  path    = "/media/data/vault3/raft"
  node_id = "oadmintst3"

  retry_join {
    leader_api_addr = "https://vault2.tmp.local:8200"
    leader_ca_cert_file = "/opt/vault/certs/withca/rootCA.crt"
    leader_client_cert_file = "/opt/vault/certs/withca/vault.crt"
    leader_client_key_file = "/opt/vault/certs/withca/vault_nopass.key"
  }
  retry_join {
    leader_api_addr = "https://vault3.tmp.local:8200"
    leader_ca_cert_file = "/opt/vault/certs/withca/rootCA.crt"
    leader_client_cert_file = "/opt/vault/certs/withca/vault.crt"
    leader_client_key_file = "/opt/vault/certs/withca/vault_nopass.key"
  }
}

listener "tcp" {
 address = "vault3.tmp.local:8200"
 cluster_address = "vault3.tmp.local:8201"
 tls_cert_file = "/opt/vault/certs/withca/vault.crt"
 tls_key_file = "/opt/vault/certs/withca/vault_nopass.key"
 tls_client_ca_file = "/opt/vault/certs/withca/rootCA.crt"
 tls_disable = 0
}

ui = true
api_addr = "https://vault3.tmp.local:8200"
cluster_addr = "https://vault3.tmp.local:8201"
cluster_name = "vault-tmp"
log_level = "INFO"
disable_mlock=true

Run

Запускаем это чудо:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vault server -config=./server-3.hcl
vault status
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       1
Threshold          1
Unseal Progress    0/1
Unseal Nonce       n/a
Version            1.15.4
Build Date         2023-12-04T17:45:28Z
Storage Type       raft
HA Enabled         true

Если на этом этапе все сделано правильно то мы типа видим Initialized true
Sealed true

Т.е vault уже инициализирован и нам надо его только рассолить

Unseal

1
2
3
4
export VAULT_ADDR='https://vault3.tmp.local:8200'
export VAULT_CACERT=/opt/vault/certs/withca/rootCA.crt
vault operator unseal  # USING UNSEAL KEY FROM VAULT2 NODE
# Key from node TWO

Check

1
2
3
4
5
6
7
export VAULT_ADDR='https://vault3.tmp.local:8200'
export VAULT_CACERT=/opt/vault/certs/withca/rootCA.crt
vault operator raft list-peers
Node          Address                  State       Voter
----          -------                  -----       -----
oadmintst2    vault2.tmp.local:8201    follower    true
oadmintst3    vault3.tmp.local:8201    leader      true

там я переключил leader на vault3 не парьтесь у вас должен быть vault2 лидером

!Addon! Join to “Node TWO”

Если вы в конфиге storage raft не написали чет типа retry_join то можно вручную заджойнится 2мя командами

Node TWO - это которая первая=)

curl Делаем payload.json вида

1
2
3
4
5
6
7
8
9
10
11
12
export ROOTCA=$(cat rootCA.crt | awk '{printf $0"\\n"}'| sed "s/.\{0,2\}$//; /^$/d") # leader_ca_cert
export VAULTCERT=$(cat vault.crt | awk '{printf $0"\\n"}'| sed "s/.\{0,2\}$//; /^$/d") # leader_client_cert
export VAULTKEY=$(cat vault_nopass.key | awk '{printf $0"\\n"}'| sed "s/.\{0,2\}$//; /^$/d") # leader_client_key

curl \
--request POST \
https://vault3.tmp.local:8200/v1/sys/storage/raft/join -d '{
  "leader_api_addr": "https://vault2.tmp.local:8200",
  "leader_ca_cert": "'"$ROOTCA"'",
  "leader_client_cert": "'"$VAULTCERT"'",
  "leader_client_key": "'"$VAULTKEY"'"
}'

Auto unseal

Эт я не думал просто стырил от сюда https://fdns.github.io/2019-08-16/Basic-Hashicorp-Vault-Autounseal спасибо добрый человек)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash

KEY="hH3wcCstmWZ57j7fHJXlPbft5F5HfJgkGgRG8CuOIsg="
URL="https://vault2.tmp.local:8200"

echo "Starting unsealer"
while true
do
    status=$(curl -k -s $URL/v1/sys/seal-status | jq '.sealed')
    if [ true = "$status" ]
    then
        echo "Unsealing"
        curl -k -s --request PUT --data "{\"key\": \"$KEY\"}" $URL/v1/sys/unseal
    fi
    sleep 10
done

P.S Чет задолбался писать пока хватит пожалуй развлечений…

P.P.S На самом деле там в конфиге сервера ясен хрен писать в retry_join саму ноду не надо просто оставил что бы конфиг был однотипный для всех нод. В иделае надо конечно делать нормально… Типа для каждого ноды должны быть описанны только ноды к которым она джойнится в нашем случаем одна. Т.е для vault3:

1
2
3
4
5
6
  retry_join {
    leader_api_addr = "https://vault2.tmp.local:8200"
    leader_ca_cert_file = "/opt/vault/certs/withca/rootCA.crt"
    leader_client_cert_file = "/opt/vault/certs/withca/vault.crt"
    leader_client_key_file = "/opt/vault/certs/withca/vault_nopass.key"
  }

P.P.S Not work… Вот это говно которое в доке вообще не работает!….

1
2
3
4
5
6
7
vault operator raft join "http://vault2.tmp.local:8200" \
        -leader-ca-cert=@rootCA.crt \
        -leader-client-cert=@vault.crt \
        -leader-client-key=@vault_nopass.key
Key       Value
---       -----
Joined    true