Home
last modified time | relevance | path

Searched hist:8 (Results 1 – 25 of 231) sorted by last modified time

12345678910

/unit/pkg/docker/
H A DDockerfile.minimaldiff 2464:8a0b4338a156 Wed May 10 17:29:00 UTC 2023 Konstantin Pavlov <thresh@nginx.com> Merged with the default branch.
diff 2119:8a9055cbe4ff Thu Jun 02 00:31:00 UTC 2022 Andrei Zeliankou <zelenkov@nginx.com> Generated Dockerfiles for Unit 1.27.0.
diff 1958:8e23e9bc94b5 Tue Sep 21 11:03:00 UTC 2021 Konstantin Pavlov <thresh@nginx.com> Regenerated Dockerfiles.
diff 1405:8bab088952dd Thu Mar 12 15:13:00 UTC 2020 Valentin Bartenev <vbart@nginx.com> Generated Dockerfiles for Unit 1.16.0.
diff 784:8f4524a9cf87 Thu Sep 20 15:19:00 UTC 2018 Valentin Bartenev <vbart@nginx.com> Generated Dockerfiles for Unit 1.4.
H A DDockerfile.jsc11diff 2464:8a0b4338a156 Wed May 10 17:29:00 UTC 2023 Konstantin Pavlov <thresh@nginx.com> Merged with the default branch.
diff 2119:8a9055cbe4ff Thu Jun 02 00:31:00 UTC 2022 Andrei Zeliankou <zelenkov@nginx.com> Generated Dockerfiles for Unit 1.27.0.
H A Dtemplate.Dockerfilediff 2464:8a0b4338a156 Wed May 10 17:29:00 UTC 2023 Konstantin Pavlov <thresh@nginx.com> Merged with the default branch.
diff 2397:817968931c58 Wed Mar 22 15:55:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Auto: mirroring installation structure in build tree.

This makes the build tree more organized, which is good for adding new
stuff. Now, it's useful for example for adding manual pages in man3/,
but it may be useful in the future for example for extending the build
system to run linters (e.g., clang-tidy(1), Clang analyzer, ...) on the
C source code.

Previously, the build tree was quite flat, and looked like this (after
`./configure && make`):

$ tree -I src build
build
├── Makefile
├── autoconf.data
├── autoconf.err
├── echo
├── libnxt.a
├── nxt_auto_config.h
├── nxt_version.h
├── unitd
└── unitd.8

1 directory, 9 files

And after this patch, it looks like this:

$ tree -I src build
build
├── Makefile
├── autoconf.data
├── autoconf.err
├── bin
│ └── echo
├── include
│ ├── nxt_auto_config.h
│ └── nxt_version.h
├── lib
│ ├── libnxt.a
│ └── unit
│ └── modules
├── sbin
│ └── unitd
├── share
│ └── man
│ └── man8
│ └── unitd.8
└── var
├── lib
│ └── unit
├── log
│ └── unit
└── run
└── unit

17 directories, 9 files

It also solves one issue introduced in
5a37171f733f ("Added default values for pathnames."). Before that
commit, it was possible to run unitd from the build system
(`./build/unitd`). Now, since it expects files in a very specific
location, that has been broken. By having a directory structure that
mirrors the installation, it's possible to trick it to believe it's
installed, and run it from there:

$ ./configure --prefix=./build
$ make
$ ./build/sbin/unitd

Fixes: 5a37171f733f ("Added default values for pathnames.")
Reported-by: Liam Crilly <liam@nginx.com>
Reviewed-by: Konstantin Pavlov <thresh@nginx.com>
Reviewed-by: Andrew Clayton <a.clayton@nginx.com>
Cc: Andrei Zeliankou <zelenkov@nginx.com>
Cc: Zhidao Hong <z.hong@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2397:817968931c58 Wed Mar 22 15:55:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Auto: mirroring installation structure in build tree.

This makes the build tree more organized, which is good for adding new
stuff. Now, it's useful for example for adding manual pages in man3/,
but it may be useful in the future for example for extending the build
system to run linters (e.g., clang-tidy(1), Clang analyzer, ...) on the
C source code.

Previously, the build tree was quite flat, and looked like this (after
`./configure && make`):

$ tree -I src build
build
├── Makefile
├── autoconf.data
├── autoconf.err
├── echo
├── libnxt.a
├── nxt_auto_config.h
├── nxt_version.h
├── unitd
└── unitd.8

1 directory, 9 files

And after this patch, it looks like this:

$ tree -I src build
build
├── Makefile
├── autoconf.data
├── autoconf.err
├── bin
│ └── echo
├── include
│ ├── nxt_auto_config.h
│ └── nxt_version.h
├── lib
│ ├── libnxt.a
│ └── unit
│ └── modules
├── sbin
│ └── unitd
├── share
│ └── man
│ └── man8
│ └── unitd.8
└── var
├── lib
│ └── unit
├── log
│ └── unit
└── run
└── unit

17 directories, 9 files

It also solves one issue introduced in
5a37171f733f ("Added default values for pathnames."). Before that
commit, it was possible to run unitd from the build system
(`./build/unitd`). Now, since it expects files in a very specific
location, that has been broken. By having a directory structure that
mirrors the installation, it's possible to trick it to believe it's
installed, and run it from there:

$ ./configure --prefix=./build
$ make
$ ./build/sbin/unitd

Fixes: 5a37171f733f ("Added default values for pathnames.")
Reported-by: Liam Crilly <liam@nginx.com>
Reviewed-by: Konstantin Pavlov <thresh@nginx.com>
Reviewed-by: Andrew Clayton <a.clayton@nginx.com>
Cc: Andrei Zeliankou <zelenkov@nginx.com>
Cc: Zhidao Hong <z.hong@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
/unit/docs/
H A Dchanges.xmldiff 2464:8a0b4338a156 Wed May 10 17:29:00 UTC 2023 Konstantin Pavlov <thresh@nginx.com> Merged with the default branch.
diff 2223:1019031754fe Wed Jan 16 07:38:00 UTC 2019 Remi Collet <remi@remirepo.net> Preferring system crypto policy.

If we don't call SSL_CTX_set_cipher_list(), then it uses the
system's default.

Link: <https://fedoraproject.org/wiki/Changes/CryptoPolicy>
Link: <https://docs.fedoraproject.org/en-US/packaging-guidelines/CryptoPolicies/>
Link: <https://www.redhat.com/en/blog/consistent-security-crypto-policies-red-hat-enterprise-linux-8>
Signed-off-by: Remi Collet <remi@remirepo.net>
Acked-by: Andrei Belov <defan@nginx.com>
[ alx: add changelog and tweak commit message ]
Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2209:8a3994540aa8 Wed Sep 28 14:51:00 UTC 2022 Zhidao HONG <z.hong@f5.com> Ruby: added support for rack V3.

Ruby applications would fail to start if they were using rack v3

2022/09/28 15:48:46 [alert] 0#80912 [unit] Ruby: Failed to parse rack script
2022/09/28 15:48:46 [notice] 80911#80911 app process 80912 exited with code 1

This was due to a change in the rack API

Rack V2

def self.load_file(path, opts = Server::Options.new)
...
cfgfile.sub!(/^__END__\n.*\Z/m, '')
app = new_from_string cfgfile, path

return app, options
end

Rack V3

def self.load_file(path)
...

return new_from_string(config, path)
end

This patch handles _both_ the above APIs by correctly handling the cases
where we do and don't get an array returned from
nxt_ruby_rack_parse_script().

Closes: <https://github.com/nginx/unit/issues/755>
Tested-by: Andrew Clayton <a.clayton@nginx.com>
Reviewed-by: Andrew Clayton <a.clayton@nginx.com>
[ Andrew: Patch by Zhidao, commit message by me with input from Zhidao ]
Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
diff 2195:8dee71bcf84e Mon Sep 12 23:31:00 UTC 2022 Andrei Zeliankou <zelenkov@nginx.com> Capitalize "HTTP" in "changes.xml" to match common style.
diff 2179:8686f63a2228 Thu Jul 28 14:10:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Fixed support for abstract Unix sockets.

