Go Library
/etc/hosts file management. It was originally built to support kubefwd for Kubernetes service forwarding.txeh provides a Go library for programmatic /etc/hosts file management. It was originally built to support kubefwd for Kubernetes service forwarding.
Installation
go get github.com/txn2/txehLoading the Hosts File
System default
hosts, err := txeh.NewHostsDefault()
if err != nil {
log.Fatal(err)
}Custom paths
hosts, err := txeh.NewHosts(&txeh.HostsConfig{
ReadFilePath: "/custom/path/hosts",
WriteFilePath: "/custom/path/hosts",
})From a string (in-memory)
raw := "127.0.0.1 localhost\n::1 localhost\n"
hosts, err := txeh.NewHosts(&txeh.HostsConfig{
RawText: &raw,
})When RawText is set, Save() returns an error since there is no file path. Use RenderHostsFile() or SaveAs() instead.
Adding Hosts
// Single hostname
hosts.AddHost("127.0.0.1", "myapp.local")
// Multiple hostnames to one IP
hosts.AddHosts("127.0.0.1", []string{"app1", "app2", "app3"})
// With an inline comment
hosts.AddHostWithComment("127.0.0.1", "myapp", "dev environment")
hosts.AddHostsWithComment("127.0.0.1", []string{"svc1", "svc2"}, "kubefwd")Removing Hosts
// By hostname
hosts.RemoveHost("myapp.local")
hosts.RemoveHosts([]string{"app1", "app2"})
// By IP address
hosts.RemoveAddress("127.0.0.1")
hosts.RemoveAddresses([]string{"10.0.0.1", "10.0.0.2"})
// By CIDR range
err := hosts.RemoveCIDRs([]string{"10.0.0.0/24"})
// By comment
hosts.RemoveByComment("dev environment")
hosts.RemoveByComments([]string{"old-env", "deprecated"})Querying
// List hostnames at an IP
hostnames := hosts.ListHostsByIP("127.0.0.1")
// List IPs for a hostname (exact or partial match)
addresses := hosts.ListAddressesByHost("myapp", true) // exact
addresses = hosts.ListAddressesByHost("myapp", false) // contains
// List hostnames in a CIDR range
hostnames = hosts.ListHostsByCIDR("10.0.0.0/24")
// Lookup a specific hostname
found, ip, ipFamily := hosts.HostAddressLookup("myapp", txeh.IPFamilyV4)
// List by comment
entries := hosts.ListHostsByComment("kubefwd")Saving and Rendering
// Save to the configured write path
err := hosts.Save()
// Save to a specific path
err = hosts.SaveAs("/tmp/hosts.test")
// Render without saving
output := hosts.RenderHostsFile()
fmt.Println(output)CIDR Operations
txeh supports CIDR (Classless Inter-Domain Routing) notation for bulk operations on IP address ranges.
Removing by CIDR
Remove all host entries whose IP addresses fall within one or more CIDR ranges.
err := hosts.RemoveCIDRs([]string{"10.0.0.0/24", "172.16.0.0/12"})
if err != nil {
log.Fatal(err)
}Note
RemoveCIDRsis the only removal method that returns an error, since CIDR parsing can fail with invalid input.
Listing by CIDR
hostnames := hosts.ListHostsByCIDR("10.0.0.0/24")
for _, hn := range hostnames {
fmt.Println(hn)
}Example: cleaning up development entries
// Remove stale entries from a previous deployment
cidrs := []string{"10.244.0.0/16", "10.96.0.0/12"}
if err := hosts.RemoveCIDRs(cidrs); err != nil {
log.Fatal(err)
}
hosts.Save()Inline Comments
txeh supports inline comments on host entries. Comments are useful for tracking which tool or purpose added specific entries.
Comments use the standard hosts file format: IP HOSTNAME [HOSTNAME...] # comment
Key behavior:
- Comments are used for grouping: hosts with the same IP and same comment are placed on the same line.
- Hosts added without a comment only match lines without a comment.
- Hosts added with a comment only match lines with the same comment.
- Comments are never modified on existing lines.
- If no matching line exists, a new line is created.
Adding with comments
hosts.AddHostWithComment("127.0.0.1", "myapp", "local development")
hosts.AddHostsWithComment("127.0.0.1", []string{"svc1", "svc2"}, "my project")Listing and removing by comment
// List by comment
entries := hosts.ListHostsByComment("local development")
// Remove by comment
hosts.RemoveByComment("local development")
hosts.RemoveByComments([]string{"old-env", "deprecated"})Modifying comments
Comments are never modified on existing lines. To change a comment, remove and re-add:
hosts.RemoveByComment("old comment")
hosts.AddHostsWithComment("127.0.0.1", []string{"app1", "app2"}, "new comment")Configuration
MaxHostsPerLine
Controls how many hostnames can appear on a single line.
| Value | Behavior |
|---|---|
0 | Auto (9 on Windows, unlimited elsewhere) |
-1 | Unlimited |
>0 | Explicit limit |
When the limit is reached, additional hostnames are placed on a new line with the same IP address.
hosts, err := txeh.NewHosts(&txeh.HostsConfig{
MaxHostsPerLine: 5,
})ReadFilePath and WriteFilePath
Override the default system hosts file location. If only ReadFilePath is set, WriteFilePath defaults to the same path.
hosts, err := txeh.NewHosts(&txeh.HostsConfig{
ReadFilePath: "/etc/hosts",
WriteFilePath: "/tmp/hosts.modified",
})Thread Safety
All public methods on Hosts acquire a mutex before reading or modifying the internal state. This makes txeh safe for concurrent use from multiple goroutines.
