kin-hub Sign in

Account install

The binary and the daemon state for one account live under ~/.local. Nothing is written under /etc or /usr. The person installing it does not need root.

kin serve started by root reads /etc/kin/keys and opens a session as the uid on the matching key line. kin serve started by any other account reads ~/.local/share/kin/keys and opens every accepted session as that same account.

Layout

~/.local/bin/kin
~/.local/share/kin/host_key
~/.local/share/kin/host_key.pub
~/.local/share/kin/keys
~/.local/share/kin/listen
~/.local/share/systemd/user/kin.service

kin serve creates ~/.local/share/kin with mode 0700 and host_key with mode 0600. It refuses to start when host_key is readable by other accounts, when the directory or keys is writable by them, or when its binary is setuid or setgid. --dir points it at another state directory.

~/.local/bin has to be on PATH for a bare kin to resolve. The full path works either way.

Keys

~/.local/share/kin/keys holds one public key per line:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... james-laptop

The comment is a label for the account owner. There is no uid= field. A line that carries one is an error, and kin refuses every key in that file until the field is removed. Every accepted key becomes the account that started kin serve.

The first key is written by someone already inside the account: at the console, from the home directory's existing files, or from a session an enrolled key already opened. Enrollment over the protocol, by password, does not exist. A lost key is replaced the same way, or with a second key already in the file.

Listener

The default is TCP port 2288 on all interfaces. ~/.local/share/kin/listen replaces that with one address per line, for example 127.0.0.1:2288. kin serve --listen ADDR replaces the file.

The kernel refuses an account a port below net.ipv4.ip_unprivileged_port_start, 1024 on most systems. kin exits with a message that names the value and the two ways an administrator can give the account a low port: a system socket unit that binds the port and hands the socket to kin, or an nftables redirect to 2288. The section on privileged ports in the README has both. kin does not try to add capabilities.

The host firewall is outside the account. A successful bind can still be unreachable if the administrator's rules drop the port.

The first kin serve creates host_key when the file is absent and prints the fingerprint. kin hostkey prints it again later.

Service

systemd loads a user unit from ~/.local/share/systemd/user/kin.service (a copy is contrib/kin-user.service):

[Unit]
Description=kin

[Service]
ExecStart=%h/.local/bin/kin serve
Restart=on-failure
KillMode=process

[Install]
WantedBy=default.target

Then:

systemctl --user daemon-reload
systemctl --user enable --now kin

Logs are journalctl --user -u kin. Without the unit, kin serve runs in the foreground and logs to its standard error.

KillMode=process keeps a restart of the daemon from killing tmux and nohup jobs started from a session; open sessions still end.

Sessions started by the user service inherit its XDG_RUNTIME_DIR, session bus and locale, so systemctl --user works inside them.

The user service stops at logout. loginctl enable-linger keeps the user manager running after that. If that command asks for an administrator password, the daemon stops when the login session ends.

Client files

Pins stay in ~/.kin/hosts. The client config stays in ~/.kin/config. Both belong to the account that runs the client, including when the daemon it reaches is a system kin.

The pin is the host together with the port. A system daemon and an account daemon on the same machine have different host keys and different ports, and the client stores a pin for each. A system daemon on 2288 leaves an account daemon to pick another port in its listen file.

Install

./install.sh, run as the account, does the steps below and enables the user service; ./install.sh --key FILE also enrolls a key. The README describes its options.

By hand, copy the static binary into place and start it once in the foreground so the host key and the fingerprint appear before the unit is enabled:

install -d -m 0700 ~/.local/bin ~/.local/share/kin
install -m 0755 kin ~/.local/bin/kin
~/.local/bin/kin serve

Write keys and, if wanted, listen, then stop the foreground process and enable the user service.