API를 이용하기 위해서는 계정 정보를 함께 전달해야 합니다. 이 때 세션 기반 인증과 API Token 인증 방식이 있는데, 간혹 몇 작업은 'root@pam' 계정 정보를 세션 기반 인증해야만 가능한 작업이 있습니다.
| 특징 | curl 방식(Ticket, CSRF) | API Token 방식 |
|---|---|---|
| 보안성 | 세션 토큰은 유출되더라도 일정 시간 후 만료됨 | API Token 유출 시 큰 보안 위협 |
| 유효기간 | 기본적으로 세션이 만료되기 전까지만 유효 | 수동으로 만료 설정 가능 (기본 무기한) |
| 복잡도 | 초기 인증 및 토큰 관리 필요 | 간단한 토큰 관리만으로 작동 |
| 용도 | 주기적인 세션 인증이 필요한 작업 | 장기간 고정적으로 사용하는 스크립트나 앱 |
| CSRF 보호 | 필요(POST, PUT, DELETE에서 CSRF 토큰 사용) | 불필요 |
사용자 ID와 비밀번호를 Proxmox API의 /api2/json/access/ticket 엔드포인트에 전송하면 올바른 계정 정보일 경우 PVEAuthCookie(세션 토큰)와 CSRF 토큰을 반환받는 구조입니다.
세션 기반 인증 토큰을 획득하기 위해서는 아래 과정이 필요합니다.
티켓 내부 데이터로 사용자 인증 정보를 대체
로그인 작업 없이 토큰을 이용하여 작업 가능
API Token을 생성하여 해당 Token 값을 사용하는 구조입니다. 보통 WAS나 실제 서비스 적용 시 이 방법으로 사용합니다.
| 항목 | 값 |
|---|---|
| End Point | https://<proxmox_host>:8006/api2/json/access/ticket |
| HTTP Method | POST |
| Content-Type | application/x-www-form-urlencoded |
| Headers | username, password 정보 필수 |
| Docu URL | https://pve.proxmox.com/pve-docs/api-viewer/index.html#/access/ticket |
서버가 반환한 JSON 데이터를 보면 ticket과 CSRF Token 값이 기재되어 있습니다. 세션 만료까지는 재사용이 가능하여 별도로 기재해두면 유용합니다.
실제 Postman에 사용하여 작업 시에는 Headers 탭에 keyword와 value를 입력하면 됩니다. 테스트로 위에서 반환된 정보를 이용하여 node 정보를 가져와보겠습니다.
| 항목 | 값 |
|---|---|
| End Point | https://<proxmox_host>:8006/api2/json/nodes |
| HTTP Method | GET |
| Headers | Cookie : PVEAuthCookie=ticket 값 CSRFPreventionToken : CSRF Token 값 |
위 과정을 자동화하고자 bash script를 간단히 작성하면 아래와 같습니다. 클러스터 node 정보 배열만 변경하여 사용하면 됩니다.
#!/bin/bash
# auth 정보
non_url_auth=(
"호스트정보(ip or domain)" # host
"root@pam" # user
"password" # pass
)
# url 인코딩 fuction
url_encode() {
local raw="$1"
local encoded=""
local length="${#raw}"
for (( i = 0; i < length; i++ )); do
char="${raw:i:1}"
case "$char" in
[a-zA-Z0-9.~_-]) encoded+="$char" ;; # 허용된 문자
' ') encoded+="%20" ;; # 공백은 %20으로
*) encoded+="$(printf '%%%02X' "'$char")" ;; # 나머지는 %HH 형식
esac
done
echo "$encoded"
}
# url 인코딩 함수 실행
for auth_item in "${non_url_auth[@]}"; do
enc_url_auth+=("$(url_encode "$auth_item")")
done
# get auth ticket
auth_response=`curl -s -k -X POST https://${enc_url_auth[0]}:8006/api2/json/access/ticket \
-d "username=${enc_url_auth[1]}" \
-d "password=${enc_url_auth[2]}"`
# CSRF Token, ticket 변수 저장
ticket=$(echo $auth_response | jq -r '.data.ticket')
csrf_t=$(echo $auth_response | jq -r '.data.CSRFPreventionToken')
echo "$ticket"
echo "==="
echo "$csrf_t"
# GET nodes TEST
curl -s -k -X GET https://${enc_url_auth[0]}:8006/api2/json/nodes \
-H "Authorization: PVEAuthCookie=${ticket}" \
-H "CSRFPreventionToken: ${csrf_t}" | jq .
API Token은 토큰에 연결할 계정 정보가 있어야 하므로 사용자 계정 생성 → 사용자 계정 권한 부여 → API Token 생성 순으로 이루어집니다. 전 단계에서 사용자 계정 권한 부여까지 완료하였으므로 API Token을 생성하면 됩니다.
WEB UI → [데이터 센터] → [권한] → [API 토큰] → [추가]
권한 생성 시 권한 구분에 체크하게 되면 사용자 정보에 있는 권한을 상속받는 것이 아니라 별도 권한을 가지게 됩니다. 따라서 별도 권한 사용 시 체크하고 권한을 새로 지정해주어야 합니다.
api_user@pve 계정이 가진 pveadmin 권한을 그대로 상속받아 사용하도록 권한 구분을 해제하겠습니다.
생성 후에는 토큰 값이 출력됩니다. 반드시 별도로 기재해두어야 합니다.
pveum user token add 계정명@방식 mytoken --privsep 0
api_user@pve → API를 사용할 계정
mytoken → 토큰의 이름
--privsep 0 → 토큰이 모든 권한을 사용할 수 있도록 설정
WEB UI에서 생성한 것과 마찬가지로 Secret 값은 한 번만 표시되니 반드시 별도로 저장해두어야 합니다.
이후 시리즈의 과정들은 대부분 API Token 방식으로 실습 예정입니다.