# Hashicorp Vault

HashiCorp Vault เป็นเครื่องมือจัดการความปลอดภัยและการเข้าถึงข้อมูลสำคัญในระบบไอที มันถูกออกแบบมาเพื่อจัดเก็บ จัดการ และควบคุมการเข้าถึงข้อมูลลับต่าง ๆ เช่น รหัสผ่าน คีย์ API และข้อมูลที่เป็นความลับอื่น ๆ โดยมีคุณสมบัติที่สำคัญดังนี้

1. **การจัดเก็บข้อมูลลับ (Secrets Management)**: Vault ช่วยในการจัดเก็บข้อมูลลับต่าง ๆ ในที่เดียว และควบคุมการเข้าถึงอย่างเข้มงวด ผู้ใช้งานสามารถกำหนดสิทธิ์การเข้าถึงได้ตามบทบาทหรือการกำหนดนโยบายเฉพาะ
2. **Dynamic Secrets**: Vault สามารถสร้างข้อมูลลับแบบชั่วคราวสำหรับการเข้าถึงระบบภายนอก เช่น ฐานข้อมูลหรือบริการอื่น ๆ ซึ่งข้อมูลลับเหล่านี้จะถูกสร้างใหม่ในทุกครั้งที่มีการร้องขอ และจะหมดอายุเมื่อใช้งานเสร็จสิ้น
3. **Encryption as a Service**: Vault ให้บริการการเข้ารหัสข้อมูลผ่าน API เพื่อใช้ในการเข้ารหัสและถอดรหัสข้อมูลต่าง ๆ โดยที่แอปพลิเคชันหรือระบบต่าง ๆ ไม่จำเป็นต้องมีการจัดการคีย์เข้ารหัสเอง
4. **การควบคุมการเข้าถึงที่ปลอดภัย (Access Control)**: Vault มีระบบการควบคุมสิทธิ์การเข้าถึงที่ละเอียด ผู้ใช้งานจะสามารถเข้าถึงเฉพาะข้อมูลที่จำเป็นตามที่ได้รับอนุญาต ซึ่งลดความเสี่ยงจากการเปิดเผยข้อมูลที่ไม่จำเป็น
5. **Audit Logging**: Vault มีการบันทึกการใช้งานเพื่อให้สามารถตรวจสอบการเข้าถึงและใช้งานข้อมูลลับต่าง ๆ ทำให้มีความโปร่งใสและสามารถติดตามการดำเนินการย้อนหลังได้

## Consul คืออะไร

Consul เป็นเครื่องมือที่ให้บริการ **service discovery** และ **distributed key-value store** ที่ใช้สำหรับเก็บข้อมูลเช่น การกำหนดค่าและข้อมูลสภาวะการทำงานของระบบแบบกระจายตัว (distributed systems) โดย Consul มีคุณสมบัติหลัก ๆ ดังนี้

1. **High Availability**: สามารถทำงานในโหมดกระจายตัวที่มีหลายโหนด (nodes) เพื่อเพิ่มความทนทานต่อการล้มเหลว
2. **Replication**: Consul จะทำการ replicates ข้อมูลระหว่างโหนดหลายโหนด เพื่อความทนทานต่อการสูญเสียข้อมูล
3. **Service Discovery**: มีคุณสมบัติการค้นหาบริการและการติดตามสุขภาพ (health checking) ของบริการในระบบ

การใช้ **Consul** เป็น backend สำหรับ HashiCorp Vault เป็นการตั้งค่าที่ช่วยให้ Vault สามารถจัดเก็บข้อมูลที่สำคัญและมีความทนทานในการทำงาน โดย Consul ทำหน้าที่เป็น **Storage Backend** ที่สามารถจัดเก็บข้อมูลต่าง ๆ ที่ Vault ต้องการเก็บ เช่น Secret, Tokens, และข้อมูลการกำหนดค่าอื่น ๆ การตั้งค่า Consul เป็น backend มีประโยชน์ในด้านการจัดเก็บที่ปลอดภัยและการกระจายโหลดสำหรับการใช้งาน Vault ใน production environment

