NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Go modules · #1042 by repository stars
Last release 3 days ago
04 Oct 2026
Ships fairly regularly
a new release about every 9 days
Nearly every release is documented
notes for 55 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
12 months old
149 releases · first in 2025
One column per month.
ADDED: Discovery takes a trusted DNS server, set under Settings, Discovery or for a single run, written as 9.9.9.9 , 127.0.0.1:53053 , tcp:// , tcp+ud
9.9.9.9, 127.0.0.1:53053, tcp://, tcp+udp:// or an https:// DNS-over-HTTPS URL, and tests a site through pinned addresses, given for a run under Pinned addresses or taken from the set the run is for - the server's answers are the reference for the DNS check, a proposed set gets the server as its DNS when a set can use it and keeps the pins, and a site whose name exists but has no address in DNS is reported as such, with a pointer to pinning, rather than as misspelled. The Fallback UDP DNS servers list and the unused Reference domain setting are gone.[redacted], and b4 refuses to load or save a configuration that still holds these placeholders.b4_status and b4_metrics and the metrics API count each connection once, so their fields changed - connections_seen, current_cps, current_pps and memory_percent gave way to per-minute connection counts, cpu_percent and rss_bytes, /api/metrics and /api/ws/metrics carry the new dashboard snapshot, and POST /api/escalations/clear clears escalations.DNS resolution failed (no such host) - the run did not tell a name without any address apart from a site that a strategy might still open.1 domains and 1 IPs, and in Russian the longer labels in the panel a set card opens from its Target, Split, Fake, Route, DNS and Escalate tabs ran into their values or wrapped onto a second line - the number was always followed by the same word, and the label column had a fixed width that the longer Russian labels did not fit.Could not fetch the installer: mkdir /tmp/b4update-...: no such file or directory when nothing could be created in /tmp, as seen in a MikroTik container after a restart, and with /tmp mounted noexec the web interface reported the update as started while nothing happened - b4 staged the installer in /tmp and ran it from there, and the installer moved to another directory only when /tmp was short of space./api/system/update with a version such as --remove or --arch=mips removed b4 or installed a binary for another architecture instead of updating - b4 passed the requested version to the installer unchecked, and the installer read it as one of its own options.Full Changelog: v1.84.0...v1.85.0
ADDED: Expose to internet switches for the ports of the web interface, the MTProto and SOCKS5 proxies and the Telegram Desktop WEB proxy, off by defau
net.bridge.bridge-nf-call-iptables at 1, which the dockerd package sets on OpenWrt, the kernel loses the handover to b4's listener for connections that enter through a bridge such as br-lan, so they hung without a single log line while the router's own connections worked. The Bridge netfilter row under Firewall in System Info names the setting to turn off.-j MASQUERADE in nat POSTROUTING, and -o <interface> -j MASQUERADE for each interface listed under NAT Masquerade - it still removed by their text the rules that versions before 1.71.0 had put there, and identical rules of the router matched.10.0.0.0/99 or a name, in a set with packet duplication kept the NFQUEUE packet engine from starting, and in TUN mode, when a set with packet duplication covered many addresses, such as a GeoIP category or an ASN, the web interface came up a minute or more after start, with a routing set the bypass then stopped for about as long again, and stopping b4 in that time timed out and left its capture rules behind - b4 handed the set's addresses to ipset or nft unchecked, and one entry the tool rejects fails the whole load; in TUN mode it gave each duplication address a firewall rule of its own and added them one command at a time, ahead of the rules that capture the first packets of every connection, and on iptables-legacy every command rewrites the whole table, so the capture chain took longer to build with every address, at start and again right after it, once the routing sets were in place.Full Changelog: v1.83.1...v1.84.0
Nothing published for this version
ADDED: When the packet engine fails to start, b4 keeps running without it, so the web interface stays reachable - the dashboard shows the reason, such
%!w(...), and a failure to open the packet queue left proxy sets sending traffic to a listener that was gone - the last error went only to errors.log, which b4 redirects stderr into, the log could not print an error that wrapped another one, and routing rules were removed only after a successful start..onion address never worked through it in any mode - the SOCKS5 server looked the name up itself and connected directly, leaving it to the firewall rules to catch the address, but b4 learns a set's addresses from the DNS answers it sees, TUN mode never shows it the answers to the router's own lookups, and a .onion name has no address to look up.Full Changelog: v1.83.0...v1.83.1
ADDED: Sets can target whole networks by their ASN - an ASN tab in the set editor takes a number such as AS15169 or an IP address, and b4 fetches the
AS15169 or an IP address, and b4 fetches the network's announced prefixes from RIPEstat and refreshes them daily. The Traffic page can add an address's announced prefix or its whole network to a set, the DPI Detector can add a hosting network, MCP b4_edit_set_targets takes the kind asns, and shared and community sets carry ASNs.geosite.dat or geoip.dat stopped b4 from starting until the file was fetched again by hand - the installer wrote each attempt over the working file and gave up on a 74 MB GeoSite after 600 seconds, the web UI likewise put an error page or a transfer cut off without a length in its place and gave up after 10 minutes, and b4 exited on a file it could not read before its web UI or the re-download of missing files started.8.8.0.0/16 and 8.8.8.0/24 stopped the bypass on nftables, and packet duplication and the MSS clamp picked up new addresses late - nft refused the overlapping ranges and b4 then removed its bypass rules, and a save that turned duplication on or changed its addresses did not refresh the firewall, nor did an add from the Traffic page or a GeoIP file update.nft call each, about 150 calls for 19,000 addresses.system.mtproto.bridge.enabled can be changed over MCP, sets in the Telegram over WebSocket routing mode work as before, and the Traffic page labels their connections and the bridge's Telegram bridge instead of -ws.sprinthost.ru as tg-ws-proxy uses, that b4 tries after a handshake for the kws*.web.telegram.org names fails, and b4 closes any handshake that does not end on a telegram.org certificate. Let sets process Worker connections, shown once a Cloudflare Worker domain is set, lets a set with a working strategy for Cloudflare process b4's own connections to the Worker; both are off by default.-444 warnings in the log - b4 tried its routes one at a time, waited three seconds on Telegram's edge before trying Cloudflare, retried dead edges every five minutes and kept spare connections for only 20 seconds, and it took an Android session's data centre from the address, which for 149.154.167.255 gave data centre 2 instead of 4.cloudflare GeoIP or GeoSite category, which break them on some networks.b4_find_bypass_strategy and b4_watchdog take a set.192.168.1.1 and only when typed as one, and the 2-second stall check ran only after a read finished, while a read waits for data until the timeout ends./login?reason=session_blocked matched the block-page markers, a single DNS timeout or error, never retried, showed as Fake DNS for a site and Substituted for a resolver, and the port 53 summary took the absence of hijacked rows as proof that every query reached its resolver, although a redirect to a well-known resolver such as Google is never marked.ip rule and ip route read as every rule and the main table.ip accepts table ids only up to 1023, so TUN did not start on it (invalid argument '9998' to 'table ID'), and TUN's cleanup deleted every rule pointing at those tables whoever had added it, flushed a table it had refused as busy and left its own two rules for the main table behind. queue.tun.route_table still sets a table by hand, and busybox ip older than 1.33 cannot run TUN at all.SIGUSR1, ran only with NFQUEUE, TUN read a set's ports, the packet limits, duplication addresses, the device filter, NAT Masquerade and MSS clamps once at start, and MAC addresses were compared case-sensitively while iptables 1.8 prints them in lowercase.Full Changelog: v1.82.3...v1.83.0
FIXED: A site with pinned addresses opened in a browser drifted to an address b4 never handed out after about a minute, and the tab ended in a timeout
GATEWAY with a note that no packet strategy from this host can change it.http:// check address whose port 80 answers everyone with a short error, and a second sweep of fake TTLs after the first had found none - the origin's 403 with an empty body failed every preset with "insufficient data" whatever the strategy, and the sweep's negative result was not kept between strategy families.Full Changelog: v1.82.2...v1.82.3
Nothing published for this version
FIXED: Saving a setting that rebuilds the firewall was followed by Tables rules missing, restoring... , sometimes a failed restore on the B4_DNSTCP ch
Tables rules missing, restoring..., sometimes a failed restore on the B4_DNSTCP chain, and on a slow router the rules were absent or half-built for up to twenty seconds - the rebuild tears every rule down and puts it back while the tables monitor keeps polling, nothing ordered the two, so a poll that landed inside the teardown started a second restore that fought the rebuild over the same chains.Tables rules missing after a firewall rewrite, restoring... replaces the warning in that case, and the warning stays for a restore the poll started on its own, which on Keenetic means the hook is missing and elsewhere means something other than b4 removed the rules.Full Changelog: v1.82.1...v1.82.2
Tables rules missing, restoring..., sometimes a failed restore on the B4_DNSTCP chain, and on a slow router the rules were absent or half-built for up to twenty seconds - the rebuild tears every rule down and puts it back while the tables monitor keeps polling, nothing ordered the two, so a poll that landed inside the teardown started a second restore that fought the rebuild over the same chains.Tables rules missing after a firewall rewrite, restoring... replaces the warning in that case, and the warning stays for a restore the poll started on its own, which on Keenetic means the hook is missing and elsewhere means something other than b4 removed the rules.did not answer the health check for one address only, whatever the reason - the cause, a failed lookup, a refused connection, a timeout or the status code, was dropped on the way to the status line, and only the last address tried was named, so a mirror entered by hand could fail first without a trace of it.regexp:.* catch-all set did, the hub never synced although every other device could open it - b4's requests to the hub went through its own packet processing like any other traffic, there was no second path when that broke the connection, and nothing showed which set was in the way.ADDED: b4 re-checks its firewall rules on SIGUSR1 , and on Keenetic the installer wires that into the NDMS netfilter.d hook directory - NDMS rebuilds
SIGUSR1, and on Keenetic the installer wires that into the NDMS netfilter.d hook directory - NDMS rebuilds its netfilter tables on a UPnP renewal, a WAN reconnect or a policy change and drops every chain it does not own, so the b4 rules were gone until the tables monitor's next poll, up to ten seconds later, on every rebuild.xt_connbytes kernel module is not available and skipped IPv4, although the module was loaded - the probe chain was flushed under the probe, and iptables answers a vanished chain with the same words as a missing match.argument list too long - every address in a batch was handed to nft as one command-line word, and the kernel refuses a single word past 128 KB before the command starts.Full Changelog: v1.82.0...v1.82.1
ADDED: Community Hub: a set can be published to hub.b4core.app, and sets other b4 users published can be browsed, applied and rated from a new Communi
b4hub service that ships alongside runs a self-hosted hub or a mirror of the central one, with the daily limits per contributor set from its moderation console and trusted keys exempt from them.coalesce UDP mode puts a padding-only QUIC Initial ahead of the client's Initial in one datagram, sealed under a different connection ID so the server cannot decrypt it and drops it while a DPI that only reads the first packet stops on it, and leaves the handshake itself unchanged.http_methodeol TCP option prepends the line and trims the User-Agent value by two characters so the request keeps its length, and inspection that expects the method first stops finding the Host header. It covers port 80 only and needs a User-Agent header; before it, a site filtered by its Host header had no strategy at all.https://<public IP>/. The placeholder can be replaced by uploading a self-contained HTML file in the same card.Full Changelog: v1.81.1...v1.82.0
FIXED: b4 could be left running after a service restart on OpenWrt, deaf to everything but kill -9, or doubled after an update - the daemon stopped li
--quiet install or update left b4 stopped, and --platform= skipped the service setup - the only start sat behind an interactive prompt, a forced platform never learned the service type, Ctrl-C at a prompt counted as the default answer, and a run without a terminal died at once.mips64_softfloat build that was never published.--remove left a killed b4's firewall rules behind, and a binary installed to a custom directory - removal relied on the process cleaning up after itself and never looked in the directory chosen at install time.Full Changelog: v1.81.0...v1.81.1
CHANGED: The DPI Detector page is rebuilt around the sites typed into it, and every site is fetched twice - once directly and once through b4, so a ro
Full Changelog: v1.80.4...v1.81.0
FIXED: Changing anything on a routing set took it apart before putting it back, so for about a second the traffic it matched left by the ordinary upli
FIXED: Changing anything on a routing set took it apart before putting it back, so for about a second the traffic it matched left by the ordinary uplink - the policy rule, the route, the prerouting jump, the chain and the addresses learned from DNS all came down before the replacement went in, and a set marks a connection only on its first packet, so a connection opened in that window stayed off the set for as long as it lived.
FIXED: Every setting changed through the MCP server left a whole copy of the configuration behind, so memory climbed by tens of megabytes and stayed there until b4 was restarted - the undo history keeps the configuration as it stood before each of the last twenty writes, and on a router with a large geosite set each of those copies carried a few megabytes of expanded domain list.
FIXED: A proxy set that resolves its upstream by domain went back to sending bare addresses a few minutes after any settings change, and stayed that way until b4 was restarted - the transparent proxy kept reading the domain index built at start-up, which the capture engine stops feeding once the configuration is applied again, so the addresses it had learned aged out with nothing to replace them. #338
FIXED: On Keenetic, the proxy and mtproto-ws routing modes were reported as unavailable after every reboot, although the firmware ships the TPROXY and socket modules for its kernel - b4 asked modprobe to load them, which needs a module index the read-only NDMS firmware does not carry, so the request failed and the check that followed read the modules as absent; the installer's start script has a direct insmod fallback, but those four modules were never on its list. #342
Full Changelog: v1.80.3...v1.80.4
Nothing published for this version
FIXED: A routing table named in /etc/iproute2/rt_tables was not recognised as the one a set was using - ip prints such a table by its name rather than
/etc/iproute2/rt_tables was not recognised as the one a set was using - ip prints such a table by its name rather than its number, which is how ASUS firmware ships tables 100 and 200, so b4 read its own live policy rule as missing and said so on every pass, the TUN engine left its rules behind on that table when it shut down, and b4 looked for those names in one file while ip also reads the copy that ships with the package.fwmark took the router's whole network down - the interface path checks such a value and assigns its own where it cannot be carried, the proxy path took it as given, and a value with bits outside the range b4 masks on leaves a policy rule the kernel reads as matching every packet that carries no routing mark at all, so all of it went into the set's local delivery table.Full Changelog: v1.80.2...v1.80.3
FIXED: The interface reported an older version than the binary on disk, with nothing to say why - the version is stamped in at build time, so a servic
FIXED: The interface reported an older version than the binary on disk, with nothing to say why - the version is stamped in at build time, so a service whose file is replaced without a restart keeps answering with the version it was compiled as while the command line reports the new one, and where the running process cannot read its own path, as in a container without /proc, the diagnostics named that path . instead of saying it did not know.
FIXED: A set routed to a tunnel or an upstream proxy could take the router down within seconds of the service starting - the rules pick a packet by its destination alone, so a packet the proxy handed back for that same address was picked again and sent straight back to it, thirty-one turns before its hop count ran out. Where such a set carried the router's own traffic as well, the proxy answered each turn by opening a connection of its own from the same box, on a fresh source port every time, until the memory was gone.
FIXED: A routed set could carry nothing at all, with nothing in the interface saying otherwise - the kernel's reverse-path check dropped every reply arriving on the set's interface, a set left on interface mode with no interface chosen or on proxy mode with no upstream port was dropped from the pass without a line in the log, turning domain-only matching off never rebuilt the set so its address list stayed empty, the firmware rebuilding its own firewall took b4's jump with it, and on a Broadcom router the firmware hands out the connection mark itself and overwrote the routing decision b4 keeps there.
FIXED: A routed set could send half a connection one way and half the other, or claim what another program was using - a domain's address is only learned when its lookup is answered, which is a moment after the connection has already started, so the handshake left by the ordinary uplink and the rest went down the set's route; the table number came from the output interface's name with nothing checking /etc/iproute2/rt_tables or the rules already pointing at it; each proxy set put its firewall jump ahead of the set before it, so the last in the list claimed addresses two of them targeted; a filter written to match a LAN client can never match a packet the router itself crafts, so a device-bound set's fakes travelled the ordinary uplink; on nftables a proxy set's mark returns sat at the top of a shared hook chain and ended it for every set below; and every rebuild deleted the set's own policy rule before putting the identical one back, so anything marked in that window found nothing pointing at the set's table and took the main one.
ADDED: A kill switch for a set's output interface - when the interface went away the kernel removed the route b4 had put in the set's table, the mark rule found the table empty, and the lookup fell through to the main table, so the set left through the ordinary uplink with the router's real address while its rules still read as correct.
CHANGED: A set routed into a tunnel no longer has its packets faked, fragmented and desynced - the work was done on the inner packet, which is wrapped or terminated on the router before anything on the network sees it, so it bought nothing and cost CPU on every connection, and the fake packets were delivered to the tunnel program's own stack one hop away with no room to expire. SYN health checks, dead-IP escalation, IP block detection and TCP duplication stop with it; a set keeps its bypass strategy when it routes to a plain second uplink and when its output interface is present but down.
FIXED: b4's own firewall work could take the whole network with it - on a router whose iptables has no lock flag the commands run unserialised while the firmware rewrites the same tables on WAN checks and DHCP events, so a command that lost that race left b4 on half a rule set and one start was fine while the next took the network off the air until a reboot; a running but overloaded b4 had its queue filled and the kernel dropped every packet past the four thousandth with nothing to say why; and stopping b4 put back a strict TCP window setting that this firewall drops packets over, so a page loaded its first fifty kilobytes and stopped.
FIXED: Picking network interfaces to monitor could switch the bypass off for the whole network with nothing saying so - the setting matches the interface a packet leaves by, which a VPN client or a transparent proxy moves without touching the list, so a selection made before that quietly stopped matching and every packet was queued to b4 and then accepted unchanged. A new Guides section covers the three interface settings and running b4 alongside Xray.
FIXED: On the TUN engine b4 captured the wrong traffic and missed what it needed - the capture rule sat below the routing rules a transparent proxy, a multi-WAN manager or a VPN script installs, so the network's packets were claimed before b4 saw them while what b4 did capture was the proxy's own upstream connection; a request from the LAN to a device on another bridge was carried into the tunnel and sent to the internet with the uplink's address; and only DNS queries were carried in, never the answers, so nothing learned an address into a routing set, stripped AAAA records or healed a dead address.
FIXED: Telegram kept reporting the MTProto proxy as incorrectly configured and switching it off - the dialog comes from a single four-byte -444 relayed back from a data center, not from a slow dial, and b4 could send an ordinary session to a data center's media edge, which answers a non-media session with exactly that; the 1.78.0 fix routed around nothing because both names lead to the same address. On a router without IPv6 the bridge also gave up on an edge whose name carries an IPv6 address, because a connection to one on a box with no IPv6 route is refused outright.
ADDED: An MCP server that can act on b4 rather than only describe it - the AI could read status and change one setting at a time, so anything a user asked for came back as instructions to carry out by hand. It gains per-setting facts, geosite and geoip search, target and set editing, the last update's transcript, and behind a separate Allow active probes permission, testing whether a domain loads and running Discovery; every tool call and every turned-away request is logged. Settings > Integrations.
FIXED: A Discovery run's result became unreachable the moment the run ended, and the watchdog judged domains on a fetch that skipped the bypass - only the copy held in memory was consulted and that is dropped 30 seconds after a run finishes, a strategy named while a run was still testing read as settled, stopping a run early threw away what it had found, the history file grew by roughly half a megabyte per domain because every strategy tried was saved with a full copy of the set built to test it, and the watchdog's own checks carried the mark b4 puts on traffic it has already handled.
FIXED: The settings folder was open for any account on the router to write to, and a downloaded backup could hold nothing - the settings file holds the web interface login and the MCP access token yet was created readable and writable by everyone, the copies kept before each upgrade the same, and restoring followed folder shortcuts left in that folder so an entry in the archive could land anywhere; b4 also skipped every file marked as a program, and on drives prepared from Windows the settings files carry that mark.
FIXED: Importing a zapret or byedpi configuration converted a fraction of what was pasted, and misdescribed what it did convert - a configuration file was read one line at a time, so multi-line values, variable references and the order its launcher joins them in were all lost.
FIXED: The MTProto settings page asked for a WEB proxy relay hostname while the proxy that serves it was off - the WEB carrier reuses the MTProto proxy's listener and its secrets, so with that proxy off the card was collecting a hostname for a relay that could not answer, beside a secrets card whose every control was dead, under header chips repeating the switch, the hostname and the transport mode already visible below them.
ADDED: Documentation for the Telegram WEB proxy, which shipped in 1.79.0 with nothing written about it - its prerequisites cannot be worked out from the interface: the MTProto proxy has to be running, the relay needs a hostname of its own with publicly trusted TLS, and the link Telegram Desktop accepts carries a different form of the secret than the settings show. It joins a Telegram section covering the three modes separately, replacing one page that described two of them and quoted log lines b4 does not write.
ADDED: Update mirrors, and a personal Cloudflare Worker to put in them - under Settings, Control, the Update mirrors field takes https addresses that the service and the installer try ahead of the built-in ones when GitHub cannot be reached, and b4 hands the list to the installer when an update starts. The documentation carries a Worker script that stands in for GitHub on a free Cloudflare account, so a reader blocked from the release host can mirror through one of their own.
ADDED: Installing an update from a file, for a router that can reach no download source at all - the update window takes a b4-linux-<arch>.tar.gz fetched on another machine, with an optional field for the SHA256 from the release page, which is the one check the automatic path cannot make independently because it reads the archive and its checksum from the same host. The upload is refused unless it holds a b4 built for that router, so the wrong architecture is named rather than installed and rolled back.
FIXED: Installing or updating the service failed where the network blocks GitHub's download hosts, and the update window could come up with no versions listed - the release archive is handed over by a redirect to a separate GitHub CDN that several providers drop by address, and the fallback proxy passed that redirect back to the router instead of following it, so the router went to the blocked host anyway and waited out a two-minute timeout, while the version list was fetched by the browser against an hourly GitHub limit shared by every user behind the same address.
Full Changelog: v1.80.1...v1.80.2
Nothing published for this version
ADDED: A WEB carrier for the MTProto proxy, which Telegram Desktop 7.1.1 reaches over ordinary HTTPS - a client on a network that blocks MTProxy and f
Settings > MTProto Proxy.Sets > Routing > DNS Redirect keeps the old behaviour.Restart command failed: signal: terminated in the error log, and an unfinished browser connection could hold a stop open for the full ten seconds until the kill landed while the firewall cleanup was still running.Settings > SOCKS5 Proxy.Sets > UDP.Settings > Core > DNS.Sets > Routing.runtime: program exceeds 10000-thread limit in the log - every matched packet started its own injection task with no ceiling, and those tasks wrote to a raw socket that had no send timeout, so an outgoing interface that stopped draining held one kernel thread per task until the Go runtime refused to create more.Full Changelog: v1.78.0...v1.79.0
ADDED: An MCP server at /api/mcp - b4 spoke no protocol an external AI app could connect to. Read-only tools report status, configuration, strategy se
ADDED: A Customize control on the dashboard: panels are reordered by dragging, widened or narrowed by dragging the right edge across a twelve column g
FIXED: Photos, videos and stickers stopped loading in 1.76.0 and 1.76.1 - the data center Telegram serves media from was addressed under another one's
2026-04-07 or later.tgprobe never tested the shared Cloudflare pool - it started from a blank configuration, so every on/off setting in it read as off.FIXED: Telegram never got past loading, with an empty chat list, in the WebSocket bridge routing mode - the bridge only ever went through a Cloudflare
FIXED: Every name lookup took five seconds once a set was routed through a proxy or an interface - each answer for such a set was written into the fir
ipset process per address, so nothing was read for as long as those processes took. Packets arriving meanwhile were dropped by the kernel without a word, and a lookup for a name b4 has no interest in crosses that queue several times, so it was the one most likely to lose a packet and wait out the resolver's five-second retry.dnsmasq alias on the router, both redone by hand each time the CDN changed its addresses. Written in hosts file order, address first. A pin only applies to names the set already targets, which is easy to get wrong silently, so a pin naming something the set does not match says so and offers to add it. Sets > DNS.FIXED: A domain was handled by a different strategy than the one Discovery found for it - every result was published with all the domains of the run,
regexp:.* or 0.0.0.0/0, and neither form appears anywhere in the interface. The IPv6 half, ::/0, was easy to leave out, so a catch-all set passed IPv6 traffic through untouched without saying so. Typing *, any or all into either field adds the same entries, and *.example.com is stored as example.com, which was taken as written and matched nothing.0.0.0.0/0 among a set's IP targets was dropped on the way to the firewall - ipset cannot store a network with a zero prefix size, so on routers using iptables the routing set lost that entry, while per-set MSS clamping and duplication lost every entry alongside it, since those are loaded in one batch that fails whole. The matching engine had accepted the same entry all along, so a set matched traffic while its firewall side stood empty. Both catch-alls are written to the firewall as their two halves.dnsmasq alias had to be done per address, per domain, and again whenever the CDN changed its addresses.Sets > Import.FIXED: b4's own output filled a router's memory - init scripts from older installers wrote b4's full log to a file kept in RAM on OpenWrt, and updates
alt-svc lifetime. Matched UDP on port 443 is refused with an ICMP port-unreachable, which browsers read as a signal to fall back to TCP. Turn the option on if the upstream implements UDP ASSOCIATE.ipinfo.io covers website-cdn.assets.ipinfo.io, while the address pre-resolve only looked up the names written in the set. Every other hostname was learned one address at a time from connections that had already left unrouted, and a site spread across a CDN kept producing them. A hostname that matches a routing set by suffix is resolved in full, and every address it answers with enters the set.nft or ipset binary, which takes longer than the client takes to send the packet that follows its DNS answer.geosite.dat or geoip.dat could only be replaced, never taken off the device, and pointing the destination directory somewhere else left the previous copy at the old path, since editing that field alone changes nothing to save. On a router with little free storage that meant two copies of a 51 MB file with no way to reach either from the interface. Remove deletes the file and clears its path and source URL, so the scheduler does not fetch it back, and a download or upload into a different directory deletes the copy b4 wrote at the old location.TCP6: upstreams, and a DC Relay address written as an IPv6 literal ([2001:db8::1]:7007) also flips the listening side to TCP6-LISTEN.FIXED: A domain added to the watchdog was listed as Healthy before anything had checked it - the entry was created green and counted toward the health
FIXED: A domain added to the watchdog was listed as Healthy before anything had checked it - the entry was created green and counted toward the healthy total, so a site the user already knows is blocked read as fine until the first check landed, and with the watchdog switched off it read that way forever. A domain waiting for its first check is marked Queued, and the force-check button is disabled while the watchdog is off, where it did nothing.
FIXED: The watchdog reported a site as healed while it was still unreachable - a healing run crowned a strategy after one successful fetch, and against a filter that blocks intermittently one of the twenty strategies it tries lands in a gap by chance. That result went straight into the set and the domain was marked healthy, with nothing checking whether ordinary traffic to the site worked afterwards. A healed strategy has to reproduce the fetch several times and survive a re-check through the live engine, or the configuration is put back.
FIXED: A healing run could quietly replace a hand-tuned set - it overwrote the whole tcp, udp, fragmentation and faking section while logging only the fragmentation strategy name, so a switch between two combo variants read as "combo -> combo" and every other tuned value disappeared without a trace.
FIXED: A fetch that returned nothing counted as a working strategy during discovery - a response without a declared length was accepted as complete even when zero bytes of the page arrived.
FIXED: The fake packet sent before a blocked greeting did not resemble the greeting it shadowed - it carried whatever length the fake payload happened to be, in one common case more than twice the real greeting, leaving a filter that reassembles the connection an untouched copy of the real bytes to read. Per-set fake_len_mode: "match" sizes it to the greeting.
FIXED: The fake greeting's TTL was ignored unless the faking strategy was set to "ttl" - a set could carry a TTL value while its fake ClientHello still went out at the full system TTL and reached the far end. The SYN fakes read the same value whatever the strategy is, so the setting looked live while doing nothing on the path that mattered. Per-set apply_ttl applies it to the greeting alongside any faking strategy.
ADDED: The TCP MD5 option on the fake greeting itself - md5_on_fake makes the far end discard the fake while a filter in between still reads it. The option only ever went on a separate fake connection opening, and only alongside a fragmentation strategy.
CHANGED: The fake and the real packet no longer share an IP identification number - one field gave away that both came from the same source.
ADDED: Fake-only discovery strategies - a low-TTL fake with no fragmentation at all, signed and unsigned, and the same shape across the per-family TTL sweep. Every strategy that carried a fake also split the greeting, and the family sweep is built on a base whose fragmentation strategy is combo, so against a filter that reassembles TCP well enough to see through any split, this shape was out of reach at every phase of discovery.
CHANGED: The TLS split position can follow the domain name - middle_sni on a set using the tls fragmentation strategy places the split inside the domain name instead of a fixed offset from the record header.
ADDED: The STUN fake payload ships with b4 - tls_stun.bin is built in and picked as "Preset: STUN" under Fake Payload Type. It had to be uploaded as a capture file on every device, and a set shared with someone else arrived pointing at a .bin they did not have.
ADDED: Import of a shared set said nothing when the set referenced a payload file the device does not have - the set pointed at a .bin capture that only existed on the machine it came from, the fake packets silently fell back to a built-in payload, and the set behaved differently than for the person who shared it. The import screen names the missing files and links to the Payloads settings.
FIXED: b4 would not start on an OpenWRT router whose kernel has no packet-queue module - startup ended with a raw firewall error that pointed nowhere near the missing kernel module. #275
FIXED: The installer reported the router as ready when it could not run b4 at all - the check passed if any one of three queue modules was present, so a router carrying the wrong one installed cleanly and failed at first start.
FIXED: The diagnostics report showed no queue number, worker count or queue mode - it read them from config keys b4 has never written, so those lines were skipped on every router.
FIXED: A failed start left part of b4's firewall rules on the router - when applying the rules stopped partway, the table, chains and hooks created up to that point stayed behind after b4 exited.
FIXED: A kernel without connection packet counters stopped b4 from starting at all - the whole queue rule was rejected and startup failed, over an optimisation that was never required.
CHANGED: System Info listed the wrong kernel modules on nftables-only routers - it marked the iptables-era modules as missing and said nothing about the nftables ones b4 depends on there.
FIXED: Telegram on Android could sit at "Connecting" when a set routed it through the built-in Telegram bridge - the bridge closed connections that stayed silent for five seconds, though Telegram opens them before it has anything to send. #277
FIXED: The "already exists in other sets" warning missed overlaps that do change routing - it compared entries character for character while traffic is matched by domain suffix, so example.com in another set drew no warning for www.example.com. #273
FIXED: The DC Relay socat helper generated commands that pointed at the wrong Telegram servers - it built them from Telegram's published proxy list, whose addresses drop the connection right after the handshake.
FIXED: The first request to a domain after an idle spell could hang for twenty seconds or time out, and YouTube on Android could sit for minutes before its interface appeared - when a client sent a TLS ClientHello too large for one packet, the domain name could land in the second one; b4 read each packet on its own and never joined them, so the set did not match and the connection went out with no bypass strategy at all. Chrome reorders the fields inside that greeting on every connection, which is why the same domain failed on one attempt and loaded on the next. #279 #280
FIXED: The first connection to an address b4 had just resolved for a client went out without the set that owned the domain - nothing linked a DNS answer, or a domain seen in a rejected QUIC attempt, to the connection that followed it, so until some connection produced a readable domain name the traffic was treated as unknown. That gap was the one place where a domain b4 had already seen went unrecognised, and on Android YouTube it could leave the app retrying for minutes. The link is remembered per client and destination and is discarded when two domains on one address belong to different sets. #279
FIXED: One device could decide which set another device's traffic went through - the domain learned for a shared CDN address was stored once for the whole network and overwritten by whichever device connected last, so on an address serving both YouTube previews and video, one phone's choice was applied to everyone else. Evidence a device produced itself, from its own DNS answers or QUIC attempts, is preferred over the shared record. #279
FIXED: A plain connection opening handshake was taken apart and re-sent for no reason - any set with fragmentation or fake-SNI turned on pulled every packet without content out of the kernel and pushed it back through a raw socket, including the opening SYN, although none of those techniques act on a packet that carries no data.
FIXED: A set built from a large geosite category took several times more memory than its domains - reading a few categories out of a 51 MB file needed around 90 MB, and the matcher and a switched-off SOCKS5 server each kept a spare copy of every domain.
FIXED: A phone that dropped off mobile data could leave a Telegram proxy connection stuck - when a mobile client backgrounded Telegram or lost signal,
ADDED: A separate MTProto secret for each person - the MTProto proxy can now hold several named secrets instead of one shared code. Each one can be na
ADDED: System Info now shows the router's kernel capabilities - a new section reports whether the router supports the underlying features that advance
ADDED: The Logs page is easier to read - log lines are now colour-coded by importance, and each type (error, warning, info, and so on) can be shown or
ADDED: System diagnostics now show the active engine and the firewall rules b4 has set up - the diagnostics page tells you whether b4 is running in NF
ADDED: New engine for devices without NFQUEUE - some minimal devices lack the kernel modules b4 normally needs, so it could not run on them. A new mod
FIXED: Sets manager felt frozen after enabling, reordering, duplicating, or deleting a set - the screen only changed once the action had been saved an
ADDED: Diagnostics now flag flow offloading - many routers have a speed feature called flow offloading that sends traffic down a fast path which skips
flow offloading that sends traffic down a fast path which skips b4 entirely, so b4 looks installed and running but nothing is actually bypassed (a common puzzle on OpenWrt). The system diagnostics (Settings system info, and the installer's diagnostics screen) now show whether flow offloading is switched on, so this can be spotted at a glance and turned off.512 to 2048 so a proxy shared by many people has room before it turns connections away.FIXED: Discovery found nothing on connections that tamper with DNS - on networks where the provider tampers with DNS (so ordinary name lookups came ba
--clear-iptables) left traces behind: adjusted system network settings, stray routing entries when two sets shared one outgoing interface, and a firewall rule that piled up with proxy or bridge routing.FIXED: Web UI update reported success but kept the old version on some setups - where b4 isn't managed by a normal service (for example running direct
update.log in the log folder (default /var/log/b4, reset each attempt), making failed updates much easier to diagnose./var/log/b4) instead of a path to errors.log, so all of b4's log files (errors, updates, and any added later) live together and can be moved in one place. Existing configs are migrated automatically (your old folder is kept); leave the field empty to turn file logging off.FIXED: Connections page slowed down the more network owners you looked up - looking up the "AS..." label for many addresses made the live list sluggis
ADDED: Encrypted DNS (DoH) for a set - a set's DNS tab can now send its name lookups over an encrypted DNS-over-HTTPS connection instead of to a plain
xbox-dns.ru for sites that say "not available in your country"), and some providers tamper with ordinary DNS - encrypted DNS gets around both. Switch the set between "Plain DNS" and "DNS-over-HTTPS", then pick a server from the built-in list or paste your own address. Only that set's lookups are affected, so the rest of your DNS stays as it is.dummy0) did not appear in Settings, so it could not be picked for monitoring or NAT masquerade. Any dummy interface that is up now shows up in both lists.youtube.com) and also ran a set that blocks or routes traffic - such as an ad-blocking set built from a category like category-ads-all - the watchdog could mistake that set for the one that owns your site, because the block list happened to contain a sub-domain of it (for example ads.youtube.com). When the site dipped and the watchdog tried to repair it, it added the site to that block/routing set, so the site got blocked instead of restored. The watchdog now only repairs sets that list the site by name, and never touches a set that has Routing turned on, so monitoring can no longer poison a blocking or routing set. Note: if an earlier version already added the monitored site to such a set, remove it there by hand once.ADDED: Blocking stats on the Dashboard - when a set uses Block (blackhole) mode and actually blocks something, the Dashboard now shows a "Blackhole" p
lavrush.in). Settings -> MTProto Proxy now has a "DC list fallback mirror" switch to turn it off or point it at your own copy.xt_connbytes feature, even though the router actually supported it. The real cause was b4 using a newer firewall command option that the router's built-in tool did not understand. b4 now adapts to the router's own tools automatically, so it starts normally with nothing extra to install.- FIXED: Connections page showed nothing when the device clock was out of sync - the time filter (30s / 1m / 5m / 15m) and the per-connection activity graph compared the live data against the browser's own clock, so a computer whose clock was off by even ~30 seconds could see an empty list and empty activity bars. Filtering and the activity graph now use the timestamps in the connection data itself, so they work regardless of the device clock or its timezone."discord.com","youtube.com", as happens when pasting a copied list), b4 kept the quote marks as part of each name, so every lookup failed and Discovery reported nothing working for any site. Surrounding quotes are now removed automatically. #241ADDED: Block (blackhole) routing mode - a new "Block" option in a set's Routing tab that blocks all matched traffic (ad/tracker domains, IPs, or a Geo
category-ads-all) across the whole network - every LAN device and the router itself - with no output interface needed. It blocks by name and not just by IP, so it keeps working even with encrypted DNS and won't break unrelated sites sharing the same servers. See Blocking for setup and details.--skip-tables got saved into the config and stuck - starting b4 with an extra command-line option used to write that option into the configuration file, so it kept applying on later starts even when you ran b4 without it. Command-line options now affect only the run you pass them to and are never saved into the config.FIXED: DNS redirect didn't work - when a set sent its DNS lookups to a chosen server (the set's DNS tab), names failed to resolve and the internet see
http://192.168.1.1), because browsers only allow the modern clipboard API over HTTPS or localhost. The fallback copy path now works in those cases too.!github + !google were treated as one literal text match, so the view usually showed nothing. The Aggregated view now uses the same filter syntax as the Raw feed: combine terms with +, exclude with !, and target a column with field:value.FIXED: Geo databases sometimes saved to a broken `b4` folder after install - in rare cases the installer would record b4/geosite.dat instead of a full
b4 folder after install - in rare cases the installer would record b4/geosite.dat instead of a full path like /etc/b4/geosite.dat, and the Web UI then refused to download new files. The installer now refuses non-absolute paths, b4 fixes any broken path it finds on startup, and the UI falls back to a safe default if the stored path looks wrong./tmp and get wiped on reboot). A separate "Schedule" picker (Off / Daily / Weekly / Monthly) runs a background refresh on its own. Missing files are also re-downloaded automatically at startup whenever a source URL is set, even with both options off.getProxyConfig (a topology file for MTProxy operators) and dialling them directly. Those backends silently dropped the connection after the handshake because clients are not allowed there. b4 now uses the well-known public data center IPs for direct dialling, like real Telegram clients do.ADDED: Memory limit setting - new "Memory Limit" field in Settings → Logging. Caps how much memory b4 may use. Leave empty for auto (half of system RA
128MiB, 256m, 1g, or off to disable.FIXED: False "another b4 instance is already running" error - b4 could refuse to start after a crash, after restarting from the Web UI, or when runnin
ADDED: Custom payload for UDP fake packets - new "Fake Packet Payload" picker in the UDP fake settings of each set. Choose a captured .bin (uploaded i
.bin (uploaded in Settings → Payloads, or auto-captured from live QUIC traffic) to use as the body of fake UDP packets. Empty = zero fill (previous behavior). The Settings → Payloads upload form now has an explicit TLS/QUIC protocol selector..bin.BusyBox table-ID limit. Now kept within the safe range too.nft. b4 now quotes interface names in routing rules, so any name works..tar.gz backup file. Selecting the backup now works in Safari.ADDED: Per-set strategy escalation - each set now has an "Escalation" tab with an "Escalate to" dropdown. Pick another set as the failover target: if
tg:// connection link, a QR code (scan with your phone camera to add the proxy to Telegram), and Copy / Open in Telegram / Share buttons.ipset - "Enable Packet Duplication" could prevent b4 from starting on routers where ipset is not installed (some Keenetic / Merlin setups). b4 now logs a warning and keeps running. For full-connection duplication, install ipset (Keenetic / Entware: opkg install ipset).2a01 and the suggested CIDRs included the port number. Adding to a set, IPInfo lookup, and ASN enrichment now work for IPv6 too.Nothing published for this version
FIXED: Upstream SOCKS5 routing didn't actually proxy — when a set was configured to route through a SOCKS5 server (local or remote), traffic was silen
nftables setups with both IPv4 and IPv6 enabled, the per-set NAT chain ended up with two byte-identical masquerade rules. The rule is now scoped per address family (meta nfproto ipv4 / ipv6), matching the split already used for the mark rules./connections links still work and redirect to the new page.Info made the Traffic page stop updating. The UI now gets traffic events through a separate channel, so you can keep the log level on Warn or Error to quiet down system logs without losing the live traffic view. Opening the Traffic page also instantly shows the last few hundred recent events instead of waiting for new traffic.IMPROVED: Refreshed UI — the whole web UI has been redesigned: cleaner typography, tighter spacing, calmer colour palette, larger and easier-to-read n
FIXED: Routing stopped working after restarting tun2socks / sing-box - if the proxy's network interface was recreated, or wasn't ready yet when B4 sta
ADDED: Manual devices — you can now add IP addresses of devices behind another router that are not visible in the ARP table. Added devices appear in d
TCP fake settings to generate a fake TLS handshake from any domain you type (e.g. example.com).mac_aliases.json file is no longer used (aliases are migrated into the config on upgrade).255, which is not supported on systems using BusyBox. Table IDs now stay within the safe range.Syn Fake was enabled, the fake SYN packet always used a built-in payload instead of the one selected in the set (custom, captured, or domain-generated).https-dns-proxy, domains from GeoSite categories were not added to routing sets. B4 now intercepts DNS queries earlier so routing works in these setups.Error in the UI, it was silently changed back to Info on the next start.ADDED: UDP Reject mode — new option for QUIC/UDP handling that sends an ICMP "Port Unreachable" response instead of silently dropping packets. Clients
ADDED: Config backup before update — B4 now automatically saves a copy of your config file before updating (e.g. b4.json.bak.v1.47.2), so you can rest
b4.json.bak.v1.47.2), so you can restore it if needed.Past Sequence and Random Sequence strategies, Timestamp Decrease only for Timestamp strategy. Reduces clutter in the UI.GeoIP category within the same set caused a firewall error. Duplicate IPs are now filtered automatically.GeoIP addresses and static IPs were added to firewall sets with a TTL and silently expired. They are now permanent. DNS-resolved IPs are periodically refreshed before they expire.IMPROVED: Discovery tests multiple domains in parallel — when checking several URLs, discovery now tests all domains at the same time instead of one b
FIXED: Routing breaks when VPN/WireGuard restarts — B4 now automatically detects when a network interface changes and refreshes routing rules. Previou
/swagger/ endpoint now redirects to the documentation site.FIXED: B4 fails to start with large configs — configs with many sets and hundreds of thousands of IPs caused an error on restart because all IPs were
10.0.0.0/24) were added to a set's target IPs, routing silently ignored them and only routed individual IPs. Now all IP ranges are routed correctly.1.46.6rc) in the update dialog incorrectly showed "Downgrade" instead of "Upgrade".FIXED: Domain-based routing not working with local DNS — on routers running their own DNS (e.g. dnsmasq on OpenWrt), B4 couldn't learn which IPs belon
dnsmasq on OpenWrt), B4 couldn't learn which IPs belong to routed domains. Now it works correctly regardless of where DNS is handled.Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →