How to Edit the Hosts File in Linux: Complete Technical Guide
The `/etc/hosts` file in Linux is a static lookup table that maps hostnames to IP addresses, processed by the operating system *before* any DNS query is sent. By adding or modifying entries in this file, you can override DNS resolution for specific domains on a per-machine basis β without touching your DNS server, router, or registrar settings.
This mechanism is controlled by the Name Service Switch (NSS), configured in `/etc/nsswitch.conf`. The default `hosts:` line typically reads `files dns`, meaning the system consults `/etc/hosts` first, then falls back to DNS resolvers defined in `/etc/resolv.conf`. Understanding this order is critical: if a hostname exists in `/etc/hosts`, the DNS query never leaves the machine.
What the Hosts File Is and How It Works
The `/etc/hosts` file predates the modern DNS system entirely. In the early ARPANET era, a single `HOSTS.TXT` file maintained by the Stanford Research Institute was distributed to every networked machine. Today's `/etc/hosts` is a direct descendant of that concept β a local, authoritative override layer that every POSIX-compliant operating system still honors.
Each non-comment line in the file follows this syntax:
“`
IP_address canonical_hostname [alias1] [alias2] …
“`
- Lines beginning with `#` are comments and are ignored.
- Whitespace (spaces or tabs) separates fields.
- A single IP address can map to multiple hostnames on the same line.
- IPv4 and IPv6 entries coexist in the same file.
A minimal default `/etc/hosts` on a fresh Linux installation looks like this:
“`
127.0.0.1 localhost
127.0.1.1 myhostname.local myhostname
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
“`
The `127.0.1.1` entry is Debian/Ubuntu-specific and maps the machine's FQDN to a loopback address when a static IP is not assigned. Removing it can break tools like `sudo` that rely on hostname resolution.
Why You Would Edit the Hosts File
The use cases span from simple developer convenience to security-critical infrastructure tasks:
Local development and staging environments
Point a production domain (e.g., `myapp.com`) to `127.0.0.1` or a LAN IP while building or testing, without modifying live DNS records. This is the most common use case for developers running a VPS Hosting environment locally or on a remote server.
Multi-server application testing
When migrating a site to a new server, point the domain to the new server's IP on your local machine only. You can verify the new environment is fully functional before updating the public DNS record β eliminating downtime risk.
Blocking malicious or unwanted domains
Redirecting a domain to `0.0.0.0` (preferred over `127.0.0.1` for blocking) causes the connection to fail immediately without waiting for a refused connection on localhost. Projects like `StevenBlack/hosts` aggregate millions of ad, tracker, and malware domains into a single hosts-format blocklist.
Container and microservice networking
In Docker or LXC environments without a custom DNS resolver, `/etc/hosts` entries inside containers (or on the host) provide lightweight service discovery. Docker's `–add-host` flag injects entries directly into a container's `/etc/hosts` at runtime.
Overriding split-horizon DNS
In corporate networks where internal and external DNS return different records for the same hostname, a hosts file entry gives you deterministic control on a specific machine.
SSL certificate validation testing
When testing a new SSL Certificates deployment on a staging server, pointing the domain to the staging IP in `/etc/hosts` lets you verify the full TLS handshake, certificate chain, and HTTPS redirect behavior before go-live.
Step-by-Step: How to Edit the Hosts File in Linux
Step 1: Open a Terminal
Access a terminal emulator. On desktop distributions, the shortcut `Ctrl + Alt + T` works on GNOME, KDE, and XFCE. On a headless server, you are already in a shell session via SSH.
Confirm your current user and privilege level:
“`bash
whoami
id
“`
Step 2: Back Up the Current Hosts File
Always create a timestamped backup before modifying any system file. A generic `hosts.backup` can be overwritten accidentally; a timestamp is unambiguous:
“`bash
sudo cp /etc/hosts /etc/hosts.bak.$(date +%Y%m%d_%H%M%S)
“`
Verify the backup was created:
“`bash
ls -lh /etc/hosts*
“`
Step 3: Check File Permissions and Ownership
Before editing, confirm the file's current ownership and permissions:
“`bash
ls -la /etc/hosts
“`
Expected output:
“`
-rw-r–r– 1 root root 221 Jan 10 09:00 /etc/hosts
“`
The file should be owned by `root:root` with permissions `644`. If permissions differ, investigate before proceeding β a world-writable `/etc/hosts` is a security vulnerability.
Step 4: Open the Hosts File with a Text Editor
Using nano (recommended for most users):
“`bash
sudo nano /etc/hosts
“`
Using vim:
“`bash
sudo vim /etc/hosts
“`
Using gedit (GUI, GNOME desktop):
“`bash
sudo gedit /etc/hosts
“`
Using tee for non-interactive/scripted additions (no editor required):
“`bash
echo "192.168.1.50 staging.myapp.com" | sudo tee -a /etc/hosts
“`
The `-a` flag appends to the file rather than overwriting it. This is the safest method for automation scripts and Ansible playbooks.
Step 5: Add, Modify, or Remove Entries
Navigate to the end of the file and add your entries. Follow these formatting rules strictly:
- One entry per line.
- IP address first, then one or more hostnames separated by whitespace.
- Use `#` inline to annotate entries for future reference.
Redirect a domain to a local development server:
“`
127.0.0.1 myproject.local # Local dev – remove before production
“`
Point a domain to a remote staging server:
“`
203.0.113.45 staging.myapp.com # Staging server – pre-DNS cutover
“`
Block a domain (preferred method using 0.0.0.0):
“`
0.0.0.0 ads.example.com
0.0.0.0 tracker.analytics-provider.com
“`
Add an IPv6 entry:
“`
::1 ipv6-service.local
“`
Map multiple aliases to one IP (useful for virtual hosts):
“`
127.0.0.1 app.local api.local static.local
“`
Step 6: Save and Exit the Editor
In nano:
- Save: `Ctrl + O`, then `Enter` to confirm the filename.
- Exit: `Ctrl + X`.
In vim:
- Return to normal mode: `Esc`
- Save and quit: `:wq` then `Enter`
- Quit without saving: `:q!` then `Enter`
Step 7: Verify the File Contents
Confirm your entries were written correctly:
“`bash
cat /etc/hosts
“`
For large hosts files, use `grep` to find specific entries:
“`bash
grep "myproject.local" /etc/hosts
“`
Check for syntax errors β an entry with a missing IP or malformed address will be silently ignored by the resolver:
“`bash
sudo python3 -c "
with open('/etc/hosts') as f:
for i, line in enumerate(f, 1):
line = line.strip()
if line and not line.startswith('#'):
parts = line.split()
if len(parts) < 2:
print(f'Line {i} may be malformed: {line}')
"
“`
Step 8: Flush the DNS Cache
Changes to `/etc/hosts` take effect immediately for new connections on most systems. However, if your system runs a local DNS caching daemon, you must flush its cache to see the changes.
systemd-resolved (Ubuntu 18.04+, most modern distros):
“`bash
sudo systemd-resolve –flush-caches
sudo systemd-resolve –statistics # Verify cache was cleared
“`
nscd (Name Service Cache Daemon):
“`bash
sudo systemctl restart nscd
“`
dnsmasq:
“`bash
sudo systemctl restart dnsmasq
“`
NetworkManager with dnsmasq plugin:
“`bash
sudo systemctl restart NetworkManager
“`
Browsers maintain their own DNS cache independently. Chrome and Firefox cache DNS records for up to 60 seconds. To clear Chrome's internal DNS cache, navigate to `chrome://net-internals/#dns` and click "Clear host cache."
Step 9: Test the Resolution
Use `getent` rather than `ping` for a more reliable test of the NSS resolution chain:
“`bash
getent hosts myproject.local
“`
`getent` queries the system's Name Service Switch directly, respecting `/etc/nsswitch.conf`, and will show you exactly what the OS resolves β not what a DNS server returns. This is the definitive test.
Additionally:
“`bash
ping -c 3 myproject.local
“`
“`bash
curl -v http://myproject.local
“`
If `getent` returns the correct IP but `ping` does not, the issue lies in the network stack or firewall, not the hosts file.
Hosts File vs. DNS: When to Use Each
| Criterion | `/etc/hosts` | DNS Server |
|---|
| — | — | — |
|---|
| Scope | Single machine only | Network-wide or global |
|---|
| Propagation delay | Instant | Minutes to 48 hours (TTL-dependent) |
|---|
| Requires network | No | Yes (for external DNS) |
|---|
| Scalability | Poor (manual, per-host) | Excellent (centrally managed) |
|---|
| Supports wildcards | No | Yes (e.g., `*.example.com`) |
|---|
| Survives reboots | Yes (file persists) | Yes (server-managed) |
|---|
| Audit trail | Only via version control | Depends on DNS provider |
|---|
| Best for | Dev/test overrides, blocking | Production infrastructure |
|---|
| IPv6 support | Yes | Yes |
|---|
| Automation-friendly | Moderate (file editing) | High (API-driven) |
|---|
For teams managing multiple servers β such as a fleet of Dedicated Servers β centralized DNS management is always superior to distributing hosts file changes manually. The hosts file is a per-machine tool, not an infrastructure tool.
Advanced Techniques and Edge Cases
Using the Hosts File with Virtual Hosts in Apache and Nginx
When running multiple websites on a single server using virtual hosting, the hosts file on your *client machine* must point the domain to the server's IP. The web server then uses the `Host:` HTTP header to route the request to the correct virtual host. The hosts file entry and the server's virtual host configuration must use the same hostname.
For example, if you have an Apache virtual host configured for `myapp.local` on a VPS with cPanel, add the server's IP to your local hosts file:
“`
198.51.100.10 myapp.local
“`
Then access `http://myapp.local` in your browser. Apache reads the `Host: myapp.local` header and serves the correct site.
Protecting the Hosts File from Unauthorized Modification
Malware frequently targets `/etc/hosts` to redirect legitimate domains (e.g., banking sites) to phishing servers. Use `chattr` to make the file immutable:
“`bash
sudo chattr +i /etc/hosts
“`
This prevents modification even by root until the immutable flag is explicitly removed:
“`bash
sudo chattr -i /etc/hosts # Remove immutability to edit
“`
Check the attribute:
“`bash
lsattr /etc/hosts
“`
Version-Controlling Your Hosts File
For teams or complex development environments, track `/etc/hosts` changes with Git:
“`bash
sudo cp /etc/hosts ~/dotfiles/hosts
cd ~/dotfiles && git add hosts && git commit -m "Add staging.myapp.com entry"
“`
Tools like etckeeper automatically version-control the entire `/etc` directory using Git or other VCS backends, providing a full audit trail of system file changes.
Hosts File in Docker and Kubernetes
In Docker, you can inject hosts file entries at container start without modifying the host system:
“`bash
docker run –add-host=myservice.local:192.168.1.100 myimage
“`
In Kubernetes, `hostAliases` in a Pod spec achieves the same result:
“`yaml
spec:
hostAliases:
- ip: "192.168.1.100"
hostnames:
- "myservice.local"
“`
These approaches are preferable to modifying the host's `/etc/hosts` when working in containerized environments.
The `0.0.0.0` vs. `127.0.0.1` Blocking Debate
Both addresses are used to block domains, but they behave differently:
- `127.0.0.1`: Routes the connection to the local loopback interface. If nothing is listening on port 80/443 locally, the connection is refused β but the OS still attempts to establish it, causing a brief delay.
- `0.0.0.0`: Represents an invalid destination on most systems. The connection fails immediately without attempting a TCP handshake, resulting in faster page loads when blocking large numbers of ad/tracker domains.
For blocklist use cases, `0.0.0.0` is the technically superior choice.
Common Errors and Troubleshooting
Changes not taking effect after editing:
- Confirm the entry is syntactically correct (IP first, then hostname).
- Flush the local DNS cache (see Step 8).
- Check `/etc/nsswitch.conf` β if `dns` appears before `files` in the `hosts:` line, DNS is queried first and the hosts file is bypassed for cached entries.
`sudo: unable to resolve host` error after editing:
- You likely removed or corrupted the line mapping your machine's hostname to `127.0.1.1` or `127.0.0.1`. Restore the backup immediately: `sudo cp /etc/hosts.bak.TIMESTAMP /etc/hosts`.
Entry ignored for a specific application:
- Some applications (notably those using `getaddrinfo` with custom NSS configurations, or those with statically linked resolvers) bypass `/etc/nsswitch.conf` entirely and query DNS directly. This is common in Go binaries compiled with CGO disabled. Verify with `strace -e trace=network yourapp`.
Hosts file works locally but not in a Docker container:
- Container networking is isolated. The container has its own `/etc/hosts`. Use `–add-host` or `hostAliases` as described above.
Key Technical Takeaways: Decision Checklist
Before editing `/etc/hosts`, run through this checklist:
- Scope check: Is this change needed on one machine only? If multiple machines need it, use DNS or a tool like Ansible to distribute the change.
- Backup first: Always create a timestamped backup (`hosts.bak.YYYYMMDD_HHMMSS`) before any edit.
- Use `0.0.0.0` for blocking: Faster failure, no loopback overhead.
- Flush the right cache: Identify whether your system uses `systemd-resolved`, `nscd`, or `dnsmasq` before restarting the wrong service.
- Test with `getent`: More reliable than `ping` for confirming NSS resolution.
- Protect the file: Use `chattr +i` on production or security-sensitive systems.
- Document your entries: Add inline comments (`# reason – added YYYY-MM-DD`) to every non-default entry.
- Remove temporary entries: Dev/test entries left in production hosts files are a common source of hard-to-diagnose routing bugs.
If you are managing a development workflow across multiple environments, consider pairing local hosts file management with a properly configured VPS Control Panels setup to centralize virtual host management and reduce per-machine configuration drift.
For projects that involve Domain Registration and staged rollouts, the hosts file remains the most reliable way to perform a full end-to-end test of a new server configuration before DNS propagation completes β giving you a zero-risk validation window before the public sees any change.
FAQ
Does editing `/etc/hosts` require a system reboot?
No. Changes to `/etc/hosts` take effect immediately for new connections. If you have a local DNS caching daemon (`systemd-resolved`, `nscd`, or `dnsmasq`), you must flush its cache. Browsers also maintain independent DNS caches that may need to be cleared manually.
Why does my hosts file entry work in the terminal but not in my browser?
Browsers cache DNS records independently of the OS resolver. Chrome caches records for up to 60 seconds. Navigate to `chrome://net-internals/#dns` and clear the host cache, or wait for the TTL to expire.
Can I use wildcards in `/etc/hosts`?
No. The `/etc/hosts` file does not support wildcard entries. Each hostname must be listed explicitly. If you need wildcard resolution (e.g., `*.local`), use a local DNS resolver like `dnsmasq` or `unbound`.
What is the maximum number of entries in `/etc/hosts`?
There is no hard-coded limit enforced by the kernel or glibc. However, performance degrades with very large files because the file is parsed linearly for each lookup. Files with tens of thousands of entries (common with ad-blocking lists) can add measurable latency to hostname resolution. For large blocklists, a dedicated DNS sinkhole like Pi-hole is more efficient.
Is it safe to delete the default entries in `/etc/hosts`?
No. The default entries (`127.0.0.1 localhost`, `::1 localhost`, and the machine's own hostname mapping) are required for correct system operation. Removing them can break `sudo`, local socket connections, and applications that rely on loopback resolution. Only add or modify entries; never remove the defaults without a specific, well-understood reason.