Unix domain sockets are normally backed by files in the
filesystem. This has historically been problematic when closing
and opening again such sockets, since SO_REUSEADDR is ignored for
Unix sockets (POSIX left the behavior of SO_REUSEADDR as
implementation-defined, and most --if not all-- implementations
decided to just ignore this flag).

Many solutions are available for this problem, but all of them
have important caveats:

- unlink(2) the file when it's not needed anymore.

This is not easy, because the process that controls the fd may
not be the same process that created the file, and may not have
file permissions to remove it.

Further solutions can be applied to that caveat:

- unlink(2) the file right after creation.

This will remove the pathname from the filesystem without
closing the socket (it will continue to live until the last fd
is closed). This is not useful for us, since we need the
pathname of the socket as its interface.

- chown(2) or chmod(2) the directory that contains the socket.

For removing a file from the filesystem, a process needs
write permissions in the containing directory. We could
put sockets in dummy directories that can be chown(2)ed to
nobody. This could be dangerous, though, as we don't control
the socket names. It is our users who configure the socket
name in their configuration, and so it's easy that they don't
understand the many implications of not chosing an appropriate
socket pathname. A user could unknowingly put the socket in a
directory that is not supposed to be owned by user nobody, and
if we blindly chown(2) or chmod(2) the directory, we could be
creating a big security hole.

- Ask the main process to remove the socket.

This would require a very complex communication mechanism with
the main process, which is not impossible, but let's avoid it
if there are simpler solutions.

- Give the child process the CAP_DAC_OVERRIDE capability.

That is one of the most powerful capabilities. A process with
that capability can be considered root for most practical
aspects. Even if the capability is disabled for most of the
lifetime of the process, there's a slight chance that a
malicious actor could activate it and then easily do serious
damage to the system.

- unlink(2) the file right before calling bind(2).

This is dangerous because another process (for example, another
running instance of unitd(8)), could be using the socket, and
removing the pathname from the filesystem would be problematic.
To do this correctly, a lot of checks should be added before the
actual unlink(2), which is error-prone, and difficult to do
correctly, and atomically.

- Use abstract-namespace Unix domain sockets.

This is the simplest solution, as it only requires accepting a
slightly different syntax (basically a @ prefix) for the socket
name, to transform it into a string starting with a null byte
('\0') that the kernel can understand. The patch is minimal.

Since abstract sockets live in an abstract namespace, they don't
create files in the filesystem, so there's no need to remove
them later. The kernel removes the name when the last fd to it
has been closed.

One caveat is that only Linux currently supports this kind of
Unix sockets. Of course, a solution to that could be to ask
other kernels to implement such a feature.

Another caveat is that filesystem permissions can't be used to
control access to the socket file (since, of course, there's no
file). Anyone knowing the socket name can access to it. The
only method to control access to it is by using
network_namespaces(7). Since in unitd(8) we're using 0666 file
sockets, abstract sockets should be no more insecure than that
(anyone can already read/write to the listener sockets).

- Ask the kernel to implement a simpler way to unlink(2) socket
files when they are not needed anymore. I've suggested that to
the <linux-fsdevel@vger.kernel.org> mailing list, in:
<lore.kernel.org/linux-fsdevel/0bc5f919-bcfd-8fd0-a16b-9f060088158a@gmail.com/T>

In this commit, I decided to go for the easiest/simplest solution,
which is abstract sockets. In fact, we already had partial
support. This commit only fixes some small bug in the existing
code so that abstract Unix sockets work:

- Don't chmod(2) the socket if it's an abstract one.

This fixes the creation of abstract sockets, but doesn't make them
usable, since we produce them with a trailing '\0' in their name.
That will be fixed in the following commit.

This closes #669 issue on GitHub.
diff 2179:8686f63a2228 Thu Jul 28 14:10:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Fixed support for abstract Unix sockets.

Unix domain sockets are normally backed by files in the
filesystem. This has historically been problematic when closing
and opening again such sockets, since SO_REUSEADDR is ignored for
Unix sockets (POSIX left the behavior of SO_REUSEADDR as
implementation-defined, and most --if not all-- implementations
decided to just ignore this flag).

Many solutions are available for this problem, but all of them
have important caveats:

- unlink(2) the file when it's not needed anymore.

This is not easy, because the process that controls the fd may
not be the same process that created the file, and may not have
file permissions to remove it.

Further solutions can be applied to that caveat:

- unlink(2) the file right after creation.

This will remove the pathname from the filesystem without
closing the socket (it will continue to live until the last fd
is closed). This is not useful for us, since we need the
pathname of the socket as its interface.

- chown(2) or chmod(2) the directory that contains the socket.

For removing a file from the filesystem, a process needs
write permissions in the containing directory. We could
put sockets in dummy directories that can be chown(2)ed to
nobody. This could be dangerous, though, as we don't control
the socket names. It is our users who configure the socket
name in their configuration, and so it's easy that they don't
understand the many implications of not chosing an appropriate
socket pathname. A user could unknowingly put the socket in a
directory that is not supposed to be owned by user nobody, and
if we blindly chown(2) or chmod(2) the directory, we could be
creating a big security hole.

- Ask the main process to remove the socket.

This would require a very complex communication mechanism with
the main process, which is not impossible, but let's avoid it
if there are simpler solutions.

- Give the child process the CAP_DAC_OVERRIDE capability.

That is one of the most powerful capabilities. A process with
that capability can be considered root for most practical
aspects. Even if the capability is disabled for most of the
lifetime of the process, there's a slight chance that a
malicious actor could activate it and then easily do serious
damage to the system.

- unlink(2) the file right before calling bind(2).

This is dangerous because another process (for example, another
running instance of unitd(8)), could be using the socket, and
removing the pathname from the filesystem would be problematic.
To do this correctly, a lot of checks should be added before the
actual unlink(2), which is error-prone, and difficult to do
correctly, and atomically.

- Use abstract-namespace Unix domain sockets.

This is the simplest solution, as it only requires accepting a
slightly different syntax (basically a @ prefix) for the socket
name, to transform it into a string starting with a null byte
('\0') that the kernel can understand. The patch is minimal.

Since abstract sockets live in an abstract namespace, they don't
create files in the filesystem, so there's no need to remove
them later. The kernel removes the name when the last fd to it
has been closed.

One caveat is that only Linux currently supports this kind of
Unix sockets. Of course, a solution to that could be to ask
other kernels to implement such a feature.

Another caveat is that filesystem permissions can't be used to
control access to the socket file (since, of course, there's no
file). Anyone knowing the socket name can access to it. The
only method to control access to it is by using
network_namespaces(7). Since in unitd(8) we're using 0666 file
sockets, abstract sockets should be no more insecure than that
(anyone can already read/write to the listener sockets).

- Ask the kernel to implement a simpler way to unlink(2) socket
files when they are not needed anymore. I've suggested that to
the <linux-fsdevel@vger.kernel.org> mailing list, in:
<lore.kernel.org/linux-fsdevel/0bc5f919-bcfd-8fd0-a16b-9f060088158a@gmail.com/T>

In this commit, I decided to go for the easiest/simplest solution,
which is abstract sockets. In fact, we already had partial
support. This commit only fixes some small bug in the existing
code so that abstract Unix sockets work:

- Don't chmod(2) the socket if it's an abstract one.

This fixes the creation of abstract sockets, but doesn't make them
usable, since we produce them with a trailing '\0' in their name.
That will be fixed in the following commit.

This closes #669 issue on GitHub.
diff 2179:8686f63a2228 Thu Jul 28 14:10:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Fixed support for abstract Unix sockets.

Unix domain sockets are normally backed by files in the
filesystem. This has historically been problematic when closing
and opening again such sockets, since SO_REUSEADDR is ignored for
Unix sockets (POSIX left the behavior of SO_REUSEADDR as
implementation-defined, and most --if not all-- implementations
decided to just ignore this flag).

