API Reference ko - FrankoonG/hy2scale GitHub Wiki
π English | δΈζ | νκ΅μ΄
HY2 SCALEμ http://<νΈμ€νΈ>:5565/scale/api/ μλμ REST APIλ₯Ό μ 곡ν©λλ€. POST /api/loginμ μ μΈν λͺ¨λ μλν¬μΈνΈλ λ‘κ·ΈμΈμΌλ‘ μ»μ μΈμ
ν ν°μ΄ νμν©λλ€.
POST /api/login
Body:
{
"username": "admin",
"password": "<sha256-hex-of-plaintext>"
}λΉλ°λ²νΈλ μ μ‘ μ μ ν΄λΌμ΄μΈνΈμμ SHA-256 ν΄μλ©λλ€. μλ²λ ν΄μλ§ μ μ₯νκ³ λΉκ΅ν©λλ€.
μλ΅:
{
"token": "hex-session-token",
"force_password_change": false
}force_password_change: trueλ μ¬μ ν κΈ°λ³Έ admin/admin μ격 μ¦λͺ
μ μ¬μ© μ€μ΄λΌλ μλ―Έμ
λλ€ β μΉ UIλ μ΄λ€ νμ΄μ§λ νμνκΈ° μ μ λΉλ°λ²νΈ λ³κ²½μ κ°μ ν©λλ€.
μ΄ν μμ²μ Bearer ν€λλ‘ ν ν°μ μ λ¬ν©λλ€:
Authorization: Bearer <token>
μ₯μκ° μ μ§λλ EventSource μλν¬μΈνΈ (νΉν /api/graph-layout/stream)λ μΆκ°λ‘ ?token=<hex> 쿼리 νλΌλ―Έν°λ‘λ ν ν°μ λ°μ΅λλ€. EventSourceλ 컀μ€ν
ν€λλ₯Ό μ€μ ν μ μκΈ° λλ¬Έμ
λλ€.
μ΄ λ Έλμ μ 체μ±κ³Ό Hysteria 2 μλ² μ€μ μ λ°νν©λλ€:
{
"node_id": "ea1b2adb",
"name": "sg-home",
"exit_node": true,
"hy2_user_auth": false,
"compat": false,
"limited": false,
"server": {
"listen": "0.0.0.0:5565",
"password": "<hex>",
"tls_cert": "/data/tls/default.crt",
"tls_key": "/data/tls/default.key"
},
"version": "1.3.0"
}λ Έλ μ€μ μ κ΅μ²΄ν©λλ€. ν¬ν¨ν νλλ§ μμ λ©λλ€.
{ "tx_bytes": 1234567890, "rx_bytes": 9876543210 }μ΅μμ νΌμ΄μ νλ©΄ λ°°μ΄μ λ°ννλ©°, κ° νΌμ΄μλ μ€μ²© κ²μμΌλ‘ λ³Ό μ μλ νΌμ΄λ€μ children νΈλ¦¬κ° ν¬ν¨λ©λλ€. Selfλ νμ 첫 λ²μ§Έμ΄λ©° direction: "local", is_self: trueμ
λλ€.
[
{
"name": "ea1b2adb",
"direction": "local",
"latency_ms": 0,
"is_self": true
},
{
"name": "jp",
"direction": "outbound",
"connected": true,
"latency_ms": 35,
"nested": true,
"version": "1.3.0",
"tx_rate": 0,
"rx_rate": 0,
"children": [
{ "name": "jp-r1", "direction": "outbound", "latency_ms": 73 }
]
}
]| Method | Path |
|---|---|
| GET | /api/clients |
| POST | /api/clients |
| PUT | /api/clients/{name} |
| DELETE | /api/clients/{name} |
| PUT |
/api/clients/{name}/disable β {"disabled": bool}
|
μμ± Body:
{
"name": "jp",
"addr": "jp.example.com:5565",
"addrs": ["jp.example.com:5565", "jp2.example.com:5565"],
"password": "<hy2-password>",
"sni": "jp.example.com",
"insecure": false,
"ca": "",
"max_tx": 0,
"max_rx": 0
}| Method | Path | μ©λ |
|---|---|---|
| GET | /api/peers/{name}/peers |
νΌμ΄μ μΊμλ μλΈ νΌμ΄ λͺ©λ‘ μ‘°ν |
| PUT | /api/peers/{name}/nested |
μ΄ νΌμ΄μ nested νλκ·Έ ν κΈ |
Nested Body:
{ "enabled": true }{name}μ 맨 μ΄λ¦ (μ§μ νΌμ΄) λλ μλΈ νΌμ΄λ₯Ό κ°λ¦¬ν€λ /-κ΅¬λΆ κ²½λ‘ (us/us-east, kr/kr-r1/kr-r1-a β¦)μΌ μ μμ΅λλ€.
μΌλ° νλ‘μ λͺ©λ‘ (SOCKS5, HTTP, Shadowsocks):
| Method | Path |
|---|---|
| GET | /api/proxies |
| POST | /api/proxies |
| PUT | /api/proxies/{id} |
| DELETE | /api/proxies/{id} |
μμ± Body (SOCKS5 / HTTP / SS κ³΅ν΅ μ€ν€λ§):
{
"id": "socks5",
"protocol": "socks5",
"listen": "0.0.0.0:1080",
"enabled": true,
"tls_cert": ""
}Shadowsocksμ κ²½μ° "method": "aes-256-gcm"λ ν¬ν¨ν©λλ€.
κ°κ° μ μ© μ€μ μλν¬μΈνΈ μμ΄ μμ΅λλ€:
| νλ‘ν μ½ | GET / PUT |
|---|---|
| L2TP | /api/l2tp |
| IKEv2 | /api/ikev2 |
| WireGuard | /api/wireguard |
PUTμ ν« λ¦¬λ‘λλ₯Ό νΈλ¦¬κ±°ν©λλ€ β μλΉμ€κ° μ€μ§λκ³ μ μ€μ μΌλ‘ μ¬μμν©λλ€.
| Method | Path |
|---|---|
| GET |
/api/wireguard (λ΄λΆμ peers ν¬ν¨) |
| POST | /api/wireguard/peers |
| PUT | /api/wireguard/peers/{name} |
| DELETE | /api/wireguard/peers/{name} |
| GET |
/api/wireguard/peers/{name}/config (text/plain WireGuard .conf) |
| GET |
/api/wireguard/qr?peer={name} (PNG QR μ½λ) |
| POST |
/api/wireguard/generate-key ({private_key, public_key} λ°ν) |
| Method | Path |
|---|---|
| GET | /api/users |
| POST | /api/users |
| PUT | /api/users/{id} |
| DELETE | /api/users/{id} |
| PUT | /api/users/{id}/toggle |
| PUT | /api/users/{id}/reset-traffic |
μμ± Body:
{
"username": "alice",
"password": "<plaintext or hashed>",
"exit_via": "us/us-east",
"exit_paths": ["us/us-east"],
"exit_mode": "direct",
"traffic_limit_gb": 500,
"expiry": "2026-12-31T00:00:00Z",
"enabled": true
}| Method | Path |
|---|---|
| GET | /api/sessions |
| DELETE |
/api/sessions/{id} β kick, 60μ΄ μ¬μ°κ²° μ°¨λ¨ |
| Method | Path |
|---|---|
| GET | /api/rules |
| POST | /api/rules |
| PUT | /api/rules/{id} |
| DELETE | /api/rules/{id} |
| PUT | /api/rules/{id}/toggle |
μμ± Body:
{
"id": "netflix",
"name": "Netflix",
"type": "domain",
"targets": ["netflix.com"],
"exit_via": "us",
"exit_paths": ["us"],
"exit_mode": "direct",
"enabled": true
}typeμ "ip" λλ "domain"μ
λλ€.
| Method | Path |
|---|---|
| GET | /api/rules/tun-mode |
| PUT | /api/rules/tun-mode |
Body:
{ "enabled": true, "mode": "mixed" }mode: "mixed" (κ·μΉμ λ§€μΉλ λμμ TUNμ ν΅ν΄, κ·Έ μΈλ νλ‘μλ₯Ό ν΅ν΄) λλ "full" (λͺ¨λ νΈλν½μ΄ TUNμ ν΅ν΄).
| Method | Path |
|---|---|
| GET | /api/tls |
| POST |
/api/tls/import (bodyμ PEM) |
| POST |
/api/tls/import-path (bodyμ νμΌ κ²½λ‘) |
| POST |
/api/tls/generate (μ체 μλͺ
λλ CA) |
| POST |
/api/tls/sign (κΈ°μ‘΄ CAλ‘ μλͺ
) |
| GET |
/api/tls/{id}/pem (text/plain μΈμ¦μ PEM) |
| DELETE | /api/tls/{id} |
POST /api/tls/generate Body:
{
"id": "vpn-cert",
"name": "vpn.sg.example",
"domains": ["vpn.sg.example"],
"days": 730,
"is_ca": false
}λ Έλ νμ΄μ§ κ·Έλνλ λ Έλ μ’νλ₯Ό μλ² μΈ‘μ μ μ₯νμ¬ λ‘κ·ΈμΈλ λͺ¨λ μΈμ μμ λμΌν λ μ΄μμμ λ³΄κ² ν©λλ€.
| Method | Path | μ©λ |
|---|---|---|
| GET | /api/graph-layout |
νμ¬ λ μ΄μμ { key: {x, y} } μ‘°ν |
| PUT | /api/graph-layout |
μ λ§΅μΌλ‘ λ μ΄μμ κ΅μ²΄ |
| GET | /api/graph-layout/stream |
SSE μ€νΈλ¦Ό β μ°κ²° μ νμ¬ λ μ΄μμμ λ΄λ³΄λ΄κ³ μ΄ν λͺ¨λ λ³μ΄λ§λ€ λ°ν |
SSE μ΄λ²€νΈλ GET μλ΅κ³Ό λμΌν ννμ JSON κ°μ²΄μ λλ€.
| Method | Path |
|---|---|
| GET | /api/backup |
| POST | /api/restore |
| Method | Path | μΈμ¦ | μ©λ |
|---|---|---|---|
| GET | /api/build-id |
μμ | λ΄μ₯ index.htmlμ sha256; SPAκ° λ°°ν¬ μ μλ 리λ‘λμ μ¬μ© |
| GET | /api/build-info |
μμ | μ 체 λΉλ μ 보: {version, license, repository, go_deps[], natives[]}
|
/api/build-infoλ μ€μ β Upgradeμ λΌμ΄μ μ€ + λ€μ΄ν°λΈ μ»΄ν¬λνΈ ν¨λμ ꡬλν©λλ€.
| Method | Path | Body |
|---|---|---|
| PUT | /api/settings/password |
{current_password, new_username?, new_password?} (λͺ¨λ SHA-256) |
| GET | /api/settings/ui |
ν¬νΈ, κΈ°λ³Έ κ²½λ‘, DNS, μΈμ νμμμ λ°ν |
| PUT | /api/settings/ui |
UI μ€μ μ λ°μ΄νΈ |
| Method | Path | μ©λ |
|---|---|---|
| POST | /api/upgrade |
μ λ°μ΄λ리λ₯Ό ν¬ν¨νλ .tar.gzλ₯Ό multipart μ
λ‘λ. μλ²κ° νμΌμ κ΅μ²΄νκ³ μ¬μμν©λλ€. |
{ "ports": [5565, 1701, 500] }μλ΅:
{ "results": { "5565": true, "1701": false, "500": false } }trueλ νΈμ€νΈμμ ν΄λΉ ν¬νΈκ° λΉμ΄ μλ€λ μλ―Έμ
λλ€.
λ€μ μλν¬μΈνΈλ 릴λ μ΄ νλ‘ν μ½ μμ²΄κ° λ Έλ κ° μ‘°μ μ μν΄ μ¬μ©ν©λλ€. μΉ UI μΈμ¦μ μ¬μ©νμ§ μμΌλ©° β μ κ·Ό μ μ΄λ Hysteria 2 ν°λ λΉλ°λ²νΈλ‘ μ΄λ€μ§λλ€.
GET /api/internal/peers β μλ°©ν₯ μ€μ²© κ²μμ μν νΌμ΄ λͺ©λ‘
μΈλΆ μλνλ₯Ό μν΄ μ€κ³λ κ²μ μλλ©° β νλ‘ν μ½ κ΅¬νμλ₯Ό μν΄ λ¬Έμνλ κ²λΏμ λλ€.