# Nginx and thttpd + cgi, remote\_addr = 127.0.0.1

**URL:** <https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186>\
**Category:** NGINX\
**Created:** [October 25, 2011, 11:11pm UTC](https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186 "2011-10-25T23:11:59Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![dubstep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/cdc98d/32.png) [@dubstep](https://www.ruby-forum.com/u/dubstep)\
**Post date:** [October 25, 2011, 11:11pm UTC](https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186/1 "2011-10-25T23:11:59Z")

</div>

Hello,

i have an issue with getting users’ real IP. I am using nginx as  
frontend with thttpd as backend. I’ve added such options to my default  
server in nginx config:

location ~ .cgi|pl$ {  
proxy\_pass [http://127.0.0.1:8000](http://127.0.0.1:8000);  
include /etc/nginx/proxy.conf;  
}

/etc/nginx/proxy.conf has such options among others:

proxy\_set\_header X-Real-IP $remote\_addr;  
proxy\_set\_header X-Forwarded-For $proxy\_add\_x\_forwarded\_for;

and I have patched latest thttpd  
([http://www.acme.com/software/thttpd/thttpd-2.25b.tar.gz](http://www.acme.com/software/thttpd/thttpd-2.25b.tar.gz)) with this  
patch: [http://wiki.nginx.org/ThttpdRealIP](http://wiki.nginx.org/ThttpdRealIP)  
also i had to rename “getline” to “mygetline” in  
thttpd-2.25b/extras/htpasswd.c because i was getting an error  
“htpasswd.c:52: error: conflicting types for ‘getline’” during  
compilation.

the whole thttpd config is:

host=127.0.0.1  
port=8000  
dir=/var/www/default  
user=www-data  
cgipat= **.cgi|**.pl  
vhost  
charset=utf-8  
logfile=/var/log/thttpd.log  
pidfile=/var/run/thttpd.pid

after installing and starting both webservers I saved this script as  
index.cgi and opened it in browser(i’m using Opera):

#!/bin/sh  
echo “Content-type: text/html; charset=UTF-8”;  
echo;  
echo “i am cgi script  
  
”;  
echo “env:   
  
”;  
env

when I opened it with Opera Turbo enabled (thus using Opera’s proxy  
server), I see output like this:

. .  
GATEWAY\_INTERFACE=CGI/1.1 REMOTE\_ADDR=127.0.0.1  
HTTP\_USER\_AGENT=Opera/9.80 (X11; Linux i686; U; ru) Presto/2.9.168  
Version/11.51 . . .

and when I open it without Opera Turbo (with my real IP), I’m getting my  
real IP in the output (a part was hidden):

. .  
GATEWAY\_INTERFACE=CGI/1.1 REMOTE\_ADDR=178.177._ **.** _  
HTTP\_USER\_AGENT=Opera/9.80 (X11; Linux i686; U; ru) Presto/2.9.168  
Version/11.51 . . .

what could I have done wrong with configuration?

//Jef, sorry for CC, but I don’t know the cause of this issue, and it  
still could be thttpd. though i hope it’s just my hands 🙂

Cheers,

Vladimir

---

<div class="post-metadata">

**Author:** ![SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7ab992/32.png) [@SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/u/SSSSSSS_SS_S_SSS)\
**Post date:** [October 26, 2011, 12:10am UTC](https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186/2 "2011-10-26T00:10:40Z")

</div>

On Wed, Oct 26, 2011 at 01:11:40AM +0400, Кирюшкин Владимир wrote:

Hi there,

> /etc/nginx/proxy.conf has such options among others:
> 
> proxy\_set\_header X-Real-IP $remote\_addr;  
> proxy\_set\_header X-Forwarded-For $proxy\_add\_x\_forwarded\_for;

That should cause two variables HTTP\_X\_REAL\_IP and HTTP\_X\_FORWARDED\_FOR  
to be visible in the CGI output.

> and I have patched latest thttpd  
> ([http://www.acme.com/software/thttpd/thttpd-2.25b.tar.gz](http://www.acme.com/software/thttpd/thttpd-2.25b.tar.gz)) with this patch:  
> [GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/ThttpdRealIP)

That patch looks like it will write the value of the X-Forwarded-For  
header into something internal to thttpd.

> #!/bin/sh  
> echo “Content-type: text/html; charset=UTF-8”;  
> echo;  
> echo “i am cgi script  
>   
> ”;  
> echo “env:   
>   
> ”;  
> env

What are HTTP\_X\_REAL\_IP and HTTP\_X\_FORWARDED\_FOR in the output of this  
cgi script?

If they are not what you expect, check what nginx is doing.

If they are what you expect, check what your patched thttpd is doing.

Good luck with it,

## f

Francis D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7ab992/32.png) [@SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/u/SSSSSSS_SS_S_SSS)\
**Post date:** [October 26, 2011, 12:18am UTC](https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186/3 "2011-10-26T00:18:06Z")

</div>

Hello,

thanks for your answer.

26.10.2011, 02:10, “Francis D.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> On Wed, Oct 26, 2011 at 01:11:40AM +0400, wrote:

> That should cause two variables HTTP\_X\_REAL\_IP and HTTP\_X\_FORWARDED\_FOR  
> to be visible in the CGI output.

alas, no. the full output is (when using proxy):

i am cgi script  
  
  
env:   
  
  
GATEWAY\_INTERFACE=CGI/1.1  
REMOTE\_ADDR=127.0.0.1  
HTTP\_USER\_AGENT=Opera/9.80 (X11; Linux i686; U; ru) Presto/2.9.168  
Version/11.51  
CGI\_PATTERN= **.cgi|**.pl  
HTTP\_ACCEPT=text/html, application/xml;q=0.9, application/xhtml+xml,  
image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, _/_;q=0.1  
HTTP\_HOST=_ **hidden** _  
SERVER\_SOFTWARE=thttpd/2.25b 29dec2003  
PATH=/usr/local/bin:/usr/ucb:/bin:/usr/bin  
HTTP\_ACCEPT\_LANGUAGE=ru, en  
SERVER\_PROTOCOL=HTTP/1.0  
REQUEST\_METHOD=GET  
PWD=/var/www/default  
SERVER\_PORT=8000  
SCRIPT\_NAME=/index.cgi  
SERVER\_NAME=127.0.0.1

> That patch looks like it will write the value of the X-Forwarded-For  
> header into something internal to thttpd.

yes, it is intended to change X-Forwarded-For into Remote-Addr, but  
seems that it doesn’t work.

> What are HTTP\_X\_REAL\_IP and HTTP\_X\_FORWARDED\_FOR in the output of this  
> cgi script?

there are no such vars at all.

> If they are not what you expect, check what nginx is doing.

how could i do that?

Cheers,

Vladimir

---

<div class="post-metadata">

**Author:** ![SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7ab992/32.png) [@SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/u/SSSSSSS_SS_S_SSS)\
**Post date:** [October 26, 2011, 3:03pm UTC](https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186/4 "2011-10-26T15:03:54Z")

</div>

On Wed, Oct 26, 2011 at 02:17:37AM +0400, Кирюшкин Владимир wrote:

> 26.10.2011, 02:10, “Francis D.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > On Wed, Oct 26, 2011 at 01:11:40AM +0400, Кирюшкин Владимир wrote:

Hi there,

> > That should cause two variables HTTP\_X\_REAL\_IP and HTTP\_X\_FORWARDED\_FOR  
> > to be visible in the CGI output.
> 
> alas, no. the full output is (when using proxy):

Ah, this thttpd doesn’t expose the full http header as HTTP\_\*  
environment  
variables. So scratch that as a test.

> > That patch looks like it will write the value of the X-Forwarded-For  
> > header into something internal to thttpd.
> 
> yes, it is intended to change X-Forwarded-For into Remote-Addr, but seems that  
> it doesn’t work.

Test the thttpd side:

curl -H ‘X-Forwarded-For: 127.0.0.2’ http://[thttpd-server]/env.cgi

If you don’t see REMOTE\_ADDR=127.0.0.2, then your thttpd is not acting  
as you expect. Nothing nginx can do can help you in that case.

And note what

curl -H ‘X-Forwarded-For: 127.0.0.2, 127.0.0.3’  
http://[thttpd-server]/env.cgi

shows that is different.

If thttpd directly works (as above) and through nginx doesn’t, then  
check  
the nginx debug log to see what exactly nginx is sending to thttpd –  
it’ll be the line with

http script copy: "X-Forwarded-For: "

and the next line will show the value.

Test using

curl http://[nginx-server]/env.cgi

and possibly

curl -H ‘X-Forwarded-For: 127.0.0.2’ http://[nginx-server]/env.cgi

> > If they are not what you expect, check what nginx is doing.
> 
> how could i do that?

debug log.

Overall, when I test here, it all works as expected, by which I mean:

when I access nginx on 10.0.2.15 which proxy\_pass’es to thttpd on  
127.0.0.1, I see REMOTE\_ADDR=10.0.2.15

when I access nginx on 10.0.2.15 through any other proxy,  
so that X-Forwarded-For is set before it gets to nginx, I see  
REMOTE\_ADDR=127.0.0.1

This patch to thttpd seems to require that X-Forwarded-For contains  
exactly one address, which means that you must not set it in nginx using

proxy\_set\_header X-Forwarded-For $proxy\_add\_x\_forwarded\_for;

You’ll instead want something like

proxy\_set\_header X-Forwarded-For $remote\_addr;

with some careful thought about what to do if X-Forwarded-For was set  
in the request to nginx.

Good luck,

## f

Francis D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7ab992/32.png) [@SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/u/SSSSSSS_SS_S_SSS)\
**Post date:** [October 26, 2011, 4:27pm UTC](https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186/5 "2011-10-26T16:27:19Z")

</div>

On Wed, Oct 26, 2011 at 01:11:40AM +0400, wrote:

> dir=/var/www/default  
> #!/bin/sh
> 
> and when I open it without Opera Turbo (with my real IP), I’m getting my real IP  
> in the output (a part was hidden):
> 
> . .  
> GATEWAY\_INTERFACE=CGI/1.1 REMOTE\_ADDR=178.177._ **.** _ HTTP\_USER\_AGENT=Opera/9.80  
> (X11; Linux i686; U; ru) Presto/2.9.168 Version/11.51 . . .
> 
> what could I have done wrong with configuration?
> 
> //Jef, sorry for CC, but I don’t know the cause of this issue, and it still  
> could be thttpd. though i hope it’s just my hands 🙂

You may want to use mini\_httpd instead of thttpd.  
There is patch to support “X-Real-IP” header in mini\_httpd:

> **[Mailman with nginx and thttpd](http://mailman.nginx.org/pipermail/nginx/2010-October/023292.html)**

–  
Igor S.

---

<div class="post-metadata">

**Author:** ![SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7ab992/32.png) [@SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/u/SSSSSSS_SS_S_SSS)\
**Post date:** [October 26, 2011, 4:34pm UTC](https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186/6 "2011-10-26T16:34:09Z")

</div>

Hello,

26.10.2011, 17:02, “Francis D.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Test the thttpd side:
> 
> curl -H ‘X-Forwarded-For: 127.0.0.2’ http://[thttpd-server]/env.cgi
> 
> If you don’t see REMOTE\_ADDR=127.0.0.2, then your thttpd is not acting  
> as you expect. Nothing nginx can do can help you in that case.

localhost\> curl -H ‘X-Forwarded-For: 127.0.0.2’  
http://_ **myserver** _:8000/index.cgi | grep -i remote  
% Total % Received % Xferd Average Speed Time Time Time  
Current  
Dload Upload Total Spent Left  
Speed  
100 471 0 471 0 0 3007 0 --:–:-- --:–:-- --:–:–  
5962  
REMOTE\_ADDR=_ **myrealip** _

myserver# grep -i x-forward /ramdisk/nginx\_debug.log  
2011/10/26 17:20:08 [debug] 11877#0: \*3 http header: “X-Forwarded-For:  
127.0.0.2”

well, seems that it’s thttpd issue.

26.10.2011, 18:26, “Igor S.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> You may want to use mini\_httpd instead of thttpd.  
> There is patch to support “X-Real-IP” header in mini\_httpd:  
> [Mailman with nginx and thttpd](http://mailman.nginx.org/pipermail/nginx/2010-October/023292.html)

thanks, i’ll follow your advice.

Cheers,

Vladimir

---

<div class="post-metadata">

**Author:** ![SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7ab992/32.png) [@SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/u/SSSSSSS_SS_S_SSS)\
**Post date:** [October 26, 2011, 5:49pm UTC](https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186/7 "2011-10-26T17:49:49Z")

</div>

Hello,

during applying the patch i’ve got these warnings:

# patch mini\_httpd.c -i realip.patch

patching file mini\_httpd.c  
patching file mini\_httpd.c  
Hunk #1 FAILED at 27.  
Hunk #2 FAILED at 163.  
2 out of 2 hunks FAILED – saving rejects to file mini\_httpd.c.rej

so i’ve added failed hunks manually.  
after installing and configuring i’ve checked the output from  
env-script, but REMOTE\_ADDR still was 127.0.0.1.  
also when i’m requesting that script without any additional headers,  
it’s ok, but when i add “X-Real-IP” it looks like mini-httpd just closes  
the connection:

# curl -H ‘X-Real-IP: 127.0.0.2’ [http://127.0.0.1:8000/index.cgi](http://127.0.0.1:8000/index.cgi)

curl: (52) Empty reply from server

then i’ve changed “X-Real-IP” to “X-Forwarded-For” in mini\_httpd.c:

else if ( strncasecmp( line, “X-Forwarded-For:”, 16 ) == 0 )  
{  
if ( strcmp(remote\_addr, xrealip ) == 0 )  
{  
cp = &line[16];  
cp += strspn( cp, " \t" );  
remote\_addr = cp;  
}  
}

and after compiling there is same result:

# curl -H ‘X-Forwarded-For: 127.0.0.2’ [http://127.0.0.1:8000/index.cgi](http://127.0.0.1:8000/index.cgi)

curl: (52) Empty reply from server

with no additional headers script works ok.

Could you please suggest me any other way to run cgi programs with  
nginx, but with getting real IPs from clients, not “127.0.0.1”?  
using apache httpd as backend will be huge performance impact.  
Thanks in advance.

Cheers,

Vladimir

---

<div class="post-metadata">

**Author:** ![SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7ab992/32.png) [@SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/u/SSSSSSS_SS_S_SSS)\
**Post date:** [October 26, 2011, 12:40am UTC](https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186/8 "2011-10-26T00:40:57Z")

</div>

Hi,

On 26.10.2011 00:17, Кирюшкин Владимир wrote:

> Hello,
> 
> thanks for your answer.
> 
> 26.10.2011, 02:10, “Francis D.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

[snipp]

> > If they are not what you expect, check what nginx is doing.
> 
> how could i do that?

> **[A debugging log](http://nginx.org/en/docs/debugging_log.html)**

Aleks

---

<div class="post-metadata">

**Author:** ![SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7ab992/32.png) [@SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/u/SSSSSSS_SS_S_SSS)\
**Post date:** [October 26, 2011, 10:38pm UTC](https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186/9 "2011-10-26T22:38:09Z")

</div>

Hello,

26.10.2011, 19:50, “Aleksandar L.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> [http://nginx.localdomain.pl/wiki/FcgiWrap](http://nginx.localdomain.pl/wiki/FcgiWrap)

installed fcgiwrap, now everything works flawlessly. Thanks for your  
advice.

Cheers,

Vladimir

---

<div class="post-metadata">

**Author:** ![SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7ab992/32.png) [@SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/u/SSSSSSS_SS_S_SSS)\
**Post date:** [October 26, 2011, 11:03pm UTC](https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186/10 "2011-10-26T23:03:27Z")

</div>

On 26.10.2011 22:37, Кирюшкин Владимир wrote:

> Hello,
> 
> 26.10.2011, 19:50, “Aleksandar L.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > [http://nginx.localdomain.pl/wiki/FcgiWrap](http://nginx.localdomain.pl/wiki/FcgiWrap)
> 
> installed fcgiwrap, now everything works flawlessly. Thanks for your  
> advice.

your welcome.

---

<div class="post-metadata">

**Author:** ![SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7ab992/32.png) [@SSSSSSS\_SS\_S\_SSS](https://www.ruby-forum.com/u/SSSSSSS_SS_S_SSS)\
**Post date:** [October 26, 2011, 5:51pm UTC](https://www.ruby-forum.com/t/nginx-and-thttpd-cgi-remote-addr-127-0-0-1/213186/11 "2011-10-26T17:51:41Z")

</div>

On 25.10.2011 23:11, Кирюшкин Владимир wrote:

> ```
> include /etc/nginx/proxy.conf;
> 
> ```
> 
> }

Maybe you will need another cgi executer 😉

[http://nginx.localdomain.pl/wiki/FcgiWrap](http://nginx.localdomain.pl/wiki/FcgiWrap)  
or

> **[Exploring Hiawatha: A Connected Traveler’s Guide for the Modern Explorer](https://hiawatha-webserver.org/)**

Cheers  
Aleks
