github linuxserver/docker-sealskin 0.4.0-ls64

3 hours ago

CI Report:

https://ci-tests.linuxserver.io/linuxserver/sealskin/0.4.0-ls64/index.html

LinuxServer Changes:

Full Changelog: 0.3.2-ls63...0.4.0-ls64

Remote Changes:

SealSkin 0.4.0

SealSkin works from any browser now. The server serves the web app at /,
users sign in with an identity provider or the reverse proxy in front of it,
sessions open under the web app's own name and install as apps of their own,
and several servers can run as one cluster over an object store. Everything
the extension and the mobile app did still works: they sign in with an
application key made on the web, or, on a single server, with their key files
as before.

Highlights

  • The web app. https://<server>:8443/ is the launcher, the file manager,
    and the admin pages, with nothing installed. A launch takes the tab, shows
    its progress, and opens the session when it is ready; a checkbox opens it
    in a new tab instead. The app installs as a PWA, and every application has a
    pinned address, /app/<app id>/, that attaches to its running session or
    launches one, with its options in the query, so a bookmark or a home-screen
    icon lands straight in a desktop.
  • Sign in with what you have. OpenID Connect, SAML, or a reverse proxy
    that signs users in through its forward-auth (Authelia, Authentik, Keycloak,
    oauth2-proxy, Pocket ID, Tinyauth, and the guides for Caddy, Traefik, SWAG,
    and Nginx Proxy Manager). The provider's groups make administrators and set
    limits; a new user in no group is held until an administrator approves them
    into groups. The sign-in page can send the browser straight to the
    provider, with #root as the way to the server's own page.
  • The built-in administrator. The first start writes two files for one
    account, admin: /config/admin.json, the key file of the companion apps,
    and /config/root_key, the root key that signs the web app in. Its
    desktops, files, and keys are one set whichever way in you take, and
    SEALSKIN_ROOT_SIGN_IN=false switches the root key off once the provider's
    administrators are in.
  • Application keys. The extension and the mobile app are companions of the
    web app: a user makes a key per device on the web, shown as text and as a
    QR code, pastes or scans it into the app, and an administrator sets how long
    keys live, which apps may hold one, when a key goes dormant, and revokes any
    of them.
  • Sessions on one origin. SealSkin serves the Selkies web client itself,
    taken out of each image at pull time, and the container answers only its
    API, so sessions live at /<session id>/ under the web app's name: one
    certificate, permissions granted once, audio that plays, no wildcard DNS.
    SEALSKIN_SESSION_ISOLATION keeps every session on a name of its own for
    images you do not trust.
  • Kubernetes. One manifest installs the server in any namespace you
    administer, with no cluster-scoped objects; every session is a pod beside
    it, with GPUs, pod templates, resource quotas, and pull secrets honored.
  • Clusters. Servers share users, groups, applications, and settings
    through an object store, an S3 bucket or the built-in file store, with
    pools of nodes, placement of sessions, GPU slots, home directories pinned to
    a node and moved between them, shared files kept in the store and encrypted
    under SEALSKIN_STORE_KEY, limits that hold across nodes, and an
    append-only audit log.
  • VPN exits. Administrators import WireGuard and OpenVPN profiles; a user
    picks one at launch and the session leaves through that tunnel and nothing
    else, with a gateway per endpoint on Docker and a hub per endpoint on
    Kubernetes, and a cap on tunnels per profile.
  • Registries and proxies. Private registries sign in through a Docker
    config.json on each node (SEALSKIN_REGISTRY_AUTH_PATH), and on
    Kubernetes through the session template's pull secrets as well; internal
    hosts that serve stores, logos, and catalogs through a netrc file
    (SEALSKIN_NETRC_PATH); SEALSKIN_IMAGE_MIRRORS sends every pull to a
    mirror per upstream registry while the records keep the upstream names; and
    the server's own fetches follow HTTPS_PROXY and trust SSL_CERT_FILE. A
    deployment without internet access runs on these alone.
  • Branding. A name, logo, accent, wallpaper, home links, and the store
    links of the companion apps, set from the dashboard with a live preview.
  • PRoot Apps catalogs. Catalogs of portable applications assigned to users
    and groups, fetched on every node and mounted into sessions, from GitHub
    repositories or any host and registry built the same way.
  • Templates. The template editor carries Selkies' current encoders, start
    policies, and session variables, among them the connection indicator, the
    audio and webcam devices, 10-bit video, the GPU id, the print spool, the
    window buttons, and the Computer-Use token beside its bind. A user with
    Allow Editing App Templates edits templates short of the DOCKER_*
    settings and the reserved identity variables, which stay an
    administrator's.
  • A new logo. assets/logo.svg is the source of every icon.
  • The home page. Sessions show live screenshots, applications are
    favorites or hidden per user, and the sidebar folds away.
  • Collaboration rooms. A room opens each participant's session with its
    token in the URL fragment, where no server log or Referer sees it; a
    participant may hold one gamepad slot per controller; and a viewer reaches
    the container on a view-only login of its own. This needs a Selkies
    release after 2.0.0 in the images you launch.

