Giving a machine a name you control
On this page
You’ve just built a virtual machine at 10.0.1.23, and there’s no DNS record for it. Typing the address every time gets old, and ssh app-server fails with Could not resolve hostname app-server, because nothing on your machine knows where app-server is. One line in the right file fixes that, without asking anyone to change DNS.
Two files can do it, and they answer slightly different needs. A hosts file line makes the name work for every program on your machine. An SSH config alias only works for SSH, but it can also fill in the user and key. Common reasons to reach for one:
- a lab machine or test server that never gets a DNS record;
- trying a new server under its real name before the DNS record is switched to it, by pointing the name at it on your machine only;
- several servers you SSH into with different users and keys, which an SSH config keeps track of for you.
This primer follows one example the whole way: a server at 10.0.1.23 that you log into as the user deploy with the key ~/.ssh/app-server.pem, and want to reach as app-server.
A few terms
- Hostname: a name for a machine, like
app-serverorwww.example.com. - Resolver: the part of the operating system that turns a hostname into an IP address when a program asks.
- DNS: the shared, network-wide system of names, explained in DNS resolution. Changing it needs access to the DNS server or zone.
- Hosts file: a plain text file on your own machine that maps addresses to names. The resolver reads it alongside DNS.
- SSH: the program used to log into another machine’s command line.
scpandsftpcopy files over the same connection. - SSH config: a file of settings for your SSH client, such as which address, user, and key to use for a given name.
- Host key: a key that identifies the server itself. SSH remembers it in
~/.ssh/known_hoststhe first time you connect, and warns if it changes [1].
Two questions, two failures
Connecting to a machine by name answers two separate questions, in order:
| Question | Answered by | Failure looks like |
|---|---|---|
| What IP address does this name mean? | An SSH config HostName, the hosts file, or DNS | Could not resolve hostname |
| Can I reach that address and log in? | Routes, firewalls, security groups, the user, the key | A timeout, Connection refused, or Permission denied |
Here’s where each part happens when you type ssh app-server, and where the two options plug in:
Both options plug into the top half, which only finds an address. Nothing in the top half can fix a problem in the bottom half.
Fixing the first question never fixes the second. A name that resolves to an address a firewall blocks still times out, just with a different error than before.
known_hosts belongs to neither question in the way people often expect. It records each server’s host key so SSH can tell it’s talking to the same machine as last time. It says nothing about where the machine is [1].
How a name becomes an address
Programs ask the operating system’s resolver, and the resolver reads the hosts file as well as asking DNS. Each line of the hosts file holds an address, a name, and optional extra names, separated by any number of spaces or tabs, with # starting a comment [2]:
10.0.1.23 app-server
Each system decides the order in its own way:
- Linux:
/etc/nsswitch.confsets it. Itshosts:line lists the sources to try, such asfiles dns, and they’re queried in that order until one finds an answer [3].filesmeans the hosts file. - macOS: the system resolver reads the hosts file and uses it alongside answers from DNS [4].
- Windows: the resolver uses the hosts file too. Even
Resolve-DnsName, the usual lookup command, only leaves it out when you pass-NoHostsFile[5].
| System | Hosts file |
|---|---|
| macOS, Linux | /etc/hosts [2] |
| Windows | C:\Windows\System32\drivers\etc\hosts [6] |
Editing it needs administrator rights on all three. Changes normally take effect immediately, except in programs that keep their own copy of the file [2].
Option 1: a hosts-file line
Add the line, as an administrator:
macOS / Linux
echo "10.0.1.23 app-server" | sudo tee -a /etc/hosts
Windows (PowerShell)
# Run PowerShell as Administrator
Add-Content -Path "$env:SystemRoot\System32\drivers\etc\hosts" -Value "10.0.1.23 app-server"
Then check what the resolver now returns for the name. These go through the same lookup programs use, hosts file included [7], [8], [5]:
macOS / Linux
getent hosts app-server # Linux
dscacheutil -q host -a name app-server # macOS
Windows (PowerShell)
Resolve-DnsName app-server
On Linux, a working entry prints the address and the name:
10.0.1.23 app-server
If an old answer seems stuck, clear the resolver’s cache [8], [9], [10]:
macOS / Linux
sudo dscacheutil -flushcache # macOS
resolvectl flush-caches # Linux with systemd-resolved
Windows (PowerShell)
Clear-DnsClientCache
The hosts file only affects the one machine it’s on, and you keep it up to date by hand. When the server’s address changes, the line goes stale and the name quietly points at the wrong place.
Option 2: an SSH config alias
The SSH client reads ~/.ssh/config, or %userprofile%\.ssh\config on Windows [11], [12]. A Host block applies its settings when the name you typed matches the name after Host [11]:
Host app-server
HostName 10.0.1.23
User deploy
IdentityFile ~/.ssh/app-server.pem
IdentitiesOnly yes
app-server is now only a label. HostName is the real address or DNS name SSH connects to, so the hosts file isn’t involved. IdentitiesOnly yes makes SSH offer only the key named here, even when an SSH agent holds others [11]. With the user and key set too, ssh app-server now does what ssh -i ~/.ssh/app-server.pem deploy@10.0.1.23 did.
ssh -G prints the settings SSH would use for a name, after reading every Host block, without connecting [1]. For app-server it shows the block took effect:
ssh -G app-server
user deploy
hostname 10.0.1.23
port 22
identitiesonly yes
identityfile ~/.ssh/app-server.pem
If it shows hostname as the name you typed and user as your own username, no block matched. A typo like ssh -G app-sever looks like that.
An Include line pulls settings in from other files, so a separate file such as ~/.ssh/config_lab only takes effect if the main config names it [11]:
Include ~/.ssh/config_lab
Which one to use
| Hosts file | SSH config | |
|---|---|---|
| Works for | Every program on the machine: browsers, curl, SSH | SSH, and the tools that run over it, like scp and sftp |
| Needs administrator rights | Yes | No, it’s in your home folder |
| Can set the user and key | No | Yes |
| Good for | A name that has to work everywhere, like trying a website on a new server | Logging into servers |
When SSH is the only thing that needs the name, the SSH config is usually the better choice. Both live on one machine only. A name everyone on the network should share belongs in DNS.
When an EC2 instance’s address changes
Both options point at a fixed address, so on a cloud server the address has to stay put, or the name goes stale. On EC2:
| Address | Changes when |
|---|---|
| Public IPv4 | The instance is stopped and started again. It gets a new one each time, unless it has an Elastic IP [13] |
| Private IPv4 | The instance is terminated and replaced. It survives a stop and start [13] |
A private address inside the VPC is usually stable enough for a hosts line or a HostName. If it moves often, use a DNS record in a private zone that every machine on the network shares, or skip addresses and reach the instance by its ID through Session Manager.
Resolving a name doesn’t open the door
After the name resolves, the connection still has to get through the network. A firewall rule that allows port 22 from 10.0.2.0/25 covers only 10.0.2.0 through 10.0.2.127. A laptop at 10.0.3.20 falls outside it, so its connection times out even though the name resolves fine. IP addresses and CIDR explains how to read a range like that.
Troubleshooting in order
Work down the diagram: find the address, reach it, then log in.
-
Does the alias say what you expect?
ssh -G app-server[1]. -
Does the name resolve? Use the resolver checks under Option 1. No answer means the first question is still unsolved.
-
Can you reach the address? Try the port directly. A hang points at routing or a firewall, and “refused” means the machine answered but nothing is listening on that port [14], [15]:
macOS / Linux
nc -vz 10.0.1.23 22Windows (PowerShell)
Test-NetConnection 10.0.1.23 -Port 22 -
Why did login fail?
ssh -v app-serverprints each step, including which keys SSH offered [1]. -
A warning that the host key changed means the server’s key no longer matches the one
known_hostsremembers for that name. SSH warns, and turns off password logins for it, because that’s also what an impostor would look like [1]. If you know the server was rebuilt,ssh-keygen -R app-serverremoves the old key so SSH can learn the new one [16].
References
Show all 16 sourcesHide sources
- [1] ↩ a b c d e f OpenBSD, “ssh(1),” OpenBSD manual pages. Accessed: Oct. 5, 2026. [Online]. Available: https://man.openbsd.org/ssh
- [2] ↩ a b c The Linux man-pages project, “hosts(5),” Linux manual pages. Accessed: Oct. 14, 2026. [Online]. Available: https://man7.org/linux/man-pages/man5/hosts.5.html
- [3] ↩ The Linux man-pages project, “nsswitch.conf(5),” Linux manual pages. Accessed: Oct. 14, 2026. [Online]. Available: https://man7.org/linux/man-pages/man5/nsswitch.conf.5.html
- [4] ↩ Apple, “hosts(5),” macOS manual pages, online copy of the Xcode man pages. Accessed: Oct. 14, 2026. [Online]. Available: https://keith.github.io/xcode-man-pages/hosts.5.html
- [5] ↩ a b Microsoft, “Resolve-DnsName,” Windows PowerShell DnsClient Module Reference. Accessed: Oct. 6, 2026. [Online]. Available: https://learn.microsoft.com/en-us/powershell/module/dnsclient/resolve-dnsname
- [6] ↩ Microsoft, “How to reset the Hosts file back to the default,” Microsoft Support. Accessed: Oct. 14, 2026. [Online]. Available: https://support.microsoft.com/en-us/windows/experience/how-to-reset-the-hosts-file-back-to-the-default
- [7] ↩ The Linux man-pages project, “getent(1),” Linux manual pages. Accessed: Oct. 14, 2026. [Online]. Available: https://man7.org/linux/man-pages/man1/getent.1.html
- [8] ↩ a b Apple, “dscacheutil(1),” macOS manual pages, online copy of the Xcode man pages. Accessed: Oct. 14, 2026. [Online]. Available: https://keith.github.io/xcode-man-pages/dscacheutil.1.html
- [9] ↩ The systemd project, “resolvectl(1),” Linux manual pages. Accessed: Oct. 14, 2026. [Online]. Available: https://man7.org/linux/man-pages/man1/resolvectl.1.html
- [10] ↩ Microsoft, “Clear-DnsClientCache,” Windows PowerShell DnsClient Module Reference. Accessed: Oct. 6, 2026. [Online]. Available: https://learn.microsoft.com/en-us/powershell/module/dnsclient/clear-dnsclientcache
- [11] ↩ a b c d OpenBSD, “ssh_config(5),” OpenBSD manual pages. Accessed: Oct. 14, 2026. [Online]. Available: https://man.openbsd.org/ssh_config
- [12] ↩ Microsoft, “OpenSSH Server configuration for Windows,” Windows Server documentation. Accessed: Oct. 14, 2026. [Online]. Available: https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh-server-configuration
- [13] ↩ a b Amazon Web Services, “Amazon EC2 instance IP addressing,” Amazon EC2 User Guide. Accessed: Oct. 5, 2026. [Online]. Available: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html
- [14] ↩ OpenBSD, “nc(1): arbitrary TCP and UDP connections and listens,” OpenBSD manual pages. Accessed: Oct. 12, 2026. [Online]. Available: https://man.openbsd.org/nc.1
- [15] ↩ Microsoft, “Test-NetConnection,” PowerShell NetTCPIP module reference. Accessed: Oct. 12, 2026. [Online]. Available: https://learn.microsoft.com/en-us/powershell/module/nettcpip/test-netconnection
- [16] ↩ OpenBSD, “ssh-keygen(1),” OpenBSD manual pages. Accessed: Oct. 14, 2026. [Online]. Available: https://man.openbsd.org/ssh-keygen
Every source cited across the primers is collected on one page.