1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-06-12 14:24:47 +02:00
Commit Graph

10696 Commits

Author SHA1 Message Date
Bram Matthys e2ed1ceca2 Load multiline by default and update release notes a little. 2026-06-11 19:57:53 +02:00
Bram Matthys 57ca415c26 Add whitespace deletion in buildvarstring() so template can have a space.
Basically if a $variable is empty, and there is a space before it in the
template string then we delete that space.

May seem (or is) a bit over the top but this way the template stays clean,
and it may be used/useful in other places as well.

This is a behavior change, but I think we can live with it. One can opt-
out via BUILDVARSTRING_KEEP_SPACE_FOR_EMPTY_VAR.
2026-06-11 19:19:53 +02:00
Bram Matthys 5850ec9434 Show TKL IDs (and related spamfilter TKL ID, if any) in TKL_ADD, TKL_DEL,
TKL_EXPIRE and SPAMFILTER_MATCH messages.

This uses the newly added functions log_data_optional_string() and
log_data_optional_name_value(). The first shows the optional string
like "abc" and the second expands to "[name: value]". What's also new
is that both of these will swallow a preceding space if there is no value.
This so you can just use "Something. $optional_string" and it will
expand to "Something." if $optional_string is empty. This makes things
less hacky and more human readable :)
2026-06-10 19:48:38 +02:00
Bram Matthys 62f3cda8f2 Make spamfilter IDs start with "SPAM" to be more visible. And this also
means shun IDs now start with "H". Update release notes.

This, after i realized that for like *LINEs that are added by spamfilter
the two ID fields in "STATS gline" are a bit confusing as to which ID is
what. Now the spamfilter one starts with "SPAM" so there can be no
confusion. The gline one still starts with "G" as before.

Since I kept the generated ID length the same, this means there is less
bits available for the spamfilter ID, but there are rarely more than 1000
spamfilters, and in that scenario there's just as little birthday attack
collision % as with 200k glines, just to illustrate (~0.0015% vs ~0.0018%)
2026-06-10 15:37:20 +02:00
Bram Matthys faecdd66cd Config-file based *LINES/Spamfilter: preserve hit counters between rehashes.
Unlike non-config-based TKLs - which go through tkldb - they are still not
preserved through restarts. But at least they are not lost due to REHASH.
This is done via a save+restore, a bit complicated, but we have little
choice (other than not doing this at all).

This also moves remove_config_tkls() from conf.c to tkl.c
2026-06-10 14:30:39 +02:00
Bram Matthys d5b799d3de Server bans and Spamfilters now track how often they are hit and the time
of the last hit, eg in `STATS gline` for GLINEs. These counts happen on
each individual server and are not network-wide. This allows IRCOps to see
which entries never get any hits and can potentially be removed.
* Important exception: config-based spamfilters/bans lose their counters
  on `REHASH` and restart atm.
* For non-config TKLs, the hit count and last hit timestamp are preserved
  across reboots (via tkldb).
* Again, see *Developers and protocol* for the exact STATS field.

The spamfilter hits already existed but all the rest is new.