Server

  • The web sign-in is a cookie on the web app's origin; every route it
    authenticates asks the browser where the request came from, the cookie is
    dropped before a request reaches a session container, and a session's pages
    may be framed by the web app alone.
  • /companion/ is the lane of the companion apps, which a reverse proxy that
    signs users in leaves unguarded; /internal/* answers the proxy's own
    sub-requests alone, wherever the API port is reachable.
  • A plain HTTP listener (SEALSKIN_HTTP_PORT) for a proxy that terminates
    TLS, answering the addresses in SEALSKIN_TRUSTED_PROXIES alone, with HTTP/3
    advertised only where browsers reach the session port directly.
  • A node's identity is its name: SEALSKIN_NODE_NAME, else the container's
    name in Docker, else the host name. A node started again with the same name
    and storage is the same node.
  • Nodes call each other with signed requests over a peer listener on 8444,
    trusting the approved nodes' certificates alone; a bucket's credentials
    make a node a member, a file store asks an administrator to approve it or
    takes a join code.
  • Per-user launch leases keep a user with a session limit from racing it.
  • Every picture a page shows comes from the server: application, PRoot, and
    home-link logos are fetched once and served from /api/logos/<name>;
    nothing loads from a third party.
  • A user in no group is in default, a built-in group the Groups table shows
    read-only: the server's defaults, which a user's own record overrides.
    Applications, VPN profiles, and pools may name default to reach exactly
    those users, where all reaches everyone; no group may be named default,
    all, or none. Approve on a held user opens the groups to place them
    in, with the groups the provider named beside; turning
    SEALSKIN_SSO_HOLD_NEW_USERS off lets new users in at once and leaves the
    held ones held.
  • Groups now restrict: where a user and their groups disagree, the stricter
    switch and the smaller limit win.
  • The security audits' fixes: a key-file client's token names the crypto
    session it is sent with, and the server refuses it with any other; a
    room's viewer reaches the container as a view-only login, never the
    controller's; a handshake reads at most 16 KiB and the crypto sessions it
    leaves are capped; the file manager, uploads, shares, and launches act
    through descriptors checked inside the home, so a symlink swapped in by the
    session cannot lead them out of it; every record file of the cluster is
    named through one checked join, and deleting a pool refuses a name with a
    path in it; a room tells each viewer its own token and an alias for the
    others and swaps only to apps open to the session's owner; a store's
    docker_overrides stay inside the container; a user's uploads are bounded;
    deleting a user ends their sessions, uploads, and shares; an app's icon goes
    only to whom the app is listed for; a share's password form closes for a
    minute after five wrong passwords and its download token dies with the
    share; every session and collaboration token is compared in constant time;
    and the session port serves other origins uncredentialed reads alone.
  • NVIDIA sessions want the NVIDIA Container Toolkit v1.20.1 or higher, whose
    refresh service creates the modeset device; the server mounts it itself only
    as the fallback for a runtime that injects none.

Client

  • The web app, the extension, and the mobile app share one served UI; the
    shells frame the same pages and add their privileged pieces.
  • The connect page offers an application key first and a key file second; a
    key carries the server's address, so the page fills it in, and the mobile
    app reads it from the QR code the web app shows.
  • The extension no longer frames a server over plain HTTP once it has
    answered over HTTPS, unless the user says so, and a page framed over plain
    HTTP says so above it. A served page can no longer read the connect page's
    draft or have the shell fetch an address on its behalf.
  • In-page modals replace every browser alert; stopping a session asks
    nothing, since the home directory stays.
  • The mobile app's pages fit a phone in portrait, and its APKs carry the
    icons.
  • Translations for every page in all seventeen other languages.

Upgrading from 0.3

On the linuxserver/sealskin container nothing on disk needs changing:
users, groups, installed_apps.yml, templates, and sessions load as
before, and key files keep signing in while SEALSKIN_LEGACY_AUTH stays on
(its default). What is new:

  • The first start writes /config/root_key, an application key of the
    administrator admin whose key file is /config/admin.json. Open
    https://<server>:8443/, sign in with it, then copy it somewhere safe and
    delete the file.
  • The server's identity in its own records is the container's name. Give the
    container a stable name (sealskin, which the server needs anyway) or set
    SEALSKIN_NODE_NAME; a server recreated under another name is another node.
  • /config/.config/sealskin/node/ holds the node's own peer certificate and
    /config/.config/sealskin/cluster/ the shared records. Port 8444 is the peer
    listener; publish it only to join a cluster.
  • To put the server behind a reverse proxy, set SEALSKIN_PUBLIC_URL,
    SEALSKIN_TRUSTED_PROXIES, and, for a proxy that terminates TLS,
    SEALSKIN_HTTP_PORT; the reverse proxy pages show each proxy.
  • Collaboration rooms need a Selkies release after 2.0.0 in the images you
    launch; older images open a room's session without its token, and a session
    launched before the upgrade has no view-only login for a room's viewers.
  • VPN profiles need the ghcr.io/selkies-project/sealskin-vpn image to be
    pullable by every node; pin its version with SEALSKIN_VPN_IMAGE.
  • NVIDIA hosts need the NVIDIA Container Toolkit v1.20.1 or higher.
  • A group that set a limit of -1 to lift a user's own limit no longer does:
    the stricter of the two holds. A group file named default, all, or
    none is refused.
  • A user in no group gets the server's defaults, shown as the default group.
    Nothing changes for them; what they get is now in plain view.

The extension and the mobile app from 0.3 keep working against this server
with their key files over HTTPS; their tokens are refused on the plain HTTP
API port on 8000, which the 0.4.0 shells sign for the session they use. The
store releases of 0.4.0 add the application-key sign-in, the QR scanner, and
the HTTPS hold.

Documentation

  • Laid out as the Selkies documentation is, with pages for signing in,
    clusters, the object store, Kubernetes, VPN profiles, registries and
    proxies, and one per reverse proxy; the Server Reference is rendered from
    the docstrings.
  • The site is published per release with a version switcher, and every page
    is served as Markdown as well, with llms.txt and copy and open-in actions
    for language models.
  • .oss-scanner/threat_model.md states what SealSkin does, its principals,
    its entry points, and the rules the code is held to; the scanner, CodeQL,
    and the other checkers' findings are fixed in code, never dismissed.

Don't miss a new docker-sealskin release

NewReleases is sending notifications on new releases.