1

I want to configure nginx so that it parses the http headers and add new parsed strings to access logs. Here is the specific scenario I need:

There is X-Forwarded-For header in incoming requests which contains multiple IP (clients' IP + some proxy server IPs).

X-Forwarded-For = "1.2.3.4, 5.6.7.8"

Here is log_format configuration in my nginx:

log_format  main  '{"timestamp":"$time_iso8601",'
                        '"clientIp":"$http_x_forwarded_for",'
                        '"conSerial":"$connection",'
                        '"agent":"$http_user_agent"}';

What I want here is parse X-Forwarded-For header and extract proxy server's IP and add it in log format with a sepearate tag like this :

log_format  main  '{"timestamp":"$time_iso8601",'
                            '"clientIp":"$http_x_forwarded_for",'
                            '"proxy": "5.6.7.8",'
                            '"conSerial":"$connection",'
                            '"agent":"$http_user_agent"}';

Note that 1.2.3.4 is clients real ip and 5.6.7.8 is proxy server's ip.

Thanks in advance, any help is appreciated.

1
  • Why not just log whole header? Commented Jun 9, 2016 at 9:29

1 Answer 1

2

The map directive can construct the variables you need by using a named capture. For example:

map $http_x_forwarded_for $proxy_label {
    default               "";
    "~, (?<proxy_ip>.*)$" "proxy";
}

log_format  main  '{"timestamp":"$time_iso8601",'
    '"clientIp":"$http_x_forwarded_for",'
    '"$proxy_label":"$proxy_ip",'
    '"conSerial":"$connection",'
    '"agent":"$http_user_agent"}';

You could do something clever with $proxy_label when there is no match, or not.

See this document for details.

EDIT: To match the last IP address on the line, you could capture only . and the digits like this...

"~(?<proxy_ip>[0-9.]+)$" "proxy";

See this useful resource for regular expressions.

Sign up to request clarification or add additional context in comments.

2 Comments

Hi @Richard, I need some special form of above regular expression; in case of multiple ip addresses in X-Forwarded-For header, the above regex return all list except first ip address. How can I just retrieve last ip in X-Forwareded-For header? (e.g. X-Forwarded-For = 1.1.1.1, 2.2.2.2, 3.3.3.3 and I need just "3.3.3.3" to be returned) Thanks in advance.
I have added an alternative regular expression.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.