When using Nginx as a reverse proxy with multiple backend services, we often need precise control over which source IP address Nginx uses when connecting to upstream servers. This becomes critical when:
- Backend servers have IP-based whitelisting
- Multiple services run on the same host with different IP requirements
- Network policies require traffic to originate from specific IPs
The proxy_bind
directive in Nginx allows you to specify exactly which local IP address should be used for outgoing connections to backend servers. Here's how to implement it:
location /integracao/ {
proxy_bind A.A.A.A;
proxy_pass http://X.X.X.X:9080/integracao/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /solr/ {
proxy_bind B.B.B.B;
proxy_pass http://Y.Y.Y.Y:8080/solr/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Here's a full server block example demonstrating proper implementation:
server {
listen 80;
server_name example.com;
# First backend service using IP A
location /service1/ {
proxy_bind 192.168.1.100;
proxy_pass http://backend1:8080/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
# Second backend service using IP B
location /service2/ {
proxy_bind 192.168.1.101;
proxy_pass http://backend2:9080/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
For more complex setups, you might need additional configuration:
# Using variables for dynamic IP selection
map $host $bind_ip {
hostnames;
default 192.168.1.100;
service1.example.com 192.168.1.100;
service2.example.com 192.168.1.101;
}
server {
listen 80;
server_name ~^(www\.)?(?.+)$;
location / {
proxy_bind $bind_ip;
proxy_pass http://backend/$domain;
}
}
- Verify IP binding with
tcpdump -i any host backend_ip
- Check Nginx error logs for binding failures
- Ensure the IP addresses are properly configured on the server
- Test connectivity separately with
curl --interface
before Nginx configuration
When using multiple IP addresses:
- Connection pooling is per IP-port combination
- Monitor kernel connection tracking table size
- Consider using
proxy_connect_timeout
andproxy_next_upstream
for resilience
When working with Nginx as a reverse proxy, we often need to control which source IP address gets used when connecting to backend servers. This becomes critical when:
- Backend servers have IP-based access restrictions
- Multiple services require different source IPs for identification
- Network policies enforce specific routing paths
The most straightforward solution is Nginx's proxy_bind
directive. Here's how to implement it:
server {
listen 80;
server_name example.com;
location /integracao/ {
proxy_bind A.A.A.A; # Replace with your actual IP
proxy_pass http://X.X.X.X:9080/integracao/;
# Standard proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /solr/ {
proxy_bind B.B.B.B; # Replace with your actual IP
proxy_pass http://Y.Y.Y.Y:8080/solr/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
After implementing, verify the source IP with these methods:
# Method 1: Check Tomcat access logs
tail -f /path/to/tomcat/logs/access.log
# Method 2: Use tcpdump on backend server
sudo tcpdump -i eth0 'port 9080 or port 8080' -nn -v
For more complex setups with upstream blocks:
upstream tomcat_integracao {
server X.X.X.X:9080;
}
upstream solr_server {
server Y.Y.Y.Y:8080;
}
server {
location /integracao/ {
proxy_bind A.A.A.A;
proxy_pass http://tomcat_integracao;
}
location /solr/ {
proxy_bind B.B.B.B;
proxy_pass http://solr_server;
}
}
- Ensure the IP addresses are properly assigned to your server's network interfaces
- Check firewall rules to confirm outbound connections are allowed from these IPs
- Verify that the backend servers are configured to accept connections from these specific IPs
- Test connectivity manually using
curl --interface
before Nginx configuration
For systems where proxy_bind
isn't available (older Nginx versions), consider using iptables:
# Mark packets for specific backend routing
iptables -t mangle -A OUTPUT -p tcp --dport 9080 -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -p tcp --dport 8080 -j MARK --set-mark 2
# Create routing tables for each marked connection
echo "100 integracao" >> /etc/iproute2/rt_tables
echo "200 solr" >> /etc/iproute2/rt_tables
# Add routing rules
ip rule add fwmark 1 table integracao
ip rule add fwmark 2 table solr
# Configure source IPs for each table
ip route add default via A.A.A.A dev eth0 table integracao
ip route add default via B.B.B.B dev eth0 table solr