Project

General

Profile

Bug #2826

stale REMOTE_ADDR when using AF_UNIX socket

Added by davidm over 1 year ago. Updated over 1 year ago.

Status:
Fixed
Priority:
Normal
Assignee:
-
Category:
core
Target version:
Start date:
2017-10-07
Due date:
% Done:

100%

Estimated time:
Missing in 1.5.x:

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?

lighttpd-remote-addr.diff (621 Bytes) lighttpd-remote-addr.diff davidm, 2017-10-07 16:07
lighttpd-remote-addr-2.diff (401 Bytes) lighttpd-remote-addr-2.diff davidm, 2017-10-07 16:26

Associated revisions

Revision 878dd9be (diff)
Added by gstrauss over 1 year ago

[core] use sun_path for addr string for AF_UNIX (fixes #2826)

(occurs when lighttpd is configured to listen on unix socket path)

x-ref:
"stale REMOTE_ADDR when using AF_UNIX socket"
https://redmine.lighttpd.net/issues/2826

History

#1

Updated by davidm over 1 year 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?

#2

Updated by gstrauss over 1 year 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.

#3

Updated by gstrauss over 1 year 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
 }
#4

Updated by davidm over 1 year 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.

#5

Updated by gstrauss over 1 year 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.

#6

Updated by gstrauss over 1 year 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.

#7

Updated by davidm over 1 year 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!

#8

Updated by gstrauss over 1 year ago

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

Updated by gstrauss over 1 year ago

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

Also available in: Atom