mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
feat(website): 09/2025 devlog (#10571)
First in a series of new monthly devlog posts to summarize what we've shipped over the previous month. Intentionally detailed and engineering focused - added a new `Engineering` section to the blog. --------- Signed-off-by: Jamil <jamilbk@users.noreply.github.com> Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
This commit is contained in:
4
website/.gitignore
vendored
4
website/.gitignore
vendored
@@ -42,3 +42,7 @@ next-env.d.ts
|
||||
|
||||
# generated timestamps
|
||||
timestamps.json
|
||||
|
||||
# AI
|
||||
.rules
|
||||
scrape_commits.py
|
||||
|
||||
18
website/src/app/blog/devlog/2025-09/_page.tsx
Normal file
18
website/src/app/blog/devlog/2025-09/_page.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
"use client";
|
||||
import Post from "@/components/Blog/Post";
|
||||
import Content from "./readme.mdx";
|
||||
import gravatar from "@/lib/gravatar";
|
||||
|
||||
export default function _Page() {
|
||||
return (
|
||||
<Post
|
||||
authorName="Jamil Bou Kheir"
|
||||
authorTitle="Founder"
|
||||
authorAvatarSrc={gravatar("jamil@firezone.dev")}
|
||||
title="September 2025 Devlog"
|
||||
date="2025-09-30"
|
||||
>
|
||||
<Content />
|
||||
</Post>
|
||||
);
|
||||
}
|
||||
11
website/src/app/blog/devlog/2025-09/page.tsx
Normal file
11
website/src/app/blog/devlog/2025-09/page.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Metadata } from "next";
|
||||
import _Page from "./_page";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "September 2025 Devlog • Firezone Blog",
|
||||
description: "September 2025 Devlog",
|
||||
};
|
||||
|
||||
export default function Page() {
|
||||
return <_Page />;
|
||||
}
|
||||
164
website/src/app/blog/devlog/2025-09/readme.mdx
Normal file
164
website/src/app/blog/devlog/2025-09/readme.mdx
Normal file
@@ -0,0 +1,164 @@
|
||||
import AboutFirezone from "@/components/Blog/AboutFirezone";
|
||||
|
||||
September brought major improvements to Firezone's reliability, performance, and administrative capabilities.
|
||||
Our focus this month was on making connections more resilient, helping admins manage client versions more effectively, and optimizing our networking stack for real-world conditions.
|
||||
|
||||
## Smarter Admin Tools
|
||||
|
||||
Managing a fleet of Clients just got easier.
|
||||
The admin portal now shows client versions directly in the clients table with a sortable version column.[^10456]
|
||||
When planning Gateway upgrades, admins can quickly identify which clients might lose connectivity due to version incompatibility.
|
||||
|
||||
We've also enhanced the "outdated Gateway" email notification system, which is now enabled by default for all accounts.[^10281]
|
||||
These emails now include a count of clients that will be affected by the Gateway upgrade, with a direct link to view them in the portal.
|
||||
|
||||
For organizations with large user bases, we added batch upsert operations for directory sync.[^10369]
|
||||
This lays the groundwork for more efficient directory synchronization that can handle thousands of users without overwhelming the system.
|
||||
|
||||
A new `/account` API endpoint provides programmatic access to billing details and seat usage.[^10302]
|
||||
This enables better integration with capacity planning and billing automation tools.
|
||||
|
||||
## Rock-Solid Connections
|
||||
|
||||
Connection reliability saw significant improvements across the board.
|
||||
We implemented graceful connection shutdown using a new peer-to-peer control protocol message.[^10076]
|
||||
When Gateways restart for maintenance or upgrades, Clients now immediately fail over to alternative Gateways instead of waiting through a 15-second ICE timeout.[^10400]
|
||||
|
||||
This graceful handling also applies when Clients sign out, making it much easier to distinguish between actual network problems and normal disconnections in the logs.
|
||||
|
||||
We fixed a synchronization issue where Clients and Gateways could disagree on authorization state.[^10462]
|
||||
Now when a Client receives an ICMP "prohibited" error from a Gateway, it automatically re-authorizes access for that Resource.
|
||||
This keeps both sides in sync even when authorization states drift out of alignment.
|
||||
|
||||
DNS resource handling got more reliable too.
|
||||
Proxy IP assignments for DNS resources now persist across Client sessions.[^10104]
|
||||
Previously, restarting the Client could reassign `100.96.0.1` to a different resource, breaking applications that cached the IP address.
|
||||
Now these mappings stay consistent for the lifetime of the tunnel process, fixing issues with long-lived connections like SSH sessions.
|
||||
|
||||
## Better DNS Resolution
|
||||
|
||||
The Gateway switched from using the system's `libc` resolver to the `hickory-resolver` library for A and AAAA record resolution.[^10373]
|
||||
This change enables proper TTL-based caching instead of the previous hardcoded 30-second cache.
|
||||
DNS responses are now cached for exactly as long as the authoritative nameserver specifies, reducing unnecessary queries while ensuring timely updates.
|
||||
|
||||
## Performance Under Load
|
||||
|
||||
We optimized the event-loop to prevent starvation of lower-priority inputs.[^10347]
|
||||
The tunnel now batch-processes input from all sources rather than prioritizing high-traffic sources to completion.
|
||||
This prevents timeout checks and DNS resolution from being delayed when UDP sockets or the TUN device are extremely busy.
|
||||
|
||||
Linux systems got a significant performance boost through better socket buffer management.[^10349]
|
||||
Clients and Gateways now attempt to set UDP receive and send buffer maximums to 128 MB and 16 MB respectively at startup.
|
||||
The default 200KB buffers were causing packet drops during high throughput scenarios, directly correlating with buffer errors visible in `nstat`.
|
||||
|
||||
We also limited the number of optimistic ICE candidates to prevent CPU spikes.[^10367]
|
||||
When clients advertise many IPv6 addresses, the previous unlimited candidate generation could cause performance issues.
|
||||
Optimistic candidates are now disabled entirely for IPv6 and limited to 2 for IPv4, focusing on the scenarios where they're most beneficial.
|
||||
|
||||
## Relay Infrastructure Advances
|
||||
|
||||
Our relay infrastructure received important eBPF improvements.
|
||||
The relay can now handle relay-to-relay candidate pairs in the eBPF kernel, which occur when both Client and Gateway allocate from the same relay.[^10286]
|
||||
Previously these packets would need to traverse userspace or fail entirely.
|
||||
|
||||
We restructured the eBPF code into modular components that handle all cross-stack translation cases, including IPv4↔IPv6 transformations.
|
||||
A comprehensive integration test with double symmetric NAT validates this behavior in continuous integration.
|
||||
|
||||
We also fixed several edge cases in the eBPF layer, including properly handling DNS replies[^10330] and re-populating the channel map when TURN channels are refreshed.[^10291]
|
||||
|
||||
## Platform-Specific Improvements
|
||||
|
||||
The Android client now launches authentication in a CustomTab instead of the default browser.[^10371]
|
||||
This fixes a Firefox bug where only the first browser tab could intercept the custom URI scheme, making subsequent sign-ins fail until users manually closed the old tab.
|
||||
CustomTabs ensure only one sandboxed authentication instance exists at a time.
|
||||
It also results in a nice UX improvement where the "You have been signed-in" tabs are no longer lingering around.
|
||||
|
||||
macOS developers got quality-of-life improvements making the workspace build correctly on macOS with appropriate stubs and conditional compilation.[^10363]
|
||||
|
||||
The macOS client now detects and alerts users when multiple instances are running, preventing interference with tunnel state.[^10313]
|
||||
|
||||
## Infrastructure and Tooling
|
||||
|
||||
All CI runners now use Ubuntu 24.04 to match production relay environments.[^10288]
|
||||
This ensures builds and tests run on the same kernel version as production, catching platform-specific issues earlier.
|
||||
|
||||
The docker-compose test environment now uses realistic network topology with separate subnets for Clients, Gateways, relays, and backend.[^10301]
|
||||
Each component has a dedicated router container performing NAT and firewall rules, enabling proper testing of relayed connections with port randomization.
|
||||
|
||||
Database performance improved with the addition of missing indexes on foreign key columns.[^10396][^10403]
|
||||
These indexes ensure efficient cascade deletes now that hard-delete has been fully rolled out.
|
||||
|
||||
## Notable Bug Fixes
|
||||
|
||||
Several important bugs were squashed:
|
||||
|
||||
- Gateway re-joins Phoenix channel topic on send errors to prevent message loss[^10397]
|
||||
- Fixed poll-after-completion panics in Client session event-loop[^10399]
|
||||
- Fixed DNS resource NAT reset when Client reassigns proxy IPs after sign out[^10310]
|
||||
- Relay filters traces by log filter to respect OTEL configuration[^10317]
|
||||
- Internet site no longer counts against Starter plan resource limits[^10336]
|
||||
|
||||
---
|
||||
|
||||
That's September in a nutshell.
|
||||
See our [changelog](https://www.firezone.dev/changelog) for a more compact version of the above or view the [full diff on GitHub](https://github.com/firezone/firezone/compare/61e0a228869f646d4ae7b4d5ee19ce57f5697df8...f07d2932dcc04441bc16f01febe011131523a39a).
|
||||
|
||||
<AboutFirezone />
|
||||
|
||||
---
|
||||
|
||||
#### Footnotes
|
||||
|
||||
[^10456]: [feat(portal): show outdated clients](https://github.com/firezone/firezone/pull/10456)
|
||||
|
||||
[^10281]: [feat(portal): enable outdated gateway email](https://github.com/firezone/firezone/pull/10281)
|
||||
|
||||
[^10369]: [feat(portal): batch_upsert and delete_unsynced functions](https://github.com/firezone/firezone/pull/10369)
|
||||
|
||||
[^10302]: [feat(api): GET /account API](https://github.com/firezone/firezone/pull/10302)
|
||||
|
||||
[^10076]: [feat(connlib): gracefully shutdown connections](https://github.com/firezone/firezone/pull/10076)
|
||||
|
||||
[^10400]: [feat(clients): gracefully close connections on shutdown](https://github.com/firezone/firezone/pull/10400)
|
||||
|
||||
[^10462]: [feat(connlib): create flow on ICMP error "prohibited"](https://github.com/firezone/firezone/pull/10462)
|
||||
|
||||
[^10104]: [feat(connlib): persistent DNS resource records across sessions](https://github.com/firezone/firezone/pull/10104)
|
||||
|
||||
[^10373]: [feat(gateway): use hickory resolver to resolve A/AAAA queries](https://github.com/firezone/firezone/pull/10373)
|
||||
|
||||
[^10347]: [refactor(connlib): improve fairness of event-loop](https://github.com/firezone/firezone/pull/10347)
|
||||
|
||||
[^10349]: [feat(linux): try to set `rmem_max` and `wmem_max` on startup](https://github.com/firezone/firezone/pull/10349)
|
||||
|
||||
[^10367]: [fix(connlib): limit the number of optimistic candidates](https://github.com/firezone/firezone/pull/10367)
|
||||
|
||||
[^10286]: [fix(relay): handle relay-relay candidate pairs in eBPF](https://github.com/firezone/firezone/pull/10286)
|
||||
|
||||
[^10330]: [fix(relay): XDP_PASS DNS replies](https://github.com/firezone/firezone/pull/10330)
|
||||
|
||||
[^10291]: [fix(relay): re-add eBPF channel map entry on refresh](https://github.com/firezone/firezone/pull/10291)
|
||||
|
||||
[^10371]: [fix(android): launch auth in CustomTab](https://github.com/firezone/firezone/pull/10371)
|
||||
|
||||
[^10363]: [chore: improve macos dev experience](https://github.com/firezone/firezone/pull/10363)
|
||||
|
||||
[^10313]: [fix(apple): Enforce single Firezone instance](https://github.com/firezone/firezone/pull/10313)
|
||||
|
||||
[^10288]: [ci: bump Ubuntu runners to 24.04](https://github.com/firezone/firezone/pull/10288)
|
||||
|
||||
[^10301]: [ci: create a more realistic network setup](https://github.com/firezone/firezone/pull/10301)
|
||||
|
||||
[^10396]: [chore(portal): add non-composite indexes](https://github.com/firezone/firezone/pull/10396)
|
||||
|
||||
[^10403]: [chore(portal): add remaining simple indexes](https://github.com/firezone/firezone/pull/10403)
|
||||
|
||||
[^10397]: [fix(gateway): re-join topic in phoenix-channel on error](https://github.com/firezone/firezone/pull/10397)
|
||||
|
||||
[^10399]: [fix(connlib): fuse event-loop future inside client session](https://github.com/firezone/firezone/pull/10399)
|
||||
|
||||
[^10310]: [fix(gateway): reset DNS resource NAT if proxy IPs change](https://github.com/firezone/firezone/pull/10310)
|
||||
|
||||
[^10317]: [fix(relay): filter traces by log filter](https://github.com/firezone/firezone/pull/10317)
|
||||
|
||||
[^10336]: [fix(portal): don't count internet site in limits](https://github.com/firezone/firezone/pull/10336)
|
||||
@@ -11,6 +11,25 @@ import { Badge } from "@/components/Badges";
|
||||
export default function Posts() {
|
||||
const [filters, setFilters] = useState("All Posts");
|
||||
const posts = [
|
||||
{
|
||||
title: "September 2025 Devlog",
|
||||
date: "September 30, 2025",
|
||||
href: "/blog/devlog/2025-09",
|
||||
authorName: "Jamil Bou Kheir",
|
||||
authorAvatarSrc: gravatar("jamil@firezone.dev"),
|
||||
type: "Engineering",
|
||||
description: (
|
||||
<p className="mb-2">
|
||||
September brought significant improvements to Firezone's
|
||||
networking stack, administrative tooling, and cross-platform
|
||||
reliability. This month's work focused on optimizing relay
|
||||
performance through eBPF, improving DNS resolution behavior, and
|
||||
enhancing the admin portal's visibility into client and Gateway
|
||||
states. )
|
||||
</p>
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
title: "Migrate your Internet Resource by March 15, 2024",
|
||||
date: "February 16, 2024",
|
||||
@@ -405,7 +424,13 @@ export default function Posts() {
|
||||
<>
|
||||
<div className="border-b-[1px] py-6 px-4 sm:px-6 md:py-4 md:px-8 lg:px-10 mx-auto max-w-screen-lg w-full">
|
||||
<Pills
|
||||
options={["All Posts", "Announcement", "Learn", "Insights"]}
|
||||
options={[
|
||||
"All Posts",
|
||||
"Announcement",
|
||||
"Engineering",
|
||||
"Learn",
|
||||
"Insights",
|
||||
]}
|
||||
filters={filters}
|
||||
setFilters={setFilters}
|
||||
/>
|
||||
|
||||
30
website/src/components/Blog/AboutFirezone/index.tsx
Normal file
30
website/src/components/Blog/AboutFirezone/index.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import Link from "next/link";
|
||||
|
||||
export default function AboutFirezone() {
|
||||
return (
|
||||
<div className="bg-neutral-100 border-l-4 border-primary-500 p-6 my-8">
|
||||
<h2 className="text-2xl font-bold mb-4">About Firezone</h2>
|
||||
<p className="mb-4">
|
||||
Firezone is an open source platform for securely managing remote access
|
||||
to your organization's networks and applications. Unlike
|
||||
traditional VPNs, Firezone takes a granular, least-privileged approach
|
||||
with group-based policies that control access to individual
|
||||
applications, entire subnets, and everything in between.{" "}
|
||||
<Link
|
||||
href="https://app.firezone.dev/sign_up"
|
||||
className="text-accent-500 underline hover:no-underline"
|
||||
>
|
||||
Get started for free
|
||||
</Link>{" "}
|
||||
or{" "}
|
||||
<Link
|
||||
href="/kb"
|
||||
className="text-accent-500 underline hover:no-underline"
|
||||
>
|
||||
learn more
|
||||
</Link>{" "}
|
||||
about how Firezone can help secure your organization.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user