How to Bind Services to a Specific IP Address on a Multi-IP Server
Level: Intermediate
Estimated time: ~25 minutes
Goal: Configure SSH, Nginx, Apache, and MySQL/MariaDB to listen only on a specific IP address instead of all interfaces on a server with multiple IPs.
Introduction
When a server has multiple IP addresses, every service listens on all of them by default. This is rarely what you want: a database should not be reachable on a public IP, and a web server for one client should not respond on another client's address. Proper multi IP server configuration ensures that each Network Interface handles the correct traffic. IP Binding gives you tighter control over access, helps manage inbound traffic routing, and reduces your attack surface. In this tutorial, we will explain how to bind service to IP address for several common services — SSH, Nginx, Apache, MySQL/MariaDB — and optimize your listen address configuration to listen on a chosen IP only.
Prerequisites
Before you begin, make sure the following conditions are met:
- Operating system: Ubuntu 20.04/22.04/24.04 LTS, Debian 11/12, or CentOS/RHEL 8/9 (If you need to configure service binding on Ubuntu, the steps are nearly identical across versions)
- Access: sudo or root access to the server
- Network: at least two IP addresses configured on the server (verify in Step 1)
- Required knowledge: confident use of the Linux command line and basic text editing
Step 1: Identify Your IP Addresses
Check which IP addresses are assigned to the server:
ip -4 addr show
Expected output (example):
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ... inet 203.0.113.10/24 brd 203.0.113.255 scope global eth0 inet 198.51.100.5/24 brd 198.51.100.255 scope global eth0:1
Throughout this tutorial we will use 203.0.113.10 as the public IP and 198.51.100.5 as the secondary IP. Replace them with your actual addresses.
If you see only one address, your server does not have multiple IPs configured yet. Contact your provider or add an address manually before proceeding.
Step 2: Bind SSH to a Specific IP
By default, SSH listens on 0.0.0.0 (all interfaces). To restrict it to one IP and achieve Linux service binding:
Back up the config:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
Open the SSH configuration file:
sudo nano /etc/ssh/sshd_config
Find the ListenAddress directive and set the Listen Address to configure listening IP address:
ListenAddress 203.0.113.10
If ListenAddress is commented out or absent, add the line anywhere in the file.
Validate the configuration:
sudo sshd -t
If no output is returned, the configuration is valid.
Before restarting SSH, make sure the IP you specified is correct and reachable. If you bind SSH to a wrong IP, you will lock yourself out. Keep a second SSH session open as a safety net, or use the provider's console access.
Restart the service:
sudo systemctl restart sshd
On some systems, the service may be named ssh instead of sshd.
Verify that SSH now listens only on the specified IP:
ss -tlnp | grep sshd
Expected output:
LISTEN 0 128 203.0.113.10:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3))
If you see 0.0.0.0:22 — the change did not take effect. Check the config for typos or conflicting ListenAddress lines.
Step 3: Bind Nginx to a Specific IP
The listen directive controls which IP and port Nginx uses. To bind application to IP, you must configure NGINX listen directive.
Back up the config:
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.backup
Open your site config:
sudo nano /etc/nginx/sites-available/default
On CentOS/RHEL the default config path is /etc/nginx/conf.d/default.conf. The syntax is the same.
Change the Listen Directive (listen) from:
listen 80; listen [::]:80;
To:
listen 203.0.113.10:80;
If you also use HTTPS:
listen 203.0.113.10:443 ssl;
Test the configuration and reload:
sudo nginx -t sudo systemctl reload nginx
Verify:
ss -tlnp | grep nginx
Expected output:
LISTEN 0 511 203.0.113.10:80 0.0.0.0:* users:(("nginx",pid=5678,fd=6))
Step 4: Bind Apache to a Specific IP
Apache uses the Listen directive in its main config.
Debian/Ubuntu:
sudo cp /etc/apache2/ports.conf /etc/apache2/ports.conf.backup sudo nano /etc/apache2/ports.conf
CentOS/RHEL:
sudo cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.backup sudo nano /etc/httpd/conf/httpd.conf
Change:
Listen 80
To:
Listen 203.0.113.10:80
For HTTPS:
Listen 203.0.113.10:443
Also update any <VirtualHost *:80> blocks to use the IP:
<VirtualHost 203.0.113.10:80>
Test and reload:
Debian/Ubuntu:
sudo apachectl configtest sudo systemctl reload apache2
CentOS/RHEL:
sudo apachectl configtest sudo systemctl reload httpd
Verify:
ss -tlnp | grep -E 'apache|httpd'
Step 5: Bind MySQL/MariaDB to a Specific IP
By default, MySQL/MariaDB listens on 127.0.0.1 (localhost only). If you need it reachable on a specific internal IP, change the bind-address to bind application to local IP.
Debian/Ubuntu (MySQL 8.x / MariaDB 10.x):
sudo cp /etc/mysql/mysql.conf.d/mysqld.cnf /etc/mysql/mysql.conf.d/mysqld.cnf.backup sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
CentOS/RHEL (MariaDB):
sudo cp /etc/my.cnf.d/mariadb-server.cnf /etc/my.cnf.d/mariadb-server.cnf.backup sudo nano /etc/my.cnf.d/mariadb-server.cnf
The exact config file path varies. If the file above does not exist, look for the [mysqld] section in /etc/my.cnf or /etc/mysql/my.cnf.
Find the bind-address line and change it:
bind-address = 198.51.100.5
Restart the service:
sudo systemctl restart mysql # or mysqld / mariadb
Verify:
ss -tlnp | grep 3306
Expected output:
LISTEN 0 80 198.51.100.5:3306 0.0.0.0:* users:(("mysqld",pid=9012,fd=22))
If you change bind-address from 127.0.0.1 to a routable IP, make sure you have a firewall rule allowing connections only from trusted sources. Never expose a database port to the public internet without protection.
Verification
After configuring all services, run a summary check:
ss -tlnp
Confirm that each service shows the IP you intended — not 0.0.0.0 or *.
ssh [email protected] # should work ssh [email protected] # should be refused if SSH is bound to the other IP
Rollback
To revert any change, restore the backed-up config and restart the service.
For SSH:
sudo cp /etc/ssh/sshd_config.backup /etc/ssh/sshd_config sudo systemctl restart sshd
For any other service — undo the listen / bind-address change in the respective config file and restart. The original value is almost always 0.0.0.0, *, or 127.0.0.1.
Conclusion
That is all. Each service can be restricted by changing a single directive, restarting, and verifying with ss -tlnp.
Document Version: 1.0
Last Updated: April 2026
Owner: Technical Documentation Team