provide standard types in first.h instead of base.h
provide lighttpd types in base_decls.h instead of settings.h
reduce headers exposed by headers for core data structures
do not expose <pcre.h> or <stdlib.h> in headers
move stat_cache_entry to stat_cache.h
reduce use of "server.h" and "base.h" in headers
fix segfault in reverse url-path mapping of Set-Cookie sent from backend
when proxy.header = ( "map-urlpath" => ( ... ) ) is used and there are
multiple Set-Cookie response headers with path= attributes which need to
be reverse mapped.
(thx ganto)
x-ref:
"Segfault with proxy-header map-urlpath"
https://redmine.lighttpd.net/issues/2879
centralize most waitpid() handling in core server, with hooks for
modules to be informed of pid and status when a process exits.
This enables faster discovery (and restart) of exited processes,
and also allows for lighttpd to manage backend processes in the
parent (master) process when server.max-worker > 0.
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
Provide a simple mechanism for mapping host and urlpath header strings
in proxied request and response well-known headers. This *is not*
intended as a one-size-fits-all, infinitely extensible, regex rewriting
engine. Instead, the proxy.header directive aims to provide built-in
functionality in mod_proxy for a few common use cases by performing
simple host matching or urlpath prefix matching, and using the
mapping of the first match. More complex use cases could possibly be
handled by a custom lighttpd module (which does not currently exist).
Note: the contents of the HTTP request-line and HTTP headers may or
may not be in normalized canonical forms, which may or may not influence
the simple matching performed. Admins should take care to provide safe
defaults (fail closed) if mapping is expected to occur and blindly
passing non-mapped requests is undesirable.
proxy.header = (
#"map-host-request" => (
#"-" => "...",#replace provided given Host request authority
#"..." => "-",#preserve existing authority (no further matching)
#"..." => "", #preserve existing authority (no further matching)
# #(equivalent to "xxx" => "xxx")
#"xxx" => "yyy", #map one string ("xxx") to another ("yyy")
#),
#"map-host-response" => (
#"-" => "...",#replace authority used in backend request
#"..." => "-",#replace with original authority
#"..." => "", #preserve existing authority (no further matching)
# #(equivalent to "xxx" => "xxx")
#"xxx" => "yyy", #map one string ("xxx") to another ("yyy")
#),
#"map-urlpath" => (
#"/xxx" => "/yyy",#map one urlpath prefix to another
#"/xxx/" => "/", #map one urlpath prefix to another
#"/xxx" => "", #map one urlpath prefix to another
#"/key" => "/value",
# Note: request headers have matching "key" prefix replaced with
# "value", and response headers have matching "value" prefix
# replaced with "key", with a pre-test of the "value" from the
# first-matched "key" in request headers (if there was a match)
#),
#"https-remap" => "enable",
# For https requests from client, map https:// to http://
# when map-host-request matches URI in request, and map http://
# to https:// when map-host-response matches URI in response.
# (mod_proxy currently sends all backend requests as http)
)
x-ref:
"feature to remove part of the URI when passing along requests..."
https://redmine.lighttpd.net/issues/152
To enable "Forwarded", must enable which params to include.
The recommended set is "for" and "proto" unless other params
are required and proper security precautions have been taken.
proxy.forwarded = ( "for" => 1,
"proto" => 1,
#"host" => 1,
#"by" => 1,
#"remote_user" => 1,
)
See https://tools.ietf.org/html/rfc7239 for info about "Forwarded"
x-ref:
"Forwarded HTTP Extension"
https://tools.ietf.org/html/rfc7239
"Forward authenticated user to proxied requests"
https://redmine.lighttpd.net/issues/2703
lighttpd appends the request "Host" to the non-standard header "X-Host"
when acting as a reverse proxy. This patch additionally appends "Host"
to the non-standard header "X-Forwarded-Host" to match the convention in
some other web servers
x-ref:
"mod_proxy should send the X-Forwarded-Host header to the proxied server"
https://redmine.lighttpd.net/issues/418
fix streaming response when server.stream-response-body = 2
and client catches up to stream from backend
(thx horgh)
x-ref:
"mod_fastcgi can fail to read entire response from server"
https://redmine.lighttpd.net/issues/2796
More specific checks on contents of array lists. Each module using
lists now does better checking on the types of values in the list
(strings, integers, arrays/lists)
This helps prevent misconfiguration of things like cgi.assign,
fastcgi.server, and scgi.server, where source code might be
served as static files if parenthesis are misplaced.
x-ref:
https://redmine.lighttpd.net/boards/2/topics/6571
It is still not a good idea for backend to send Transfer-Encoding unless
backend is mod_proxy, and mod_proxy should not currently receive chunked
response since mod_proxy sends HTTP/1.0 request.
If mod_proxy is changed to sent HTTP/1.1 request, then lighttpd would
need to check if client is HTTP/1.0 and would need to de-chunk and
remove any other transfer-codings if not supported by next-hop.
x-ref:
"error 500 (mod_cgi.c.601) cgi died"
https://redmine.lighttpd.net/issues/2786
The (misnamed) connection_reset hook is always called after a request,
whether request completes or is aborted, and whether keep-alive or not,
so no needed to repeat the same function in the handle_connection_close
hook.
attempt to route requests to same backends based on requestor (client)
IP address and target host and port of request.
(thx bra)
x-ref:
"Source IP sticky load balancing patch"
https://redmine.lighttpd.net/issues/2117
support Transfer-Encoding: chunked request body in conjunction with
server.stream-request-body = 0
dynamic handlers will still return 411 Length Required if
server.stream-request-body = 1 or 2 (!= 0)
since CGI-like env requires CONTENT_LENGTH be set
(and mod_proxy currently sends HTTP/1.0 requests to backends,
and Content-Length recommended for robust interaction with backend)
x-ref:
"request: support Chunked Transfer Coding for HTTP PUT"
https://redmine.lighttpd.net/issues/2156
(for persistence across multiple re-entries into routines upon
receiving fdevent)
(setting module debug flag in global scope is still recommended
since there are places where p->conf.debug is checked since
handler_ctx might not be available at all points)
Due to the POLLHUP behavior triggered on *BSD/Darwin, the shutdown()
had previously been limited to local connections. If interested in
squeezing the last bits of performance out of a machine, an admin
should configure local connections to be AF_UNIX instead of AF_INET
or AF_INET6 to localhost. The reason the shutdown() was originally
added in mod_proxy and mod_scgi was to aggressively reduce the number
of potential sockets in TIME_WAIT held by lighttpd.
(See commit:923688d2 "drain backend socket/pipe bufs upon FDEVENT_HUP",
done for reliability given the aforementioned *BSD/Darwin behavior.)
When using AF_UNIX, the TIME_WAIT issue does not exist, ergo, the
recommendation is to use AF_UNIX for local sockets, when available.
Using AF_UNIX sockets is a better solution to eliminate TIME_WAIT
than is TCP shutdown() half-close which, as we have seen, might not
be handled well by frameworks which are more complex than basic read
request, send response, and close.
x-ref:
"1.4.40/41 mod_proxy, mod_scgi may trigger POLLHUP on *BSD,Darwin"
https://redmine.lighttpd.net/issues/2743
mod_fastcgi, mod_scgi, and mod_proxy must enforce wait for POLLWR
after EINPROGRESS or else getsockopt(fd, SOL_SOCKET, SO_ERROR, ...)
may succeed even though socket connection is not yet established,
and subsequent writev() will fail ENOTCONN.
(thx pkubaj)
x-ref:
"1.4.40/41 writev failed: Socket is not connected (fastcgi,scgi,proxy)"
https://redmine.lighttpd.net/issues/2744
shutdown(fd, SHUT_WR) after sending request to proxy or SCGI
only if remote is local and platform is not *BSD or Darwin.
The reason this fix is special-casing *BSD and Darwin is that the Single
Unix Specification and POSIX.1-2013 clearly specify that POLLHUP event
should be returned by poll only when the stream is no longer writable.
A half-closed socket that is still writable clearly does not match that
condition, yet that is what I am seeing on Darwin (El Capitan), and
presumably what others are seeing on *BSD, from which Apple originally
inherited the Darwin TCP stack.
Single Unix Specification (SUSv2) from 1997
(yes, that is nearly 20 years ago):
http://pubs.opengroup.org/onlinepubs/007908799/xsh/poll.html
POLLHUP
The device has been disconnected. This event and POLLOUT are
mutually exclusive; a stream can never be writable if a hangup has
occurred. However, this event and POLLIN, POLLRDNORM, POLLRDBAND or
POLLPRI are not mutually exclusive. This flag is only valid in the
revents bitmask; it is ignored in the events member.
Updated version of The Open Group Base Specifications Issue 7
(published in 2013):
http://pubs.opengroup.org/onlinepubs/9699919799/
POLLHUP
A device has been disconnected, or a pipe or FIFO has been closed
by the last process that had it open for writing. Once set, the
hangup state of a FIFO shall persist until some process opens the
FIFO for writing or until all read-only file descriptors for the
FIFO are closed. This event and POLLOUT are mutually-exclusive;
a stream can never be writable if a hangup has occurred. However,
this event and POLLIN, POLLRDNORM, POLLRDBAND, or POLLPRI are not
mutually-exclusive. This flag is only valid in the revents bitmask;
it shall be ignored in the events member.
x-ref:
"1.4.40/41 mod_proxy, mod_scgi may trigger POLLHUP on *BSD,Darwin"
https://redmine.lighttpd.net/issues/2743
Strip bogus "Proxy" header before creating subprocess environment.
(mod_cgi, mod_fastcgi, mod_scgi, mod_ssi, mod_proxy)
Do not emit HTTP_PROXY to subprocess environment.
Some executables use HTTP_PROXY to configure outgoing proxy.
This is not a lighttpd security issue per se, but this change to
lighttpd adds a layer of defense to protect backend processes which
might be vulnerable due to blindly using this untrusted environment
variable. The HTTP_PROXY environment variable should not be trusted
by a program running in a CGI-like environment.
Mitigation in lighttpd <= 1.4.40 is to reject requests w/ Proxy header:
* Create "/path/to/deny-proxy.lua", read-only to lighttpd, with content:
if (lighty.request["Proxy"] == nil) then return 0 else return 403 end
* Modify lighttpd.conf to load mod_magnet and run lua code
server.modules += ( "mod_magnet" )
magnet.attract-raw-url-to = ( "/path/to/deny-proxy.lua" )
References:
https://www.kb.cert.org/vuls/id/797896
CGI web servers assign Proxy header values from client requests to
internal HTTP_PROXY environment variables
https://httpoxy.org/
httpoxy: A CGI application vulnerability
cygwin does not support ioctl on sockets, returning EOPTNOTSUPP
(would be better if cygwin used Windows ioctlsocket() instead)
Windows uses signed (socklen_t), so add some casts to quiet warnings
Windows path handling is convoluted, so disable one tests in mod_fastcgi
since trailing spaces are removed from URL for _WIN32 and __CYGWIN__ in
response.c