Project

General

Profile

Actions

Bug #2826

closed

stale REMOTE_ADDR when using AF_UNIX socket

Added by davidm over 6 years ago. Updated over 6 years ago.

Status:
Fixed
Priority:
Normal
Category:
core
Target version:
ASK QUESTIONS IN Forums:

Description

It appears lighttpd v1.4.45 returns a bogus (stale) IP address for CGI requests received via an AF_UNIX socket. From what I can tell, REMOTE_ADDR gets set to the value last used with a non-AF_UNIX socket.

The attached patch fixes the problem by setting REMOTE_ADDR to an empty string for the AF_UNIX case. However, I don't think it's the proper way to solve it. I see inet_ntop_cache.c has changed quite a bit since v1.4.45 and it now handles AF_UNIX for more cases but it looks to me like inet_ntop_cache_get_ip() still has the same issue. Perhaps it should be updated to return sun_path for the AF_UNIX case?


Files

Actions #1

Updated by davidm over 6 years ago

Perhaps this is a better fix. According to RFC3875:

The REMOTE_ADDR variable MUST be set to the network address of the client sending the request to the server.

It then defines the syntax of the REMOTE_ADDR value as being either an IPv4 or IPv6 address.

Returning the loopback address may be the best we can do here?

Actions #2

Updated by gstrauss over 6 years ago

Do you think this is still an issue in lighttpd git master? CGI gets REMOTE_ADDR from con->dst_addr_buf, which will be "" for AF_UNIX with current behavior of inet_ntop_cache_get_ip(). Maybe sun_path should be returned for AF_UNIX (as you first suggested), since con->dst_addr_buf is used in many places, not just for the CGI environment. (As an aside, there is a bug if the OS is so old that inet_ntop() is not available to lighttpd.)

Regarding the language in RFC3875, if you are using lighttpd with AF_UNIX sockets, and you need a valid REMOTE_ADDR, you are probably proxying, and so you can use mod_extforward to have lighttpd update con->dst_addr_buf to the actual remote address, leading to an IP address in REMOTE_ADDR for your CGI.

Actions #3

Updated by gstrauss over 6 years ago

--- a/src/inet_ntop_cache.c
+++ b/src/inet_ntop_cache.c
@@ -474,6 +474,9 @@ const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr) {

        int i;
        UNUSED(srv);
+      #ifdef HAVE_SYS_UN_H
+       if (addr->plain.sa_family == AF_UNIX) return addr->un.sun_path;
+      #endif
        for (i = 0; i < INET_NTOP_CACHE_MAX; i++) {
                if (inet_ntop_cache[i].family == addr->plain.sa_family) {
                        if (inet_ntop_cache[i].family == AF_INET6 &&
@@ -515,6 +518,9 @@ const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr) {
        return inet_ntop_cache[i].b2;
 #else
        UNUSED(srv);
+      #ifdef HAVE_SYS_UN_H
+       if (addr->plain.sa_family == AF_UNIX) return addr->un.sun_path;
+      #endif
        return inet_ntoa(addr->ipv4.sin_addr);
 #endif
 }
Actions #4

Updated by davidm over 6 years ago

gstrauss wrote:

Do you think this is still an issue in lighttpd git master? CGI gets REMOTE_ADDR from con->dst_addr_buf, which will be "" for AF_UNIX with current behavior of inet_ntop_cache_get_ip().

That would work fine for our purposes. We just need a way to identify a request that was forwarded from our proxy.

Maybe sun_path should be returned for AF_UNIX (as you first suggested), since con->dst_addr_buf is used in many places, not just for the CGI environment.

I tried that but sun_path doesn't (usually) have a valid path so you get garbage there.

Regarding the language in RFC3875, if you are using lighttpd with AF_UNIX sockets, and you need a valid REMOTE_ADDR, you are probably proxying, and so you can use mod_extforward to have lighttpd update con->dst_addr_buf to the actual remote address, leading to an IP address in REMOTE_ADDR for your CGI.

In our case, we just need to know whether the request come from our proxy (running on the same machine) or directly via LAN/WAN. We don't care about the IP address of where the request originated.

Actions #5

Updated by gstrauss over 6 years ago

I tried that but sun_path doesn't (usually) have a valid path so you get garbage there.

What operating system? With the patch above, con->dst_addr_buf should contain the value obtained from the (sockaddr *) filled in by accept() or accept4() or paccept(), as long as you're testing with lighttpd git master.

Actions #6

Updated by gstrauss over 6 years ago

In our case, we just need to know whether the request come from our proxy (running on the same machine) or directly via LAN/WAN. We don't care about the IP address of where the request originated.

For this specific need, you can use mod_setenv to set an environment variable of your choosing within the $SERVER["socket"] condition in your lighttpd config.

Actions #7

Updated by davidm over 6 years ago

gstrauss wrote:

In our case, we just need to know whether the request come from our proxy (running on the same machine) or directly via LAN/WAN. We don't care about the IP address of where the request originated.

For this specific need, you can use mod_setenv to set an environment variable of your choosing within the $SERVER["socket"] condition in your lighttpd config.

Oh, I wasn't aware of that possibility. It seems to work great and is probably a more reliably solution as well. Thanks for the suggestion!

Actions #8

Updated by gstrauss over 6 years ago

  • Status changed from New to Patch Pending
  • Target version changed from 1.4.x to 1.4.46
Actions #9

Updated by gstrauss over 6 years ago

  • Status changed from Patch Pending to Fixed
  • % Done changed from 0 to 100
Actions

Also available in: Atom