Many solutions are available for this problem, but all of them
have important caveats:

- unlink(2) the file when it's not needed anymore.

This is not easy, because the process that controls the fd may
not be the same process that created the file, and may not have
file permissions to remove it.

Further solutions can be applied to that caveat:

- unlink(2) the file right after creation.

This will remove the pathname from the filesystem without
closing the socket (it will continue to live until the last fd
is closed). This is not useful for us, since we need the
pathname of the socket as its interface.

- chown(2) or chmod(2) the directory that contains the socket.

For removing a file from the filesystem, a process needs
write permissions in the containing directory. We could
put sockets in dummy directories that can be chown(2)ed to
nobody. This could be dangerous, though, as we don't control
the socket names. It is our users who configure the socket
name in their configuration, and so it's easy that they don't
understand the many implications of not chosing an appropriate
socket pathname. A user could unknowingly put the socket in a
directory that is not supposed to be owned by user nobody, and
if we blindly chown(2) or chmod(2) the directory, we could be
creating a big security hole.

- Ask the main process to remove the socket.

This would require a very complex communication mechanism with
the main process, which is not impossible, but let's avoid it
if there are simpler solutions.

- Give the child process the CAP_DAC_OVERRIDE capability.

That is one of the most powerful capabilities. A process with
that capability can be considered root for most practical
aspects. Even if the capability is disabled for most of the
lifetime of the process, there's a slight chance that a
malicious actor could activate it and then easily do serious
damage to the system.

- unlink(2) the file right before calling bind(2).

This is dangerous because another process (for example, another
running instance of unitd(8)), could be using the socket, and
removing the pathname from the filesystem would be problematic.
To do this correctly, a lot of checks should be added before the
actual unlink(2), which is error-prone, and difficult to do
correctly, and atomically.

- Use abstract-namespace Unix domain sockets.

This is the simplest solution, as it only requires accepting a
slightly different syntax (basically a @ prefix) for the socket
name, to transform it into a string starting with a null byte
('\0') that the kernel can understand. The patch is minimal.

Since abstract sockets live in an abstract namespace, they don't
create files in the filesystem, so there's no need to remove
them later. The kernel removes the name when the last fd to it
has been closed.

One caveat is that only Linux currently supports this kind of
Unix sockets. Of course, a solution to that could be to ask
other kernels to implement such a feature.

Another caveat is that filesystem permissions can't be used to
control access to the socket file (since, of course, there's no
file). Anyone knowing the socket name can access to it. The
only method to control access to it is by using
network_namespaces(7). Since in unitd(8) we're using 0666 file
sockets, abstract sockets should be no more insecure than that
(anyone can already read/write to the listener sockets).

- Ask the kernel to implement a simpler way to unlink(2) socket
files when they are not needed anymore. I've suggested that to
the <linux-fsdevel@vger.kernel.org> mailing list, in:
<lore.kernel.org/linux-fsdevel/0bc5f919-bcfd-8fd0-a16b-9f060088158a@gmail.com/T>

In this commit, I decided to go for the easiest/simplest solution,
which is abstract sockets. In fact, we already had partial
support. This commit only fixes some small bug in the existing
code so that abstract Unix sockets work:

- Don't chmod(2) the socket if it's an abstract one.

This fixes the creation of abstract sockets, but doesn't make them
usable, since we produce them with a trailing '\0' in their name.
That will be fixed in the following commit.

This closes #669 issue on GitHub.
diff 2019:8fcb7e44c663 Thu Nov 25 16:58:00 UTC 2021 Valentin Bartenev <vbart@nginx.com> PHP: fixed crash when calling module functions in OPcache preload.

In PHP, custom fastcgi_finish_request() and overloaded chdir() functions can be
invoked by an OPcache preloading script (it runs when php_module_startup() is
called in the app process setup handler). In this case, there was no runtime
context set so trying to access it caused a segmentation fault.

This closes #602 issue on GitHub.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
/unit/
H A DCHANGESdiff 1722:8d987b7880f9 Thu Nov 19 16:59:00 UTC 2020 Valentin Bartenev <vbart@nginx.com> Added version 1.21.0 CHANGES.
diff 1222:8ffcee3c43dd Thu Oct 03 13:30:00 UTC 2019 Valentin Bartenev <vbart@nginx.com> Added version 1.12.0 CHANGES.
/unit/test/
H A Dtest_asgi_application.pydiff 2592:e079c44a8340 Wed Nov 08 18:37:00 UTC 2023 Andrei Zeliankou <zelenkov@nginx.com> Tests: 8XXX used as default port range.

After the launch of the project, the testing infrastructure was shared with
nginx project in some cases. To avoid port overlap, a decision was made
to shift the port range for Unit tests. This problem was resolved a long time
ago and is no longer relevant, so it is now safe to use port 8XXX range as the
default, as it is more appropriate for testing purposes.
diff 2592:e079c44a8340 Wed Nov 08 18:37:00 UTC 2023 Andrei Zeliankou <zelenkov@nginx.com> Tests: 8XXX used as default port range.

After the launch of the project, the testing infrastructure was shared with
nginx project in some cases. To avoid port overlap, a decision was made
to shift the port range for Unit tests. This problem was resolved a long time
ago and is no longer relevant, so it is now safe to use port 8XXX range as the
default, as it is more appropriate for testing purposes.
H A Dtest_reconfigure_tls.pydiff 2694:c11223916183 Wed Feb 07 16:23:00 UTC 2024 Andrei Zeliankou <zelenkov@nginx.com> Tests: skip some of TLS reconfiguration tests under AddressSanitizer

These tests cause router crash when run with AddressSanitizer:

=================================================================
==77196==ERROR: AddressSanitizer: heap-use-after-free on address 0x60c000079340 at pc 0x55d56b132d4b bp 0x7f8cc7f346b0 sp 0x7f8cc7f346a0
READ of size 1 at 0x60c000079340 thread T1
#0 0x55d56b132d4a in nxt_openssl_conn_io_shutdown src/nxt_openssl.c:1466
#1 0x55d56b0f6a25 in nxt_h1p_closing src/nxt_h1proto.c:2069
#2 0x55d56b1009a6 in nxt_h1p_shutdown src/nxt_h1proto.c:2038
#3 0x55d56b1014c3 in nxt_h1p_request_close src/nxt_h1proto.c:1718
#4 0x55d56b1045c0 in nxt_http_request_close_handler src/nxt_http_request.c:864
#5 0x55d56b104988 in nxt_http_request_done src/nxt_http_request.c:795
#6 0x55d56b0ba0c3 in nxt_event_engine_start src/nxt_event_engine.c:542
#7 0x55d56b0dcac2 in nxt_router_thread_start src/nxt_router.c:3645
#8 0x55d56b0b421b in nxt_thread_trampoline src/nxt_thread.c:126
#9 0x7f8ccab95ac2 (/lib/x86_64-linux-gnu/libc.so.6+0x94ac2)
#10 0x7f8ccac2784f (/lib/x86_64-linux-gnu/libc.so.6+0x12684f)
diff 2592:e079c44a8340 Wed Nov 08 18:37:00 UTC 2023 Andrei Zeliankou <zelenkov@nginx.com> Tests: 8XXX used as default port range.

After the launch of the project, the testing infrastructure was shared with
nginx project in some cases. To avoid port overlap, a decision was made
to shift the port range for Unit tests. This problem was resolved a long time
ago and is no longer relevant, so it is now safe to use port 8XXX range as the
default, as it is more appropriate for testing purposes.
diff 2592:e079c44a8340 Wed Nov 08 18:37:00 UTC 2023 Andrei Zeliankou <zelenkov@nginx.com> Tests: 8XXX used as default port range.

