docs/USAGE.md (2909 bytes)
1 # 9p-store 2 3 A small, disk-backed 9P file server for a private network. It uses diod 4 (Debian package) because plan9port has no persistent disk server: its ramfs 5 keeps files in RAM only. diod idles at under 1 MB of memory. 6 7 ## Server 8 9 ```sh 10 LISTEN_ADDR=10.0.0.1 ./install.sh 11 ``` 12 13 The unit listens on `$LISTEN_ADDR` and on 127.0.0.1 (for SSH tunnels), with a 14 64 MB memory cap and restart on failure. 15 16 ### Security 17 18 diod runs with no 9P authentication (`-n`). Access control is the network: 19 20 - Bind only to a private address, for example a WireGuard interface. 21 - Drop traffic to that address unless it arrives on the private interface: 22 23 ```sh 24 nft add rule inet filter input ip daddr 10.0.0.1 iifname != "wg0" drop 25 ``` 26 27 - Check that nothing listens on a public address: `ss -ltnp | grep :564`. 28 - Never store secrets in the export. 29 30 Hosts outside the private network can reach the loopback listener through an 31 SSH forward limited with `permitopen="127.0.0.1:564"` in `authorized_keys`. 32 33 ## Clients 34 35 ### Linux kernel (v9fs) 36 37 Needs `CONFIG_9P_FS` and `CONFIG_NET_9P` (`modprobe 9p`). 38 39 ```sh 40 mount -t 9p -o trans=tcp,port=564,aname=/srv/9pstore,version=9p2000.L,access=any 10.0.0.1 /mnt/9pstore 41 ``` 42 43 Through an SSH tunnel: 44 45 ```sh 46 ssh -fN -L 127.0.0.1:5640:127.0.0.1:564 tunnel@server 47 mount -t 9p -o trans=tcp,port=5640,aname=/srv/9pstore,version=9p2000.L,access=any 127.0.0.1 /mnt/9pstore 48 ``` 49 50 ### plan9port 51 52 ```sh 53 9p -a tcp!10.0.0.1!564 -A /srv/9pstore ls / 54 9p -a tcp!10.0.0.1!564 -A /srv/9pstore read /file.txt 55 echo hi | 9p -a tcp!10.0.0.1!564 -A /srv/9pstore write /file.txt 56 9pfuse -A /srv/9pstore 'tcp!10.0.0.1!564' /mnt/9pstore 57 ``` 58 59 ### diod tools 60 61 ```sh 62 diodls -s 127.0.0.1:564 -a /srv/9pstore 63 diodcat -s 127.0.0.1:564 -a /srv/9pstore file.txt 64 ``` 65 66 Windows has no built-in 9P TCP client; use a Linux host or plan9port. 67 68 ### Client behind a WireGuard sidecar container 69 70 A host without its own WireGuard interface can run a small container that 71 holds the tunnel and forwards 9P to the host's loopback. Placeholders: 72 `SERVER_WG_IP`, `CLIENT_WG_IP`, `SERVER_PUBKEY`, `SERVER_HOST`. 73 74 ```sh 75 # entrypoint.sh (alpine + wireguard-tools-wg, iproute2-minimal, socat) 76 ip link add wg0 type wireguard 77 wg set wg0 private-key /keys/privatekey peer SERVER_PUBKEY \ 78 endpoint SERVER_HOST:51820 allowed-ips SERVER_WG_IP/32 persistent-keepalive 25 79 ip addr add CLIENT_WG_IP/32 dev wg0 80 ip link set wg0 up 81 ip route add SERVER_WG_IP/32 dev wg0 82 exec socat TCP-LISTEN:564,fork,reuseaddr TCP:SERVER_WG_IP:564 83 ``` 84 85 ```sh 86 docker run -d --name wg-9p --restart unless-stopped --cap-drop ALL \ 87 --cap-add NET_ADMIN --memory 32m -v "$PWD/privatekey:/keys/privatekey:ro" \ 88 -p 127.0.0.1:564:564 wg-9p 89 mount -t 9p -o trans=tcp,port=564,aname=/srv/9pstore,version=9p2000.L 127.0.0.1 /mnt/9pstore 90 ``` 91 92 The server needs a `[Peer]` with the container's public key and 93 `AllowedIPs = CLIENT_WG_IP/32`. One sidecar can forward several services.