Unofficial
Na této stránce
  1. 01Co jail poskytuje
  2. 02Než začnete
  3. 03Profil
  4. 04Bloky
  5. 05Sestavení, podepsání, instalace
  6. 06Ověření izolace
  7. 07Zastavení, odstranění a zbývající data

Spusťte službu svého balíčku v jailu: vlastní účet, bez roota, jen povolená síť

Skript služby balíčku QPKG běží jako root. S blokem Start in a jail v editoru služeb běží spouštěné programy pod vlastním účtem v sandboxu: bez capabilities a možnosti je získat, s filtrem nebezpečných systémových volání a s vlastní sítí. Příklad poskytuje stránku, která ukazuje, co sandbox dovoluje.

  1. Profilco běží a co vidí
  2. Blokyúčet, složky, jail
  3. Sestaveníbvs-jail a bwrap jsou součástí
  4. Podepsánípřípad 1, pak instalace
  5. Kontrolastránka popisuje své prostředí

Obrázky pocházejí z Bucket & Code Server IDE 1.0.0-49. Příklad byl sestaven, podepsán, nainstalován a ověřen na testovacím NASu s QTS 6.1. Účet se jmenuje ola.

01Co jail poskytuje

  • Služby běží pod účtem uvedeným v profilu, nikdy jako root, bez capabilities a s nastaveným NoNewPrivs. Filtr seccomp odmítá připojování souborových systémů, nové jmenné prostory, moduly jádra, bpf, io_uring, ptrace a další volání využívaná exploity jádra.
  • Vidí aplikaci jen pro čtení, své datové složky pro čtení i zápis, vlastní /tmp, /proc a /dev a glibc NASu. Žádnou jinou sdílenou složku, žádné /etc/config, žádný jiný balíček.
  • Jejich síť má vlastní loopback. Každý port inbound se přeposílá z NASu na vnitřní port. Odchozí spojení procházejí HTTP proxy, která odmítá soukromé adresy, loopback a vlastní adresy NASu.
  • Limit paměti, váha CPU a limit procesů platí pro celý jail.

Balíček obsahuje samotný jail: bin/bvs-jail a statický bin/bwrap (bubblewrap), připravené při sestavení pro každou architekturu.

02Než začnete

  • Potřebujete projekt QPKG vytvořený přes New project, QDK na stránce Toolchains a prostředí pro sestavení Ubuntu 24.04. Jejich nastavení popisuje Vlastní App Center; příklad používá šablonu služby Empty.
  • Certifikát pro podepisování kódu, který vám vystavil QNAP, ve formě souborů. App Center instaluje pouze podepsané balíčky.

03Profil

Profil je soubor JSON v balíčku. Zde je v projektu uložen jako shared/etc/jail/jailbox.json; balíček ho nainstaluje jako etc/jail/jailbox.json do své instalační složky.

# shared/etc/jail/jailbox.json
{
  "name": "jailbox",
  "user": "jailbox",
  "app": "@QPKG_ROOT@",
  "data": ["@QPKG_DATA@"],
  "services": [
    {"name": "checks", "cmd": ["@QPKG_ROOT@/bin/busybox", "sh", "@QPKG_ROOT@/share/jailbox/checks.sh", "@QPKG_ROOT@", "@QPKG_DATA@"], "oneshot": true},
    {"name": "web", "cmd": ["@QPKG_ROOT@/bin/busybox", "httpd", "-f", "-p", "127.0.0.1:8080", "-h", "@QPKG_DATA@/www"], "wait_port": 8080}
  ],
  "inbound": [{"listen": "0.0.0.0:19975", "port": 8080}],
  "egress": {},
  "limits": {"memory_mb": 256},
  "stop_seconds": 10
}
  • @QPKG_ROOT@ a @QPKG_DATA@ zastupují instalační a datovou složku, jejichž cesty jsou známé až na NASu. Každé spuštění je doplní do kopie, kterou může měnit jen root. Jail používá tuto kopii. Neznámé klíče jsou odmítnuty.
  • app se připojuje jen pro čtení. Zde jde o celou instalační složku, aby služby mohly používat BusyBox z balíčku; skutečná aplikace odkazuje na svůj vlastní strom, například @QPKG_ROOT@/app.
  • services se spouštějí postupně. Nejprve doběhne oneshot; wait_port čeká, až služba začne naslouchat, a pak spustí další. Alespoň jedna služba zůstává spuštěná.
  • inbound přeposílá port 19975 NASu na vnitřní port 8080. egress poskytuje službám proxy na 127.0.0.1:3128 pro porty 80 a 443 veřejných adres; seznam allow propouští pojmenované cíle bez ohledu na jejich adresu.
  • limits.memory_mb má výchozí hodnotu 2048; stop_seconds určuje, jak dlouho jail čeká na ukončení služeb.

První služba spouští tento skript, který je také součástí balíčku jako shared/share/jailbox/checks.sh. Zapisuje výsledky kontroly sandboxu do složky poskytované druhou službou.