## การติดตั้ง Hashicorp Vault

### ติดตั้ง Consul

จากตัวอย่างนี้ จะติดตั้ง consul บน Kubernetes cluster ผ่าน Helm Chart ของ Hashicorp

#### Architecture

ตาม recommend ของ Hashicorp กำหนดว่า consul server ควรมีอย่างน้อย 5 node และกระจายกันอยู่ใน 3 AZ แต่โดยส่วนมากสำหรับ small production site ใช้ 3 node ก็เพียงพอ เช่นกัน

<figure><img src="/files/QMxQMr5aV105jFfYg33Z" alt=""><figcaption><p>consul for production</p></figcaption></figure>

#### Hardware Requirement

<table><thead><tr><th width="92">Size</th><th width="101">CPU</th><th width="105">Memory</th><th width="138">Disk Capacity</th><th width="147">Disk IO</th><th>Disk Throughput</th></tr></thead><tbody><tr><td>Small</td><td>2-4 core</td><td>8-16 GB</td><td>100+ GB</td><td>3000+ IOPS</td><td>75+ MB/s</td></tr><tr><td>Large</td><td>8-16 core</td><td>32-64 GB</td><td>200+ GB</td><td>7500+ IOPS</td><td>250+ MB/s</td></tr></tbody></table>

#### Network Latency Requirement

round trip time (RTT) ในการสื่อสารกันระหว่าง agent ต้องไม่เกิน ดังนี้

* RTT ของทุก traffic โดยเฉลี่ย ต้องไม่เกิน 50ms
* RTT ที่ percentile 99 ต้องไม่เกิน 100ms

#### Firewall rule

