
Running a VPS means managing network configuration. Here's what every VPS owner needs to know about DNS, ports, and IP addresses. The examples use 203.0.113.10, 198.51.100.7 and 2001:db8::10, which are reserved for documentation, and the domain example.com: replace them with your own.
IP Addresses
IPv4 vs IPv6
| Feature | IPv4 | IPv6 |
|---|---|---|
| Address size | 32 bits, about 4.3 billion addresses | 128 bits |
| Written as | Four decimal numbers: 203.0.113.10 | Eight groups of hexadecimal in lowercase, with one run of zero groups shortened to ::: 2001:db8::10 |
| Free addresses | Scarce: IANA's free pool ran out on 3 February 2011, and RIPE NCC, the registry for Europe, ran out on 25 November 2019 | Plenty: one standard /64 subnet alone holds 2^64 addresses |
| NAT | Common: devices with private addresses (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) share one public address | Not needed to save addresses, and the IETF does not recommend it; the NPTv6 prefix translation of RFC 6296 is experimental |
| DNS record | A | AAAA |
Your provider decides which of these your VPS gets, so check with the commands below. Having both doesn't mean your software uses both: our IPv4 vs IPv6 guide shows how to check what listens on each address and when to add an AAAA record.
Check Your IPs
# Public IPv4 address, as the internet sees it
curl -4 ifconfig.me
# Public IPv6 address (fails if the VPS has no working IPv6)
curl -6 ifconfig.me
# All addresses on all network interfaces
ip addr show
-4 and -6 make curl use only IPv4 or only IPv6 addresses, and ip addr show lists the IPv4 and IPv6 addresses on every interface.
DNS Management
Record Types
| Record | Purpose | Example |
|---|---|---|
| A | Points a name to an IPv4 address | example.com A 203.0.113.10 |
| AAAA | Points a name to an IPv6 address | example.com AAAA 2001:db8::10 |
| CNAME | Makes a name an alias of another name | www CNAME example.com |
| MX | Mail server for the domain, with a preference (lower wins) | example.com MX 10 mail.example.com |
| TXT | Text data (SPF, DKIM, verification) | v=spf1 mx -all |
| NS | Nameservers for the zone | example.com NS ns1.example.net |
| SRV | Host and port of a service | _service._tcp.example.com SRV priority weight port target |
A CNAME can't share its name with other records, and the bare domain always carries the zone's NS and SOA records, so point example.com itself with A and AAAA records and use the CNAME for www. For a worked SRV example, see our guide to putting a Minecraft server on your own domain.
Setting Up DNS for Your VPS
- Buy a domain from a registrar
- At your DNS host, point the domain's A record (and AAAA, if your VPS has IPv6) to your VPS
- Check the answers with dig (below)
example.com A 203.0.113.10
www.example.com CNAME example.com
How Long DNS Changes Take
There is no fixed "propagation" time. A new record works as soon as your DNS host publishes it. A resolver that already looked the name up keeps its cached answer until the record's TTL (time to live, in seconds) runs out, so a changed record can take as long as its old TTL to reach everyone. If someone looked the name up before the record existed, resolvers can also cache that "no such name" answer, for as long as the zone's SOA record allows. Before a planned move, lower the TTL, wait for the old TTL to pass, and then change the address.
Changing nameservers at your registrar can take longer, because resolvers also cache the delegation from the top-level domain. dig +trace shows each step.
Verify DNS
# A record, short answer
dig example.com A +short
# One type at a time
dig example.com AAAA +short
dig example.com MX +short
dig example.com TXT +short
# Full answer line; the number after the name is the TTL in seconds
dig example.com A +noall +answer
# What two public resolvers have cached
dig @8.8.8.8 example.com A +short
dig @1.1.1.1 example.com A +short
# Follow the delegation from the root servers down
dig example.com +trace
Skip dig example.com ANY: RFC 8482 lets DNS servers answer an ANY query with a single record set instead of everything, so it doesn't show all your records. 8.8.8.8 is Google Public DNS and 1.1.1.1 is Cloudflare's resolver; if they disagree with your DNS host, wait for the TTL to run out.
Port Management
Common Ports
| Port | Service | Protocol |
|---|---|---|
| 22 | SSH | TCP |
| 25 | SMTP (mail transfer) | TCP |
| 80 | HTTP | TCP |
| 443 | HTTPS | TCP, plus UDP for HTTP/3 |
| 587 | Mail submission | TCP |
| 3306 | MySQL | TCP |
| 5432 | PostgreSQL | TCP |
| 6379 | Redis | TCP |
| 8080 | HTTP alternate | TCP |
Firewall Rules
# See current rules
sudo ufw status verbose
# Before enabling UFW, allow SSH so the firewall doesn't cut your session
sudo ufw allow 22/tcp
sudo ufw enable
# Allow a port
sudo ufw allow 3000/tcp
# Allow one IP address only
sudo ufw allow from 198.51.100.7 to any port 3306 proto tcp
# Deny a port
sudo ufw deny 8080/tcp
# Delete a rule
sudo ufw delete allow 3000/tcp
If you run services in Docker, UFW does not cover the ports you publish with -p: Docker's documentation says traffic to a published container port "gets diverted before it goes through the ufw firewall settings". Publish a database port on the loopback address only, for example -p 127.0.0.1:5432:5432, or don't publish it at all. Keep Docker current as well: the same documentation warns that in releases older than 28.0.0, hosts on the same network segment can reach ports published to localhost.
Only Expose What's Needed
| Service | Should Be Public? | Firewall Rule |
|---|---|---|
| Web server (80, 443) | Yes | Allow from anywhere |
| SSH | Yes (restricted) | Allow from your IP or all |
| Database | No | No rule: listen on localhost only |
| Redis | No | No rule: listen on localhost only |
| Admin panels | No | Allow from your IP only |
Binding to Localhost
On Debian 12 and Ubuntu 24.04, the packaged MariaDB and Redis (and MySQL 8.0 on Ubuntu) already listen only on the loopback address. Check that nobody changed these lines:
# MariaDB: /etc/mysql/mariadb.conf.d/50-server.cnf
bind-address = 127.0.0.1
# MySQL 8.0 on Ubuntu: /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 127.0.0.1
# Redis: /etc/redis/redis.conf (with the "-", Redis still starts when ::1 is not available)
bind 127.0.0.1 -::1
protected-mode yes
PostgreSQL's listen_addresses defaults to localhost. On Debian and Ubuntu it lives in /etc/postgresql/<version>/<cluster>/postgresql.conf.
Reverse DNS (rDNS)
Reverse DNS maps an IP address back to a name with a PTR record. It matters most for email: Google's sender guidelines tell every sender to make sure their sending domains or IPs "have valid forward and reverse DNS records, also referred to as PTR records". Point the PTR record of your sending IP to a name such as mail.example.com, and give that name an A record that points back to the same IP.
The reverse zone follows the IP address space, not your domain, so you set the PTR record through your VPS provider, in its control panel or through support. Check it with:
dig -x 203.0.113.10 +short
HTTPS with Let's Encrypt
On Debian 12 and Ubuntu 24.04 the web server plugins are separate packages:
# For Nginx
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
# For Apache
sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d example.com -d www.example.com
The certbot package installs a systemd timer, certbot.timer, that runs certbot renew twice a day, and renew only replaces certificates that are near expiry. See the timer with systemctl list-timers and test renewal with sudo certbot renew --dry-run, which uses Let's Encrypt's staging server.
Network Performance
| Test | Command |
|---|---|
| Latency and loss | ping -c 10 google.com |
| Route, hop by hop | mtr -rwc 10 google.com (package mtr-tiny) |
| DNS resolution speed | dig google.com | grep "Query time" |
| Throughput | iperf3 between two machines you control |
Our guide to testing VPS network speed and latency shows how to read these results and run iperf3 in both directions.
Space-Node's VPS plans run in an EU data center with a 1 Gbps port, DDoS protection, and IPv4 and IPv6.
Sources
All opened on 31 October 2026:
- IETF: RFC 791 (IPv4), RFC 8200 (IPv6), RFC 4291 and RFC 5952 (IPv6 addresses and how to write them), RFC 5737 and RFC 3849 (documentation addresses), RFC 1918 (private IPv4), RFC 3022 (NAT), RFC 6296 (NPTv6), RFC 4864 (IPv6 without NAT)
- Address registries: NRO, Free Pool of IPv4 Address Space Depleted, and RIPE NCC, The RIPE NCC has run out of IPv4 Addresses
- DNS: RFC 1034, RFC 1035, RFC 2308 (negative caching), RFC 3596 (AAAA), RFC 2782 (SRV), RFC 7208 (SPF), RFC 8482 (ANY queries), dig(1), Debian 12, Google Public DNS, Cloudflare 1.1.1.1
- Ports: IANA Service Name and Transport Protocol Port Number Registry, RFC 9114 (HTTP/3)
- Tools: curl manual, ip-address(8), ufw(8), Ubuntu 24.04, mtr(8), Debian 12, mtr-tiny on Ubuntu 24.04, iperf3(1), Ubuntu 24.04
- Docker: Packet filtering and firewalls, Port publishing
- Database defaults: MariaDB 50-server.cnf in Debian 12 and Ubuntu 24.04, MySQL 8.0 mysqld.cnf in Ubuntu 24.04, redis.conf in Debian 12 and Ubuntu 24.04, PostgreSQL connection settings, pg_createcluster(1)
- Email: Google email sender guidelines
- Certbot: User Guide, Debian 12 package files certbot.timer and certbot.service, plugin packages for Debian 12 and Ubuntu 24.04