After the launch of the project, the testing infrastructure was shared with
nginx project in some cases. To avoid port overlap, a decision was made
to shift the port range for Unit tests. This problem was resolved a long time
ago and is no longer relevant, so it is now safe to use port 8XXX range as the
default, as it is more appropriate for testing purposes.
H A Dtest_njs.pydiff 2592:e079c44a8340 Wed Nov 08 18:37:00 UTC 2023 Andrei Zeliankou <zelenkov@nginx.com> Tests: 8XXX used as default port range.

After the launch of the project, the testing infrastructure was shared with
nginx project in some cases. To avoid port overlap, a decision was made
to shift the port range for Unit tests. This problem was resolved a long time
ago and is no longer relevant, so it is now safe to use port 8XXX range as the
default, as it is more appropriate for testing purposes.
diff 2592:e079c44a8340 Wed Nov 08 18:37:00 UTC 2023 Andrei Zeliankou <zelenkov@nginx.com> Tests: 8XXX used as default port range.

After the launch of the project, the testing infrastructure was shared with
nginx project in some cases. To avoid port overlap, a decision was made
to shift the port range for Unit tests. This problem was resolved a long time
ago and is no longer relevant, so it is now safe to use port 8XXX range as the
default, as it is more appropriate for testing purposes.
/unit/test/unit/applications/lang/
H A Djava.pydiff 2592:e079c44a8340 Wed Nov 08 18:37:00 UTC 2023 Andrei Zeliankou <zelenkov@nginx.com> Tests: 8XXX used as default port range.

After the launch of the project, the testing infrastructure was shared with
nginx project in some cases. To avoid port overlap, a decision was made
to shift the port range for Unit tests. This problem was resolved a long time
ago and is no longer relevant, so it is now safe to use port 8XXX range as the
default, as it is more appropriate for testing purposes.
diff 2592:e079c44a8340 Wed Nov 08 18:37:00 UTC 2023 Andrei Zeliankou <zelenkov@nginx.com> Tests: 8XXX used as default port range.

After the launch of the project, the testing infrastructure was shared with
nginx project in some cases. To avoid port overlap, a decision was made
to shift the port range for Unit tests. This problem was resolved a long time
ago and is no longer relevant, so it is now safe to use port 8XXX range as the
default, as it is more appropriate for testing purposes.
diff 1678:a9042510f953 Tue Nov 03 01:31:00 UTC 2020 Andrei Zeliankou <zelenkov@nginx.com> Tests: force applications to build for JVM 8.

This change is made to avoid situations when an application
is compiled for a version newer than the Java module used.
/unit/src/
H A Dnxt_router.cdiff 2371:458231ee5aba Sat Mar 04 23:52:00 UTC 2023 Andrew Clayton <a.clayton@nginx.com> Router: Fix allocation of request buffer sent to application.

This fixes an issue reported by @Peter2121 on GitHub.

In nxt_router_prepare_msg() we create a buffer (nxt_unit_request_t *req)
that gets sent to an application process that contains details about a
client request.

The req structure comprises various members with the final member being
an array (specified as a flexible array member, with its actual length
denoted by the req->fields_count member) of nxt_unit_field_t's. These
structures specify the length and offset for the various request headers
name/value pairs which are stored after some request metadata that is
stored immediately after this array of structs as individual nul
terminated strings.

After this we have the body content data (if any). So it looks a little
like

(gdb) x /64bs 0x7f38c976e060
0x7f38c976e060: "\353\346\244\t\006" <-- First nxt_unit_field_t
0x7f38c976e066: ""
0x7f38c976e067: ""
0x7f38c976e068: "T\001"
0x7f38c976e06b: ""
0x7f38c976e06c: "Z\001"
0x7f38c976e06f: ""
...
0x7f38c976e170: "\362#\244\v$" <-- Last nxt_unit_field_t
0x7f38c976e176: ""
0x7f38c976e177: ""
0x7f38c976e178: "\342\002"
0x7f38c976e17b: ""
0x7f38c976e17c: "\352\002"
0x7f38c976e17f: ""
0x7f38c976e180: "POST" <-- Start of request metadata
0x7f38c976e185: "HTTP/1.1"
0x7f38c976e18e: "unix:"
0x7f38c976e194: "unix:/dev/shm/842.sock"
0x7f38c976e1ab: ""
0x7f38c976e1ac: "fedora"
0x7f38c976e1b3: "/842.php"
0x7f38c976e1bc: "HTTP_HOST" <-- Start of header fields
0x7f38c976e1c6: "fedora"
0x7f38c976e1cd: "HTTP_X_FORWARDED_PROTO"
0x7f38c976e1e4: "https"
...
0x7f38c976e45a: "HTTP_COOKIE"
0x7f38c976e466: "PHPSESSID=8apkg25r9s9vju3pi085i21eh4"
0x7f38c976e48b: "public_form=sended" <-- Body content

Well that's how things are supposed to look! When using Unix domain
sockets what we actually got looked like

...
0x7f6141f3445a: "HTTP_COOKIE"
0x7f6141f34466: "PHPSESSID=uo5b2nu9buijkc89jotbgmd60vpublic_form=sended"

Here, the body content (from a POST for example) has been appended
straight onto the end of the last header field value. In this case
corrupting the PHP session cookie. The body content would still be
found by the application as its offset into this buffer is correct.

