server_name and listen behaviour

Igor Sysoev igor at sysoev.ru
Wed Feb 13 05:18:36 UTC 2013


On Feb 13, 2013, at 9:06 , ivan babrou wrote:

> On 13 February 2013 08:57, Igor Sysoev <igor at sysoev.ru> wrote:
> On Feb 13, 2013, at 8:49 , ivan babrou wrote:
> 
>> On 12 February 2013 23:06, Igor Sysoev <igor at sysoev.ru> wrote:
>> On Feb 12, 2013, at 21:10 , ivan babrou wrote:
>> 
>> > Hi, I have a question. It's better to describe with example
>> >
>> > I point one.local and two.local to 127.0.0.1 and create following servers in config for nginx:
>> >
>> > server {
>> >   listen 80;
>> >   server_name one.local;
>> >
>> >   location / {
>> >     return 404;
>> >   }
>> > }
>> >
>> > server {
>> >   listen two.local:80;
>> >   server_name two.local;
>> >
>> >   location / {
>> >     return 403;
>> >   }
>> > }
>> >
>> > If I request one.local then 403 is returned. If i change listen for one.local to one.local:80 then 404 correctly returned, but only after restart, reload doesn't help (that's probably bug too).
>> 
>> Is there in error_log error something like "listen(127.0.0.1:80) failed (98: Address already in use)" ?
>> 
>> No, there's no such thing.
> 
> Then it should work with just reload.
> 
> Found that in logs after reload.

This is Linux "feature".

>> > I expect to get 404 if i request one.local even if I listen on all addresses. Am I right?
>> 
>> 
>> No. Your first configuration is
>> 
>> server {
>>    listen *:80;
>>    server_name  one.local;
>> }
>> 
>> server {
>>   listen 127.0.0.1:80;
>>   server_name  two.local;
>> }
>> 
>> A client connects to 127.0.0.1:80, so nginx uses the second server to processes request.
>> When you change listen in the first server to 127.0.0.1:80, nginx has two servers for this
>> listen port and chooses server using "Host" header.
>> 
>> This is what netstat says:
>> 
>> callisto ~ # netstat -ntl      
>> Active Internet connections (only servers)
>> Proto Recv-Q Send-Q Local Address           Foreign Address         State      
>> tcp        0      0 127.0.0.1:21213         0.0.0.0:*               LISTEN     
>> tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
>> tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
>> tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN     
>> tcp6       0      0 ::1:21213               :::*                    LISTEN     
>> tcp6       0      0 :::22                   :::*                    LISTEN     
>> tcp6       0      0 :::5432                 :::*                    LISTEN
>> 
>> Here I only see 0.0.0.0:80 and 127.0.0.1:80 looks like a subset for this. So why can't nginx use the same socket? 
> 
> If there is "listen *:80", nginx uses this single socket to accept all connections to 80 port and
> then learn local address with getsockaddr(), see Ruslan email for details.
> 
> I don't see why nginx cant' find that server_name one.local matches incoming request on that socket. Nginx may check not only listen with 127.0.0.1, but also listen with *, why not?

On Linux there is no way to listen on both wildcard address and specific addresses.
You have to listen on either on wildcard addresss or several specific addresses.
So on Linux there is no way to limit a host to specific address and nginx emulates
other OSes behaviour. If you want to process one.local on both *:80 and 127.0.0.1:80
you should use this:

server {
  listen *:80;
  listen 127.0.0.1:80
  server_name  one.local;
}

server {
  listen 127.0.0.1:80
  server_name  two.local;
}


--
Igor Sysoev
http://nginx.com/support.html

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20130213/e7cd6caa/attachment.html>


More information about the nginx-devel mailing list