The Linux hosts file at /etc/hosts is a plain text file that maps hostnames to IP addresses, checked before DNS when your system resolves a domain name. Each line contains an IP address followed by one or more hostnames: 192.168.1.10 myserver makes myserver resolve to 192.168.1.10, and 127.0.0.1 blocked-site.com effectively blocks that site by redirecting it to localhost. Edit it with sudo nano /etc/hosts — changes take effect immediately without restarting anything.
The Oldest Name Resolution System Still in Use
Long before DNS (the Domain Name System) was invented in 1983, Unix systems used a simple text file to map hostnames to IP addresses. This file — /etc/hosts — was the original name resolution mechanism on ARPANet, the predecessor of the internet. Every machine on the network maintained its own copy, and when you typed a hostname, the system looked it up in this file to find the corresponding IP address.
As the internet grew from dozens of machines to millions, maintaining a central hosts file became impossible — DNS was invented to handle distributed, scalable name resolution. But /etc/hosts was not retired. It persisted on every Unix and Linux system, checked before DNS for every hostname lookup. Today, /etc/hosts remains one of the first places the Linux name resolution system looks when converting a hostname to an IP address.
This persistence is not mere historical inertia — it is practical utility. /etc/hosts provides immediate, local hostname resolution that requires no network, no DNS server, and no complex configuration. It lets you define custom hostnames for machines on your network, create memorable names for frequently accessed servers, block domain names by redirecting them to localhost, and set up local development hostnames for web projects. All of this with nothing more than editing a text file.
Understanding /etc/hosts thoroughly — what it contains, how it fits into the broader name resolution process, and how to use it for common real-world tasks — is one of the most useful small pieces of Linux knowledge you can have.
What /etc/hosts Contains
Open the hosts file on any Linux system and you see a small, structured text file:
$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 mycomputer.local mycomputer
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
The File Format
Each non-comment line follows this structure:
IP_address hostname [alias1] [alias2] ...
- IP address — IPv4 or IPv6 address
- Hostname — the primary name for this address (typically the fully qualified domain name)
- Aliases — additional names that resolve to the same address (space-separated)
Lines beginning with # are comments and are ignored:
# This is a comment
# Added by the system installer
127.0.0.1 localhost
Whitespace (spaces or tabs) separates fields. Multiple spaces or tabs between fields are treated as a single separator. There is no limit on the number of aliases per line, but long lines are often split into multiple entries for readability.
The Default Entries Explained
127.0.0.1 localhost — The IPv4 loopback address. Any traffic sent to localhost is directed to the loopback interface (lo) and never leaves the machine. This is how services that bind to localhost remain inaccessible from the network.
127.0.1.1 mycomputer.local mycomputer — On Debian and Ubuntu, the machine’s own hostname is mapped to 127.0.1.1 (a different loopback address from 127.0.0.1). This prevents lookup delays when programs try to resolve the local hostname. On some systems, the machine’s actual IP address is used here instead.
::1 localhost ip6-localhost ip6-loopback — The IPv6 loopback address, equivalent to IPv4’s 127.0.0.1. ip6-localhost and ip6-loopback are aliases for the same address.
ff02::1 ip6-allnodes — The IPv6 multicast address for all nodes on the local network segment.
ff02::2 ip6-allrouters — The IPv6 multicast address for all routers on the local network segment.
How Name Resolution Works: The /etc/hosts Priority
When your system needs to resolve a hostname (for example, when you type ssh myserver or visit http://myapp.local in a browser), it does not immediately contact DNS. It follows a configured order of resolution mechanisms, defined in /etc/nsswitch.conf:
$ grep hosts /etc/nsswitch.conf
hosts: files dns myhostname
This line says: resolve hostnames by checking:
files—/etc/hosts(and/etc/networksfor network names)dns— DNS server (configured in/etc/resolv.conf)myhostname— the local machine’s own hostname
Because files comes before dns, entries in /etc/hosts take precedence over DNS. If /etc/hosts has an entry for google.com, that entry is used and DNS is never consulted for that hostname.
This precedence is both the power and the responsibility of the hosts file: you can override any DNS resolution locally, which is extremely useful but should be done intentionally.
What Happens Step by Step
When you run ping myserver:
- The resolver checks
/etc/nsswitch.confto determine resolution order - It reads
/etc/hostsline by line looking formyserver - If found: returns the IP address from the hosts file — done
- If not found: queries the DNS server in
/etc/resolv.conf - If DNS responds: returns the DNS answer
- If DNS fails: tries
myhostnameand other listed mechanisms
The whole process typically takes milliseconds. The /etc/hosts lookup is essentially instant since it is just a file read.
Editing /etc/hosts
/etc/hosts requires root privileges to edit. The standard approach:
$ sudo nano /etc/hosts
Or with your preferred editor:
$ sudo vim /etc/hosts
$ sudo gedit /etc/hosts # Graphical editor (may need adjustments for sudo + GUI)
For graphical editors with sudo, use sudoedit which handles the privilege escalation correctly:
$ sudoedit /etc/hosts
Changes Take Effect Immediately
Unlike many system configuration files that require a service restart, changes to /etc/hosts take effect immediately. The next hostname lookup after saving will use the updated file. No restart required, no service to reload.
However, browsers and applications often cache DNS results. After editing /etc/hosts, you may need to:
- Clear browser DNS cache: In Chrome, visit
chrome://net-internals/#dnsand click “Clear host cache” - Clear Firefox DNS cache: Visit
about:networking#dnsand click “Clear DNS Cache” - Or simply close and reopen the application
Backup Before Editing
The hosts file rarely causes system-breaking problems if edited incorrectly (unlike many system files), but backup is still good practice:
$ sudo cp /etc/hosts /etc/hosts.backup
Common Uses of /etc/hosts
1. Mapping Local Network Machines
Instead of remembering 192.168.1.105 for your development server, add a memorable hostname:
192.168.1.105 devserver devserver.local
192.168.1.110 nas nas.local
192.168.1.120 printer
192.168.1.1 router gateway
Now you can ssh devserver, ping nas, or open http://devserver in a browser without remembering IP addresses. This is particularly useful for home lab setups, small office networks, or any situation where you do not have a local DNS server.
Note: These entries only work on the machine whose /etc/hosts you edited. Other machines on your network see only the IP addresses unless they have their own entries. For network-wide hostname resolution, a local DNS server (like Pi-hole or a router with DNS functionality) is more appropriate.
2. Local Development: Virtual Hosts
Web developers frequently run multiple websites locally, each needing its own hostname. Apache and nginx support virtual hosts — different website configurations triggered by the hostname in the HTTP request.
Add development hostnames to /etc/hosts:
127.0.0.1 myproject.local
127.0.0.1 api.myproject.local
127.0.0.1 staging.myproject.local
127.0.0.1 client1.local
127.0.0.1 client2.local
Now visiting http://myproject.local in a browser resolves to 127.0.0.1 (localhost), where your local web server handles the request. The web server uses the Host: header (myproject.local) to determine which virtual host configuration to apply.
This is a standard workflow for PHP, Django, Rails, and Node.js web development on Linux.
3. Blocking Unwanted Domains
Redirecting a domain to 127.0.0.1 (or 0.0.0.0) effectively blocks it — traffic to that domain goes to your own machine rather than the real server, where nothing is listening (or where you could serve a custom block page):
# Block advertising and tracking domains
127.0.0.1 ads.example.com
127.0.0.1 tracking.analytics.com
0.0.0.0 malware-site.com
# Block time-wasting social media during work hours
127.0.0.1 www.reddit.com
127.0.0.1 twitter.com
127.0.0.1 x.com
0.0.0.0 is sometimes used instead of 127.0.0.1 for blocking because connections to 0.0.0.0 fail immediately rather than waiting for a connection timeout to localhost. Either works for blocking, but 0.0.0.0 may be marginally faster for blocked domains.
Community hosts files for ad blocking: Several community projects maintain comprehensive hosts files blocking thousands of ad networks, tracking services, and malware domains:
- StevenBlack’s unified hosts —
https://github.com/StevenBlack/hosts— curated lists blocking ads, tracking, malware, and more - hosts.extras — regular updates with many blocking categories
These can be downloaded and appended to your /etc/hosts:
$ sudo curl -o /tmp/blocklist.txt https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
$ sudo cat /tmp/blocklist.txt >> /etc/hosts
Note: While hosts-file blocking works, dedicated DNS-level solutions like Pi-hole are more flexible and work network-wide rather than only on the machine where you edit the file.
4. Overriding DNS for Testing
Testing a website before changing its DNS — when you want to check how a site looks on a new server before pointing the actual domain there:
# Temporarily point example.com to the new server for testing
203.0.113.50 example.com www.example.com
Now your browser resolves example.com to 203.0.113.50 (the new server) while the rest of the internet still reaches the old server at the real DNS address. Test everything, confirm it works, then update DNS for everyone. Remove the entry from /etc/hosts afterward.
5. Making VPN Hostnames Resolve
When connected to a company VPN, internal hostnames may not automatically resolve if your VPN’s DNS configuration is incomplete:
10.0.0.5 internal-db.company.com
10.0.0.10 jenkins.company.com
10.0.0.20 wiki.company.com
Adding internal server addresses to /etc/hosts provides a quick fix while DNS configuration is sorted out.
6. Speeding Up Local Service Resolution
If you frequently connect to your own machine’s services by hostname, adding the hostname explicitly prevents DNS lookups:
127.0.0.1 localhost myapp.local api.local
This is minor but can slightly speed up development workflows.
/etc/hosts and IPv6
The hosts file fully supports IPv6 addresses. IPv6 entries follow the same format:
::1 localhost
2001:db8::1 myipv6server
fd00::10 internal-ipv6.local
When both IPv4 and IPv6 entries exist for the same hostname, the behavior depends on the application’s address family preference. Most modern applications prefer IPv6 when both are available.
To force IPv4 for a hostname (some applications connect to IPv6 unexpectedly):
# Only provide IPv4 address for this hostname
192.168.1.105 devserver
To provide both:
192.168.1.105 devserver devserver.local
fd00::105 devserver devserver.local
Understanding the Interaction with systemd-resolved
On modern Ubuntu and Debian systems, DNS resolution is handled by systemd-resolved, which provides a local DNS caching resolver at 127.0.0.53. The /etc/resolv.conf points to this resolver:
$ cat /etc/resolv.conf
nameserver 127.0.0.53
options edns0 trust-ad
systemd-resolved reads /etc/hosts and incorporates its entries into its resolution. This means:
/etc/hostsentries are respected through the systemd-resolved pathsystemd-resolvedcaches/etc/hostsentries- Changes to
/etc/hostsare picked up without restartingsystemd-resolved
However, the caching means a brief propagation delay (usually under a second) for changes in some scenarios. If you need to be certain a change is applied immediately:
$ sudo systemctl restart systemd-resolved # Flush the resolved cache
Or flush the DNS cache directly:
$ sudo resolvectl flush-caches
Practical /etc/hosts Example: Complete Development Setup
Here is a realistic /etc/hosts for a developer’s machine combining all common use cases:
# Standard loopback entries
127.0.0.1 localhost
127.0.1.1 workstation workstation.local
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
# Local development virtual hosts
127.0.0.1 myapp.local
127.0.0.1 api.myapp.local
127.0.0.1 admin.myapp.local
127.0.0.1 client-project.local
127.0.0.1 staging.client-project.local
# Home lab machines
192.168.1.1 router gateway
192.168.1.5 nas storage.local
192.168.1.10 dev-server devserver.local
192.168.1.20 pi raspberrypi.local
192.168.1.100 printer
# VPN internal resources (when connected to work VPN)
# 10.0.0.10 internal-wiki.company.com
# 10.0.0.20 jira.company.com
# Temporary: testing example.com on new server (remove after DNS update)
# 203.0.113.50 example.com www.example.com
# Domain blocking
0.0.0.0 distracting-site.com
Note the commented VPN and testing entries — keeping them in the file but commented makes it easy to enable them when needed without retyping.
Hosts File Syntax Gotchas
Case Sensitivity
Hostname matching in /etc/hosts is case-insensitive on Linux. MYSERVER, myserver, and MyServer all match the same entry. However, by convention, lowercase is standard.
Wildcards Are Not Supported
Unlike DNS, /etc/hosts does not support wildcard entries. You cannot write *.myproject.local to match all subdomains. Each subdomain must be listed explicitly:
# You must list each one:
127.0.0.1 myproject.local
127.0.0.1 api.myproject.local
127.0.0.1 admin.myproject.local
127.0.0.1 staging.myproject.local
If you need wildcard subdomains for local development, a local DNS resolver like dnsmasq is the solution:
$ sudo apt install dnsmasq
$ echo "address=/.local/127.0.0.1" | sudo tee -a /etc/dnsmasq.conf
$ sudo systemctl restart dnsmasq
Multiple Hostnames Per Line vs. Multiple Lines
Both approaches work:
# Single line with multiple names:
192.168.1.105 devserver devserver.local dev.local
# Multiple lines for the same IP (also valid):
192.168.1.105 devserver
192.168.1.105 devserver.local
192.168.1.105 dev.local
The single-line approach is more compact; multiple lines can be easier to comment out individual names. Both are functionally identical.
Avoid Duplicate Entries
If the same hostname appears multiple times with different IP addresses, the first match wins:
192.168.1.105 devserver # This wins
192.168.1.106 devserver # This is ignored
The first matching entry stops the search. Keep entries organized and avoid duplicates to prevent confusion.
Security Considerations
The Hosts File Can Be Attacked
Malware, viruses, and exploits sometimes modify /etc/hosts to redirect legitimate domains to malicious servers — for example, redirecting your banking website to a phishing site that looks identical.
Periodically verify your hosts file is clean:
$ cat /etc/hosts
Look for unexpected entries — especially entries redirecting well-known domains (banks, email providers, operating system update servers) to unusual IP addresses. The legitimate entries should be minimal: localhost entries, your machine’s own hostname, and only entries you deliberately added.
File Permission Check
/etc/hosts should be owned by root and not writable by others:
$ ls -la /etc/hosts
-rw-r--r-- 1 root root 312 Feb 18 11:00 /etc/hosts
The permissions should be 644 (owner read-write, group read, others read). If permissions are 777 or writable by non-root users, that is a security concern:
$ sudo chmod 644 /etc/hosts
$ sudo chown root:root /etc/hosts
Quick Reference: /etc/hosts
| Task | Details |
|---|---|
| File location | /etc/hosts |
| Edit command | sudo nano /etc/hosts |
| Format | IP_address hostname [aliases...] |
| Comments | Lines starting with # |
| Takes effect | Immediately (no restart needed) |
| Priority | Before DNS (defined in /etc/nsswitch.conf) |
| Flush DNS cache | sudo resolvectl flush-caches |
| Supports wildcards | No |
| IPv6 support | Yes (::1 localhost) |
| Block a domain | 0.0.0.0 domain.com or 127.0.0.1 domain.com |
| Add local hostname | 192.168.1.x myname |
| Local dev hostname | 127.0.0.1 myapp.local |
Conclusion: Small File, Big Power
/etc/hosts is one of the smallest configuration files on a Linux system, but it sits at the foundation of every hostname lookup. Its simplicity is its strength — a plain text file, one line per mapping, taking effect immediately when saved. No service to restart, no complex configuration syntax, no tools to install.
The practical applications are immediate and valuable: giving memorable names to machines on your home network, setting up local development hostnames for web projects, blocking distracting or malicious domains, and testing server configurations before changing public DNS. All of these take nothing more than a text editor and an understanding of the file’s format.
Understanding where /etc/hosts sits in the resolution order — checked before DNS, every time, for every hostname lookup — is the key insight. With that understanding, you can use the file deliberately: making local overrides that work immediately, testing changes without affecting DNS for others, and knowing exactly why a hostname resolves to a particular address on your system.




