hosts/docs/user-guide.md
phg d5a143ee36 feat: Add sudo authentication screen and update authorization flow
- Introduced a new module for terminal presentation during sudo authentication.
- Updated the application to display a temporary authentication notice.
- Enhanced tests to cover the new sudo authentication flow and its edge cases.
2026-09-04 20:02:46 +02:00

249 lines
9.2 KiB
Markdown

# User guide
`hosts` is a keyboard-first terminal application for inspecting and editing the
system Hosts File. It starts in Read-only Mode and requires explicit sudo
authorization before it can change `/etc/hosts`.
> [!WARNING]
> `hosts` is alpha software. Read [Persistence and recovery](#persistence-and-recovery)
> before entering Privileged Mode. In particular, sorting and save
> failures can currently leave the interface and `/etc/hosts` out of sync.
## Before you begin
You need macOS or Linux, Python 3.13 or newer, `sudo`, and
[uv](https://docs.astral.sh/uv/). The normal user entry point runs the current
revision from the project's default branch:
```bash
uvx git+https://git.s1q.dev/phg/hosts.git
```
The project does not yet publish versioned releases. The `uvx` command can
therefore run newer code on a later invocation.
## Inspect the Hosts File safely
The application opens in Read-only Mode. In this mode you can:
- select a Host Entry and inspect all of its hostnames, comment, state, and DNS
details;
- search by hostname, IP address, or comment;
- use `Ctrl+F` to combine status, entry-type, DNS-resolution, and search
filters;
- sort by IP address or Canonical Hostname;
- show or hide Default Entries from the configuration screen; and
- reload `/etc/hosts` from disk.
The footer shows `Read-only` while system-file mutations are blocked. Press `?`
for in-application help.
### A warning about sorting
Sorting is intended as a view operation, but currently reorders the in-memory
Hosts File. If you later enter Privileged Mode and save or perform an auto-saved
mutation, that sorted order can be written to `/etc/hosts`. Reload with `Ctrl+R`
before entering Privileged Mode if you sorted only for inspection.
## Enter Privileged Mode
Press `Ctrl+E`. The application first checks for existing sudo authorization.
If authorization is not already available, it temporarily returns control of
the terminal to `sudo` and its configured PAM authentication method. Before
enabling mutations it verifies write access and creates a Pre-edit Backup.
If authorization, permission validation, or backup creation fails, the
application remains in Read-only Mode.
The footer shows `Edit` while Privileged Mode is active. This label refers to
Privileged Mode; it is separate from the Entry Editor used to change one Host
Entry.
## Change a Host Entry
In Privileged Mode:
- Press `n` to add a Host Entry.
- Select a non-default Host Entry and press `e` to open the Entry Editor.
- Press `d` and confirm to delete the selected Host Entry.
- Press `Space` to activate or deactivate the selected Host Entry.
- Press `Shift+Up` or `Shift+Down` to change its file order.
A Host Entry requires a valid IPv4 or IPv6 address, at least one valid hostname,
and may include a comment. The first hostname is its Canonical Hostname; any
additional hostnames are Aliases.
Default Entries represent protected baseline localhost or broadcasthost
mappings. They cannot be changed, deleted, activated, deactivated, or moved.
Successful mutations are saved to `/etc/hosts` immediately. Read the
status message after every action. If saving fails, the application restores
the Host Entries, visible selection, and undo/redo history from before the
action.
## Use a DNS Entry
Choose the DNS Name Entry type when adding or editing an entry, then provide:
- the DNS name whose address should be resolved; and
- one or more local hostnames that should map to that address.
The application resolves the DNS name in the background. A successful result
replaces the entry's stored IP address, records DNS metadata in the serialized
comment, activates a newly created DNS Entry, and saves the Hosts File. DNS
refresh is manual rather than continuous:
- Press `r` to refresh the selected DNS Entry.
- Press `Shift+R` to refresh all DNS Entries.
Both actions require Privileged Mode because a successful result changes
`/etc/hosts`. A failed lookup reports the failure and keeps the previously
stored mapping.
## Verify what is on disk
The details shown by the application normally match the last successful save.
To discard in-memory state and read `/etc/hosts` again, press `Ctrl+R`.
You can also inspect the file from another terminal:
```bash
sed -n '1,240p' /etc/hosts
```
Remember that saving is normalized rather than byte-preserving. The serializer
aligns fields, groups comments, removes original blank-line placement, and adds
a management header while retaining the modeled Host Entries and comments.
## Persistence and recovery
### What saves immediately
Adding, editing, deleting, moving, activating, deactivating, undoing, redoing,
and successfully refreshing DNS Entries save immediately. `Ctrl+S` explicitly
saves the entire current in-memory Hosts File.
If an immediate save fails, the application restores the complete pre-action
in-memory state, visible selection, and undo/redo history. A later mutation
therefore cannot accidentally persist the failed change.
### Locate a Pre-edit Backup
Entering Privileged Mode creates one timestamped Pre-edit Backup below the
operating system's temporary directory. The application does not currently show
this path. Ask Python for the directory used on your system:
```bash
python3 -c 'import tempfile; print(tempfile.gettempdir() + "/hosts-manager-backups")'
```
List the directory printed by that command. Backup files are named
`hosts.backup.<timestamp>`:
```bash
ls -lt /path/printed/by/the/previous/command
```
The application does not remove old Pre-edit Backups, apply retention rules, or
record which file belongs to a later session. Do not choose a backup solely
because it is the newest; inspect its timestamp and contents first.
### Restore manually
Restoration is not available through the TUI. To restore manually:
1. Leave the application or return it to Read-only Mode.
2. Locate and inspect the intended Pre-edit Backup.
3. Copy that explicit file over `/etc/hosts` with sudo.
4. Relaunch the application or press `Ctrl+R` to verify the restored contents.
For example, after replacing the placeholder with the exact file you inspected:
```bash
sudo cp /exact/path/to/hosts.backup.TIMESTAMP /etc/hosts
```
This replaces the current Hosts File. Never paste a guessed path or automate
selection of the newest backup without inspecting it.
## Leave Privileged Mode
Press `Ctrl+E` again. The application clears its undo/redo history and forgets
which Pre-edit Backup belongs to the session. The backup file remains in the
temporary directory. It does not alter your cached sudo timestamp, including
authorization used by other terminal sessions.
## Configuration
Press `c` to open configuration. The supported screen controls whether Default
Entries are visible; they are hidden by default. The setting is stored at
`~/.config/hosts-manager/config.json`.
Other values may exist in that file but are internal until their behavior is
reachable through the TUI. Editing them manually is not a supported workflow.
## Troubleshooting
### Privileged Mode needs authentication
This is expected when no cached sudo authorization is available. `hosts` first
shows a temporary authentication notice, then `sudo` and PAM present any
configured authentication method, such as Touch ID or a password prompt.
`hosts` never collects credentials. Canceling authentication leaves the
application in Read-only Mode.
### Privileged Mode cannot be enabled
The application requires all three safety gates: valid sudo authorization,
write access to `/etc/hosts`, and successful creation of a Pre-edit Backup. A
failure in any gate leaves mutations disabled. Read the status message for the
specific failure.
### The display differs from `/etc/hosts`
This can occur after a failed save or sorting followed by other actions. Press
`Ctrl+R` to discard in-memory state and reload the file. If an unwanted change
reached disk, follow the manual restoration procedure above.
### DNS resolution fails
DNS resolution uses the operating system resolver and a per-query timeout. A
failure can result from an invalid DNS name, resolver failure, timeout, or no
address being returned. The application reports the failure rather than
continually retrying it.
## Key reference
### General
| Key | Action |
| --- | --- |
| `Up` / `Down` | Select a Host Entry |
| `Home` / `End` | Select the first or last visible Host Entry |
| `Page Up` / `Page Down` | Move by one page |
| `i` | Sort by IP address |
| `h` | Sort by Canonical Hostname |
| `Ctrl+R` | Reload `/etc/hosts` |
| `Ctrl+F` | Open advanced filters |
| `c` | Open configuration |
| `?` | Show help |
| `q` or `Ctrl+C` | Quit |
| `Ctrl+E` | Enter or leave Privileged Mode |
### Privileged Mode
| Key | Action |
| --- | --- |
| `n` | Add a Host Entry |
| `e` | Open the selected Host Entry in the Entry Editor |
| `d` | Delete the selected Host Entry |
| `Space` | Activate or deactivate the selected Host Entry |
| `Shift+Up` / `Shift+Down` | Move the selected Host Entry |
| `r` | Refresh the selected DNS Entry |
| `Shift+R` | Refresh all DNS Entries |
| `Ctrl+Z` / `Ctrl+Y` | Undo or redo and save the result |
| `Ctrl+S` | Save the current in-memory state |
Within the Entry Editor, use `Tab` and `Shift+Tab` to move between fields and
`Escape` to leave the form. If values changed, the application asks whether to
save, discard, or continue editing.