#!/bin/sh
# Runs inside the jail and writes what the sandbox allows into the page folder.
R=$1 D=$2 B=$R/bin/busybox V=$($B dirname "$D")
{
  $B grep -E '^(Uid|CapEff|NoNewPrivs|Seccomp):' /proc/self/status
  if $B touch "$R/probe" 2>/dev/null; then echo 'write the install folder: allowed'; else echo 'write the install folder: refused'; fi
  if $B ls /etc/config >/dev/null 2>&1; then echo 'read /etc/config: allowed'; else echo 'read /etc/config: refused'; fi
  echo "what $V holds here: $($B ls -A "$V" | $B tr '\n' ' ')"
  echo "network interfaces: $($B tail -n +3 /proc/net/dev | $B cut -d: -f1 | $B tr -d ' ' | $B tr '\n' ' ')"
} >"$D/www/checks.txt"
echo 'Served from inside the jail.' >"$D/www/index.html"

04Bloky

Na stránce projektu, karta Service and package, záložka Blocks: použijte Add a block pod At start pětkrát v tomto pořadí.

Přidání bloku, skupina The program: Create a group, Create an account, Owner and mode, Start the program, Start in a jail, Wait for a port, Wait for a socket
  1. Data folder on the volume, název jailbox: složka $QPKG_DATA.
  2. Create an account, název jailbox: účet uvedený v profilu.
  3. Create a folder, $QPKG_DATA/www, vlastník jailbox:jailbox, režim 750: jediná složka, do níž služby zapisují.
  4. Start in a jail, ID jailbox, profil $QPKG_ROOT/etc/jail/jailbox.json. Čekání při zastavení musí trvat alespoň hodnotu stop_seconds z profilu plus 15; výchozích 90 zde stačí. The Start in a jail block: ID jailbox, Profile $QPKG_ROOT/etc/jail/jailbox.json, Seconds to wait at stop 90, Restart it when it stops off, Undo it at stop on, and the lines it writes: qpkg_jail and, at stop, qpkg_daemon_stop with bin/bvs-jail
  5. Wait for a port, 19975: spuštění skončí, jakmile přeposílaný port odpoví.

Pod At a status check bloky Is it running? s ID jailbox a Is the port open? s 19975 zajistí kontrolu jailu příkazem status skriptu služby. Save zobrazí rozdíly každého souboru a Commit je uloží do repozitáře projektu.

Potvrzení změn: service.json se spouštěcími bloky a shared/jailbox.sh s řádky qpkg_data_dir, qpkg_user, qpkg_dir, qpkg_jail a qpkg_wait_port

05Sestavení, podepsání, instalace

Build na stránce projektu spustí qbuild z QDK. Log uvádí součásti jailu přibalené do balíčku.

Log sestavení: balíček x86_64 s bin/busybox, bin/chpst, share/busybox/, bin/bvs-jail, bin/bwrap a share/bubblewrap/; sestaven build/jailbox_0.1.0_x86_64.qpkg, bez podpisu kódu

Bez certifikátu se balíček sestaví nepodepsaný a stránka projektu upozorní, že testovací nasazení a repozitář vyžadují podepsaný balíček.

Pipeline projektu: Build dokončen; Test deploy vyžaduje balíček s podpisem kódu; Publish: nepodepsáno, repozitář přijímá pouze podepsané balíčky
  1. Umístěte soubory certifikátu certificate, private_key a ca_certs vedle qpkg.cfg ve složce projektu a sestavte znovu: balíček bude podepsaný. Soubor .gitignore ze šablony je vyloučí z gitu. V CI pocházejí z tajných hodnot repozitáře, jak popisuje Vlastní App Center.
  2. Podepsaný balíček nainstalujte přes Test deploy na stránce projektu (admin), Install Manually v App Center nebo vlastní repozitář App Center na NASu.

06Ověření izolace

Otevřete http://<NAS address>:19975/: stránka přes přeposílaný port zobrazí „Served from inside the jail.“. Vedlejší soubor checks.txt obsahuje zjištění první služby:

# http://192.168.1.20:19975/checks.txt
Uid:	222	222	222	222
CapEff:	0000000000000000
NoNewPrivs:	1
Seccomp:	2
write the install folder: refused
read /etc/config: refused
what /share/CACHEDEV1_DATA holds here: .qpkg jailbox
network interfaces: lo
  • Složka svazku obsahuje jen složky balíčku: instalační pod .qpkg a datovou složku. Žádnou sdílenou složku ani jiný balíček.
  • V relaci SSH jako admin ukáže grep -E '^(Uid|CapEff|NoNewPrivs|Seccomp):' /proc/<pid>/status pro službu totéž. Dva procesy bubblewrap, které jail hlídají zvenčí, také nemají capabilities a mají nastavené NoNewPrivs, ale bez filtru.
  • Log jailu je log/jailbox.log v datové složce: spuštění každé služby, její port a zastavení. Log zaznamená, když datová složka patří rootovi; služby zapisují jen do složky přidělené účtu blokem Create a folder.

07Zastavení, odstranění a zbývající data

  • /etc/init.d/jailbox.sh stop nebo zastavení v App Center ukončí služby v opačném pořadí a jail zapíše ended (0) do logu. Nezůstane žádný proces účtu, cgroup ani naslouchající port.
  • Odstranění balíčku zastaví jail a smaže instalační složku i skript služby. Účet a datová složka zůstanou, protože je žádný blok neodstraňuje: Your own shell lines pod At removal může odstranit i je.
  • Běhová složka jailu, /var/run/bvs-jail/jailbox, zůstane do příštího spuštění, které ji přepíše. Leží v paměťovém souborovém systému QTS a při příštím restartu zmizí.