Vault là một công cụ nguồn mở cung cấp một cách an toàn, đáng tin cậy để lưu trữ và phân phối các bí mật như khóa API, mã thông báo truy cập (access tokens) và mật khẩu. Phần mềm như Vault có thể cực kỳ quan trọng khi triển khai các ứng dụng yêu cầu sử dụng dữ liệu bí mật hoặc dữ liệu nhạy cảm.
Trong hướng dẫn này, bạn sẽ:
Khi áp dụng một số chính sách bổ sung, bạn sẽ có thể sử dụng Vault để quản lý an toàn dữ liệu nhạy cảm cho các ứng dụng và công cụ khác nhau của mình.
Giống như bất kỳ dịch vụ nào quản lý thông tin nhạy cảm, bạn nên cân nhắc đọc tài liệu bổ sung về các phương pháp triển khai hay nhất của Vault trước khi sử dụng trong môi trường giống như sản xuất. Ví dụ: hướng dẫn tăng cường sản xuất của Vault bao gồm các chủ đề như chính sách, root tokens và kiểm toán.
Trước khi bạn bắt đầu hướng dẫn này, bạn sẽ cần những thứ sau:
Lưu ý: Vault tạo chứng chỉ TLS tự ký khi bạn cài đặt gói lần đầu tiên. Nếu bạn không có tên miền hoặc chứng chỉ TLS để sử dụng với Vault, nhưng muốn làm theo các bước trong hướng dẫn này, bạn có thể bỏ qua xác minh TLS bằng cách thêm cờ -tls-skip-verify
vào các lệnh trong hướng dẫn này, hoặc bằng cách xác định biến môi trường VAULT_SKIP_VERIFY
.
Tùy chọn này chỉ phù hợp để thử nghiệm với Vault và không được sử dụng trong môi trường sản xuất.
HashiCorp cung cấp Vault dưới dạng gói Debian/Ubuntu điển hình, vì vậy chúng ta sẽ thực hiện các bước thông thường để thêm kho lưu trữ gói của họ vào danh sách nguồn gói của máy chủ.
Trước tiên, hãy thêm khóa GPG của Hashicorp vào trình quản lý gói của bạn để hệ thống của bạn tin tưởng vào kho lưu trữ gói của họ:
- curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
Sau đó thêm kho lưu trữ vào danh sách các nguồn gói của bạn để nó sẽ được kiểm tra các bản cập nhật thường xuyên:
- sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
Sau đó cài đặt gói:
- sudo apt install vault
Bây giờ bạn có thể sử dụng lệnh vault
. Hãy thử kiểm tra phiên bản của Vault để đảm bảo nó hoạt động.
- vault --version
OutputVault v1.8.5 (647eccfe0bd5817bdd8628f3c3171402dfc8a8fc)
Tệp thực thi Vault được cài đặt trên máy chủ của bạn, vì vậy, bước tiếp theo là thiết lập cấu hình tệp thực thi này để chạy dưới dạng dịch vụ hệ thống.
Việc cài đặt gói Vault sẽ tự động tạo vault
user trên hệ thống của bạn và thiết lập dịch vụ hệ thống để chạy Vault trong nền. Chúng ta cần thực hiện một số thay đổi đối với cấu hình mặc định của nó để sử dụng chứng chỉ HTTPS do Let's Encrypt tạo.
Lưu ý: Trong hướng dẫn này và theo mặc định, Vault sử dụng phần phụ trợ của hệ thống tệp để lưu trữ các bí mật được mã hóa trên hệ thống tệp cục bộ tại /opt/vault
. Điều này phù hợp cho việc triển khai cục bộ hoặc một máy chủ không cần sao chép. Các chương trình phụ trợ khác của Vault, chẳng hạn như chương trình phụ trợ Consul, sẽ lưu trữ các bí mật được mã hóa ở trạng thái lưu trữ trong kho lưu trữ key/value phân tán.
Cấu hình mặc định của Vault được lưu trữ trong /etc/vault.d/vault.hcl
. Bạn sẽ sử dụng tệp này để kiểm soát các tùy chọn khác nhau trong Vault, chẳng hạn như nơi lưu trữ các bí mật được mã hóa.
Mở vault.hcl
bằng nano
hoặc trình soạn thảo văn bản yêu thích của bạn.
- sudo nano /etc/vault.d/vault.hcl
Tìm phần listener "tcp"
của tệp bên dưới #HTTPS listener
có chứa khối này. Nếu bạn đang sử dụng nano
, bạn có thể nhấn Ctrl + W
, sau đó nhập listener “tcp”
để tìm trực tiếp dòng đó:
...
#HTTPS listener
...
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/opt/vault/tls/tls.crt"
tls_key_file = "/opt/vault/tls/tls.key"
...
}
Chỉnh sửa các dòng tls_cert_file
và tls_key_file
để trỏ tới các tệp khóa và chứng chỉ Let's Encrypt của bạn. Đừng quên thay thế tên miền của riêng bạn thay cho phần your_domain
được tô sáng của mỗi dòng.
listener "tcp" {
...
tls_cert_file = "/etc/letsencrypt/live/your_domain/fullchain.pem"
tls_key_file = "/etc/letsencrypt/live/your_domain/privkey.pem"
}
Lưu ý: Bạn cũng nên thay đổi address = "0.0.0.0:8200"
thành address = “127.0.0.1:8200”
để ngăn các kết nối bên ngoài đến máy chủ này ngay bây giờ. 127.0.0.1
chỉ là địa chỉ dành riêng cho máy chủ cục bộ. Điều này là để đảm bảo rằng dịch vụ không được tiếp xúc với internet công cộng trước khi nó được bảo mật đúng cách. Bạn có thể cập nhật điều này sau, nhưng hiện tại, thay đổi cấu hình này sẽ cho phép chúng ta sử dụng lệnh vault
và giải quyết chính xác tên miền được bảo mật bằng HTTPS.
Lưu và đóng tập tin. Nếu bạn đang sử dụng nano
, hãy nhấn Ctrl+X
, sau đó nhấn Y
khi được nhắc lưu tệp và nhấn Enter
để xác nhận.
Tiếp theo, vault
system user cũng cần có quyền đọc các chứng chỉ này. Theo mặc định, các chứng chỉ và khóa riêng tư này chỉ có thể truy cập được bằng quyền root
. Để cung cấp những tệp này một cách an toàn, chúng ta sẽ tạo một nhóm đặc biệt gọi là pki
để truy cập các tệp này. Chúng ta sẽ tạo nhóm và sau đó thêm vault
user vào đó.
- sudo groupadd pki
Cập nhật quyền trên hai thư mục trong thư mục /etc/letsencrypt
để cho phép các thành viên của nhóm pki
đọc nội dung.
- sudo chgrp -R pki /etc/letsencrypt/archive
- sudo chgrp -R pki /etc/letsencrypt/live
- sudo chmod -R g+rx /etc/letsencrypt/archive
- sudo chmod -R g+rx /etc/letsencrypt/live
Sau đó, thêm vault
user vào nhóm pki
. Điều này sẽ cấp cho Vault quyền truy cập vào các chứng chỉ để Vault có thể phân phối các yêu cầu một cách an toàn qua HTTPS.
- sudo usermod -a -G pki vault
Bước cuối cùng để thuận tiện, hãy thêm quy tắc trong /etc/hosts
để chuyển các yêu cầu từ Vault tới localhost
.
Thay thế your_domain
trong lệnh sau bằng miền mà bạn đã nhận được chứng chỉ Let's Encrypt cho:
- echo 127.0.0.1 your_domain.com | sudo tee -a /etc/hosts
Lệnh này nối thêm dòng 127.0.0.1 your_domain.com
vào /etc/hosts
để mọi yêu cầu HTTP mà bạn thực hiện trên máy chủ Vault tới your_domain.com
đều bỏ qua DNS và được gửi trực tiếp tới localhost
.
Với dịch vụ Vault được thiết lập và tệp cấu hình Vault hoàn tất, giờ đây chúng ta đã sẵn sàng khởi động Vault và khởi chạy kho lưu trữ bí mật.
Khi bạn khởi động Vault lần đầu tiên, nó vẫn chưa được khởi tạo, nghĩa là nó chưa sẵn sàng để nhận và lưu trữ dữ liệu. Trong phần này của hướng dẫn, bạn sẽ khởi động máy chủ Vault, sau đó khởi tạo nó bằng một bộ khóa bí mật sẽ được sử dụng để hủy niêm phong (mở) các cửa hàng bí mật của Vault.
Lần đầu tiên bạn khởi động Vault, chương trình phụ trợ thực sự lưu trữ các bí mật được mã hóa cũng chưa được khởi tạo. Bắt đầu dịch vụ hệ thống Vault để khởi tạo chương trình phụ trợ và bắt đầu chạy Vault.
- sudo systemctl start vault.service
Bạn có thể chạy kiểm tra nhanh để xác nhận dịch vụ đã bắt đầu thành công.
- sudo systemctl status vault.service
Bạn sẽ nhận được đầu ra tương tự như sau:
Output● vault.service - "HashiCorp Vault - A tool for managing secrets"
Loaded: loaded (/lib/systemd/system/vault.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2021-11-16 21:55:13 UTC; 22s ago
Docs: https://www.vaultproject.io/docs/
Main PID: 104207 (vault)
Tasks: 7 (limit: 1137)
Memory: 179.3M
CGroup: /system.slice/vault.service
└─104207 /usr/bin/vault server -config=/etc/vault.d/vault.hcl
Đầu ra của lệnh đó sẽ bao gồm một số thông tin về dịch vụ đang chạy, chẳng hạn như process ID và mức sử dụng tài nguyên của nó. Đảm bảo rằng dòng sau được bao gồm trong đầu ra, cho biết rằng dịch vụ đang chạy đúng cách.
Output. . .
Active: active (running)
. . .
Nếu dịch vụ không hoạt động, hãy xem các dòng nhật ký đi kèm ở cuối đầu ra của lệnh để xem đầu ra của Vault, điều này có thể giúp xác định bất kỳ vấn đề nào.
Tiếp theo, chúng ta sẽ đặt một biến môi trường để cho lệnh vault
biết cách kết nối với máy chủ Vault. Ở Bước 1, bạn đã thiết lập cấu hình Vault để chỉ nghe trên giao diện loopback cục bộ, vì vậy hãy đặt biến môi trường VAULT_ADDR
thành điểm cuối HTTPS cục bộ.
- export VAULT_ADDR=https://your_domain:8200
Lệnh vault
hiện có thể giao tiếp với daemon. Lưu ý rằng việc xác định tên máy chủ thực tế thay vì chỉ localhost
hoặc 127.0.0.1
là cần thiết để xác thực đúng chứng chỉ HTTPS.
Xác nhận rằng máy chủ vault đang ở trạng thái chưa được khởi tạo bằng cách kiểm tra trạng thái của nó.
- vault status
Máy chủ sẽ trả về một số đầu ra để bạn có thể biết nó đang hoạt động nhưng chưa được khởi tạo.
Key Value
--- -----
Seal Type shamir
Initialized false
Sealed true
Total Shares 0
Threshold 0
Unseal Progress 0/0
Unseal Nonce n/a
Version 1.8.5
Storage Type file
HA Enabled false
Có hai phần thông tin mà Vault sẽ hiển thị tại thời điểm khởi tạo sẽ không có sẵn tại bất kỳ thời điểm nào khác:
Cụ thể hơn, quy trình hủy niêm phong của Vault giải mã phần phụ trợ bằng cách sử dụng khóa được tạo bởi các chia sẻ khóa. Khi bạn khởi tạo Vault lần đầu tiên, bạn có thể chọn số lượng khóa bỏ niêm phong để tạo, và số lượng khóa cần thiết tại thời điểm hủy niêm phong để hủy niêm phong thành công Vault. Để tìm hiểu thêm về cơ chế niêm phong của Vault, bạn có thể tham khảo tài liệu của Vault.
Một cấu hình điển hình cho các tham số hủy niêm phong sẽ là tạo ba khóa và yêu cầu ít nhất hai trong số các khóa đó tại thời điểm hủy niêm phong. Điều này cho phép chia sẻ khóa quan trọng được tách riêng và lưu trữ ở các vị trí riêng biệt để đảm bảo rằng việc xâm phạm một khóa là không đủ để hủy niêm phong Vault.
Nói cách khác, bất cứ khi nào Vault được khởi động, ít nhất hai khóa chưa được niêm phong sẽ được yêu cầu để làm cho dịch vụ trở nên khả dụng và sẵn sàng sử dụng. Trong khi được niêm phong, các tệp lưu trữ các giá trị bí mật thực tế sẽ vẫn được mã hóa và không thể truy cập được.
Khởi tạo Vault bằng ba khóa bỏ niêm phong bằng cách sử dụng tùy chọn -key-shares=3
và yêu cầu ít nhất hai khóa để hủy niêm phong vault bằng cờ -key-threshold=2
.
- vault operator init -key-shares=3 -key-threshold=2
Bạn sẽ nhận được đầu ra như sau:
OutputUnseal Key 1: eZcJeydRrqeSMZ1zTN+VVll9TFT2KvJy7VlnxUgtvuz5
Unseal Key 2: ntmqCKq8rgNnKT1YSLCjVmCCZBAA3NwUeqxIyRpYD4Wm
Unseal Key 3: 3FK1+Hsorh4p8/L9mki3VskaEU2eQhLqGOI/pJkTHMbx
Initial Root Token: s.hY0ieybfDqCadz7JpL88uO3x
Đảm bảo lưu từng mã thông báo chưa niêm phong và mã thông báo gốc ban đầu theo cách an toàn. Bạn sẽ không thể lấy lại các khóa và mã thông báo gốc này. Ví dụ: một tùy chọn sẽ là lưu trữ một khóa chưa niêm phong trong trình quản lý mật khẩu, một tùy chọn khác trên ổ USB và một tùy chọn khác trong tệp được mã hóa GPG.
Nếu bạn kiểm tra lại vault status
, trạng thái Initialized
giờ đây sẽ được đặt thành true
và các giá trị Total Shares
và Threshold
sẽ phản ánh số lượng phân đoạn khóa và số lượng khóa tối thiểu mà bạn sẽ cần để hủy niêm phong vault.
- vault status
Output. . .
Initialized true
Sealed true
Total Shares 3
Threshold 2
Unseal Progress 0/2
. . .
Lưu ý rằng dòng Unseal Progess
hiển thị giá trị 0/2
. Bắt đầu hủy niêm phong Vault bằng cách sử dụng mã thông báo hủy niêm phong mới tạo của bạn. Chạy lệnh vault operator unseal
và nhập bất kỳ phím nào của bạn khi được nhắc:
- vault operator unseal
Lệnh sẽ yêu cầu mã thông báo chưa được niêm phong:
OutputKey (will be hidden):
Sau khi nhập nó, đầu ra từ lệnh sẽ cho biết quá trình hủy niêm phong đang diễn ra nhưng vẫn yêu cầu thêm một khóa hủy niêm phong nữa trước khi Vault sẵn sàng sử dụng.
OutputKey Value
--- -----
Seal Type shamir
Initialized true
Sealed true
Total Shares 3
Threshold 2
Unseal Progress 1/2
Unseal Nonce 0f3a328b-e0c6-6294-d6a2-56da49271dff
Version 1.8.5
Storage Type file
HA Enabled false
Lưu ý cách dòng Unseal Progress 1/2
đã thay đổi trong đầu ra. Chạy lại lệnh unseal
.
- vault operator unseal
Và nhập một khóa khác với khóa bạn đã sử dụng:
OutputKey (will be hidden):
Đầu ra của lệnh chỉ ra rằng quá trình hủy niêm phong đã hoàn tất thành công.
OutputKey Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 3
Threshold 2
Version 1.8.5
Storage Type file
Cluster Name vault-cluster-3042c7bc
Cluster ID c3e9d814-cf2a-2901-f0e4-ebc52d29e5cc
HA Enabled false
Vault hiện chưa được niêm phong và sẵn sàng để sử dụng. Các bước hủy niêm phong này là cần thiết bất cứ khi nào Vault được khởi động hoặc khởi động lại.
Tuy nhiên, hủy niêm phong là một quy trình khác với tương tác thông thường với Vault (chẳng hạn như đọc và ghi giá trị), được xác thực bằng mã thông báo. Trong các bước tiếp theo, chúng ta sẽ tạo các chính sách và mã thông báo truy cập cần thiết để lưu trữ các giá trị bí mật và đọc/ghi vào các đường dẫn cụ thể trong Vault.
Có một số chương trình phụ trợ bí mật mà bạn có thể sử dụng với Vault, nhưng trong ví dụ này, chúng ta sẽ sử dụng chương trình phụ trợ bí mật kv
. Chương trình phụ trợ này lưu trữ các cặp key/value đơn giản trong Vault. Tuy nhiên, nó không được kích hoạt theo mặc định.
Trong phần hướng dẫn này, bạn sẽ kích hoạt chương trình phụ trợ bí mật kv
, sau đó tìm hiểu cách đọc và ghi các bí mật vào đó.
Đầu tiên, lưu mã thông báo gốc đã tạo trước đó vào một biến shell để dễ sử dụng.
- root_token=your_root_token_here
Tiếp theo, trong khi xác thực bằng mã thông báo gốc, hãy bật phụ trợ kv
:
- VAULT_TOKEN=$root_token vault secrets enable kv
Bạn sẽ nhận được kết quả như sau nếu lệnh thành công:
OutputSuccess! Enabled the kv secrets engine at: kv/
Sau đó, bạn có thể xác minh rằng nó đã được thêm vào danh sách phụ trợ bí mật có sẵn tại địa phương của bạn:
- VAULT_TOKEN=$root_token vault secrets list
Bạn sẽ nhận được đầu ra như sau:
OutputPath Type Accessor Description
---- ---- -------- -----------
cubbyhole/ cubbyhole cubbyhole_abc1631b per-token private secret storage
identity/ identity identity_631fe262 identity store
kv/ kv kv_4d5855c8 n/a
sys/ system system_79b13f2f system endpoints used for control, policy and debugging
Lưu ý dòng được đánh dấu cho biết chương trình phụ trợ kv
mới đã được bật. Bây giờ chúng ta có thể lưu trữ một số dữ liệu với chương trình phụ trợ này.
- VAULT_TOKEN=$root_token vault write kv/message value=mypassword
Trong lệnh này, tiền tố kv/
được đánh dấu cho biết rằng chúng ta đang ghi vào chương trình phụ trợ kv
được gắn tại đường dẫn kv
, và chúng ta đang lưu trữ key value
tại đường dẫn message
với giá trị mypassword
. Chúng ta đã sử dụng mã thông báo gốc, có đặc quyền superuser, để viết bí mật chung.
Kiểm tra bí mật mà bạn đã tạo bằng lệnh vault read
:
- VAULT_TOKEN=$root_token vault read kv/message
Bạn sẽ nhận được đầu ra như sau, với nội dung của bí mật mà bạn đã tạo:
OutputKey Value
--- -----
refresh_interval 768h
value mypassword
Tuy nhiên, việc tạo, đọc và tương tác với Vault chỉ bằng cách sử dụng Root Token là không an toàn, có thể mở rộng trong cài đặt nhóm và không cho phép kiểm soát quyền truy cập chi tiết vào các bí mật. Trong phần tiếp theo, bạn sẽ tìm hiểu cách xác định chính sách và tạo mã thông báo truy cập bổ sung để hạn chế cách người dùng có thể tương tác với Vault.
Trong tình huống thực tế, bạn có thể lưu trữ các giá trị như khóa API hoặc mật khẩu mà các công cụ bên ngoài có thể sử dụng. Mặc dù bạn có thể đọc lại giá trị bí mật bằng cách sử dụng mã thông báo gốc, nhưng việc tạo mã thông báo ít đặc quyền hơn với quyền read-only đối với bí mật duy nhất của chúng ta là minh họa.
Trong phần hướng dẫn này, bạn sẽ tạo một chính sách Vault sẽ thực thi quyền truy cập chỉ đọc vào các bí mật. Để tạo chính sách, bạn cần chỉnh sửa tệp rồi tải tệp đó vào Vault bằng cách sử dụng lệnh vault policy
.
Để bắt đầu tạo chính sách, hãy mở tệp có tên policy.hcl
bằng nano
hoặc trình chỉnh sửa ưa thích của bạn:
- nano policy.hcl
Điền vào tệp bằng chính sách Vault dưới đây, chính sách này xác định quyền truy cập read-only vào đường dẫn bí mật:
path "kv/message" {
capabilities = ["read"]
}
Lưu và đóng tệp, sau đó ghi chính sách này vào Vault. Lệnh sau sẽ tải tệp policy.hcl
vào Vault và tạo một chính sách có tên là message-readonly
với khả năng read-only.
- VAULT_TOKEN=$root_token vault policy write message-readonly policy.hcl
Tiếp theo, tạo mã thông báo mà bạn sẽ sử dụng cho quyền truy cập read-only vào Vault. Thêm cờ -policy=”message-readonly”
vào lệnh vault token create
để sử dụng chính sách mới mà bạn đã tạo:
- VAULT_TOKEN=$root_token vault token create -policy="message-readonly"
Đầu ra sẽ trông như thế này:
OutputKey Value
--- -----
token your_token_value
token_accessor your_token_accessor
token_duration 768h0m0s
token_renewable true
token_policies ["default" "message-readonly"]
identity_policies []
policies ["default" "message-readonly"]
Lưu giá trị your_token_value
được đánh dấu vào biến môi trường có tên app_token
:
- app_token=your_token_value
Bạn có thể sử dụng giá trị của app_token
để truy cập dữ liệu được lưu trữ trong đường dẫn kv/message
(và không có giá trị nào khác trong Vault).
- VAULT_TOKEN=$app_token vault read kv/message
OutputKey Value
--- -----
refresh_interval 768h0m0s
value mypassword
Bạn cũng có thể kiểm tra để đảm bảo rằng mã thông báo không có đặc quyền này không thể thực hiện các hoạt động khác, chẳng hạn như liệt kê các bí mật trong Vault.
- VAULT_TOKEN=$app_token vault list kv/
OutputError reading kv/: Error making API request.
URL: GET https://your_domain:8200/v1/secret?list=true
Code: 403. Errors:
* 1 error occurred:
* permission denied
Điều này xác minh rằng mã thông báo ứng dụng ít đặc quyền hơn không thể thực hiện bất kỳ hành động phá hoại nào, hoặc truy cập các giá trị bí mật khác ngoài những giá trị được nêu rõ ràng trong chính sách Vault của nó. Nếu bạn muốn tiếp tục sử dụng read-only token, hãy đảm bảo ghi lại mã đó ở nơi an toàn để sử dụng trong tương lai.
Trong bài viết này, bạn đã cài đặt, thiết lập cấu hình và triển khai Vault trên Ubuntu 20.04. Bạn cũng đã tạo khóa phân đoạn để hủy niêm phong Vault, bật kho lưu trữ bí mật phụ trợ kv
và xác định chính sách read-only để hạn chế cách người dùng có thể tương tác với bí mật Vault.
Mặc dù hướng dẫn này chỉ trình bày cách sử dụng mã thông báo không có đặc quyền, nhưng tài liệu Vault có nhiều ví dụ hơn về các cách bổ sung để lưu trữ và truy cập bí mật cũng như các phương pháp xác thực thay thế.
Các hướng dẫn này trình bày cách triển khai và sử dụng một số tính năng cốt lõi của Vault. Nhu cầu của bạn có thể yêu cầu thay đổi cấu hình khác và các chính sách phức tạp hơn. Hãy nhớ đọc tài liệu về Vault và thực hiện các thay đổi cấu hình phù hợp với nhu cầu của bạn. Một số thay đổi sẵn sàng sản xuất có thể bao gồm:
app_token
trong hướng dẫn này minh họa cách bạn có thể tạo các chính sách và mã thông báo có đặc quyền hạn chế.