Recently Written · git

9p-store

Small disk-backed 9P file server (diod) for a private network

git clone https://github.com/equwal/9p-store

Log | Files | Refs


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.