Directive can have multiple meanings. Each variant is separated with horizontal line


[edit] listen

Syntax: listen address [: port ] [ default_server ] [ setfib = number ] [ backlog = number ] [ rcvbuf = size ] [ sndbuf = size ] [ accept_filter = filter ] [ deferred ] [ bind ] [ ipv6only = on | off ] [ ssl ] [ so_keepalive = on | off |[ keepidle ]:[ keepintvl ]:[ keepcnt ]]
listen port [ default_server ] [ setfib = number ] [ backlog = number ] [ rcvbuf = size ] [ sndbuf = size ] [ accept_filter = filter ] [ deferred ] [ bind ] [ ipv6only = on | off ] [ ssl ] [ so_keepalive = on | off |[ keepidle ]:[ keepintvl ]:[ keepcnt ]]
listen unix: path [ default_server ] [ backlog = number ] [ rcvbuf = size ] [ sndbuf = size ] [ accept_filter = filter ] [ deferred ] [ bind ] [ ssl ] [ so_keepalive = on | off |[ keepidle ]:[ keepintvl ]:[ keepcnt ]]
Default: *:80 | *:8000
Context: server
Reference: listen


The listen directive specifies the address and port accepted by the enclosing server {...} block. It is possible to specify only an address, only a port, or a server name as the address.

listen 127.0.0.1:8000;
listen 127.0.0.1;
listen 8000;
listen *:8000;
listen localhost:8000;

IPv6 address(0.7.36) are set in square brackets:

listen [::]:8000; 
listen [fe80::1];

In Linux by default any IPv6 TCP socket also accepts IPv4 traffic using the IPv4 to IPv6 mapped address format, i.e., ::ffff:<IPv4 adddress in dotted decimal notation>. E.g., ::ffff:192.168.0.27 maps the IPv4 address 192.168.0.27 to an IPv6 address.

When you enable the address [::]:80, binding port 80 using IPv6, in the listen directive, in Linux, by default, the IPv4 port 80 is also enabled. Meaning that nginx listens for both IPv4 and IPv6 incoming traffic. Therefore if you erroneously specify also a IPv4 address you'll get an already bind address error when reloading nginx configuration.

In Linux the separation of the IPv6 and IPv4 stacks is controlled through the runtime parameter: net.ipv6.bindv6only which has the value 0 by default.

If you want to use separate sockets for IPv4 and IPv6 you should set this parameter to 1 using sysctl.

Note that any nginx instance that was running before you made the change will continue to accept IPv4 traffic. Therefore you should edit your nginx configuration to reflect the new setup for IPv6 and IPv4 packet handling and do a restart.

If on the other hand you launched another server instance (vhost) and you expect it to also handle IPv4 traffic by using only, for example:

listen [::]:80;

the binding of the IPv4 address will fail. The correct way to to this is by using the "ipv6only=on" option in the IPv6 listen directive and also specifying a IPv4 listen directive in the respective server block.

This re-editing of the configuration must be done after you changed your kernel runtime parameter. This is the most generic situation in that case (separation of IPv6 and IPv4 sockets):

listen [::]:80 ipv6only=on; # listen for IPv6 only traffic on IPv6 sockets
listen 80; # listen also for IPv4 traffic on "regular" IPv4 sockets

In FreeBSD the default is separate IPv4 and IPv6 sockets. Therefore "listen [::]:80" only binds port 80 for listening to IPv6 traffic. It's always necessary to specify also IPv4 listen directives if you wish to also handle IPv4 traffic.

It's possible to specify only IPv6 addresses in the listen directive. Using the "default_server ipv6only=on" option. Specific IPv6 addresses can be used with a IPv6 only default directive. Other server directives can also specifiy listen directives with IPv4 addresses. The uniqueness of the IPv6 handling concerns only the same server {...} block.

listen [2a02:750:5::123]:80;
listen [::]:80 default_server ipv6only=on;

If only the address is given, the default port nginx binds to is 80.

If the directive has the default_server parameter, then the enclosing server {...} block will be the default server for the address:port pair. This is useful for name-based virtual hosting where you wish to specify the default server block for hostnames that do not match any server_name directives. If there are no directives with the default_server parameter, then the default server will be the first server block in which the address:port pair appears. The default_server parameter appeared in version 0.8.21 thus deprecating the parameter default.

The listen directive accepts several parameters, specific to the system calls listen(2) and bind(2). These parameters must follow the default parameter.

backlog=num -- is assigned parameter backlog in call listen(2). By default backlog equals -1.

rcvbuf=size -- assigned to the parameter SO_RCVBUF for the listening socket.

sndbuf=size -- assigned to the parameter SO_SNDBUF for the listening socket.

accept_filter=filter -- is assigned name accept-filter.

. It works only to FreeBSD, it is possible to use two filters -- dataready and httpready. On the signal -HUP accept-filter it is possible to change only in the quite last versions FreeBSD: 6.0, 5.4-STABLE and 4.11-STABLE.

deferred -- indicates to use that postponed accept(2) on Linux with

. the aid of option TCP_DEFER_ACCEPT.

bind -- indicates that it is necessary to make bind(2) separately

. for this pair of address:port. The fact is that if are described several directives listen with the identical port, but by different addresses and one of the directives listen listens to on all addresses for this port (*:port), then nginx will make bind(2) only to *:port. It is necessary to consider that in this case for determining the address, on which the connections arrive, is done the system call getsockname(). But if are used parameters backlog, rcvbuf, sndbuf, accept_filter or deferred, then it is always done separately for this pair of address:port bind(2).

ssl -- parameter (0.7.14) not related to listen(2) and bind(2) syscalls

. but instead specifies that connections accepted on this port should work in SSL mode. This allows to specify compact configurations for servers working with both HTTP and HTTPS. For example:
listen  80;
listen  443 default_server ssl;

Example of the use of the parameters:

listen  127.0.0.1 default_server accept_filter=dataready backlog=1024;

Since version 0.8.21 nginx is able to listen on unix sockets:

listen unix:/tmp/nginx1.sock;

Module: HttpCoreModule

[edit] listen

syntax: listen address:port [ bind ]

default: no

context: server

The directive specifies the address and port, on which the server accepts requests. It is possible to specify address or port only, besides, an address can be the server name, for example:

listen 127.0.0.1:8000;
listen 127.0.0.1;
listen 8000;
listen *:8000;
listen localhost:8000;

IPv6 address(>=0.7.58) are set in square brackets:

listen  [::]:8000; 
listen  [fe80::1];

In directive listen it is possible to indicate the system call bind(2).

bind -- indicates that it is necessary to make bind(2) separately for this pair of address:port. If several directives listen with identical port but with different addresses and one of the directives listen to all addresses for this port (*:port) then Nginx will make bind(2) only to *:port. In this case the address is determined by the system call getsockname().


Module: MailCoreModule