This problem was actually caused by a0327445 ("PHP: allowed to specify
URLs without a trailing '/'.") which added an extra item into this
request buffer specifying the port number that unit is listening on that
handled this request.

Unfortunately when I wrote that patch I didn't increase the size of this
request buffer to accommodate it.

When using normal TCP sockets we actually end up allocating more space
than required for this buffer, we track the end of this buffer up to
where the body content would go and so we have a few spare bytes between
the nul byte of the last field header value and the start of the body
content.

When using Unix domain sockets, they have no associated port number and
thus the port number has a length of 0 bytes, but we still write a '\0'
in there using up a byte that we didn't account for, this causes us to
loose the nul byte of the last header fields value causing the body data
to be appended to the last header field value.

The fix is simple, account for the local port length, we also add 1 to
it, this covers the nul byte, even if there is no port as with Unix
domain sockets.

Closes: <https://github.com/nginx/unit/issues/842>
Fixes: a0327445 ("PHP: allowed to specify URLs without a trailing '/'.")
Reviewed-by: Alejandro Colomar <alx@nginx.com>
Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1829:8fb5cbfe761a Thu Mar 25 11:16:00 UTC 2021 Max Romanov <max.romanov@nginx.com> Releasing shm buffers for large body requests.

This fixes memory and shm file descriptor leakage that occurred when a large
request body was passed via shared memory. The leakage was caught with the
"test_settings_body_buffer_size" test. The main condition is the
"body_buffer_size" value exceeding 10 Mb (a shm segment). Thus, the router was
forced to split the body into several shm segments, but these buffers were not
freed because of dummy completion handlers.
diff 1375:8fe1059958d8 Tue Mar 03 15:28:00 UTC 2020 Max Romanov <max.romanov@nginx.com> Fixing request_app_link reference counting for delayed requests.

Router built with debug may stop with assertion during stalled requests
re-schedule. This was caused by missing reference counting increment
before nxt_router_port_select() call.
diff 134:8fb12b30c429 Fri Jul 07 18:20:00 UTC 2017 Igor Sysoev <igor@sysoev.ru> Router: a fix in the previous changeset.
H A Dnxt_main_process.cdiff 2179:8686f63a2228 Thu Jul 28 14:10:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Fixed support for abstract Unix sockets.

Unix domain sockets are normally backed by files in the
filesystem. This has historically been problematic when closing
and opening again such sockets, since SO_REUSEADDR is ignored for
Unix sockets (POSIX left the behavior of SO_REUSEADDR as
implementation-defined, and most --if not all-- implementations
decided to just ignore this flag).

Many solutions are available for this problem, but all of them
have important caveats:

- unlink(2) the file when it's not needed anymore.

This is not easy, because the process that controls the fd may
not be the same process that created the file, and may not have
file permissions to remove it.

Further solutions can be applied to that caveat:

- unlink(2) the file right after creation.

This will remove the pathname from the filesystem without
closing the socket (it will continue to live until the last fd
is closed). This is not useful for us, since we need the
pathname of the socket as its interface.

- chown(2) or chmod(2) the directory that contains the socket.

For removing a file from the filesystem, a process needs
write permissions in the containing directory. We could
put sockets in dummy directories that can be chown(2)ed to
nobody. This could be dangerous, though, as we don't control
the socket names. It is our users who configure the socket
name in their configuration, and so it's easy that they don't
understand the many implications of not chosing an appropriate
socket pathname. A user could unknowingly put the socket in a
directory that is not supposed to be owned by user nobody, and
if we blindly chown(2) or chmod(2) the directory, we could be
creating a big security hole.

- Ask the main process to remove the socket.

This would require a very complex communication mechanism with
the main process, which is not impossible, but let's avoid it
if there are simpler solutions.

- Give the child process the CAP_DAC_OVERRIDE capability.

That is one of the most powerful capabilities. A process with
that capability can be considered root for most practical
aspects. Even if the capability is disabled for most of the
lifetime of the process, there's a slight chance that a
malicious actor could activate it and then easily do serious
damage to the system.

- unlink(2) the file right before calling bind(2).

This is dangerous because another process (for example, another
running instance of unitd(8)), could be using the socket, and
removing the pathname from the filesystem would be problematic.
To do this correctly, a lot of checks should be added before the
actual unlink(2), which is error-prone, and difficult to do
correctly, and atomically.

- Use abstract-namespace Unix domain sockets.

This is the simplest solution, as it only requires accepting a
slightly different syntax (basically a @ prefix) for the socket
name, to transform it into a string starting with a null byte
('\0') that the kernel can understand. The patch is minimal.

Since abstract sockets live in an abstract namespace, they don't
create files in the filesystem, so there's no need to remove
them later. The kernel removes the name when the last fd to it
has been closed.

One caveat is that only Linux currently supports this kind of
Unix sockets. Of course, a solution to that could be to ask
other kernels to implement such a feature.

Another caveat is that filesystem permissions can't be used to
control access to the socket file (since, of course, there's no
file). Anyone knowing the socket name can access to it. The
only method to control access to it is by using
network_namespaces(7). Since in unitd(8) we're using 0666 file
sockets, abstract sockets should be no more insecure than that
(anyone can already read/write to the listener sockets).

- Ask the kernel to implement a simpler way to unlink(2) socket
files when they are not needed anymore. I've suggested that to
the <linux-fsdevel@vger.kernel.org> mailing list, in:
<lore.kernel.org/linux-fsdevel/0bc5f919-bcfd-8fd0-a16b-9f060088158a@gmail.com/T>

In this commit, I decided to go for the easiest/simplest solution,
which is abstract sockets. In fact, we already had partial
support. This commit only fixes some small bug in the existing
code so that abstract Unix sockets work:

- Don't chmod(2) the socket if it's an abstract one.

This fixes the creation of abstract sockets, but doesn't make them
usable, since we produce them with a trailing '\0' in their name.
That will be fixed in the following commit.

This closes #669 issue on GitHub.
diff 2179:8686f63a2228 Thu Jul 28 14:10:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Fixed support for abstract Unix sockets.

Unix domain sockets are normally backed by files in the
filesystem. This has historically been problematic when closing
and opening again such sockets, since SO_REUSEADDR is ignored for
Unix sockets (POSIX left the behavior of SO_REUSEADDR as
implementation-defined, and most --if not all-- implementations
decided to just ignore this flag).

Many solutions are available for this problem, but all of them
have important caveats:

- unlink(2) the file when it's not needed anymore.

This is not easy, because the process that controls the fd may
not be the same process that created the file, and may not have
file permissions to remove it.

Further solutions can be applied to that caveat:

- unlink(2) the file right after creation.

This will remove the pathname from the filesystem without
closing the socket (it will continue to live until the last fd
is closed). This is not useful for us, since we need the
pathname of the socket as its interface.

- chown(2) or chmod(2) the directory that contains the socket.

For removing a file from the filesystem, a process needs
write permissions in the containing directory. We could
put sockets in dummy directories that can be chown(2)ed to
nobody. This could be dangerous, though, as we don't control
the socket names. It is our users who configure the socket
name in their configuration, and so it's easy that they don't
understand the many implications of not chosing an appropriate
socket pathname. A user could unknowingly put the socket in a
directory that is not supposed to be owned by user nobody, and
if we blindly chown(2) or chmod(2) the directory, we could be
creating a big security hole.

- Ask the main process to remove the socket.

This would require a very complex communication mechanism with
the main process, which is not impossible, but let's avoid it
if there are simpler solutions.

- Give the child process the CAP_DAC_OVERRIDE capability.

That is one of the most powerful capabilities. A process with
that capability can be considered root for most practical
aspects. Even if the capability is disabled for most of the
lifetime of the process, there's a slight chance that a
malicious actor could activate it and then easily do serious
damage to the system.

- unlink(2) the file right before calling bind(2).

This is dangerous because another process (for example, another
running instance of unitd(8)), could be using the socket, and
removing the pathname from the filesystem would be problematic.
To do this correctly, a lot of checks should be added before the
actual unlink(2), which is error-prone, and difficult to do
correctly, and atomically.

- Use abstract-namespace Unix domain sockets.

This is the simplest solution, as it only requires accepting a
slightly different syntax (basically a @ prefix) for the socket
name, to transform it into a string starting with a null byte
('\0') that the kernel can understand. The patch is minimal.

Since abstract sockets live in an abstract namespace, they don't
create files in the filesystem, so there's no need to remove
them later. The kernel removes the name when the last fd to it
has been closed.

One caveat is that only Linux currently supports this kind of
Unix sockets. Of course, a solution to that could be to ask
other kernels to implement such a feature.

Another caveat is that filesystem permissions can't be used to
control access to the socket file (since, of course, there's no
file). Anyone knowing the socket name can access to it. The
only method to control access to it is by using
network_namespaces(7). Since in unitd(8) we're using 0666 file
sockets, abstract sockets should be no more insecure than that
(anyone can already read/write to the listener sockets).

- Ask the kernel to implement a simpler way to unlink(2) socket
files when they are not needed anymore. I've suggested that to
the <linux-fsdevel@vger.kernel.org> mailing list, in:
<lore.kernel.org/linux-fsdevel/0bc5f919-bcfd-8fd0-a16b-9f060088158a@gmail.com/T>

In this commit, I decided to go for the easiest/simplest solution,
which is abstract sockets. In fact, we already had partial
support. This commit only fixes some small bug in the existing
code so that abstract Unix sockets work:

- Don't chmod(2) the socket if it's an abstract one.

This fixes the creation of abstract sockets, but doesn't make them
usable, since we produce them with a trailing '\0' in their name.
That will be fixed in the following commit.

This closes #669 issue on GitHub.
diff 2179:8686f63a2228 Thu Jul 28 14:10:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Fixed support for abstract Unix sockets.

Unix domain sockets are normally backed by files in the
filesystem. This has historically been problematic when closing
and opening again such sockets, since SO_REUSEADDR is ignored for
Unix sockets (POSIX left the behavior of SO_REUSEADDR as
implementation-defined, and most --if not all-- implementations
decided to just ignore this flag).

Many solutions are available for this problem, but all of them
have important caveats:

- unlink(2) the file when it's not needed anymore.

This is not easy, because the process that controls the fd may
not be the same process that created the file, and may not have
file permissions to remove it.

Further solutions can be applied to that caveat:

- unlink(2) the file right after creation.

This will remove the pathname from the filesystem without
closing the socket (it will continue to live until the last fd
is closed). This is not useful for us, since we need the
pathname of the socket as its interface.

- chown(2) or chmod(2) the directory that contains the socket.

For removing a file from the filesystem, a process needs
write permissions in the containing directory. We could
put sockets in dummy directories that can be chown(2)ed to
nobody. This could be dangerous, though, as we don't control
the socket names. It is our users who configure the socket
name in their configuration, and so it's easy that they don't
understand the many implications of not chosing an appropriate
socket pathname. A user could unknowingly put the socket in a
directory that is not supposed to be owned by user nobody, and
if we blindly chown(2) or chmod(2) the directory, we could be
creating a big security hole.

- Ask the main process to remove the socket.

This would require a very complex communication mechanism with
the main process, which is not impossible, but let's avoid it
if there are simpler solutions.

- Give the child process the CAP_DAC_OVERRIDE capability.

That is one of the most powerful capabilities. A process with
that capability can be considered root for most practical
aspects. Even if the capability is disabled for most of the
lifetime of the process, there's a slight chance that a
malicious actor could activate it and then easily do serious
damage to the system.

- unlink(2) the file right before calling bind(2).

This is dangerous because another process (for example, another
running instance of unitd(8)), could be using the socket, and
removing the pathname from the filesystem would be problematic.
To do this correctly, a lot of checks should be added before the
actual unlink(2), which is error-prone, and difficult to do
correctly, and atomically.

- Use abstract-namespace Unix domain sockets.

This is the simplest solution, as it only requires accepting a
slightly different syntax (basically a @ prefix) for the socket
name, to transform it into a string starting with a null byte
('\0') that the kernel can understand. The patch is minimal.

Since abstract sockets live in an abstract namespace, they don't
create files in the filesystem, so there's no need to remove
them later. The kernel removes the name when the last fd to it
has been closed.

One caveat is that only Linux currently supports this kind of
Unix sockets. Of course, a solution to that could be to ask
other kernels to implement such a feature.

Another caveat is that filesystem permissions can't be used to
control access to the socket file (since, of course, there's no
file). Anyone knowing the socket name can access to it. The
only method to control access to it is by using
network_namespaces(7). Since in unitd(8) we're using 0666 file
sockets, abstract sockets should be no more insecure than that
(anyone can already read/write to the listener sockets).

- Ask the kernel to implement a simpler way to unlink(2) socket
files when they are not needed anymore. I've suggested that to
the <linux-fsdevel@vger.kernel.org> mailing list, in:
<lore.kernel.org/linux-fsdevel/0bc5f919-bcfd-8fd0-a16b-9f060088158a@gmail.com/T>

In this commit, I decided to go for the easiest/simplest solution,
which is abstract sockets. In fact, we already had partial
support. This commit only fixes some small bug in the existing
code so that abstract Unix sockets work:

- Don't chmod(2) the socket if it's an abstract one.

This fixes the creation of abstract sockets, but doesn't make them
usable, since we produce them with a trailing '\0' in their name.
That will be fixed in the following commit.

This closes #669 issue on GitHub.
diff 2078:0996dd223cdd Sat Dec 18 23:58:00 UTC 2021 Alejandro Colomar <alx.manpages@gmail.com> Fixed indentation.

Some lines (incorrectly) had an indentation of 3 or 5, or 7 or 9,
or 11 or 13, or 15 or 17 spaces instead of 4, 8, 12, or 16. Fix them.

Found with:

$ find src -type f | xargs grep -n '^ [^ ]';
$ find src -type f | xargs grep -n '^ [^ *]';
$ find src -type f | xargs grep -n '^ [^ ]';
$ find src -type f | xargs grep -n '^ [^ *]';
$ find src -type f | xargs grep -n '^ [^ +]';
$ find src -type f | xargs grep -n '^ [^ *+]';
$ find src -type f | xargs grep -n '^ [^ +]';
$ find src -type f | xargs grep -n '^ [^ *+]';
diff 354:8fc82db3530b Thu Oct 05 13:46:00 UTC 2017 Valentin Bartenev <vbart@nginx.com> Improved applications versions handling.
H A Dnxt_conf_validation.cdiff 2266:3f66d6e064e2 Tue Dec 06 00:56:00 UTC 2022 Andrew Clayton <a.clayton@nginx.com> Configuration: made large_header_buffers a valid setting.

This is an extension to the previous commit, which made
large_header_buffer_size a valid configuration setting.

This commit makes a related value, large_header_buffers, a valid
configuration setting.

While large_header_buffer_size effectively limits the maximum size of
any single header (although unit will try to pack multiple headers into
a buffer if they wholly fit).

large_header_buffers limits how many of these 'large' buffers are
available. It makes sense to also allow this to be user set.

large_header_buffers is already set by the configuration system in
nxt_router.c it just isn't set as a valid config option in
nxt_conf_validation.c

With this change users can set this option in their config if required
by the following

"settings": {
"http": {
"large_header_buffers": 8
}
},

It retains its default value of 4 if this is not set.

NOTE: This is being released as undocumented and subject to change as it
exposes internal workings of unit.

Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
diff 2078:0996dd223cdd Sat Dec 18 23:58:00 UTC 2021 Alejandro Colomar <alx.manpages@gmail.com> Fixed indentation.

Some lines (incorrectly) had an indentation of 3 or 5, or 7 or 9,
or 11 or 13, or 15 or 17 spaces instead of 4, 8, 12, or 16. Fix them.

Found with:

$ find src -type f | xargs grep -n '^ [^ ]';
$ find src -type f | xargs grep -n '^ [^ *]';
$ find src -type f | xargs grep -n '^ [^ ]';
$ find src -type f | xargs grep -n '^ [^ *]';
$ find src -type f | xargs grep -n '^ [^ +]';
$ find src -type f | xargs grep -n '^ [^ *+]';
$ find src -type f | xargs grep -n '^ [^ +]';
$ find src -type f | xargs grep -n '^ [^ *+]';
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1936:953434450ea9 Thu Aug 12 08:23:00 UTC 2021 Oisin Canty <o.canty@f5.com> Router: client IP address replacement.

This commit introduces the replacement of the client address based on the value
of a specified HTTP header. This is intended for use when Unit is placed
behind a reverse proxy like nginx or a CDN.

You must specify the source addresses of the trusted proxies. This can be
accomplished with any valid IP pattern supported by Unit's match block:

["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"]

The feature is configured per listener.

The client address replacement functionality only operates when there is a
source IP match and the specified header is present. Typically this would be
an 'X-Forwarded-For' header.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
},
"pass": "applications/my_app"
},
}
}