<table><thead><tr><th width="150">Name</th><th>Port / Protocol</th><th>Source</th><th>Destination</th><th>Description</th></tr></thead><tbody><tr><td>RPC</td><td>8300 / TCP</td><td>All agents (client &#x26; server)</td><td>Server agents</td><td>Used by servers to handle incoming requests from other agents.</td></tr><tr><td>Serf LAN</td><td>8301 / TCP &#x26; UDP</td><td>All agents (client &#x26; server)</td><td>All agents (client &#x26; server)</td><td>Used to handle gossip in the LAN. Required by all agents.</td></tr><tr><td>Serf WAN</td><td>8302 / TCP &#x26; UDP</td><td>Server agents</td><td>Server agents</td><td>Used by server agents to gossip over the WAN to other server agents. Only used in multi-cluster environments.</td></tr><tr><td>HTTP/HTTPS</td><td>8500 &#x26; 8501 TCP</td><td>Localhost of client or server agent</td><td>Localhost of client or server agent</td><td>Used by clients to talk to the HTTP API. HTTPS is disabled by default.</td></tr><tr><td>DNS</td><td>8600 TCP &#x26; UDP</td><td>Localhost of client or server agent</td><td>Localhost of client or server agent</td><td>Used to resolve DNS queries.</td></tr><tr><td>gRPC (Optional)</td><td>8502 TCP</td><td>Envoy proxy</td><td>Client agent or server agent that manages the sidecar proxies service registration</td><td>Used to expose the xDS API to Envoy proxies. Disabled by default.</td></tr><tr><td>Sidecar Proxy (Optional)</td><td>21000 - 21255 TCP</td><td>All agents (client &#x26; server)</td><td>Client agent or server agent that manages the sidecar proxies service registration</td><td>Port range used for automatically assigned sidecar service registrations.</td></tr></tbody></table>

#### ตัวอย่าง value file

สร้างไฟล์ `consul.values.yaml`

```yaml
global:
  name: consul
  datacenter: dc1
  gossipEncryption:
    autoGenerate: true
server:
  replicas: 3
  storage: 10Gi
  resources:
    requests:
      memory: '1Gi'
      cpu: '1'
    limits:
      memory: '1Gi'
      cpu: null # override existing cpu limit value
  topologySpreadConstraints: |
    - maxSkew: 1
      topologyKey: topology.kubernetes.io/zone
      whenUnsatisfiable: DoNotSchedule
      labelSelector:
        matchLabels:
          app: {{ template "consul.name" . }}
          release: "{{ .Release.Name }}"
          component: server
client:
  enabled: true
  resources:
    requests:
      memory: '512Mi'
      cpu: '500m'
    limits:
      memory: '512Mi'
      cpu: null # override existing cpu limit value
ui:
  enabled: true
  service:
    type: ClusterIP
```

ติดตั้งด้วยคำสั่งดังนี้

```bash
helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
helm upgrade --install consul hashicorp/consul --values consul.values.yaml --create-namespace --namespace vault
```

***

### ติดตั้ง Vault

เตรียม YAML file ชื่อ `vault.values.yaml` ดังนี้

```yaml
server:
  ha:
    enabled: true
    replicas: 3
  auditStorage:
    enabled: true
    size: 10Gi
  resources:
    requests:
      memory: "1Gi"
      cpu: "250m"
    limits:
      memory: "1Gi"
  topologySpreadConstraints: |
    - maxSkew: 1
      topologyKey: topology.kubernetes.io/zone
      whenUnsatisfiable: DoNotSchedule
      labelSelector:
        matchLabels:
          app.kubernetes.io/name: {{ include "vault.name" . }}
          app.kubernetes.io/instance: {{ .Release.Name }}
          component: server
ui:
  enabled: true
```

ติดตั้งด้วยคำสั่งดังนี้

```bash
helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
helm upgrade --install vault hashicorp/vault --values vault.values.yaml --create-namespace --namespace vault
```

หลังจากติดตั้งเสร็จ ตรวจสอบสถานะ vault

```bash
kubectl exec vault-0 -n vault -- vault status
```

จะขึ้นผลลัพธ์ว่าถูก seal ไว้อยู่

```
Key                Value
---                -----
Seal Type          shamir
Initialized        false
Sealed             true
Total Shares       0
Threshold          0
Unseal Progress    0/0
Unseal Nonce       n/a
Version            1.17.2
Build Date         2024-07-05T15:19:12Z
Storage Type       consul
HA Enabled         true
```

ใช้ command ดังนี้เพื่อ generate root key <mark style="color:orange;">**ใช้ในการ bootstrap cluster ครั้งแรกเท่านั้น**</mark>

```bash
kubectl exec vault-0 -n vault -- vault operator init -key-shares=1 -key-threshold=1 -format=json > cluster-keys.json
```

{% hint style="warning" %}
จากตัวอย่างจากกำหนด key 1 ตัวเท่านั้น เพื่อความง่าย

ใน enterprise อาจจะไม่ควรใส่ `-key-shares=1 -key-threshold=1`
{% endhint %}

ทำการ unseal vault server

```bash
VAULT_UNSEAL_KEY=$(cat cluster-keys.json | jq -r ".unseal_keys_b64[]")
kubectl exec vault-0 -n vault -- vault operator unseal $VAULT_UNSEAL_KEY
```

จะได้ผลลัพธ์ดังนี้

```
Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false
Total Shares    1
Threshold       1
Version         1.17.2
Build Date      2024-07-05T15:19:12Z
Storage Type    consul
Cluster Name    vault-cluster-7e64d0dc
Cluster ID      05f0b39c-2def-5ce6-5597-71863db4864e
HA Enabled      true
HA Cluster      https://vault-0.vault-internal:8201
HA Mode         active
Active Since    2024-10-11T10:15:00.540042962Z
```

ทำ port-forward เพื่อทดสอบใช้งาน Vault

```bash
kubectl port-forward svc/vault-ui -n vault 8200:8200
```

เข้า web browser ผ่าน <http://localhost:8200>

ทดสอบ login ผ่าน UI ด้วย token ของ root

{% hint style="info" %}
root token ได้มาจากตอน bootstrap cluster ด้วยคำสั่ง vault operator init

ดังนั้นสามารถหาได้จากคำสั่ง

```bash
cat cluster-keys.json |jq '.root_token'
```

{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://handbook.novice.solutions/tools/security/hashicorp-vault.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
