rate limit quota 만들기
rate limit quota 만들기
Vault의 rate limit quota를 사용하면 Vault 관리자가 대상 namespace, mount, path 또는 role에 한도를 설정해 트래픽이 Vault 클러스터로 들어오는 방식을 제어할 수 있습니다. 이는 Community 및 Enterprise 에디션 모두에서 사용할 수 있는 Vault 핵심 기능 세트의 일부입니다.
출처: 문서
본문
Community vs. Enterprise rate limit quota의 기본 동작은 rate limit을 적용하기 위해 수신 요청을 소스 IP 주소를 기준으로 그룹화하는 것입니다. 이는 Vault Community Edition의 유일한 사용 가능한 모드입니다. Vault Enterprise는 추가 모드를 제공합니다. 추가 기능에 대해 알아보려면 Rate limit quotas - collective, by IP, by entity 페이지를 읽어보세요.
시작하기 전에
- Vault 인스턴스의 root 또는 관리 namespace에 접근 권한이 있는지 확인하세요. rate limit quota를 수정하는 것은 제한된 활동입니다.
1단계: 적절한 세분성(granularity) 결정
rate limit의 세분성은 Vault 클러스터의 성능에 영향을 줄 수 있습니다. 특히 rate limit으로 인해 거부되는 요청 수가 급격히 늘어나면 audit 로깅 증가가 Vault 성능에 영향을 줄 수 있습니다.
2단계: audit 로그 활성화
기본적으로 rate limit quota 위반으로 거부된 요청은 audit 로그에 기록되지 않습니다. 따라서 추적 가능성을 위해 거부된 요청을 로깅하려면 sys/quotas/config 엔드포인트에 대해 enable_rate_limit_audit_logging을 true로 설정해야 합니다. lease count quota에 도달해 거부된 요청은 항상 로깅되므로 파라미터를 설정할 필요가 없습니다.
성능 고려 사항 rate limit audit 로깅을 활성화하면 거부된 요청의 양이 많을 때 Vault 성능에 영향을 줄 수 있습니다.
/var/log/vault-audit.log(또는 원하는 파일 위치)로 출력하는 파일 audit 디바이스를 활성화합니다.
$ vault audit enable file file_path="/var/log/vault-audit.log"
- rate limit quota에 대한 audit 로깅을 활성화하려면 다음 명령을 실행합니다.
$ vault write sys/quotas/config enable_rate_limit_audit_logging=true
- quota 구성을 읽어 확인합니다.
$ vault read sys/quotas/config
Key Value
--- -----
absolute_rate_limit_exempt_paths []
enable_rate_limit_audit_logging true
enable_rate_limit_response_headers false
rate_limit_exempt_paths []
- 파일 audit 디바이스를 활성화합니다.
먼저 audit 로그 경로가 /var/log/vault-audit.log(또는 원하는 파일 위치)로 지정된 HTTP 요청 페이로드를 만듭니다.
$ tee audit-payload.json <<EOF
{
"type": "file",
"options": {
"file_path": "/var/log/vault-audit.log"
}
}
EOF
sys/audit 엔드포인트를 사용해 파일 audit 로그를 활성화합니다.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data @audit-payload.json \
$VAULT_ADDR/v1/sys/audit/file
대상 file_path를 원하는 위치로 설정하세요.
- rate limit quota audit 로깅을 활성화하는 HTTP 요청 페이로드를 만듭니다.
$ tee payload.json <<EOF
{
"enable_rate_limit_audit_logging": true
}
EOF
sys/quotas/config엔드포인트를 호출합니다.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data @payload.json \
$VAULT_ADDR/v1/sys/quotas/config
- quota 구성을 읽어 확인합니다.
$ curl -s --header "X-Vault-Token: $VAULT_TOKEN" \
$VAULT_ADDR/v1/sys/quotas/config | jq -r ".data"
예시 출력:
{
"absolute_rate_limit_exempt_paths": [],
"enable_rate_limit_audit_logging": true,
"enable_rate_limit_response_headers": false,
"rate_limit_exempt_paths": []
}
3단계: rate limit quota 만들기
다음 파라미터를 사용해 rate limit quota를 만듭니다:
-
name(string: "")- quota 규칙의 이름 -
path(string: "")- quota 규칙을 적용할 대상 namespace, mount 또는 path입니다.*로 끝날 수 있습니다(예:auth/token/create*). 빈 path는 전역 rate limit quota를 구성합니다. -
ratefloat- 허용되는 초당 요청 수(RPS)의 속도 -
role(string: "")- 이 quota를 적용할 로그인 role입니다. 이 파라미터를 설정할 때는 role 개념이 있는 유효한 auth method로 path를 구성해야 합니다. -
interval(int: 0)- rate limiting을 적용할 기간(기본값은 1초) -
block_interval(string: "")- 설정하면 클라이언트가 rate limit 임계값에 도달했을 때block_interval이 경과할 때까지 Vault가 클라이언트의 추가 요청을 금지합니다. -
inheritable(boolean: false)-Enterprise quota 규칙을 하위 namespace에 적용할지 여부를 결정합니다.
-
group_by(string: "")-Enterprise 수신 요청을 그룹화하는 방법을 정의합니다. 자세한 내용은 identity-based rate limit quotas를 참고하세요.
-
secondary_rate(float: 0.0)–Enterprise
group_by모드entity_then_ip또는entity_then_none에만 설정할 수 있습니다. "ip" 또는 "none" 그룹에 속하는 요청에 적용되는 rate limit이며, 엔티티 ID를 포함한 인증된 요청은 대신rate필드의 적용을 받습니다. 기본값은rate와 같은 값입니다.
vault write와 sys/quotas/rate-limit/{quota-name} 경로를 사용해 새 rate limit quota를 만듭니다.
$ vault write sys/quotas/rate-limit/<QUOTA_NAME> \
name="<QUOTA_RULE_NAME>" \
path="<TARGET_PATH>" \
rate=<ALLOWED_REQUEST_RATE> \
role="<ROLE_NAME>" \
interval=<DURATION_OF_RATE_LIMIT> \
block_interval=<DURATION_TO_BLOCK_REQUESTS> \
inheritable=<BOOLEAN> \
예시: Vault 클러스터에 적용되는 rate limit quota를 만듭니다.
- 인바운드 워크로드를 초당 100개 요청으로 제한하는 "global-rate"라는 rate limit quota를 만듭니다.
$ vault write sys/quotas/rate-limit/global-rate rate=100
Success! Data written to: sys/quotas/rate-limit/global-rate
global-rate규칙을 읽어 구성이 올바른지 확인합니다.
$ vault read sys/quotas/rate-limit/global-rate
Key Value
--- -----
block_interval 0
group_by ip
inheritable true
interval 1
name global-rate
path n/a
rate 100
role n/a
type rate-limit
참고
path가 없으면 이 quota 규칙은 특정 mount나 namespace 대신 전역 수준에 적용됩니다.
예시: Transit secrets engine에 대한 접근을 분당(60초) 1,000개 요청으로 제한하는 "transit-limit"라는 rate limit quota를 만듭니다. 요청을 소스 IP 주소별로 그룹화합니다.
transit에 Transit secrets engine을 활성화합니다.
$ vault secrets enable transit
Success! Enabled the transit secrets engine at: transit/
- rate limit quota를 만듭니다.
$ vault write sys/quotas/rate-limit/transit-limit \
path="transit" \
rate=1000 \
interval=60
출력:
Success! Data written to: sys/quotas/rate-limit/transit-limit
transit-limit규칙을 읽어 구성이 올바른지 확인합니다.
$ vault read sys/quotas/rate-limit/transit-limit
출력:
Key Value
--- -----
block_interval 0
group_by ip
inheritable true
interval 60
name transit-limit
path transit/
rate 1000
role n/a
type rate-limit
경로 세분성(Path granularity)
path를 마운트 지점(이 예시에서는 transit/)보다 더 깊게 설정할 수 있습니다.
예시: orders 키를 사용하는 데이터 암호화 요청을 초당 500개로 제한하는 "transit-order"라는 rate limit quota를 만듭니다.
- "orders"라는 암호화 키를 만듭니다.
$ vault write -f transit/keys/orders
Key Value
--- -----
allow_plaintext_backup false
auto_rotate_period 0s
deletion_allowed false
derived false
exportable false
imported_key false
keys map[1:1695147293]
latest_version 1
min_available_version 0
min_decryption_version 1
min_encryption_version 0
name orders
supports_decryption true
supports_derivation true
supports_encryption true
supports_signing false
type aes256-gcm96
- "transit-order" rate limit quota를 만듭니다.
$ vault write sys/quotas/rate-limit/transit-order \
path="transit/encrypt/orders" \
rate=500
출력:
Success! Data written to: sys/quotas/rate-limit/transit-order
- rate limit quota 구성을 확인합니다.
$ vault read sys/quotas/rate-limit/transit-order
출력:
Key Value
--- -----
block_interval 0
group_by ip
inheritable true
interval 1
name transit-order
path transit/encrypt/orders
rate 500
role n/a
type rate-limit
Vault Enterprise namespaces
Vault Enterprise 클러스터의 경우 inheritable 파라미터를 사용해 namespace에 설정된 리소스 quota를 그 하위 namespace에 적용할 수 있습니다.
다음 namespace 계층 구조를 생각해 보세요:
root
└── parent
└── child
└── grand-child
root namespace 아래에 parent namespace가 있고, 그 다음 parent/child와 parent/child/grand-child namespaces가 있습니다.
inheritable 파라미터를 true로 설정하면 parent namespace에 리소스 quota를 설정해 하위 namespaces에 상속되게 적용할 수 있습니다. 기본값은 false입니다.
- 하위 namespaces가 상속할
us-westnamespace에 quota 규칙을 만듭니다. rate limit은 분당 500개 요청입니다.
$ vault write sys/quotas/rate-limit/us-west \
path="us-west" \
rate=500 \
interval=1m \
inheritable=true
출력:
Success! Data written to: sys/quotas/rate-limit/us-west
- quota 규칙을 확인합니다.
$ vault read sys/quotas/rate-limit/us-west
Key Value
--- -----
block_interval 0
group_by ip
inheritable true
interval 60
name us-west
path us-west/
rate 500
role n/a
type rate-limit
quota 설정이 포함된 페이로드 파일을 만들고 sys/quotas/rate-limit/{quota-name} 엔드포인트를 호출합니다.
{
"name": "<QUOTA_RULE_NAME>",
"path": "<TARGET_PATH>",
"rate": <ALLOWED_REQUEST_RATE>,
"role": "<ROLE_NAME>",
"interval": <DURATION_OF_RATE_LIMIT>,
"block_interval": <DURATION_TO_BLOCK_REQUESTS>,
"inheritable": <BOOLEAN>
}
예시: 인바운드 워크로드를 초당 100개 요청으로 제한하는 "global-rate"라는 rate limit quota를 만듭니다.
sys/quotas/rate-limit엔드포인트를 호출합니다.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{ "rate": 100 }' \
$VAULT_ADDR/v1/sys/quotas/rate-limit/global-rate
- 새로 만든
global-ratequota 규칙을 읽습니다.
$ curl -s --header "X-Vault-Token: $VAULT_TOKEN" \
$VAULT_ADDR/v1/sys/quotas/rate-limit/global-rate | jq -r ".data"
출력:
{
"block_interval": 0,
"group_by": "ip",
"inheritable": true,
"interval": 1,
"name": "global-rate",
"path": "",
"rate": 100,
"role": "",
"type": "rate-limit"
}
참고
path가 없으면 이 quota 규칙은 특정 mount나 namespace 대신rootnamespace에 적용됩니다.
예시: Transit secrets engine에 대한 접근을 분당(60초) 1000개 요청으로 제한하는 "transit-limit"라는 rate limit quota를 만듭니다.
transit에 Transit secrets engine을 활성화합니다.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"type":"transit"}' \
$VAULT_ADDR/v1/sys/mounts/transit
- "transit-limit" rate limit quota를 만듭니다.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"path": "transit", "rate": 1000, "interval": 60 }' \
$VAULT_ADDR/v1/sys/quotas/rate-limit/transit-limit
transit-limit규칙을 읽어 구성이 올바른지 확인합니다.
$ curl -s --header "X-Vault-Token: $VAULT_TOKEN" \
$VAULT_ADDR/v1/sys/quotas/rate-limit/transit-limit | jq -r ".data"
출력:
{
"block_interval": 0,
"group_by": "ip",
"inheritable": true,
"interval": 60,
"name": "transit-limit",
"path": "transit/",
"rate": 1000,
"role": "",
"type": "rate-limit"
}
경로 세분성
path를 마운트 지점(이 예시에서는 transit/)보다 더 깊게 설정할 수 있습니다.
예시: orders 키를 사용하는 데이터 암호화 요청을 초당 500개로 제한하는 "transit-order"라는 rate limit quota를 만듭니다.
- "orders"라는 암호화 키를 만듭니다.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
$VAULT_ADDR/v1/transit/keys/orders
- "transit-order" rate limit quota를 만듭니다.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{ "path": "transit/encrypt/orders", "rate": 500 }' \
$VAULT_ADDR/v1/sys/quotas/rate-limit/transit-order
- rate limit quota 구성을 확인합니다.
$ curl -s --header "X-Vault-Token: $VAULT_TOKEN" \
$VAULT_ADDR/v1/sys/quotas/rate-limit/transit-order | jq -r ".data"
출력:
{
"block_interval": 0,
"group_by": "ip",
"inheritable": true,
"interval": 1,
"name": "transit-order",
"path": "transit/encrypt/orders",
"rate": 500,
"role": "",
"type": "rate-limit"
}
Vault Enterprise namespaces
Vault Enterprise 클러스터의 경우 inheritable 파라미터를 사용해 namespace에 설정된 리소스 quota를 그 하위 namespace에 적용할 수 있습니다.
다음 namespace 계층 구조를 생각해 보세요:
root
└── parent
└── child
└── grand-child
root namespace 아래에 parent namespace가 있고, 그 다음 parent/child와 parent/child/grand-child namespaces가 있습니다.
inheritable 파라미터를 true로 설정하면 parent namespace에 리소스 quota를 설정해 하위 namespaces에 상속되게 적용할 수 있습니다. 기본값은 false입니다.
- 하위 namespace가 상속할
us-westnamespace에 quota 규칙을 만듭니다. rate limit은 분당 500개 요청입니다.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"path": "us-west", "rate": 500, "interval": 60, "inheritable": true }' \
$VAULT_ADDR/v1/sys/quotas/rate-limit/us-west
- quota 규칙을 확인합니다.
$ curl -s --header "X-Vault-Token: $VAULT_TOKEN" \
$VAULT_ADDR/v1/sys/quotas/rate-limit/us-west | jq -r ".data"
출력:
{
"block_interval": 0,
"group_by": "ip",
"inheritable": true,
"interval": 60,
"name": "us-west",
"path": "us-west/",
"rate": 500,
"role": "",
"type": "rate-limit"
}
HashiCorp Terraform을 사용해 rate limit quota를 설정할 수 있습니다.
예시:
main.tf라는 파일을 다음 내용으로 만듭니다.
# Use Vault provider
provider vault {}
# Create "global-rate" which limits inbound workload to 100 requests per second
resource "vault_quota_rate_limit" "global" {
name = "global-rate"
path = ""
rate = 100
}
# Create "transit-limit" which limits the access to the Transit secrets engine to be 1000 requests per minute (60 seconds)
resource "vault_quota_rate_limit" "transit-limit" {
name = "transit-limit"
path = "transit/"
rate = 1000
interval = 60
depends_on = [ vault_mount.transit ]
}
# Path granularity: Create a rate limit quota, "transit-order" to limit the data encryption requests using orders key to be 500 per second
resource "vault_quota_rate_limit" "transit-order" {
name = "transit-order"
path = "transit/encrypt/orders"
rate = 500
depends_on = [ vault_mount.transit, vault_transit_secret_backend_key.key ]
}
# Enable transit secrets engine & create a test key
resource "vault_mount" "transit" {
path = "transit"
type = "transit"
description = "Test resource quota"
}
resource "vault_transit_secret_backend_key" "key" {
backend = vault_mount.transit.path
name = "orders"
}
main.tf는 다음 작업을 수행합니다:
-
인바운드 워크로드를 초당 100개 요청으로 제한하는 "global-rate"라는 rate limit quota를 만듭니다(5-9줄).
-
Transit secrets engine에 대한 접근을 분당 1000개 요청으로 제한하는 "transit-limit"라는 rate limit quota를 만듭니다(12-19줄).
-
orders 키를 사용하는 데이터 암호화 요청을 초당 500개로 제한하는 "transit-order"라는 rate limit quota를 만듭니다(22-28줄).
-
테스트를 위해 transit secrets engine을 활성화합니다(31-35줄).
-
테스트를 위해
orders라는 암호화 키를 만듭니다(37-40줄). -
Terraform을 초기화합니다.
$ terraform init
Initializing the backend...
Initializing provider plugins...
...snip...
Terraform has been successfully initialized!
terraform init실행 후terraform plan으로 리소스가 생성될지 확인할 수 있습니다.
$ terraform plan
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
...snip...
Plan: 5 to add, 0 to change, 0 to destroy.
-
출력에 리소스가 나열되는지 확인해야 합니다.
-
terraform apply로 리소스를 배포합니다.
$ terraform apply -auto-approve
Terraform used the selected providers to generate the following execution plan.
...snip...
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.
Terraform에 대해 더 알아보려면 Terraform tutorials 사이트를 방문하세요.
Vault Enterprise namespaces
Vault Enterprise 클러스터의 경우 inheritable 파라미터를 사용해 namespace에 설정된 리소스 quota를 그 하위 namespace에 적용할 수 있습니다.
다음 namespace 계층 구조를 생각해 보세요:
root
└── parent
└── child
└── grand-child
root namespace 아래에 parent namespace가 있고, 그 다음 parent/child와 parent/child/grand-child namespaces가 있습니다.
inheritable 파라미터를 true로 설정하면 parent namespace에 리소스 quota를 설정해 하위 namespaces에 상속되게 적용할 수 있습니다. 기본값은 false입니다.
Terraform을 사용해 하위 namespaces가 상속할 us-west namespace에 quota 규칙을 만들 수 있습니다. 다음 Terraform 구성은 rate limit을 분당 500개 요청으로 설정합니다.
provider vault {}
# Create a "us-west" namespace
resource "vault_namespace" "us-west" {
path = "us-west"
}
# Create a "us-west" rate limit quota
resource "vault_quota_rate_limit" "us-west" {
name = "us-west"
path = "us-west"
rate = 500
interval = 60
inheritable = true
}
다음 단계
사전 예방적 모니터링과 주기적인 사용 분석은 문제가 악화되기 전에 잠재적 문제를 식별하는 데 도움이 됩니다.
- 일반적인 Vault 리소스 quota에 대해 자세히 알아보세요.
- Vault Enterprise의 lease count quota에 대해 알아보세요.
- Vault Enterprise 클러스터를 실행 중이라면 Rate limit quotas - collective, by IP, by entity를 검토하세요.