Install HashiCorp Vault for Secrets Management on VPS
HashiCorp Vault is an enterprise-grade tool for managing secrets that securely stores API keys, passwords, certificates, and other sensitive data. This guide covers installing Vault on your VPS, setting up policies and access controls, and creating dynamic secrets for Docker and applications. Vault uses encryption to protect data and implements the "Unsealing" concept to prevent single points of failure through Shamir's Secret Sharing algorithm.
Understanding Vault Fundamentals
HashiCorp Vault is a centralized secrets management system that encrypts and protects your sensitive information. Key features include:
- Secrets Management: Store passwords, API keys, and certificates in one secure location
- Dynamic Secrets: Generate temporary credentials for databases and services on-demand
- Access Control: Manage secret access through fine-grained policies
- Audit Logging: Track all secret access and changes with comprehensive logs
- Multiple Auth Methods: Support for password, LDAP, AppRole, Kubernetes, OAuth, and more
Vault uses a "Sealed" state on startup where the root key is protected. You must "Unseal" the server using Shamir's Secret Sharing to prevent any single person from gaining complete access. This distributed model ensures security even if one unseal key is compromised.
System Requirements and Prerequisites
Before installing Vault, ensure your VPS meets these requirements:
- OS: Linux (Ubuntu 20.04+, CentOS 8+, Debian 11+)
- CPU: 2 cores minimum
- RAM: 4 GB or more
- Disk Space: 10 GB for data storage
- Network: Ports 8200 (HTTP API) and 8201 (cluster communication) must be open
Check your system details and permissions:
uname -a
sudo -l
whoami
Download and Install HashiCorp Vault
Follow these steps to install Vault on your VPS:
cd /tmp
wget https://releases.hashicorp.com/vault/1.15.0/vault_1.15.0_linux_amd64.zip
unzip vault_1.15.0_linux_amd64.zip
sudo mv vault /usr/local/bin/
rm vault_1.15.0_linux_amd64.zip
Verify the installation:
vault version
Expected output:
Vault v1.15.0 (7cd4637e5f7e4d1d6f7e8c9b0a1b2c3d)
Create a dedicated user for Vault:
sudo useradd --system --home /var/lib/vault --shell /bin/false vault
sudo mkdir -p /var/lib/vault /etc/vault
sudo chown vault:vault /var/lib/vault /etc/vault
sudo chmod 700 /var/lib/vault /etc/vault
Configure Vault Settings
Create the Vault configuration file:
sudo nano /etc/vault/vault.hcl
Add the following configuration:
ui = true
storage "file" {
path = "/var/lib/vault/data"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = 0
tls_cert_file = "/etc/vault/tls/tls.crt"
tls_key_file = "/etc/vault/tls/tls.key"
}
api_addr = "https://127.0.0.1:8200"
cluster_addr = "https://127.0.0.1:8201"
ui = true
Note: For initial development, you can set tls_disable = 1 to disable TLS temporarily, but never use this in production environments.
Generate TLS Certificates and Start Vault
Create TLS certificates for Vault communication:
sudo mkdir -p /etc/vault/tls
cd /etc/vault/tls
# Generate private key
sudo openssl genrsa -out tls.key 2048
# Create self-signed certificate
sudo openssl req -new -x509 -key tls.key -out tls.crt -days 365 \
-subj "/CN=127.0.0.1/O=Vault/C=US"
sudo chown vault:vault tls.key tls.crt
sudo chmod 600 tls.key tls.crt
Create a systemd service file for Vault:
sudo nano /etc/systemd/system/vault.service
Add this content:
[Unit]
Description=HashiCorp Vault
Documentation=https://www.vaultproject.io/docs/
Requires=network-online.target
After=network-online.target
ConditionFileNotEmpty=/etc/vault/vault.hcl
[Service]
Type=notify
ProtectSystem=full
ProtectHome=yes
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
SecureBits=keep-caps
AmbientCapabilities=CAP_IPC_LOCK
CapabilityBoundingSet=CAP_SYSLOG CAP_IPC_LOCK
LimitNOFILE=65536
LimitNPROC=512
KillMode=process
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
LimitMEMLOCK=infinity
ExecStart=/usr/local/bin/vault server -config=/etc/vault/vault.hcl
ExecReload=/bin/kill -HUP $MAINPID
StandardOutput=journal
StandardError=journal
SyslogIdentifier=vault
User=vault
Group=vault
[Install]
WantedBy=multi-user.target
Start and enable Vault:
sudo systemctl daemon-reload
sudo systemctl enable vault
sudo systemctl start vault
sudo systemctl status vault
Initialize and Unseal Vault
When Vault starts, it's in a sealed state. Initialize it to create the root token and unseal keys:
export VAULT_ADDR='https://127.0.0.1:8200'
export VAULT_SKIP_VERIFY=true
vault operator init -key-shares=5 -key-threshold=3
The output will display unseal keys and the root token. Example:
Unseal Key 1: 7ZzX9K2mQ4R5T8vU1W2X3Y4Z5A6B7C8D
Unseal Key 2: 9E0F1G2H3I4J5K6L7M8N9O0P1Q2R3S4T
Unseal Key 3: 5U6V7W8X9Y0Z1A2B3C4D5E6F7G8H9I0J
Unseal Key 4: 1K2L3M4N5O6P7Q8R9S0T1U2V3W4X5Y6Z
Unseal Key 5: 7A8B9C0D1E2F3G4H5I6J7K8L9M0N1O2P
Initial Root Token: s.7Q8R9S0T1U2V3W4X5Y6Z7A8B9C0D1E2F
Critical: Store unseal keys and the root token in a secure location, preferably offline. Never store them on the server or in plain text files. After initialization, create policies and use application tokens instead of the root token for daily operations.
Unseal the server using the unseal keys (requires 3 keys in this example):
vault operator unseal 7ZzX9K2mQ4R5T8vU1W2X3Y4Z5A6B7C8D
vault operator unseal 9E0F1G2H3I4J5K6L7M8N9O0P1Q2R3S4T
vault operator unseal 5U6V7W8X9Y0Z1A2B3C4D5E6F7G8H9I0J
Check the Vault status:
vault status
Expected output:
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 5
Threshold 3
Version 1.15.0
Storage Type file
Cluster Name vault-cluster-1
Cluster ID 8f4c5d3e-2b1a-4c3d-9e0f-1a2b3c4d5e6f
Set Up Policies and Access Control
Vault uses policies to control access to secrets. Create a policy for your application:
vault login s.7Q8R9S0T1U2V3W4X5Y6Z7A8B9C0D1E2F
Create a policy file:
cat > /tmp/app-policy.hcl << 'EOF'
# Allow reading app secrets
path "secret/data/app/*" {
capabilities = ["read", "list"]
}
# Allow reading secret metadata
path "secret/metadata/app/*" {
capabilities = ["read", "list"]
}
# Deny all delete operations
path "secret/*" {
capabilities = ["deny"]
}
# Allow reading token info
path "auth/token/lookup-self" {
capabilities = ["read"]
}
# Allow token renewal
path "auth/token/renew-self" {
capabilities = ["update"]
}
EOF
Write the policy to Vault:
vault policy write app-policy /tmp/app-policy.hcl
Enable and configure the AppRole authentication method for applications:
vault auth enable approle
vault write auth/approle/role/app-role \
token_ttl=1h \
token_max_ttl=4h \
policies="app-policy"
vault read auth/approle/role/app-role/role-id
vault write -f auth/approle/role/app-role/secret-id
Create Secrets and Dynamic Credentials
Create static secrets for your application:
vault kv put secret/app/database \
username="dbuser" \
password="SecurePassword123!" \
host="db.example.com"
vault kv put secret/app/stripe \
api_key="sk_live_4eC39HqLyjWDarhtT1ZdV7hG"
vault kv put secret/app/jwt \
secret="your-jwt-secret-key-here"
Retrieve secrets to verify they're stored correctly:
vault kv get secret/app/database
vault kv get -field=password secret/app/database
For dynamic secrets, you'll need to enable and configure the database secrets engine. First check available auth and secret engines:
vault auth list
vault secrets list
Verify HashiCorp Vault is Working
Test Vault functionality with these verification commands:
# Check Vault status
vault status
# Verify the service is running
sudo systemctl status vault
# Test API connectivity
curl -k https://127.0.0.1:8200/v1/sys/health
# Check seal status
vault status | grep "Sealed"
# Retrieve a stored secret
vault kv get secret/app/database
# List available secrets
vault kv list secret/app/
Tip: Use VAULT_SKIP_VERIFY=true for self-signed certificates in development environments. Always update certificates for production use.
Troubleshooting Common Issues
Error: "permission denied" when starting Vault service
This occurs when file permissions are not set correctly for the Vault directories:
# Fix directory ownership and permissions
sudo chown -R vault:vault /var/lib/vault
sudo chown -R vault:vault /etc/vault
sudo chmod 700 /var/lib/vault
sudo chmod 700 /etc/vault
# Verify permissions
ls -la /var/lib/vault
ls -la /etc/vault
# Restart the service
sudo systemctl restart vault
Error: "failed to acquire lock" when starting Vault
This happens when another Vault process is running or a lock file is stuck:
# Check for running Vault processes
ps aux | grep vault
# Kill any existing Vault processes
sudo pkill -f 'vault server'
# Remove the stuck lock file
sudo rm -f /var/lib/vault/data/.vault.lock
# Start Vault again
sudo systemctl start vault
Error: "x509: certificate signed by unknown authority"
This indicates an invalid TLS certificate configuration:
# Temporarily skip certificate verification
export VAULT_SKIP_VERIFY=true
# Or regenerate the certificates
cd /etc/vault/tls
sudo rm -f tls.key tls.crt
sudo openssl genrsa -out tls.key 2048
sudo openssl req -new -x509 -key tls.key -out tls.crt -days 365 \
-subj "/CN=127.0.0.1/O=Vault/C=US"
sudo chown vault:vault tls.key tls.crt
sudo chmod 600 tls.key tls.crt
sudo systemctl restart vault
Error: "unseal key invalid" or "could not verify seal"
This occurs when using incorrect unseal keys or storage corruption:
# Check storage directory
ls -la /var/lib/vault/data/
# Attempt unseal with the correct unseal key
vault operator unseal [CORRECT_UNSEAL_KEY]
# Verify seal status
vault status
# If corruption is suspected, attempt storage migration
vault operator migrate
Frequently Asked Questions
What is the cost of HashiCorp Vault?
HashiCorp Vault offers a free Community Edition (open source) and a paid Enterprise Edition. The Community Edition includes all core secrets management features but lacks enterprise support and advanced capabilities. Enterprise Edition adds features like advanced audit logging, replication, and performance tuning. Most 29VPS users can leverage the Community Edition without cost, which provides robust functionality for production-grade secrets management.
Do I need to unseal Vault manually every time the server reboots?
Yes, by default Vault requires manual unsealing after restarts because unseal keys are not stored in the data storage. For production environments, you can implement "Auto-Unseal" using key management services like AWS KMS, Google Cloud KMS, or physical Hardware Security Modules (HSMs) to automate the unsealing process and improve operational efficiency.
How should I securely store unseal keys and root tokens?
Unseal keys and root tokens are the most critical secrets in Vault and should be stored offline in secure locations such as encrypted USB drives, physical vaults, or dedicated secrets management systems. Never store them on the server, in plain text files, or in shared password managers. After initialization, create operational policies and use application-specific tokens instead of the root token for everyday operations. Consider distributing unseal keys among trusted team members as physical backups.