A Home Assistant API-ja szerintem nem elég védett azzal az egy szem jelszóval amit be lehet állítani a konfigurációs fájljába. Elkezdtem írni egy API gatewayt ami elvégzi a felhasználók azonosítását és továbbítja a kéréseket a Home Assistant API felé. Már eljutottam vele egy szintre ahol lehetett használni, mikor szembe jött velem a Kong. Ahogy olvasgattam az oldalát, egyre jobban megtetszett. Körbenéztem azért a neten, hogy a többi API gateway mit tud. Amiket találtam azok nem voltak annyira szimpatikusak, vagy nem teljesítették a kritériumokat. Számomra fontos, hogy ingyenes legyen, mivel saját célra kell és nem fog bevételt termelni. A másik fontos szempont az volt, hogy az otthoni szerveremen fusson, hogy elérje a Home Assistant-ot.
A Kong
A Kong egy nyílt forráskódú API gateway. A kapott kéréseket továbbítja a beállított API felé. Több API-t is tud kezelni egyidőben. Vannak hozzá pluginek amikkel be lehet állítani a felhasználók azonosítását, logolást, limiteket, stb. Lua nyelven lehet hozzá plugint írni. Még többet is tud, mint amire szükségem van.
A Kong telepítése
Ahogy mostanában minden új szolgáltatás, úgy ez is Docker konténerbe került, ill konténerekbe. Először nem indult el az otthoni szerveremen, kis keresgélés után kiderült, hogy túl régi neki a processzor, még hiányzik belőle az SSE4.2-es utasításkészlet amit szeretne használni a Kong. Szerencsére már nagyon időszerű volt a szerver upgrade, így csak kicsit kellett pihentetnem a projektet.
Van egy hivatalos Docker compose példa, azt alakítottam át, az adatbázist és a két kong konténert tartottam meg.
version: "2.1"
services:
kong-database:
image: postgres:alpine
container_name: kong-database
restart: always
volumes:
- ./db:/var/lib/postgresql/data
environment:
- POSTGRES_USER=xxxxx
- POSTGRES_PASSWORD=xxxxx
- POSTGRES_DB=xxxxx
expose:
- 5432
ports:
- "5432:5432"
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
interval: 10s
timeout: 5s
retries: 5
kong-migration:
image: kong:latest
container_name: kong-migration
depends_on:
kong-database:
condition: service_healthy
environment:
- KONG_DATABASE=postgres
- KONG_PG_HOST=kong-database
- KONG_PG_USER=xxxxx
- KONG_PG_PASSWORD=xxxxx
- KONG_PG_DATABASE=xxxxx
- KONG_ANONYMUS_REPORTS=off
- KONG_MEM_CACHE_SIZE=32m
- KONG_LOG_LEVEL=warn
volumes:
- ./konglog:/usr/local/kong/logs
command: kong migrations up
kong:
image: kong:latest
container_name: kong
hostname: api
domainname: xxxxxx.xyz
restart: always
depends_on:
kong-database:
condition: service_healthy
kong-migration:
condition: service_started
environment:
- KONG_ADMIN_LISTEN=0.0.0.0:8001
- KONG_DATABASE=postgres
- KONG_PG_HOST=kong-database
- KONG_PG_USER=xxxxx
- KONG_PG_PASSWORD=xxxxx
- KONG_PG_DATABASE=xxxxx
- KONG_ANONYMUS_REPORTS=off
- KONG_MEM_CACHE_SIZE=32m
- KONG_REAL_IP_HEADER=X-Forwarded-For
- KONG_REAL_IP_RECURSIVE=on
- KONG_SERVER_TOKENS=off
- KONG_LATENCY_TOKENS=off
- KONG_LOG_LEVEL=warn
- KONG_PROXY_ACCESS_LOG=/dev/stdout
- KONG_PROXY_ERROR_LOG=/dev/stderr
expose:
- 8000
- 8001
- 8443
- 8444
ports:
- "8000:8000"
- "8001:8001"
volumes:
- ./konglog:/usr/local/kong/logs
Egy
# docker-compose up -d
parancs elindítja sorban a fenti fájlban lévő konténereket. Környezeti változók beállításával minden opciót felül lehet írni ami a Kong konfigurációs fájljában található. A fenti beállításokkal a proxy logok a kimenetre kerülnek, ezt egy
# docker-compose logs -f
parancssal nyomon lehet követni. Az Admin API logjai a konglog könyvtárba kerülnek mentésre.
Mivel a 443-as portot az Apache használja, ő proxyzza a kéréseket a Kong felé. Vettem régebben egy random 6 számjegyből álló .xyz domaint, mert M2M (Machine To Machine, gépek közötti) kommunikációra tökéletes és olcsó volt. Ez alá kapott egy aldomaint a Kong.
Kong Admin API
A szolgáltatások, elérési utak, fogyasztók, stb beállítására a Kong egy Admin API nevű RESTful interfészt ad. A dokumentációjában nagyon jól le van írva minden.
Új szolgáltatást például curl parancs segítségével a következőképpen lehet létrehozni:
# curl -i -X POST \\
--url http://localhost:8001/services/ \\
--data 'name=kongtest' \\
--data 'url=https://domain.xyz:443/kongtest/index.php'
Meg kell adni az új szolgáltatás nevét és urljét. Utóbbinál fontos, hogy a port is legyen megadva, mert hiába szerepel a https protokoll a linkben, a 80-as portot fogja alapértelmezetten használni a Kong.
A következő lépésben a szolgáltatáshoz elérési uta(ka)t kell rendelni, az ide érkező kéréseket fogja az előbb beállított urlre továbbítani a Kong.
# curl -i -X POST \\
--url http://localhost:8001/services/kongtest/routes \\
--data 'paths\[\]=/test'
Valamivel kényelmesebb a folyamat Advenced RESC Client használatával:
Mint látható a program felületén kell kitölteni egy űrlapot. A kéréseket el is lehet menteni, hogy később könnyebb legyen őket lefuttatni újra.
Kis keresgélés után lehet találni grafikus felületet a Konghoz. A Konga-t próbáltam ki. Ő is fut Docker konténerben.
Mint a fenti képen is látszik, sajnos nem támogatja a szolgáltatások és utak kezelését, cserébe az elavult API objektumokat kezeli. Ettől eltekintve, szép és könnyen kezelhető felületet ad a Konghoz. A készítő ígérete szerint egy későbbi verzióban pótolják ezeket a hiányosságokat.
Biztonság
Ami a biztonságot illeti, több plugin közül lehet válogatni, ezeket csak be kell állítani. Létre lehet hozni felhasználókat (consumernek - fogyasztónak hívja őket a Kong). A felhasználókhoz - attól függően, hogy milyen plugin lett bekapcsolva - rendelhető API kulcs, jelsző, vagy akár egy titok is amivel aláírható a kérés fejléce, törzse. Az ACL plugin segítségével a felhasználókat csoportokba lehet rendezni és megadható, hogy melyik elérési utat/szolgáltatást melyik csoport tagjai érhetik el.
Elég sok időt és munkát spóroltam meg azzal, hogy rátaláltam a Kongra. A Kong segítségével legfeljebb néhány óra alatt be lehet állítani egy réteget az API elé. Nélküle sokkal több időt kellett volna fejlesztéssel töltenem.