Suggested by BlackBishop in https://bugs.unrealircd.org/view.php?id=6304
(in particular, time of the last hit)
2026-06-08 13:44:00 +02:00
LeCoyote 74557f2378 help.fr.conf: translation update, include eline, tline, new snomasks (#342) 2026-06-08 12:21:35 +02:00
Bram Matthys 27a086b03a Add TKL IDs via message tags in S2S.
By default - assuming you don't set set::reject-message things by yourself -
the *LINE id is appended at the end of the rejection that is shown to the
user, like: [ID: G7K2MP9WQX3].

Also new is spamfilter to *LINE mapping, so you can see which *LINE was
set by which SPAMFILTER. For this STATS gline and friends were enhanced.
In fact, multiple fields were added there, including some that are 0
(zero) placeholders at the moment. These will be set in a future commit.
Some things were combined here so we only have to break STATS and tkldb
database format once (unless i made a mistake, then the follow up commit
will correct that i guess :D).

This was requested by Hero in https://bugs.unrealircd.org/view.php?id=4397
in 2015. Again by musk in https://bugs.unrealircd.org/view.php?id=4397
in 2022. And on IRC by Chris and others.

As you can see it was not SUPER easy and a lot of thought went into this
(and in terms of S2S traffic it is part of something bigger too)
2026-06-07 17:19:00 +02:00
Bram Matthys b19573d562 Update release notes
[skip ci]
2026-06-05 18:29:57 +02:00
Bram Matthys 3571c9e75b Create BASEDIR with 0700. Just like we already did for almost all subdirs.
Only for ~/unrealircd/lib/ we had this ommision, and for ~/unrealircd itself.
I doubt this means a change for users, as all subdirs were already 0700
so then tightening of ~/unrealircd is not very important.
And only upsides... making things safer..
2026-06-05 17:24:25 +02:00
Bram Matthys be08bc2e33 Let's call it "./unrealircd mkcert" instead (like mkpasswd). Fix test suite. 2026-06-05 16:51:22 +02:00
Bram Matthys 982325fc82 Move "make pem" to "./unrealircd makecert" and make tools use this
and refer to this as well.

Suggested by PeGaSuS in https://bugs.unrealircd.org/view.php?id=6610

This also moves extras/tls.cnf to doc/conf/tls/tls.cnf which
also gets installed in ~/unrealircd/conf/tls/ (or whatever CONFDIR is)

And just to be clear: this means you can run "./unrealircd makecert"
without needing to go into BUILDDIR (or even having it at all).

At the same time, the generation commands have been modified slightly
so two warnings during certificate generation are no longer there.
2026-06-05 16:08:40 +02:00
Bram Matthys cbc9213d5e Similarly to previous, fix allow channel::except and spamfilter::except
so they actually work.
2026-06-05 10:36:46 +02:00
Bram Matthys 425a9b978a Fix deny channel::mask not working if security group. Reported by PeGaSuS. 2026-06-05 10:06:33 +02:00
Bram Matthys dee26e2e12 Add const to third argument of unreal_create_match() 2026-06-05 10:00:14 +02:00
Bram Matthys f0c0feff4f Set PCRE2 limits explicitly (to more sensible defaults), reported by Link420. 2026-06-05 09:43:22 +02:00
Bram Matthys caa01c9c8c Call update_known_user_cache() right before "Client connecting" log.
This is after PRE_LOCAL_CONNECT hook and can be useful in case some
module in there did something to the user that made them known-users.

And mention explicitly to module devs if they have things like
authentication mods that may move users between known<->unknown
that they should update the cache.
2026-05-20 10:16:29 +02:00
Bram Matthys 5e8a859102 Bump version and add placeholder empty release notes 2026-05-17 10:52:29 +02:00
Bram Matthys cfa1d7614c Another fix in url_unreal for rogue HTTPS servers (not super important) 2026-05-17 10:51:32 +02:00
Bram Matthys b46c0f20ab OutgoingWebRequest max_size is now also obeyed for file-backed URL API.
And the defines are more clear now (if .max_size is not set by caller.

DOWNLOAD_MAX_SIZE_MEMORY_BACKED: 1M
DOWNLOAD_MAX_SIZE_FILE_BACKED: 50M

The file-backed is mostly a defense-in-depth measure, so we don't
store infinite amounts of data in a download. Even though, in practice,
these - at least at the moment in unrealircd itself - all come from
trusted paths like remote includes.

In url_unreal.c we do the counting ourselves. In url_curl.c we use the
option CURLOPT_MAXFILESIZE_LARGE but this does not ensure it in all
cases so we still do our own counting as well in that file as well.
2026-05-17 10:30:11 +02:00
Bram Matthys 8b93339e42 url_unreal: limit chunked transfer header length (hardening) 2026-05-17 10:07:14 +02:00
Bram Matthys 1250b7f014 ** UnrealIRCd 6.2.5 ** 2026-05-15 13:35:12 +02:00
Bram Matthys 75bd6e87d3 Fix set::antimixedutf8::except not working
Reported by Le_Coyote in https://bugs.unrealircd.org/view.php?id=6625
2026-05-15 09:23:19 +02:00
Bram Matthys 9ba54b7eb3 Add +x to HELPOP SNOMASKS 2026-05-15 09:15:04 +02:00
Bram Matthys 69b2116826 Fix typo in linking message, mentioned by Gottem. 2026-05-14 11:24:49 +02:00
Bram Matthys 0f62b20972 Bump maxperip and connthrottle module version to 2.0.0 2026-05-13 15:40:50 +02:00
Bram Matthys 0007ccda47 Connthrottle has a start delay, but this makes no sense for the ipv6 stuff.
The start delay is there for the rate limit (since lots of users may
connect after starting the server). The IPv6 is not a ratelimit but a limit.
2026-05-13 13:34:21 +02:00
Bram Matthys 80771ac3b4 Handle some invalid values. Not an issue now, but if some caller screws up. 2026-05-13 13:09:48 +02:00
Bram Matthys 4af3695347 Show BUG_CT_NEGATIVE_COUNTER also in non-DEBUGMODE and limit to 5:60.
Not only that one, but all BUG_CT_* connthrottle "something isn't
right here" messages.
2026-05-13 13:08:38 +02:00
Bram Matthys 31b43dcb08 Fix CONNTHROTTLE_CHECK and use <addr>/<prefix> in 'STATS maxperip'
just like we do in 'STATS connthrottle'.
2026-05-13 08:30:45 +02:00
Bram Matthys 4c0d830ae1 Write release notes. 2026-05-08 19:24:07 +02:00
Bram Matthys a4361b7c90 Add set::known-cloud-services [yes|no] (enabled by default)
Install default maxperip/connect-flood exception for IRC platforms
that are so big that they are known to trip default maxperip restrictions
(per IPv4 IP or per IPv6 /64: 3 local users, 4 network-wide users)
on dozens of networks and that publish a stable list of IP ranges.
Currently only IRCCloud qualifies for this.

IRCCloud is in example conf since May 2023 (commit 82dbc4a297) as:
except ban { mask *.irccloud.com; type { maxperip; connect-flood; } }.
Unfortunately DNS sometimes fails to resolve. We have seen this happen
during an outage or server restart. People then mass-connect, but DNS
is not fully working (yet), leading to unresolved hostnames.

Recent stricter maxperip treatment for /64 IPv6 and the new /56, /48
and /32 restrictions in connthrottle make this problem worse. Without
these IP exceptions it would cause unwanted rejections.

If you don't want this, use: set { known-cloud-services no; }
(And then presumably you also don't want the except ban block
 that example conf has been shipping since 2023)
2026-05-07 09:15:36 +02:00
Bram Matthys 05ef211900 For connthrottle rate limiting (new-users) now check except tkl type 'c'
(connect-flood). Those users are exempt and not counted towards new users.

And the new ipv6-unknown-users-limit in connthrottle (which has nothing
do with rates, but counts, similar to maxperip, but only on unknown-users)
now checks tkl type 'm' (maxperip). Those are counted as "except unknowns".

This is more of what the admin would expect.
2026-05-06 18:54:10 +02:00
Bram Matthys 8bafd33286 Update example.conf with the new set::connthrottle::ipv6-unknown-users-limit
functionality.
[skip ci]
2026-05-06 10:28:32 +02:00
Bram Matthys 3e6f9f06e2 set::connthrottle::disabled-when::reputation-gathering default of 1 week
was stated in docs at https://www.unrealircd.org/docs/Connthrottle but
if this item was not there then the default was actually zero (0).
Now, that isn't too common, since we ship with example.conf with the
connthrottle block as shown there, so lots of users have the proper
default, but just in case someone hand-writes or removed that connthrottle
settings block ("because they are the default)"... :)
2026-05-06 09:39:40 +02:00
Bram Matthys e5be93a9f8 Suppress high rate events via set::log-throttle (similar to Linux kernel)
And ship with these by default (no need to copy this set block):

set {
	log-throttle {
		CONNTHROTTLE_IPV6_LIMIT 100:60;
		MAXPERIP_LIMIT 100:60;
	};
};

You can do the same for other events, or even override existing ones,
and use the special value "unlimited" to turn default set ratelimits off:

set {
	log-throttle {
		CONNTHROTTLE_IPV6_LIMIT 50:60;
		MAXPERIP_LIMIT unlimited;
	};
};

Suggested in 2020 at https://bugs.unrealircd.org/view.php?id=5523
(and keeping it simple)
2026-05-05 19:07:42 +02:00
Bram Matthys f765905b15 New snomask 'x' (set by default): maxperip/connthrottle connect rejections
When a client is rejected by maxperip (not new) or connthrottle
ipv6-unknown-users-limit (that one is new), a notice to +s +x will be sent.

maxperip ipv4 example:
*** Client testuser4 with IP 1.2.3.4 rejected: maxperip limit exceeded (4 global, max 3)

maxperip ipv6 with /64 example:
*** Client testuser4 with IP 2001:dbe:0:0:0:0:0:4 rejected: maxperip limit exceeded for 2001:dbe::/64 (4 local, max 3)

connthrottle example where /56 limit is exceeded:
*** Client testuser5 with IP 2001:db8:cafe:abcd:0:0:0:5 rejected:
    connthrottle ipv6-unknown-users-limit (cidr-56, max 4) exceeded for
    2001:db8:cafe::/56 (5 unknown / 0 excepted / 0 known)

Oh and this commit also fixes a typo in existing CONNTHROTTLE events,
which previously were CONNTHROTLE (a missing T).
2026-05-05 16:33:19 +02:00
Bram Matthys 0940ed5d13 Update the messages regarding too many (new) connections.
Changed "Too many connections from your IP" to have "[maxperip]" at the end.
Also create new setting and swap it with existing-one-during-development.

Long story short, we now have 3 different messages for these limits:

set::reject-message::too-many-connections
 "Too many connections from your IP [maxperip]"

set::reject-message::too-many-connections-ipv6-range
 "Too many connections from your IPv6 range ($prefix_addr/$prefix_len) [maxperip]"

set::reject-message::too-many-new-connections-ipv6-range
 "Too many new connections from this IPv6 range ($prefix_addr/$prefix_len) [connthrottle]"

So we explicitly mention whether it is maxperip or connthrottle limiting the
user, that should provide enough clue to the IRCOp if the user pastes the
message to them.
2026-05-05 13:24:01 +02:00
Bram Matthys 32e7dbfb3c Add connthrottle self-test that (only) runs in DEBUGMODE.
This verifies state every second. Obviously not for production.
2026-05-05 10:03:26 +02:00
Bram Matthys 2ae69be391 Implement IPv6 CIDR restrictions for unknown-users
Will do more in follow-up commits.
2026-05-05 10:03:25 +02:00
Bram Matthys 46e404f95f Remove setting that never worked and refer to set::default-ipv6-clone-mask 2026-05-05 10:03:25 +02:00
Bram Matthys 3a429dbd42 Add helper functions and start the IPv6 /128 to /64 transition in
connect-flood and maxperip module. This so they actually take
set::default-ipv6-clone-mask into account.

This also changes the maxperip module to a more simple method of
just freeing all entries and rebuilding the hash table on load.
That's necessary since now set::default-ipv6-clone-mask can change.
2026-05-05 10:03:22 +02:00
Bram Matthys 4adaddeee1 set_client_ip() was not updating client->sockhost. That meant in WEBIRC
situations connect-flood may not be working (it used the webirc ip,
which is almost always exempt, instead of the spoofed IP).
2026-05-05 09:51:19 +02:00
Bram Matthys 665d01b7ea Update release notes
[skip ci]
2026-05-02 19:34:30 +02:00
Bram Matthys 99f1f6a047 Update libsodium to 1.0.22. They may have fixed that arm64 compile issue ;)
We previously upgraded to 1.0.21 and then downgraded to 1.0.20.

Benefit of 1.0.22 is that they also claim to have fixed a warning flood
i am getting with clang 22.
2026-05-02 19:15:07 +02:00
Bram Matthys b96c1d2d1e Add autoconf/m4/pkg.m4 for now because otherwise my Ubuntu 26.04
uses their pkg.m4 which made pkg-config a hard requirement.
Such a hard requirement is probably fine later, but.. i don't want
to suddenly require that of users during UnrealIRCd 6 series.
2026-05-02 19:14:10 +02:00
Bram Matthys c0f68bfd08 Deprecate link::verify-certificate, as 'Client Authentication EKU' is being
dropped by public certificate authorities (as per Chrome Root Program).

The fix is to simply use 'spkifp'. The config warning has all the details.
2026-05-01 19:47:28 +02:00
Bram Matthys 17f78de265 Bump version to 6.2.5-git 2026-05-01 19:47:03 +02:00
Bram Matthys 717c9cbfa5 Fix OOB write on URL callback with 2GB+ response. Add new size limit.
The OOB write did not happen on file-backed downloads, such as remote
includes. It only happened for memory-backed requests, which are only
these 4 in standard UnrealIRCd: centralblocklist, central spam report,
other spamreport blocks (eg to dronebl) and the log block with
destination webhook. All those 4 cases are very likely to be trusted
web servers, given the nature of the data you are sending to them.

The fix was to extend the size fields everywhere to 64 bits. It was
applied to both URL backends: url_unreal.c and url_curl.c.

The new API feature is a 'max_size' in OutgoingWebRequest, which
defaults to 1MB. This is only used for memory-backed responses,
so not for real file downloads. This fixes not only the reported
bug but also the case where a rogue webserver was unbounded in
terms of what response it could send back, potentially filling
up gigabytes of server memory.

Reported by Link420.
2026-04-21 19:46:21 +02:00
Bram Matthys abbbcd16a9 ** UnrealIRCd 6.2.4 ** 2026-04-17 06:13:38 +02:00