If a request occurs and Unit receives a header like below:

"X-Forwarded-For: 84.123.23.23"

By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR
will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8.

If Unit runs behind consecutive reverse proxies and receives a header similar
to the following:

"X-Forwarded-For: 84.123.23.23, 10.0.0.254"

You will need to enable "recursive" checking, which walks the header from
last address to first and chooses the first non-trusted address it finds.

{
"listeners": {
"127.0.0.1:8080": {
"client_ip": {
"header": "X-Forwarded-For",
"source": [
"10.0.0.0/8"
]
"recursive": true,
},
"pass": "applications/my_app"
},
}
}

If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254
is also a trusted address so the client address will be replaced with
84.123.23.23.

If all IP addresses in the header are trusted, the client address is set to
the first address in the header:

If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1",
the client address will be replaced with 10.0.0.3.
diff 1651:8dcd8563fe99 Mon Oct 12 21:56:00 UTC 2020 Igor Sysoev <igor@sysoev.ru> Using union instead of "void *".
H A Dnxt_application.hdiff 354:8fc82db3530b Thu Oct 05 13:46:00 UTC 2017 Valentin Bartenev <vbart@nginx.com> Improved applications versions handling.
H A Dnxt_application.cdiff 354:8fc82db3530b Thu Oct 05 13:46:00 UTC 2017 Valentin Bartenev <vbart@nginx.com> Improved applications versions handling.
H A Dnxt_listen_socket.cdiff 1449:8bcb79f5d69d Wed Apr 08 12:15:00 UTC 2020 Valentin Bartenev <vbart@nginx.com> Removed unused code related to testing of address binding.
H A Dnxt_var.hdiff 1954:8f18a05d4c58 Tue Sep 07 13:13:00 UTC 2021 Zhidao HONG <z.hong@f5.com> Router: refactored variable pass.

