270 lines
10 KiB
Markdown
270 lines
10 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 `PRIVILEGED` while Privileged Mode is active. This label 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.
|
|
- Press `Shift+N` to add a Host Entry based on the selected 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.
|
|
|
|
### Restore the session Pre-edit Backup
|
|
|
|
Entering Privileged Mode creates one timestamped Pre-edit Backup below the
|
|
operating system's temporary directory. While that Privileged Mode session is
|
|
active, press `b` to open the restore review. It displays the exact backup
|
|
source path and `/etc/hosts` target path, then shows a Git-style diff of the
|
|
current Hosts File (before) and Pre-edit Backup (after restoration). At 120 or
|
|
more columns the diff is side by side; at smaller supported sizes it is a
|
|
unified diff. Use `[` and `]` to move between changed hunks, `f` to toggle the
|
|
full diff, and `r` to refresh it.
|
|
|
|
Choose **Restore Hosts File** only when those paths are the ones you intend.
|
|
The application copies the displayed backup over the Hosts File, reloads the
|
|
on-disk contents into the interface, and clears undo/redo history. If the copy
|
|
fails, the current Hosts File and interface remain unchanged and the status
|
|
message names the failure. The application checks both displayed files again
|
|
when you confirm; if either changed, it refreshes the diff and requires a new
|
|
confirmation. Cancel leaves both files unchanged.
|
|
|
|
The TUI does not list old backups, apply retention rules, or retain the session
|
|
association after leaving Privileged Mode. For recovery outside that session,
|
|
locate and restore a backup manually. Ask Python for the temporary directory 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 outside the session
|
|
|
|
To restore a backup that is no longer associated with an active Privileged Mode
|
|
session:
|
|
|
|
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 |
|
|
| `Shift+N` | Add a Host Entry based on the selected 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 |
|
|
| `b` | Review session backup changes and confirm restoration |
|
|
|
|
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.
|