Kosmylo
Kosmylo

Reputation: 428

How to set remote_addr to the real client IP?

I have the following nginx.conf and in the access.log I am getting the same IP for every request in remote_addr, which is the IP of my VM.

events{}
# See blow link for Creating NGINX Plus and NGINX Configuration Files 
# https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/
http {

    include /etc/nginx/mime.types;
    default_type  application/octet-stream;

    # The identifier Backend is internal to nginx, and used to name this specific upstream
    upstream backend {
    # BACKEND_HOST is the internal DNS name used by the Backend Service inside the Kubernetes cluster 
    # or in the services list of the docker-compose. 
    server ${BACKEND_HOST}:${BACKEND_PORT};
    }

    server {
        listen ${NODE_PORT};
        root /usr/share/nginx/html;
        index index.html;

        location / {
        try_files $uri $uri/ /index.html;
        }

        location /api/ {
        resolver 127.0.0.11; 
        #nginx will not crash if host is not found    
        # The following statement will proxy traffic to the upstream
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

}

However, I need to have in the remote_addr field be the initial client IP. I know that I can use the variable realip_remote_addr, but I wanted to ask if there is any configuration that changes the remote_addr. Is this somehow possible?

As I search more about it I think that it is important to mention that I use docker-compose to run nginx as part of a frontend service. Maybe this is related to the network of Docker.

Upvotes: 3

Views: 15247

Answers (3)

SilentEntity
SilentEntity

Reputation: 354

We have to understand the importance of the field remote_addr, it tell the application server where to respond back, if you overwrite this value than the server won't pass the response to the network interface it came from. So for this use case you want to log real client IP , please refer to the below snippet, it might help:

events{}
# See blow link for Creating NGINX Plus and NGINX Configuration Files 
# https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/
log_format  logs_requested  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$request_time" "$upstream_response_time" "$pipe" "$http_x_forwarded_for"';

http {

    include /etc/nginx/mime.types;
    default_type  application/octet-stream;

    # The identifier Backend is internal to nginx, and used to name this specific upstream
    upstream backend {
    # BACKEND_HOST is the internal DNS name used by the Backend Service inside the Kubernetes cluster 
    # or in the services list of the docker-compose. 
    server ${BACKEND_HOST}:${BACKEND_PORT};
    }

    server {
        listen ${NODE_PORT};
        access_log  /var/log/nginx/access_logs.log  logs_requested;
        root /usr/share/nginx/html;
        index index.html;

        location / {
        try_files $uri $uri/ /index.html;
        }

        location /api/ {
        resolver 127.0.0.11; 
        #nginx will not crash if host is not found    
        # The following statement will proxy traffic to the upstream
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

}

In above snippet logs_requested is the log_format that is defined according to one's requirement. Client IP information can be see in http_x_forwarded_for variable, and access_log /var/log/nginx/access_logs.log logs_requested line is included in server block to log the request in this logs_requested format.

Upvotes: 1

Adrian
Adrian

Reputation: 41

Check the Nginx documentation on setting up your access log desired format https://docs.nginx.com/nginx/admin-guide/monitoring/logging/#access_log

Some more info: https://docs.splunk.com/Documentation/AddOns/released/NGINX/Setupv2

Upvotes: 0

tom
tom

Reputation: 10581

Usually it is enough to add these two fields to the request header:

proxy_set_header x-real-ip $remote_addr;
proxy_set_header X-forwarded-for $proxy_add_x_forwarded_for;

See the documentation at proxy_set_header for more details.

In your case:

server {
    listen ${NODE_PORT};
    root /usr/share/nginx/html;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        resolver 127.0.0.11; 
        #nginx will not crash if host is not found    
        # The following statement will proxy traffic to the upstream
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header x-real-ip $remote_addr;
        proxy_set_header X-forwarded-for $proxy_add_x_forwarded_for;
    }
}

Upvotes: 2

Related Questions