Set Up a Secure HashiCorp Vault Server on Ubuntu 24.04
Modern software systems depend on a variety of sensitive credentials such as API keys, database passwords, TLS certificates, and encryption keys. When these secrets are hardcoded into applications, stored in plain text, or shared through insecure methods, they create severe security vulnerabilities. HashiCorp Vault solves this problem by offering a centralized and secure way to store and manage confidential information. It provides secret storage, dynamic credential generation, encryption as a service, and fine-grained access control.
This guide explains how to deploy a production-ready Vault server on Ubuntu 24.04. It covers installing Vault from HashiCorp’s official repository, creating TLS certificates via Let’s Encrypt, configuring Vault for secure operation, initializing it with unseal keys, and accessing the system through the command line and web interface.
Prerequisites
Before proceeding, make sure you have the following requirements in place:
- Access to an Ubuntu 24.04 server using a non-root user with sudo privileges.
- A domain A record that points to the server’s public IP address.
Install Vault from HashiCorp Repository
In this section, you’ll add HashiCorp’s official APT repository to your Ubuntu system and install Vault. This ensures you receive verified, up-to-date packages directly from HashiCorp.
Update Your Package List
$ sudo apt update
Install Required Dependencies
$ sudo apt install gnupg curl lsb-release -y
Add HashiCorp’s GPG Key
The GPG key verifies that packages originate from HashiCorp and haven’t been tampered with.
$ curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
Add the HashiCorp Repository
Include HashiCorp’s repository in your system sources to enable access to the latest releases.
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
Update the Package Index Again
$ sudo apt update
Install Vault
$ sudo apt install vault -y
Verify the Installation
$ vault --version
Example output:
Vault v1.20.4 (55bd8f18c6c84aa89fdede4850a622c57f03bd7e), built 2025-09-23T13:22:38Z
Enable Shell Autocompletion
This feature improves the command-line experience when working with Vault.
$ vault -autocomplete-install
$ exec $SHELL
Configure Firewall Access
To make the Vault service reachable, configure the firewall to permit HTTPS traffic. The following steps enable access to Vault’s web interface and CLI through secure ports.
Allow HTTPS Access
Vault’s web interface and API operate on port 8200. Allow this port through the firewall.
$ sudo ufw allow 8200/tcp
Temporarily Open Port 80
Port 80 is required by Certbot to verify domain ownership when issuing TLS certificates. Enable it temporarily.
$ sudo ufw allow 80/tcp
Reload the Firewall
Apply the rule changes by reloading UFW.
$ sudo ufw reload
Generate TLS Certificates with Let’s Encrypt
Next, obtain free TLS certificates using Certbot and Let’s Encrypt. These certificates secure traffic between clients and the Vault server.
Install Certbot
$ sudo apt install certbot -y
Request a TLS Certificate
Replace vault.example.com with your own domain and your-email@example.com with your valid email address.
$ sudo certbot certonly --standalone -d vault.example.com --non-interactive --agree-tos --email your-email@example.com
Remove Port 80 Rule
After the certificate has been issued, close port 80 to maintain a stricter security posture.
$ sudo ufw delete allow 80/tcp
Reload the Firewall Again
$ sudo ufw reload
Create a Directory for Vault Certificates
Store all certificate files in a dedicated Vault TLS directory.
$ sudo mkdir -p /opt/vault/tls
Copy the Certificates
Replace vault.example.com with your domain name when copying the files.
$ sudo cp /etc/letsencrypt/live/vault.example.com/fullchain.pem /opt/vault/tls/cert.pem
$ sudo cp /etc/letsencrypt/live/vault.example.com/privkey.pem /opt/vault/tls/key.pem
Set Ownership and Permissions
Restrict file access to the Vault user and secure the certificate keys.
$ sudo chown -R vault:vault /opt/vault/tls
$ sudo chmod 600 /opt/vault/tls/cert.pem /opt/vault/tls/key.pem
Create an Automatic Renewal Script
This script ensures Vault automatically reloads after Certbot renews certificates.
$ sudo tee /etc/letsencrypt/renewal-hooks/deploy/vault.sh > /dev/null << 'EOF'
#!/bin/bash
cp /etc/letsencrypt/live/vault.example.com/fullchain.pem /opt/vault/tls/cert.pem
cp /etc/letsencrypt/live/vault.example.com/privkey.pem /opt/vault/tls/key.pem
chown -R vault:vault /opt/vault/tls
chmod 600 /opt/vault/tls/*
systemctl reload vault
EOF
Make the Renewal Script Executable
$ sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/vault.sh
Configure Vault for Production
This section explains how to create a production-ready Vault configuration file. This configuration defines the storage backend, network listeners, and security settings to ensure Vault runs safely and reliably.
Back Up the Default Configuration
Before making changes, create a backup of the existing Vault configuration file.
$ sudo cp /etc/vault.d/vault.hcl /etc/vault.d/vault.hcl.backup
Create a Production Configuration File
Edit the configuration to include secure listener settings and storage options. Replace vault.example.com with your actual domain name.
$ sudo tee /etc/vault.d/vault.hcl > /dev/null << 'EOF'
# Vault production configuration
# Enable the web UI
ui = true
# Disable memory locking (set to false if your server has limited memory)
disable_mlock = true
# Storage backend - local file system
storage "file" {
path = "/opt/vault/data"
}
# HTTPS listener
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/opt/vault/tls/cert.pem"
tls_key_file = "/opt/vault/tls/key.pem"
# Enforce minimum TLS version
tls_min_version = "tls12"
# Define strong cipher suites
tls_cipher_suites = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
# Do not require client-side certificates
tls_require_and_verify_client_cert = "false"
tls_disable_client_certs = "true"
}
# Network advertisement
api_addr = "https://vault.example.com:8200"
cluster_addr = "https://vault.example.com:8201"
EOF
Enable the Vault Service
Configure Vault to start automatically on system boot.
$ sudo systemctl enable vault
Restart the Vault Service
Restart the service to apply the new configuration settings.
$ sudo systemctl restart vault
Check the Service Status
Verify that Vault is active and running without errors.
$ sudo systemctl status vault
Example output:
● vault.service - HashiCorp Vault - A tool for managing secrets
Loaded: loaded (/usr/lib/systemd/system/vault.service; enabled; preset: enabled)
Active: active (running) since Thu 2025-10-02 22:15:08 UTC; 3s ago
Set Up the Vault Environment
Now that Vault is installed and running, configure environment variables to allow the Vault CLI to communicate with the server.
Set the Vault Address
Replace vault.example.com with your Vault domain name.
$ echo 'export VAULT_ADDR="https://vault.example.com:8200"' >> ~/.bashrc
Reload the Shell Configuration
$ source ~/.bashrc
Verify the Environment Variable
$ echo $VAULT_ADDR
Expected output:
https://vault.example.com:8200
Test Connectivity
Check whether the CLI can reach the Vault server successfully.
$ vault status
Example output:
Key Value
--- -----
Seal Type shamir
Initialized false
Sealed true
Initialize and Unseal Vault
When Vault first starts, it is sealed. In this state, Vault knows where the data is stored but cannot read it until unseal keys are provided. This section explains how to initialize Vault, generate encryption keys, and unseal it to make it operational.
Understanding the Unseal Process
During initialization, Vault generates several key components:
- Master Key: Used to encrypt all stored secrets.
- Unseal Keys: Split portions of the master key, created through Shamir’s Secret Sharing algorithm.
- Root Token: Provides administrative access to the Vault system.
By default, five unseal keys are generated with a threshold of three, meaning any three of the five are required to unseal Vault. This setup ensures that no single person can gain full control of the system.
Initialize Vault
Run the following command to initialize Vault with the default configuration.
$ vault operator init
Example output:
Unseal Key 1: nk+b+gZRPzUcTx5yDaY7Rxv26m/JqPuuhlYKVLxqvcLV
Unseal Key 2: kXi4dk1pDpTj0efjPekMMEnqMFIGVbbIECyAbYXu4XIi
Unseal Key 3: jPyTlTCeKAMHu16+EYHc6FcmqW+hQ8B9ZN02vQ8VnOmd
Unseal Key 4: 5rvMMnEvcIQdcAtKd+UxQX7FqsDbMEtuHqRijFlyjR9l
Unseal Key 5: igcpq67F04IhxzAFQ/i+VbC5+vPSRNY5Zsg/xHu+qgID
Initial Root Token: hvs.4H1RRGrHO8cbu2QumVuXUfOV
Important: Store all keys in secure, separate locations. They will not be shown again.
Unseal the Vault
Vault must be unsealed using three of the five unseal keys. Each key is entered one at a time.
Start the unseal process with the first key:
$ vault operator unseal
After entering the first key, you’ll see progress like:
Unseal Progress 1/3
Continue with the second key:
$ vault operator unseal
Example progress:
Unseal Progress 2/3
Use the third key to complete the unseal process:
$ vault operator unseal
Once all three keys are accepted, the output confirms that Vault is unsealed:
Sealed false
Note: If the process fails, ensure that you are using three different keys rather than repeating the same ones.
Log In with the Root Token
After unsealing, authenticate using the initial root token generated during initialization.
$ vault login
When prompted, enter the initial root token to gain administrative access to the Vault instance.
Access the Vault Web UI
Vault also includes a graphical web interface that complements the command-line tool. You can use it to monitor system status, configure secrets engines, and manage authentication methods.
Open the Vault Dashboard
Launch your preferred browser and navigate to your Vault domain:
https://vault.example.com:8200
Once loaded, you’ll see the login screen. Choose Token as the authentication method and enter your root token, then click Sign In.
After successful login, the dashboard displays your Vault’s status, active secrets engines, and configuration options.
Web UI Overview
- The left navigation menu allows quick access to secrets, policies, and system configuration.
- The main panel shows Vault’s health, seal status, and audit logs.
- You can manage users, enable engines like
kv, and review access control lists (ACLs).
Conclusion
At this point, you have successfully deployed and configured a production-grade HashiCorp Vault instance on Ubuntu 24.04. The setup includes TLS encryption via Let’s Encrypt, automatic certificate renewal, and both command-line and web-based management capabilities.
Your Vault server is now ready to securely store and manage secrets such as API keys, credentials, and encryption materials across your infrastructure. Continue exploring the official Vault documentation for advanced features like dynamic secrets, audit logging, and cluster replication to enhance security and scalability.