Since the "pass" option supports both strings and variables, a generic
nxt_var_t structure can be used in the configuration phase, and the "name"
field in actions is redundant.

No functional changes.
H A Dnxt_runtime.cdiff 1449:8bcb79f5d69d Wed Apr 08 12:15:00 UTC 2020 Valentin Bartenev <vbart@nginx.com> Removed unused code related to testing of address binding.
diff 354:8fc82db3530b Thu Oct 05 13:46:00 UTC 2017 Valentin Bartenev <vbart@nginx.com> Improved applications versions handling.
diff 54:8c3dfaedd423 Tue Jun 06 15:53:00 UTC 2017 Igor Sysoev <igor@sysoev.ru> The controller did not work because of changes in the previous
changeset.
/unit/auto/modules/
H A Djavadiff 2397:817968931c58 Wed Mar 22 15:55:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Auto: mirroring installation structure in build tree.

This makes the build tree more organized, which is good for adding new
stuff. Now, it's useful for example for adding manual pages in man3/,
but it may be useful in the future for example for extending the build
system to run linters (e.g., clang-tidy(1), Clang analyzer, ...) on the
C source code.

Previously, the build tree was quite flat, and looked like this (after
`./configure && make`):

$ tree -I src build
build
├── Makefile
├── autoconf.data
├── autoconf.err
├── echo
├── libnxt.a
├── nxt_auto_config.h
├── nxt_version.h
├── unitd
└── unitd.8

1 directory, 9 files

And after this patch, it looks like this:

$ tree -I src build
build
├── Makefile
├── autoconf.data
├── autoconf.err
├── bin
│ └── echo
├── include
│ ├── nxt_auto_config.h
│ └── nxt_version.h
├── lib
│ ├── libnxt.a
│ └── unit
│ └── modules
├── sbin
│ └── unitd
├── share
│ └── man
│ └── man8
│ └── unitd.8
└── var
├── lib
│ └── unit
├── log
│ └── unit
└── run
└── unit

17 directories, 9 files

It also solves one issue introduced in
5a37171f733f ("Added default values for pathnames."). Before that
commit, it was possible to run unitd from the build system
(`./build/unitd`). Now, since it expects files in a very specific
location, that has been broken. By having a directory structure that
mirrors the installation, it's possible to trick it to believe it's
installed, and run it from there:

$ ./configure --prefix=./build
$ make
$ ./build/sbin/unitd

Fixes: 5a37171f733f ("Added default values for pathnames.")
Reported-by: Liam Crilly <liam@nginx.com>
Reviewed-by: Konstantin Pavlov <thresh@nginx.com>
Reviewed-by: Andrew Clayton <a.clayton@nginx.com>
Cc: Andrei Zeliankou <zelenkov@nginx.com>
Cc: Zhidao Hong <z.hong@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2397:817968931c58 Wed Mar 22 15:55:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Auto: mirroring installation structure in build tree.

This makes the build tree more organized, which is good for adding new
stuff. Now, it's useful for example for adding manual pages in man3/,
but it may be useful in the future for example for extending the build
system to run linters (e.g., clang-tidy(1), Clang analyzer, ...) on the
C source code.

Previously, the build tree was quite flat, and looked like this (after
`./configure && make`):

$ tree -I src build
build
├── Makefile
├── autoconf.data
├── autoconf.err
├── echo
├── libnxt.a
├── nxt_auto_config.h
├── nxt_version.h
├── unitd
└── unitd.8

1 directory, 9 files

And after this patch, it looks like this:

$ tree -I src build
build
├── Makefile
├── autoconf.data
├── autoconf.err
├── bin
│ └── echo
├── include
│ ├── nxt_auto_config.h
│ └── nxt_version.h
├── lib
│ ├── libnxt.a
│ └── unit
│ └── modules
├── sbin
│ └── unitd
├── share
│ └── man
│ └── man8
│ └── unitd.8
└── var
├── lib
│ └── unit
├── log
│ └── unit
└── run
└── unit

17 directories, 9 files

It also solves one issue introduced in
5a37171f733f ("Added default values for pathnames."). Before that
commit, it was possible to run unitd from the build system
(`./build/unitd`). Now, since it expects files in a very specific
location, that has been broken. By having a directory structure that
mirrors the installation, it's possible to trick it to believe it's
installed, and run it from there:

$ ./configure --prefix=./build
$ make
$ ./build/sbin/unitd

Fixes: 5a37171f733f ("Added default values for pathnames.")
Reported-by: Liam Crilly <liam@nginx.com>
Reviewed-by: Konstantin Pavlov <thresh@nginx.com>
Reviewed-by: Andrew Clayton <a.clayton@nginx.com>
Cc: Andrei Zeliankou <zelenkov@nginx.com>
Cc: Zhidao Hong <z.hong@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
H A Dwasm-wasi-component2688:83a6f5cccb92 Tue Feb 06 04:20:00 UTC 2024 Andrew Clayton <a.clayton@nginx.com> Wasm-wc: Wire it up to the build system

Et voila...

$ ./configure wasm-wasi-component
configuring wasm-wasi-component module
Looking for rust compiler ... found.
Looking for cargo ... found.
+ wasm-wasi-component module: wasm_wasi_component.unit.so
$ make install
test -d /opt/unit/sbin || install -d /opt/unit/sbin
install -p build/sbin/unitd /opt/unit/sbin/
test -d /opt/unit/state || install -d /opt/unit/state
test -d /opt/unit || install -d /opt/unit
test -d /opt/unit || install -d /opt/unit
test -d /opt/unit/share/man/man8 || install -d /opt/unit/sh
man/man8
install -p -m644 build/share/man/man8/unitd.8 /opt/unit/share/ma
n8/
make build/src/nxt_unit.o
make[1]: Entering directory '/home/andrew/src/unit'
make[1]: 'build/src/nxt_unit.o' is up to date.
make[1]: Leaving directory '/home/andrew/src/unit'
cargo build --release --manifest-path src/wasm-wasi-component/Cargo.toml
Finished release [optimized] target(s) in 0.55s
install -d /opt/unit/modules
install -p src/wasm-wasi-component/target/release/libwasm_wasi_component.so \
/opt/unit/modules/wasm_wasi_component.unit.so

Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
H A Dconfdiff 2688:83a6f5cccb92 Tue Feb 06 04:20:00 UTC 2024 Andrew Clayton <a.clayton@nginx.com> Wasm-wc: Wire it up to the build system

Et voila...

$ ./configure wasm-wasi-component
configuring wasm-wasi-component module
Looking for rust compiler ... found.
Looking for cargo ... found.
+ wasm-wasi-component module: wasm_wasi_component.unit.so
$ make install
test -d /opt/unit/sbin || install -d /opt/unit/sbin
install -p build/sbin/unitd /opt/unit/sbin/
test -d /opt/unit/state || install -d /opt/unit/state
test -d /opt/unit || install -d /opt/unit
test -d /opt/unit || install -d /opt/unit
test -d /opt/unit/share/man/man8 || install -d /opt/unit/sh
man/man8
install -p -m644 build/share/man/man8/unitd.8 /opt/unit/share/ma
n8/
make build/src/nxt_unit.o
make[1]: Entering directory '/home/andrew/src/unit'
make[1]: 'build/src/nxt_unit.o' is up to date.
make[1]: Leaving directory '/home/andrew/src/unit'
cargo build --release --manifest-path src/wasm-wasi-component/Cargo.toml
Finished release [optimized] target(s) in 0.55s
install -d /opt/unit/modules
install -p src/wasm-wasi-component/target/release/libwasm_wasi_component.so \
/opt/unit/modules/wasm_wasi_component.unit.so

Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
diff 215:8a9196260805 Thu Aug 17 18:47:00 UTC 2017 Igor Sysoev <igor@sysoev.ru> Removing auto/modules directory before commiting the new module
configuration infrastructure.
/unit/auto/
H A Dhelpdiff 2688:83a6f5cccb92 Tue Feb 06 04:20:00 UTC 2024 Andrew Clayton <a.clayton@nginx.com> Wasm-wc: Wire it up to the build system

