diff --git a/CVE-2025-8671.patch b/CVE-2025-8671.patch deleted file mode 100644 index d3176d38bf6f714a8be97670f98a64339bc70a91..0000000000000000000000000000000000000000 --- a/CVE-2025-8671.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 8442ca4c699566cdd7369e09690926f403b54fc9 Mon Sep 17 00:00:00 2001 -From: Glenn Strauss -Date: Wed, 13 Aug 2025 08:52:15 -0400 -Subject: [PATCH] [h2] attempt to detect HTTP/2 MadeYouReset DoS - -attempt to detect HTTP/2 MadeYouReset DoS attack VU#767506 CVE-2025-8671 - -x-ref: - https://kb.cert.org/vuls/id/767506 - https://www.cve.org/CVERecord?id=CVE-2025-8671 ---- - src/h2.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- - src/h2.h | 1 + - 2 files changed, 103 insertions(+), 4 deletions(-) - -diff --git a/src/h2.c b/src/h2.c -index 7926a5e9e..b4299453b 100644 ---- a/src/h2.c -+++ b/src/h2.c -@@ -349,6 +349,11 @@ h2_send_rst_stream_state (request_st * const r, h2con * const h2c) - } - - -+__attribute_cold__ -+static void -+h2_send_goaway_e (connection * const con, const request_h2error_t e); -+ -+ - __attribute_cold__ - static void - h2_send_rst_stream (request_st * const r, connection * const con, const request_h2error_t e) -@@ -356,6 +361,97 @@ h2_send_rst_stream (request_st * const r, connection * const con, const request_ - /*(set r->x.h2.state=H2_STATE_CLOSED)*/ - h2_send_rst_stream_state(r, (h2con *)con->hx); - h2_send_rst_stream_id(r->x.h2.id, con, e); -+ -+ /* attempt to detect HTTP/2 MadeYouReset DoS attack VU#767506 CVE-2025-8671 -+ * heuristic to detect excessive err sent by client to cause reset by server -+ * Ignore H2_E_NO_ERROR and H2_E_INTERNAL_ERROR. -+ * Were H2_E_INTERNAL_ERROR to be included, there might be false positives -+ * (not attacks) in the count. Ignoring H2_E_INTERNAL_ERROR here does not -+ * count *response* headers too long, but that is not a client error. -+ * Ignore H2_E_REFUSED_STREAM, which is counted separately, elsewhere, -+ * but not listed in conditional below since H2_E_REFUSED_STREAM is sent -+ * directly via h2_send_rst_stream_id(), not h2_send_rst_stream() -+ * Include all other errors, though some are more prevalent than others: -+ * H2_E_PROTOCOL_ERROR, H2_E_FLOW_CONTROL_ERROR, H2_E_STREAM_CLOSED, -+ * H2_E_FRAME_SIZE_ERROR, H2_E_COMPRESSION_ERROR, ... -+ * Many such errors are sent with GOAWAY, so not as relevant to count here. -+ * If r->x.h2.state is not H2_STATE_CLOSED, include H2_E_STREAM_CLOSED here. -+ * -+ * Errors for unrecognized (not currently active) stream id are not counted -+ * here, but also do not affect potentially in-progress streams which are -+ * consuming resources in lighttpd and/or backends, e.g. if request headers -+ * are not yet complete, a backend to handle request has not been started. -+ * -+ * Similar to h2_recv_rst_stream() for HTTP/2 Rapid Reset attack, -+ * send GOAWAY with H2_E_NO_ERROR if count exceeds the policy limit since if -+ * peer is triggering server to send RST_STREAM, the peer is misbehaving, -+ * whether or not it is multiplexing requests from different clients, but a -+ * naive peer multiplexing requests from different clients could result in -+ * more reset (failed) streams of valid streams if one client could trigger -+ * too many resets sent by server on a single multiplexed connection, and -+ * server resets all streams and sends GOAWAY w/ error (not H2_E_NO_ERROR). -+ * log watchers such as fail2ban could watch for error log trace indicating -+ * detection of this attack, and could respond accordingly, across multiple -+ * servers. In lighttpd, a client could trigger server-sent reset stream w/ -+ * e.g. mismatch between received data and Content-Length, when provided. -+ */ -+ if (e != H2_E_NO_ERROR && e != H2_E_INTERNAL_ERROR) { -+ /* simulate receiving TCP FIN from client to trigger imminent shutdown() -+ * on socket connection to backend, indicating request terminated. -+ * Note: mod_cgi must be configured for this to have any effect, -+ * e.g. cgi.limits += ("tcp-fin-propagate" => "SIGTERM") -+ * Regardless of whether or not this optimization is performed, -+ * lighttpd will schedule close() on backend socket (or CGI pipe) -+ * and will close() backend socket (or kill CGI) upon next poll cycle */ -+ /*r->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_TCP_FIN;*/ -+ if (r->handler_module) -+ joblist_append(con); /*(cause short poll for next poll cycle)*/ -+ -+ /* increment h2c->n_send_rst_stream_err and check for policy violation -+ * -+ * time step interval currently 2 secs: (log_monotonic_secs >> 1) -+ * store time bits in upper nibble of h2c->n_send_rst_stream_err -+ * (32-second time slice: ((log_monotonic_secs >> 1) & 0xF)) -+ * time_bits are only 4 bits, so repeated time_bits could cause false -+ * positive and not decay the counter, but well-behaved peers should -+ * not trigger *any* RST_STREAM, so tripping the policy sooner is ok. -+ * (rather than potentially missing policy violation (false negative)) -+ * decay counter (divide by 2 (>> 1)) when time step interval changes -+ * (any time interval change; not shifting by (cur_bits - time_bits)) -+ * counter is 4 bits, so max is 15 (0xF) unless bit masks are adjusted -+ * -+ * XXX: server triggered to send RST_STREAM w/ error is unexpected -+ * A stricter implementation might send GOAWAY H2_E_NO_ERROR -+ * upon first occurrence. -+ */ -+ h2con * const h2c = (h2con *)con->hx; -+ uint8_t cur_bits = (log_monotonic_secs >> 1) & 0xF; -+ uint8_t time_bits = h2c->n_send_rst_stream_err >> 4; -+ if (cur_bits != time_bits) -+ h2c->n_send_rst_stream_err = -+ (cur_bits << 4) | ((h2c->n_send_rst_stream_err & 0xF) >> 1); -+ if (!h2c->sent_goaway && (++h2c->n_send_rst_stream_err & 0xF) > 4) { -+ log_error(NULL, __FILE__, __LINE__, -+ "h2: %s triggered too many RST_STREAM too quickly (xaddr:%s)", -+ con->request.dst_addr_buf->ptr, r->dst_addr_buf->ptr); -+ h2_send_goaway_e(con, H2_E_NO_ERROR); -+ /* h2_send_goaway_e w/ H2_E_PROTOCOL_ERROR or H2_E_ENHANCE_YOUR_CALM -+ * would cause other request streams to be reset (and would have to -+ * check h2c->send_goaway <= 0 above instead of !h2c->sent_goaway)*/ -+ } -+ } -+} -+ -+ -+__attribute_cold__ -+__attribute_noinline__ -+static void -+h2_send_rst_stream_closed (request_st * const r, connection * const con) -+{ -+ if (r->x.h2.state == H2_STATE_CLOSED) /*already closed; rst_stream_id only*/ -+ h2_send_rst_stream_id(r->x.h2.id, con, H2_E_STREAM_CLOSED); -+ else /*(r->x.h2.state == H2_STATE_HALF_CLOSED_REMOTE)*/ -+ h2_send_rst_stream(r, con, H2_E_STREAM_CLOSED); - } - - -@@ -593,6 +689,8 @@ h2_recv_rst_stream (connection * const con, const uint8_t * const s, const uint3 - /* XXX: ? add debug trace including error code from RST_STREAM ? */ - r->state = CON_STATE_ERROR; - r->x.h2.state = H2_STATE_CLOSED; -+ if (r->handler_module) -+ joblist_append(con); /*(cause short poll for next poll cycle)*/ - - /* attempt to detect HTTP/2 rapid reset attack (CVE-2023-44487) - * Send GOAWAY if 17 or more requests in recent batch of up to 32 -@@ -608,8 +706,8 @@ h2_recv_rst_stream (connection * const con, const uint8_t * const s, const uint3 - (h2c->n_recv_rst_stream >> 4) + (h2c->n_recv_rst_stream & 0xf); - if (n_recv_rst_stream > 16) { - log_error(NULL, __FILE__, __LINE__, -- "h2: %s sent too many RST_STREAM too quickly", -- con->request.dst_addr_buf->ptr); -+ "h2: %s sent too many RST_STREAM too quickly (xaddr:%s)", -+ con->request.dst_addr_buf->ptr, r->dst_addr_buf->ptr); - h2_send_goaway_e(con, H2_E_NO_ERROR); - } - } -@@ -1137,7 +1235,7 @@ h2_recv_data (connection * const con, const uint8_t * const s, const uint32_t le - - if (r->x.h2.state == H2_STATE_CLOSED - || r->x.h2.state == H2_STATE_HALF_CLOSED_REMOTE) { -- h2_send_rst_stream_id(id, con, H2_E_STREAM_CLOSED); -+ h2_send_rst_stream_closed(r, con); /* H2_E_STREAM_CLOSED */ - chunkqueue_mark_written(cq, 9+len); - h2_send_window_update_unit(con, h2r, len); /*(h2r->x.h2.rwin)*/ - return 1; -@@ -1515,7 +1613,7 @@ h2_recv_trailers_r (connection * const con, h2con * const h2c, const uint32_t id - } - if (r->x.h2.state != H2_STATE_OPEN - && r->x.h2.state != H2_STATE_HALF_CLOSED_LOCAL) { -- h2_send_rst_stream(r, con, H2_E_STREAM_CLOSED); -+ h2_send_rst_stream_closed(r, con); /* H2_E_STREAM_CLOSED */ - return NULL; - } - /* RFC 7540 is not explicit in restricting HEADERS (trailers) following -diff --git a/src/h2.h b/src/h2.h -index 2112c6377..53541fe54 100644 ---- a/src/h2.h -+++ b/src/h2.h -@@ -91,6 +91,7 @@ struct h2con { - uint8_t n_refused_stream; - uint8_t n_discarded_headers; - uint8_t n_recv_rst_stream; -+ uint8_t n_send_rst_stream_err; - }; - typedef struct h2con h2con; - diff --git a/lighttpd-1.4.77.tar.xz b/lighttpd-1.4.77.tar.xz deleted file mode 100644 index b091875d32a896286d1299705602f3185a706fc0..0000000000000000000000000000000000000000 Binary files a/lighttpd-1.4.77.tar.xz and /dev/null differ diff --git a/lighttpd-1.4.77-defaultconf.patch b/lighttpd-1.4.79-defaultconf.patch similarity index 38% rename from lighttpd-1.4.77-defaultconf.patch rename to lighttpd-1.4.79-defaultconf.patch index bda5243c73a52bf8a557cc64e814ffc1f4255add..d4fb40e0b0002db0899461df8ca2e641355a2969 100644 --- a/lighttpd-1.4.77-defaultconf.patch +++ b/lighttpd-1.4.79-defaultconf.patch @@ -1,5 +1,20 @@ ---- doc/config/lighttpd.annotated.conf.orig 2025-01-10 12:38:45.338557175 -0600 -+++ doc/config/lighttpd.annotated.conf 2025-01-10 12:39:45.326238702 -0600 +diff --git a/doc/config/conf.d/tls.conf b/doc/config/conf.d/tls.conf +index 365c23f..e55d35a 100644 +--- a/doc/config/conf.d/tls.conf ++++ b/doc/config/conf.d/tls.conf +@@ -23,7 +23,7 @@ server.modules += ( "mod_openssl" ) + ## lighttpd TLS defaults are strict and compatible with modern clients. + ## If your organization requires use of system-managed TLS defaults to + ## override lighttpd TLS defaults, use "CipherString" => "PROFILE=SYSTEM" +-#ssl.openssl.ssl-conf-cmd += ("CipherString" => "PROFILE=SYSTEM") ++ssl.openssl.ssl-conf-cmd += ("CipherString" => "PROFILE=SYSTEM") + + ## enable TLS on specified listening addresses + #$SERVER["socket"] == "*:443" { +diff --git a/doc/config/lighttpd.annotated.conf b/doc/config/lighttpd.annotated.conf +index e0f806e..81c58bb 100644 +--- a/doc/config/lighttpd.annotated.conf ++++ b/doc/config/lighttpd.annotated.conf @@ -14,8 +14,8 @@ ## chroot example as well. ## @@ -11,7 +26,7 @@ var.home_dir = "/var/lib/lighttpd" var.conf_dir = "/etc/lighttpd" -@@ -114,7 +114,7 @@ +@@ -114,7 +114,7 @@ server.groupname = "lighttpd" ## ## Document root ## @@ -20,12 +35,3 @@ ## ## The value for the "Server:" response field. -@@ -415,7 +415,7 @@ - ## # lighttpd TLS defaults are strict and compatible with modern clients. - ## # If your organization requires use of system-managed TLS defaults to - ## # override lighttpd TLS defaults, use "CipherString" => "PROFILE=SYSTEM" --## #ssl.openssl.ssl-conf-cmd += ("CipherString" => "PROFILE=SYSTEM") -+ssl.openssl.ssl-conf-cmd += ("CipherString" => "PROFILE=SYSTEM") - ## - ## $SERVER["socket"] == "*:443" { - ## ssl.engine = "enable" diff --git a/lighttpd-1.4.81.tar.xz b/lighttpd-1.4.81.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..8943cb30c13048b8296477cf17c560f58d3ec43a Binary files /dev/null and b/lighttpd-1.4.81.tar.xz differ diff --git a/lighttpd.logrotate b/lighttpd.logrotate index 28bb9018c70965b4e7318dc5a3c64553228b7222..aceb5090774cba734776d4586e9b139b9bfd374f 100644 --- a/lighttpd.logrotate +++ b/lighttpd.logrotate @@ -10,6 +10,6 @@ notifempty sharedscripts postrotate - /usr/bin/killall -HUP lighttpd &>/dev/null || : + /usr/bin/systemctl kill --signal=HUP --kill-whom=main lighttpd.service 2>/dev/null || true endscript } diff --git a/lighttpd.service b/lighttpd.service deleted file mode 100644 index 6eac246133b3a49578c5ab84c4e32307b2a25c2c..0000000000000000000000000000000000000000 --- a/lighttpd.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=Lightning Fast Webserver With Light System Requirements -After=syslog.target network.target - -[Service] -PIDFile=/run/lighttpd.pid -EnvironmentFile=-/etc/sysconfig/lighttpd -ExecStartPre=/usr/sbin/lighttpd -tt -f /etc/lighttpd/lighttpd.conf -ExecStart=/usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf -ExecReload=/bin/kill -USR1 $MAINPID -Restart=on-failure - -[Install] -WantedBy=multi-user.target - diff --git a/lighttpd.spec b/lighttpd.spec index 390e97f618fc72162af5451345b87d6d9e4346ca..93a0f5dfb31d40ec4223b2b10fd5a16110bcdb64 100644 --- a/lighttpd.spec +++ b/lighttpd.spec @@ -4,7 +4,7 @@ %bcond_with pcre %bcond_without pcre2 %bcond_without nettle -%bcond_with unwind +%bcond_with libunwind %bcond_without lua %bcond_without brotli %bcond_with bzip2 @@ -27,22 +27,17 @@ %bcond_without tmpfiles Summary: Lightning fast webserver with light system requirements Name: lighttpd -Version: 1.4.77 -Release: 2 -License: BSD-3-Clause and OML and GPLv3 and GPLv2 -URL: https://github.com/lighttpd/lighttpd1.4 -Source0: http://download.lighttpd.net/lighttpd/releases-1.4.x/lighttpd-%{version}.tar.xz +Version: 1.4.81 +Release: 1 +License: BSD-3-Clause +URL: https://www.lighttpd.net/ +Source0: https://download.lighttpd.net/lighttpd/releases-1.4.x/lighttpd-%{version}.tar.xz Source1: lighttpd.logrotate Source2: php.d-lighttpd.ini -Source3: lighttpd.service -Patch0: lighttpd-1.4.77-defaultconf.patch -# https://github.com/lighttpd/lighttpd1.4/commit/8442ca4c699566cdd7369e09690926f403b54fc9 -Patch1: CVE-2025-8671.patch - +Source4: lighttpd.sysusers.conf +Patch0: lighttpd-1.4.79-defaultconf.patch Requires: %{name}-filesystem system-logos -Requires(post): systemd -Requires(preun): systemd -Requires(postun): systemd +%{?systemd_requires} BuildRequires: systemd Requires(post): %{name}-mod_deflate Requires(post): %{name}-mod_webdav @@ -56,7 +51,7 @@ BuildRequires: /usr/bin/awk, libattr-devel, m4, pkg-config %{?with_pcre:BuildRequires: pcre-devel} %{?with_pcre2:BuildRequires: pcre2-devel} %{?with_nettle:BuildRequires: nettle-devel} -%{?with_unwind:BuildRequires: libunwind-devel} +%{?with_libunwind:BuildRequires: libunwind-devel} Provides: %{name}-mod_authn_mysql = %{version}-%{release} Obsoletes: %{name}-mod_authn_mysql <= 1.4.63-1 @@ -281,16 +276,14 @@ WebDAV module for lighttpd. %package filesystem Summary: The basic directory layout for lighttpd BuildArch: noarch -Requires(pre): /usr/sbin/useradd +%{?sysusers_requires_compat} %description filesystem The lighttpd-filesystem package contains the basic directory layout for the lighttpd server including the correct permissions for the directories. %prep -%setup -q -%patch -P 0 -b .defaultconf -%patch -P 1 -p1 +%autosetup -p1 %{name}-%{version} %build autoreconf -if @@ -319,7 +312,7 @@ autoreconf -if %{confswitch bzip2} \ %{confswitch brotli} \ %{confswitch maxminddb} \ - %{confswitch unwind} + %{confswitch libunwind} %make_build %install @@ -328,7 +321,7 @@ install -D -p -m 0644 %{SOURCE1} \ %{buildroot}%{_sysconfdir}/logrotate.d/lighttpd install -D -p -m 0644 %{SOURCE2} \ %{buildroot}%{_sysconfdir}/php.d/lighttpd.ini -install -D -p -m 0644 %{SOURCE3} \ +install -D -p -m 0644 doc/systemd/lighttpd.service \ %{buildroot}%{_unitdir}/lighttpd.service mkdir -p %{buildroot}%{webroot} rm -rf config @@ -346,9 +339,10 @@ echo 'D /run/lighttpd 0750 lighttpd lighttpd -' > \ %endif mkdir -p %{buildroot}%{_var}/lib/lighttpd/ +install -p -D -m 0644 %{S:4} %{buildroot}%{_sysusersdir}/lighttpd.conf + %pre filesystem -/usr/sbin/useradd -s /sbin/nologin -M -r -d %{webroot} \ - -c 'lighttpd web server' lighttpd &>/dev/null || : +%sysusers_create_compat %{S:4} %post %systemd_post lighttpd.service @@ -520,8 +514,14 @@ mkdir -p %{buildroot}%{_var}/lib/lighttpd/ %attr(0750, lighttpd, lighttpd) %{_var}/lib/lighttpd/ %attr(0750, lighttpd, lighttpd) %{_var}/log/lighttpd/ %attr(0700, lighttpd, lighttpd) %dir %{webroot}/ +%{_sysusersdir}/lighttpd.conf %changelog +* Tue Aug 19 2025 Funda Wang - 1.4.81-1 +- update to 1.4.81 +- use upstream systemdservice +- change group creation script into systemd style + * Mon Aug 18 2025 liweigang - 1.4.77-2 - Fix CVE-2025-8671 diff --git a/lighttpd.sysusers.conf b/lighttpd.sysusers.conf new file mode 100644 index 0000000000000000000000000000000000000000..dc74ef733e732a117baf73763eea371b9ecdc312 --- /dev/null +++ b/lighttpd.sysusers.conf @@ -0,0 +1 @@ +u lighttpd - 'lighttpd web server' /var/www/lighttpd - diff --git a/lighttpd.yaml b/lighttpd.yaml index bd04dfb26dfc51ae81a342f571e71c875fdce052..85763d171ce67aeb1fa9f7b44f47dc2a8a52d4e2 100644 --- a/lighttpd.yaml +++ b/lighttpd.yaml @@ -1,4 +1,4 @@ -version_control: github -src_repo: lighttpd/lighttpd1.4 -tag_prefix: "lighttpd-" +version_control: git +src_repo: https://git.lighttpd.net/lighttpd/lighttpd1.4.git +tag_prefix: "^lighttpd-" separator: .