A terminal UI for OpenSnitch, the GNU/Linux application firewall. Replaces the default Python/Qt GUI with a keyboard-driven TUI built in Go.
Dashboard — live stats updated every second from the daemon. Connection and rule counters with proportional bars, a togglable top-N panel (processes, destinations, ports), and grouped recent connections with marquee scrolling for long names, relative timestamps, and service name resolution for common ports.
Connection Prompt — when the daemon intercepts an unknown connection, a modal overlay appears showing the process, destination, port, protocol, and user. Choose allow/deny/reject, pick a duration, and select what to match. Supports compound rules — check multiple targets (e.g. executable + destination host) with space to create AND conditions. Sends a desktop notification and terminal bell so you don't miss it. 90 second timeout with countdown.
Rules Management — split view with a rule list and detail card. Add, edit, toggle, and delete rules. Inline editor with dropdown selectors for action, duration, operator type, and all 22 operands. Create rules directly from grouped connections on the dashboard. Renaming a rule properly deletes the old one. Export rules to NixOS format with x for use with services.opensnitch.rules.
Node Management — view connected daemons with status, version, rule count, and connection stats. Toggle interception on/off per node. Delete nodes (cascades to their rules and connections).
Alerts — color-coded alert log from the daemon (errors, warnings, kernel events) with type and priority indicators.
ostui implements the same gRPC server interface (ui.proto) as the official OpenSnitch GUI. The daemon (opensnitchd) connects to ostui exactly as it would to the Qt UI — no daemon modifications needed. Just point the daemon at ostui's socket and it works.
Requires Go 1.21+ and protoc with Go plugins.
# Build
make build
# Or directly
go build -o ostui .To regenerate protobuf code (only needed if ui.proto changes):
make proto# Start with default socket (unix:///tmp/osui.sock)
./ostui
# Custom socket
./ostui --socket unix:///tmp/osui.sock
# All options
./ostui \
--socket unix:///tmp/osui.sock \
--db-file ~/.config/ostui/ostui.db \
--default-action deny \
--default-duration "until restart" \
--default-timeout 90 \
--group-window 60 \
--history-days 7 \
--max-connections 100000 \
--max-alerts 10000 \
--max-log-size 10485760Make sure opensnitchd is configured to connect to the same socket address.
ostui pauses cosmetic ticks and reuses its last rendered frame when the terminal is not visible. OpenSnitch RPC handling, connection accounting, and rule prompts continue in the background.
Kitty focus tracking works without extra configuration: ostui requests terminal focus reporting and Kitty sends focus-in/focus-out events. On Linux under Sway, ostui also subscribes directly to the native Sway IPC socket from SWAYSOCK and checks the matching window's visible state, so switching to another workspace pauses rendering even when keyboard-focus reporting is delayed. This integration is event-driven and does not invoke swaymsg.
If Kitty is running inside tmux, enable focus forwarding in tmux.conf:
set -g focus-events onIf multiple compositor windows share the same owning PID and cannot be identified uniquely, ostui safely falls back to Kitty's terminal focus events.
| Flag | Default | Description |
|---|---|---|
--socket |
unix:///tmp/osui.sock |
gRPC socket address |
--db-file |
~/.config/ostui/ostui.db |
SQLite database path |
--default-action |
deny |
Action when prompt times out |
--default-duration |
until restart |
Default rule duration |
--default-timeout |
90 |
Prompt timeout in seconds |
--group-window |
60 |
Seconds to group recent connections |
--log-file |
~/.config/ostui/ostui.log |
Log file path |
--max-msg-length |
4194304 |
gRPC max message size |
--history-days |
7 |
Days to retain connection and alert history; 0 disables age cleanup |
--max-connections |
100000 |
Maximum connection rows to keep; 0 disables count cleanup |
--max-alerts |
10000 |
Maximum alert rows to keep; 0 disables count cleanup |
--max-log-size |
10485760 |
Rotate ostui.log to .1 above this many bytes; 0 disables rotation |
| Key | Action |
|---|---|
1-5 |
Switch tab (Dashboard, Rules, Nodes, Firewall, Alerts) |
? |
Help overlay |
q |
Quit |
| Key | Action |
|---|---|
j/k |
Navigate grouped connections |
t |
Cycle top-N panel (Processes / Destinations / Ports) |
r |
Cycle group window (1m / 5m / 60m) |
a / Enter |
Create rule from selected connection |
| Key | Action |
|---|---|
j/k |
Navigate rules |
a |
Add new rule |
e / Enter |
Edit selected rule |
t |
Toggle enable/disable |
d |
Delete (with confirmation) |
x |
Export rules to NixOS format |
| Key | Action |
|---|---|
Tab / Shift+Tab |
Next / previous field |
Left / Right |
Change dropdown value |
Space |
Toggle boolean field |
Ctrl+S |
Save |
Esc |
Cancel |
| Key | Action |
|---|---|
a |
Allow |
d |
Deny |
r |
Reject |
Tab / Shift+Tab |
Cycle duration |
Up / Down |
Navigate match targets |
Space |
Toggle match target (combine for compound rules) |
i |
Toggle details |
Esc |
Apply default action |
| Key | Action |
|---|---|
j/k |
Navigate nodes |
i |
Toggle interception |
d |
Delete node (with confirmation) |
All errors and events are logged to ~/.config/ostui/ostui.log. The log rotates to ostui.log.1 when it exceeds --max-log-size. Tail it for debugging:
tail -f ~/.config/ostui/ostui.logostui uses SQLite with a schema compatible with the official OpenSnitch GUI. Recent connection history persists across restarts and is loaded on startup. The database is stored at ~/.config/ostui/ostui.db by default, with cleanup controlled by --history-days, --max-connections, and --max-alerts.
GPL-3.0 — see LICENSE.