Et voila...

$ ./configure wasm-wasi-component
configuring wasm-wasi-component module
Looking for rust compiler ... found.
Looking for cargo ... found.
+ wasm-wasi-component module: wasm_wasi_component.unit.so
$ make install
test -d /opt/unit/sbin || install -d /opt/unit/sbin
install -p build/sbin/unitd /opt/unit/sbin/
test -d /opt/unit/state || install -d /opt/unit/state
test -d /opt/unit || install -d /opt/unit
test -d /opt/unit || install -d /opt/unit
test -d /opt/unit/share/man/man8 || install -d /opt/unit/sh
man/man8
install -p -m644 build/share/man/man8/unitd.8 /opt/unit/share/ma
n8/
make build/src/nxt_unit.o
make[1]: Entering directory '/home/andrew/src/unit'
make[1]: 'build/src/nxt_unit.o' is up to date.
make[1]: Leaving directory '/home/andrew/src/unit'
cargo build --release --manifest-path src/wasm-wasi-component/Cargo.toml
Finished release [optimized] target(s) in 0.55s
install -d /opt/unit/modules
install -p src/wasm-wasi-component/target/release/libwasm_wasi_component.so \
/opt/unit/modules/wasm_wasi_component.unit.so

Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
diff 1825:8d0b26746b02 Wed Mar 24 15:45:00 UTC 2021 Konstantin Pavlov <thresh@nginx.com> Added build system support for a man page.
/unit/src/test/
H A Dnxt_rbtree1.c384:8f86d3ff3e29 Tue Nov 21 15:55:00 UTC 2017 Andrey Zelenkov <zelenkov@nginx.com> Tests: move existing tests to "src" folder.
H A Dnxt_rbtree1.h384:8f86d3ff3e29 Tue Nov 21 15:55:00 UTC 2017 Andrey Zelenkov <zelenkov@nginx.com> Tests: move existing tests to "src" folder.
/unit/tools/
H A Dsetup-unitdiff 2327:21ea08716cdb Wed Jan 11 14:25:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Tools: using nicer characters for showing a tree.

Especially in small trees, ASCII characters are confusing. Use nicer
UTF-8 characters, which are more readable to the audience of this
script. We don't expect the audience of this script to have limited
environments where these characters will not be shown, but if that
happens, we could improve the script to select the caracters based on
the locale.

Suggested-by: Liam Crilly <liam@nginx.com>
Reviewed-by: Andrew Clayton <a.clayton@nginx.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2296:150700770bec Fri Dec 16 20:39:00 UTC 2022 Alejandro Colomar <alx@nginx.com> Tools: setup-unit: workarounded macOS tmp file permissions.

mktemp(1) in macOS uses a weird directory where only the running user
has permissions. If we use that for the welcome website, unitd(8) won't
be able to read the page. Use a directory at $HOME before trying a tmpdir.

Reported-by: Liam Crilly <lcrilly@nginx.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2275:bbbd019be180 Mon Nov 21 17:20:00 UTC 2022 Alejandro Colomar <alx@nginx.com> Tools: Added subcommands to setup-unit.

This script combines the old setup-unit (as the repo-config command),
with new functionality, to provide an easy welcome website for
first-time users, and also some more commands that are useful for
administrating a running unitd(8) instance.

Suggested-by: Liam Crilly <liam@nginx.com>
Cc: Konstantin Pavlov <thresh@nginx.com>
Cc: Artem Konev <a.konev@f5.com>
Cc: Timo Start <t.stark@nginx.com>
Cc: Andrew Clayton <a.clayton@nginx.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
/unit/docs/man/man8/
H A Dunitd.8.indiff 2447:86c75d5004cf Mon May 08 16:07:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Docs: removed incorrect Pp call in unitd.8.

Pp is used to separate paragraphs, not to introduce them. A Pp macro
call right after Sh is wrong, and it is ignored by the formatter, which
reports a warning about it.

Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2446:fc4b80122a9c Thu Apr 27 12:21:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Docs: using appropriate mdoc(7) macros for URIs in unitd.8.

Reviewed-by: Artem Konev <a.konev@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2445:8dc162d8d979 Wed Apr 26 14:18:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Docs: changed Authors section to Copyright section in unitd.8.

The Authors section is meant to list the main authors. However, the
section only contained the copyright notice, so the Copyright section
seems more appropriate. While we change that, it makes sense to also
specify the license, and update the copyright year.

Reviewed-by: Liam Crilly <liam@nginx.com>
Reviewed-by: Artem Konev <a.konev@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2445:8dc162d8d979 Wed Apr 26 14:18:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Docs: changed Authors section to Copyright section in unitd.8.

The Authors section is meant to list the main authors. However, the
section only contained the copyright notice, so the Copyright section
seems more appropriate. While we change that, it makes sense to also
specify the license, and update the copyright year.

Reviewed-by: Liam Crilly <liam@nginx.com>
Reviewed-by: Artem Konev <a.konev@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2444:e1ad7b09d607 Wed Apr 26 13:55:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Docs: updated unitd.8 date.

We've applied significant changes to the page, so let's update the date.
While we're at it, let's change it to use ISO 8601 format for the date.

Reviewed-by: Artem Konev <a.konev@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2443:847d56226c4e Wed Apr 26 13:50:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Docs: setting the project name in unitd.8.

Not setting it produces the default value of 'BSD' or 'GNU', depending
on the software formatting the manual page. We're neither, so let's
specify our project name. See groff_mdoc(7). While mandoc_mdoc(7)
formally says that .Os is only for the operating system, and not for the
package name, that's an oversimplification, and only meant for software
inherent to the OS. For portable software, mandoc(1)'s (and OpenBSD's)
maintainer Ingo Schwarze agreed that it is more sensible to specify the
project name (and optionally, the version).

Reviewed-by: Artem Konev <a.konev@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2442:5be10db7f89f Wed Apr 26 13:40:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Docs: documenting the renamed directory flags in unitd.8.

Reviewed-by: Artem Konev <a.konev@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2441:4d73bc809457 Wed Apr 26 13:29:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Docs: not using shouty caps in unitd.8.

There was a recent unanimous agreement by maintainers of groff, mandoc,
the Linux man-pages, and other relevant programmers, that manual pages
should not use uppercase unnecessarily. Use of uppercase in the title
and in the section's titles dates from before one could use bold,
italics, and other such formatting, so that it was the way of giving
more importance to certain parts of a page. Nowadays, we use bold, so
uppercase is unnecessary.

Moreover, using uppercase in the title is bad, since it removes
information. If we keep the exact casing used in the program (or
function) name, we provide more information. And anyway, if users want
to read in uppercase, they can program certain mdoc(7) or man(7) macros
to transform their arguments into uppercase. This could be done via
</etc/groff/mdoc.local> and </etc/groff/man.local>.

There's a plan of transforming OpenBSD pages and the Linux man-pages to
stop using uppercase. Other projects may join. That will likely happen
in the following months. Let's align with this.

Reviewed-by: Artem Konev <a.konev@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
diff 2440:446c6763c8f8 Wed Apr 26 13:02:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Docs: removed '-v' from unitd.8.

This short option is not really supported. Probably it was just a typo.

Reviewed-by: Artem Konev <a.konev@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>
2439:4cabfc9895f4 Mon Apr 24 15:59:00 UTC 2023 Alejandro Colomar <alx@nginx.com> Docs: moved uintd.8 to man8/ subdirectory.

Reviewed-by: Artem Konev <a.konev@f5.com>
Signed-off-by: Alejandro Colomar <alx@nginx.com>

12345678910