Commit Graph

8433 Commits

Author SHA1 Message Date
Thomas Eizinger
ff3ff93e1a fix(dns-types): use base64url encoding without padding (#10875)
According to the DoH spec, the base64url encoded query must not include
any padding characters.
2025-11-13 12:48:21 +00:00
Thomas Eizinger
81023dbf52 feat(connlib): make parallel requests with HttpClient (#10856)
Our `socket-factory`-aware HttpClient is currently only able to handle a
single request at a time. That is a result of the requirement that we
wanted to support connections to different domains but also be able to
"self-heal" those connections by establishing a new one if the current
one failed.

As I am learning more about how connlib's DoH support is going to work,
it became apparent that we will only ever need to connect to a single
domain per instance of the `HttpClient`. In addition, it is quite
important to allow for concurrent requests: We don't want to process DoH
queries in sequence but instead make full use of the underlying HTTP2
protocol and send multiple requests in parallel.

This PR refactors the `HttpClient` (which isn't in use anywhere yet) to
only support a single connection per instance. That connection is
established when the instance is created. This is also conceptually
easier to understand as we only manage a single connection without
mutable state.

Related: #4668
2025-11-13 12:47:38 +00:00
Thomas Eizinger
53113c645f fix(connlib): don't panic in fallible function (#10874)
Panicking - even though it is unlikely to happen here - is unnecessary
because we can simply return an error instead.
2025-11-13 12:35:28 +00:00
Thomas Eizinger
103aa16b2f fix: use our own docker install action (#10877) 2025-11-13 15:16:07 +11:00
Thomas Eizinger
cd650de1f8 refactor: prepare client init for upstream DoH servers (#10851)
In order to support multiple different protocols of upstream DNS
resolvers, we deprecate the `upstream_dns` field in the client's `init`
message and introduce two new fields:

- `upstream_do53`
- `upstream_doh`

For now, only `upstream_do53` is populated and `upstream_doh` is always
empty.

On the client-side, we for now only introduce the `upstream_do53` field
but fall-back to `upstream_dns` if that one is empty. This makes this PR
backwards-compatible with the portal version that is currently deployed
in production. Thus, this PR can be merged even prior to deploying the
portal.

Internally, we prepare connlib's abstractions to deal with different
kinds of upstreams by renaming all existing "upstream DNS" references to
`upstream_do53`: DNS over port 53. That includes UDP as well as TCP DNS
resolution.

Resolves: #10791

---------

Co-authored-by: Jamil Bou Kheir <jamilbk@users.noreply.github.com>
2025-11-12 05:40:58 +00:00
dependabot[bot]
4bd768aed5 build(deps): bump @types/node from 24.5.2 to 24.7.2 in /rust/gui-client (#10834)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 24.5.2 to 24.7.2.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=24.5.2&new-version=24.7.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-12 04:35:22 +00:00
Thomas Eizinger
8af8978ad5 chore(connlib): include "packet kind" in decapsulation errors (#10867)
When looking at error logs from Gateways or Clients, it can be useful to
know, what kind of packet we failed to process.
2025-11-12 04:26:20 +00:00
Thomas Eizinger
ee38ccc120 chore(connlib): log index of failed connections (#10866)
Logging the peer index of a failed connection makes it easier to
correlate it with logs when we receive packets for an unknown
connection.
2025-11-12 03:37:39 +00:00
Thomas Eizinger
32e1c088e7 chore(gateway): include domain in "not allowed" log (#10863)
The resource could be a wildcard DNS resource. It is useful to know,
which particular domain the client tried to access.
2025-11-12 03:37:03 +00:00
Thomas Eizinger
94985a7b77 fix(scripts): replace all occurrences of version marker (#10865)
Related: #10860
2025-11-12 02:20:15 +00:00
dependabot[bot]
64da55707f build(deps): bump @types/node from 24.5.2 to 24.7.2 in /website (#10835)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 24.5.2 to 24.7.2.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=24.5.2&new-version=24.7.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-12 02:04:03 +00:00
Thomas Eizinger
4a64ff889b fix(website): redirect to correct release (#10864)
Quick-fix to ensure Gateway upgrades work. Fix for the script will come later.

Resolves: #10860
2025-11-12 11:27:37 +11:00
Thomas Eizinger
5f61eaf8f2 feat(connlib): encode and decode DoH messages (#10857)
In order to support DoH, we need to be able to encode and decode DNS
queries and responses from and to HTTP requests and responses. We
therefore extend your `dns-types` crate with the required functionality.

The [RFC8484](https://datatracker.ietf.org/doc/html/rfc8484) provides us
with two test vectors that we can test against.

Related: #4668

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thomaseizinger <5486389+thomaseizinger@users.noreply.github.com>
2025-11-11 15:27:25 +00:00
Thomas Eizinger
cf14a8694c fix(connlib): use system DNS resolvers to re-resolve portal URL (#10853)
In #10817, we landed a fix that allows Clients to re-resolve the portal
URL every time the WebSocket connection fails. Currently, we use the
active upstream resolvers for this.

This can lead to a kind of deadlock in case the upstream resolver is a
CIDR resource that we are not yet connected to. In that case, we'd need
a connection to the portal to establish a connection to the Gateway.

By always using the system resolvers for this, we avoid this circular
dependency.
2025-11-11 07:50:26 +00:00
Thomas Eizinger
3e849ae852 fix(gui-client): use Wayland rendering backend on Linux (#10849)
Previously, we opted into the X11 GTK backend when rendering the GUI
Client's window. This is causing issues on newer Linux distributions
such as Fedora 43 where Wayland is now the only available compositor.

Removing the X11 GTK requires us to draw our own CSDs such as titlebars
and a close button. This PR does exactly that by adding a minimalistic
title bar. To make better use of the space, we move the section headers
into there.

|Before|After|
|---|---|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-11"
src="https://github.com/user-attachments/assets/9439a69b-65ba-41d6-b1f8-4448e0f80728"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-40-55"
src="https://github.com/user-attachments/assets/7884b2cc-3d9c-4b47-9a1e-c6462aef36ab"
/>|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-16"
src="https://github.com/user-attachments/assets/2cfea825-5c08-45a5-873c-5afcbc1dbf16"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-40-58"
src="https://github.com/user-attachments/assets/43ddd7c9-ce65-42f7-b972-28c6b172b70d"
/>|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-19"
src="https://github.com/user-attachments/assets/446873a7-9023-4266-9377-ea7b8b4353ee"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-41-01"
src="https://github.com/user-attachments/assets/64439383-f33f-461d-9b4a-6b4138bd675b"
/>|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-22"
src="https://github.com/user-attachments/assets/6c39e06c-1d77-471f-91f1-32a78b90a21c"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-41-04"
src="https://github.com/user-attachments/assets/b56912cb-9c85-4b5a-9295-dae6139b25c6"
/>|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-26"
src="https://github.com/user-attachments/assets/5a5d638c-15bf-4523-8466-2e0977a03e22"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-41-06"
src="https://github.com/user-attachments/assets/ed169b52-ef86-4dc4-8f25-852da622eaa1"
/>|
2025-11-11 05:51:08 +00:00
Thomas Eizinger
0008539b65 refactor(connlib): use dedicated UDP DNS client (#10850)
By default, DNS queries are sent over UDP by most systems. UDP is an
easy to understand protocol because each packet stands by itself and at
least as far as UDP is concerned, the payload is contained within a
single packet.

In Firezone, we receive all DNS traffic on the TUN device as IP packets.
Processing the UDP packets is trivial as each query is contained within
a single IP packet. For TCP, we first need to assemble the TCP stream
before we can read the entire query.

In case a DNS query is not for a Firezone DNS resource, we want to
forward it to the specified upstream resolver, either directly from the
system or - in case the specified upstream resolver is an IP resource -
through the tunnel as an IP packet. Specifically, the forwarding of UDP
DNS packets through the tunnel currently happens like this:

IP packet -> read UDP payload -> parse DNS query -> mangle original
destination IP to new upstream -> send through tunnel

For TCP DNS queries, it is not quite as easy as we have to decode the
incoming TCP stream first before we can parse the DNS query. Thus, when
we want to then forward the query, we need to open our own TCP stream to
the upstream resolver and encode the DNS query onto that stream, sending
each IP packet from the TCP client through the tunnel.

The difference in these designs makes several code paths in connlib hard
to follow.

Therefore - and despite the simplicity of DNS over UDP - we already
created our own "Layer 3 UDP DNS"-client. This PR now integrates this
client into the tunnel. Using this new client, we can simplify the
processing of UDP DNS queries because we never have to "go back" to the
original IP packet. Instead, when a DNS query needs to be forwarded to
an usptream resolver through the tunnel, we simply tell the Layer 3 UDP
DNS client to make a new DNS query. The processing of the resulting IP
packet then happens in a different place, right next to where we also
process the IP packets of the TCP DNS client.

That simplifications unlocks further refactorings where we now only
process DNS queries in a single place and the transport we received it
over is a simple function parameter with the control flow for both of
them being identical.

Related: #4668
2025-11-11 03:53:25 +00:00
Thomas Eizinger
de7d3bff89 fix(connlib): re-resolve portal host on WS hiccup (#10817)
Currently, the DNS records for the portal's hostname are only resolved
during startup. When the WebSocket connection fails, we try to reconnect
but only with the IPs that we have previously resolved. If the local IP
stack changed since then or the hostname now points to different IPs, we
will run into the reconnect-timeout configured in `phoenix-channel`.

To fix this, we re-resolve the portal's hostname every time the
WebSocket connection fails. For the Gateway, this is easy as we can
simply reuse the already existing `TokioResolver` provided by hickory.
For the Client, we need to write our own DNS client on top of our socket
factory abstraction to ensure we don't create a routing loop with the
resulting DNS queries. To simplify things, we only send DNS queries over
UDP. Those are not guaranteed to succeed but given that we do this on
every "hiccup", we already have a retry mechanism. We use the currently
configured upstream DNS servers for this.

Resolves: #10238
2025-11-11 03:24:36 +00:00
Thomas Eizinger
189c358975 feat(portal): add Debian/Ubuntu deployment tab (#10741)
Now that we have an APT repository for Debian / Ubuntu packages, we
should also tell our users about it. We introduce a new "Debian /
Ubuntu" tab on the deployments screen in the portal. The tab is selected
by default as it should provide the best user experience for manually
deployed Gateways:

- Updates are as easy as `sudo apt upgrade`
- The systemd file and token are fully managed in the background

Here is what the new tab looks like:

<img width="679" height="786" alt="image"
src="https://github.com/user-attachments/assets/da69fc55-6a6a-476d-bed4-634dd05df8bc"
/>


Resolves: #10701

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
2025-11-11 02:18:33 +00:00
dependabot[bot]
a982f0bafb build(deps-dev): bump typescript from 5.9.2 to 5.9.3 in /website (#10840)
Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.9.2
to 5.9.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/microsoft/TypeScript/releases">typescript's
releases</a>.</em></p>
<blockquote>
<h2>TypeScript 5.9.3</h2>
<p>Note: this tag was recreated to point at the correct commit. The npm
package contained the correct content.</p>
<p>For release notes, check out the <a
href="https://devblogs.microsoft.com/typescript/announcing-typescript-5-9/">release
announcement</a></p>
<ul>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.9.0%22+is%3Aclosed+">fixed
issues query for Typescript 5.9.0 (Beta)</a>.</li>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.9.1%22+is%3Aclosed+">fixed
issues query for Typescript 5.9.1 (RC)</a>.</li>
<li><em>No specific changes for TypeScript 5.9.2 (Stable)</em></li>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.9.3%22+is%3Aclosed+">fixed
issues query for Typescript 5.9.3 (Stable)</a>.</li>
</ul>
<p>Downloads are available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/typescript">npm</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c63de15a99"><code>c63de15</code></a>
Bump version to 5.9.3 and LKG</li>
<li><a
href="8428ca4cc8"><code>8428ca4</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/microsoft/TypeScript/issues/62438">#62438</a>
(Fix incorrectly ignored dts file fr...) into release-5.9 (#...</li>
<li><a
href="a131cac683"><code>a131cac</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/microsoft/TypeScript/issues/62351">#62351</a>
(Add missing Float16Array constructo...) into release-5.9 (#...</li>
<li><a
href="0424333358"><code>0424333</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/microsoft/TypeScript/issues/62423">#62423</a>
(Revert PR 61928) into release-5.9 (<a
href="https://redirect.github.com/microsoft/TypeScript/issues/62425">#62425</a>)</li>
<li><a
href="bdb641a434"><code>bdb641a</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/microsoft/TypeScript/issues/62311">#62311</a>
(Fix parenthesizer rules for manuall...) into release-5.9 (#...</li>
<li><a
href="0d9b9b92e2"><code>0d9b9b9</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/microsoft/TypeScript/issues/61978">#61978</a>
(Restructure CI to prepare for requi...) into release-5.9 (#...</li>
<li><a
href="2dce0c58af"><code>2dce0c5</code></a>
Intentionally regress one buggy declaration output to an older version
(<a
href="https://redirect.github.com/microsoft/TypeScript/issues/62163">#62163</a>)</li>
<li>See full diff in <a
href="https://github.com/microsoft/TypeScript/compare/v5.9.2...v5.9.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=typescript&package-manager=npm_and_yarn&previous-version=5.9.2&new-version=5.9.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 01:41:33 +00:00
dependabot[bot]
c6aa971947 build(deps): bump fast-xml-parser from 5.2.5 to 5.3.0 in /website (#10841)
Bumps
[fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser)
from 5.2.5 to 5.3.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md">fast-xml-parser's
changelog</a>.</em></p>
<blockquote>
<p><!-- raw HTML omitted -->Note: If you find missing information about
particular minor version, that version must have been changed without
any functional change in this library.<!-- raw HTML omitted --></p>
<p><strong>5.3.1 / 2025-11-03</strong></p>
<ul>
<li>Performance improvement for stopNodes (By <a
href="https://github.com/macieklamberski">Maciek Lamberski</a>)</li>
</ul>
<p><strong>5.3.0 / 2025-10-03</strong></p>
<ul>
<li>Use <code>Uint8Array</code> in place of <code>Buffer</code> in
Parser</li>
</ul>
<p><strong>5.2.5 / 2025-06-08</strong></p>
<ul>
<li>Inform user to use <a
href="https://github.com/NaturalIntelligence/fxp-cli">fxp-cli</a>
instead of in-built CLI feature</li>
<li>Export typings  for direct use</li>
</ul>
<p><strong>5.2.4 / 2025-06-06</strong></p>
<ul>
<li>fix (<a
href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/747">#747</a>):
fix EMPTY and ANY with ELEMENT in DOCTYPE</li>
</ul>
<p><strong>5.2.3 / 2025-05-11</strong></p>
<ul>
<li>fix (<a
href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/747">#747</a>):
support EMPTY and ANY with ELEMENT in DOCTYPE</li>
</ul>
<p><strong>5.2.2 / 2025-05-05</strong></p>
<ul>
<li>fix (<a
href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/746">#746</a>):
update strnum to fix parsing issues related to enotations</li>
</ul>
<p><strong>5.2.1 / 2025-04-22</strong></p>
<ul>
<li>fix: read DOCTYPE entity value correctly</li>
<li>read DOCTYPE NOTATION, ELEMENT exp but not using read values</li>
</ul>
<p><strong>5.2.0 / 2025-04-03</strong></p>
<ul>
<li>feat: support metadata on nodes (<a
href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/593">#593</a>)
(By <a href="https://github.com/srl295">Steven R. Loomis</a>)</li>
</ul>
<p><strong>5.1.0 / 2025-04-02</strong></p>
<ul>
<li>feat: declare package as side-effect free (<a
href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/738">#738</a>)
(By <a href="https://github.com/tbouffard">Thomas Bouffard</a>)</li>
<li>fix cjs build mode</li>
<li>fix builder return type to string</li>
<li></li>
</ul>
<p><strong>5.0.9 / 2025-03-14</strong></p>
<ul>
<li>fix: support numeric entities with values over 0xFFFF (<a
href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/726">#726</a>)
(By <a href="https://github.com/mcdurdin">Marc Durdin</a>)</li>
<li>fix: update strnum to fix parsing 0 if skiplike option is used</li>
</ul>
<p><strong>5.0.8 / 2025-02-27</strong></p>
<ul>
<li>fix parsing 0 if skiplike option is used.
<ul>
<li>updating strnum dependency</li>
</ul>
</li>
</ul>
<p><strong>5.0.7 / 2025-02-25</strong></p>
<ul>
<li>fix (<a
href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/724">#724</a>)
typings for cjs.</li>
</ul>
<p><strong>5.0.6 / 2025-02-20</strong></p>
<ul>
<li>fix cli output (By <a href="https://github.com/angeld7">Angel
Delgado</a>)
<ul>
<li>remove multiple JSON parsing</li>
</ul>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="badf18960c"><code>badf189</code></a>
Use <code>Uint8Array</code> in place of <code>Buffer</code> in
Parser</li>
<li><a
href="418ab9535c"><code>418ab95</code></a>
fix <a
href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/764">#764</a>
(<a
href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/765">#765</a>)</li>
<li><a
href="ad17aa4b12"><code>ad17aa4</code></a>
Fix typo in types (<a
href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/760">#760</a>)</li>
<li>See full diff in <a
href="https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.2.5...v5.3.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=fast-xml-parser&package-manager=npm_and_yarn&previous-version=5.2.5&new-version=5.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 01:40:47 +00:00
dependabot[bot]
a9058c7f55 build(deps): bump known-folders from 1.3.1 to 1.4.0 in /rust (#10831)
Bumps [known-folders](https://github.com/artichoke/known-folders-rs)
from 1.3.1 to 1.4.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/artichoke/known-folders-rs/releases">known-folders's
releases</a>.</em></p>
<blockquote>
<h2>v1.4.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump thor from 1.3.2 to 1.4.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/85">artichoke/known-folders-rs#85</a></li>
<li>Bump rubocop from 1.77.0 to 1.79.1 in the bundler-deps group by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/86">artichoke/known-folders-rs#86</a></li>
<li>Bump the gha-deps group with 3 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/87">artichoke/known-folders-rs#87</a></li>
<li>Use zizmor audit action by <a
href="https://github.com/lopopolo"><code>@​lopopolo</code></a> in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/88">artichoke/known-folders-rs#88</a></li>
<li>Bump rubocop from 1.79.1 to 1.81.1 in the bundler-deps group by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/89">artichoke/known-folders-rs#89</a></li>
<li>Bump the gha-deps group with 5 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/91">artichoke/known-folders-rs#91</a></li>
<li>Relax windows-sys version requirement, prepare for v1.4.0 release by
<a href="https://github.com/lopopolo"><code>@​lopopolo</code></a> in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/92">artichoke/known-folders-rs#92</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/artichoke/known-folders-rs/compare/v1.3.1...v1.4.0">https://github.com/artichoke/known-folders-rs/compare/v1.3.1...v1.4.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="69fd83233a"><code>69fd832</code></a>
Merge pull request <a
href="https://redirect.github.com/artichoke/known-folders-rs/issues/92">#92</a>
from artichoke/dev/lopopolo-windows-sys-bump</li>
<li><a
href="ff9e8f7f7c"><code>ff9e8f7</code></a>
working</li>
<li><a
href="d8f5cc7b1a"><code>d8f5cc7</code></a>
powershell</li>
<li><a
href="1ad9c0cd63"><code>1ad9c0c</code></a>
try again</li>
<li><a
href="4ee5739bb0"><code>4ee5739</code></a>
precise needs a fully formed version</li>
<li><a
href="039c0992a9"><code>039c099</code></a>
Merge pull request <a
href="https://redirect.github.com/artichoke/known-folders-rs/issues/91">#91</a>
from artichoke/dependabot/github_actions/gha-deps-f417...</li>
<li><a
href="8f8402d463"><code>8f8402d</code></a>
Use a valid spec</li>
<li><a
href="b0af2f35da"><code>b0af2f3</code></a>
address zizmor complaint</li>
<li><a
href="2281b61f94"><code>2281b61</code></a>
don't have to actually relax MSRV</li>
<li><a
href="dce5052821"><code>dce5052</code></a>
update CI</li>
<li>Additional commits viewable in <a
href="https://github.com/artichoke/known-folders-rs/compare/v1.3.1...v1.4.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=known-folders&package-manager=cargo&previous-version=1.3.1&new-version=1.4.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 01:36:11 +00:00
dependabot[bot]
e9fcb20564 build(deps): bump nu-ansi-term from 0.50.1 to 0.50.3 in /rust (#10830)
Bumps [nu-ansi-term](https://github.com/nushell/nu-ansi-term) from
0.50.1 to 0.50.3.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/nushell/nu-ansi-term/commits">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=nu-ansi-term&package-manager=cargo&previous-version=0.50.1&new-version=0.50.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 01:35:25 +00:00
Thomas Eizinger
6e85638360 chore(connlib): silence hickory_resolver (#10848)
Logs from the `hickory_resolver` module are a bit noisy, so filter those
out from our logs.
2025-11-11 01:04:41 +00:00
Thomas Eizinger
49b7701536 ci: promote preview .deb to stable on release (#10846)
The current CI job expects the release to have the `.deb` files
attached. Since writing that workflow, I've changed my mind on attaching
the `.deb` files there. Instead, they are only uploaded to the
repository. Without documentation on how to use them, these `.deb` files
are unlikely to provide a good user experience.

We change the job to instead promote the latest "preview` archives to
the stable repo.
2025-11-10 19:57:02 +00:00
Jamil
bd2abbaae3 feat(apple): config to hide resource list (#10824)
Adds a configuration variable `hideResourceList` accessible by
provisioning profile only to hide or show the Resource list. This is
helpful when end-users need not be concerned with the resources
available to their account.

Also updates the associated ProfileManifests, docs, and a little bit of
housekeeping around `configuration`, making it public for direct access.

<img width="292" height="228" alt="Screenshot 2025-11-09 at 9 12 47 PM"
src="https://github.com/user-attachments/assets/a4ce5586-bf92-4ebc-bc0d-51215e1efd61"
/>


Related: https://github.com/ProfileManifests/ProfileManifests/pull/839
Fixes: #10808

---------

Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-10 19:55:27 +00:00
Firezone Bot
5ae2707719 chore: publish gateway 1.4.18 (#10823) 2025-11-10 19:08:17 +11:00
Thomas Eizinger
3022c019e1 chore(connlib): set user.account_slug for Sentry logs (#10815)
By default, the Sentry SDK doesn't include custom user attributes when
it sends logs. To make viewing logs easier, we add the `account_slug`
attribute to all logs that are posted to Sentry.
2025-11-10 04:08:45 +00:00
Thomas Eizinger
166b0d1573 feat(linux): compute device ID from /etc/machine-id (#10805)
All of our Linux applications have a soft-dependency on systemd. That
is, in the default configuration, we expect systemd to be present on the
machine. The only exception here are the docker containers for Headless
Client and Gateway.

For the GUI client in particular, systemd is a hard-dependency in order
to control DNS on the system which we do via `systemd-resolved`. To
secure the communication between the GUI client and its tunnel process,
we automatically create a group called `firezone-client` to which the
user gets added. All members of the group are allowed to access the unix
socket which is used for IPC between the two processes. Membership in
this group is also a prerequisite for accessing any of the configuration
files.

On the first launch of the GUI client on a Linux system, this presents a
problem. For group membership changes to take the effect, the user needs
to reboot. We say that in the documentation but it is unclear whether
all users will read that thoroughly enough. To help the user, the GUI
client checks for membership of the current user in the group and alerts
the user via a dialog box if that isn't the case. This would all be fine
if it would actually work. Unfortunately, that check ends up being too
late in the process. If we aren't a member of the group, we cannot read
the device ID and bail early, thus never reaching the check and
terminating the process without any dialog box or user-visible error.

We could attempt to fix this by shuffling around some of the startup
init code. That is a sub-optimal solution however because it a) may get
broken again in the future and b) it means we have to delay
initialisation of telemetry until a much later point.

Given that this is only a problem on Linux, a better solution is to
simply not rely on the disk-based device ID at all. Instead, we can
integrate with systemd and deterministically derive a device ID from the
unique machine ID and a randomly chosen "app ID".

For backwards-compatibility reasons, the disk-based device ID is still
prioritised. For all new installs however, we will use the one based on
`/etc/machine-id`.
2025-11-10 02:29:52 +00:00
Thomas Eizinger
8651413a95 chore(gateway): downgrade warning if peer not found (#10814)
Logging this on WARN appears to be a bit excessive and there is not
really anything we can do about it.

Resolves: #10813
2025-11-10 01:45:50 +00:00
Thomas Eizinger
f4216710e0 fix(telemetry): don't append duplicate attributes in Sentry log (#10819)
When we are building the log message that is sent to Sentry, we append
several attributes to mimic the formatting that we get from
`tracing_subscriber::fmt`. To do that, we strip the span name from the
attribute which can result in us processing the same attribute such as
`cid` twice: Once from a span and once from the actual log message. In
order to not append the same message twice, we check for its presence in
the attributes map first.

This avoids having message in Sentry such as:

```
Sampled relay cid=c18e1da8-8ef8-4e11-a325-28d6b387d503 rid=3af15c76-9e84-46a6-90e1-63ecb2bc9f80 cid=c18e1da8-8ef8-4e11-a325-28d6b387d503
```
2025-11-10 01:42:01 +00:00
Thomas Eizinger
bc95a1f425 chore(snownet): log connection state on failure (#10820)
When investigating, why a connection fails it is useful to know right
away, what the last connection state was, including the kind of
connection, such as `PeerToPeer`, `RelayToPeer` etc.
2025-11-10 01:41:23 +00:00
Thomas Eizinger
123c5a5d97 chore(connlib): always include wire::api as Sentry breadcrumb (#10821)
Sentry appends "breadcrumbs" to every error that gets sent to the
backend. By default, those include the last 500 DEBUG logs. Our
`phoenix_channel` module logs the incoming and outgoing messages on
TRACE using the `wire::api::send` and `wire::api::recv` targets.

To make debugging these easier, we always include anything on
`wire::api` in the breadcrumbs.
2025-11-10 01:40:30 +00:00
Thomas Eizinger
74bd28d25a ci(gui-client): fix .deb test installation (#10816)
The current test installation fails because it is operating in a
headless environment without a display user. Some more testing of the
`who` command showed that we can simply take the first user. That avoids
`grep` which was previously failing with an exit code of 1, aborting the
installation because our `postinst` script has `pipefail` set.
2025-11-09 16:50:33 +00:00
Thomas Eizinger
3eead925fe chore(gui-client): tidy up postinst script (#10804)
Specifying `sudo` in the script is unnecessary as it already runs as
root. Additionally, only executing `systemd-sysusers` for our config
file is better because it narrows the scope of what should be done.
2025-11-07 21:55:03 +00:00
Thomas Eizinger
f98c4dd428 fix(gateway): declare hard-dependency on systemd (#10803)
Several aspects of the Gateway's Debian package depend on `systemd`
being present. Without it, we don't have the necessary users and files
in place for the Gateway to function. With that specified, we can fail
the `postinst` script (and therefore the installation) if anything in
there goes wrong.
2025-11-07 14:33:30 +00:00
dependabot[bot]
839cc4b7b3 build(deps): bump parking_lot from 0.12.4 to 0.12.5 in /rust (#10780)
Bumps [parking_lot](https://github.com/Amanieu/parking_lot) from 0.12.4
to 0.12.5.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md">parking_lot's
changelog</a>.</em></p>
<blockquote>
<h2><code>parking_lot</code> - <a
href="https://github.com/Amanieu/parking_lot/compare/parking_lot-v0.12.4...parking_lot-v0.12.5">0.12.5</a>
- 2025-09-30</h2>
<ul>
<li>Bumped MSRV to 1.71</li>
<li>Fixed Miri when the <code>hardware-lock-elision</code> feature is
enabled (<a
href="https://redirect.github.com/Amanieu/parking_lot/issues/491">#491</a>)</li>
<li>Added missing <code>into_arc(_fair)</code> methods (<a
href="https://redirect.github.com/Amanieu/parking_lot/issues/472">#472</a>)</li>
<li>Fixed <code>RawRwLock::bump_*()</code> not releasing lock when there
are multiple readers (<a
href="https://redirect.github.com/Amanieu/parking_lot/issues/471">#471</a>)</li>
</ul>
<h2><code>parking_lot_core</code> - <a
href="https://github.com/Amanieu/parking_lot/compare/parking_lot_core-v0.9.11...parking_lot_core-v0.9.12">0.9.12</a>
- 2025-09-30</h2>
<ul>
<li>Bumped MSRV to 1.71</li>
<li>Switched from <code>windows-targets</code> to
<code>windows-link</code>. (<a
href="https://redirect.github.com/Amanieu/parking_lot/issues/493">#493</a>)</li>
<li>Replaced <code>thread-id</code> dependency with
<code>std::thread::ThreadId</code> (<a
href="https://redirect.github.com/Amanieu/parking_lot/issues/483">#483</a>)</li>
<li>Added SGX implementation for <code>ThreadParker.park_until</code>
(<a
href="https://redirect.github.com/Amanieu/parking_lot/issues/481">#481</a>)</li>
</ul>
<h2><code>lock_api</code> - <a
href="https://github.com/Amanieu/parking_lot/compare/lock_api-v0.4.13...lock_api-v0.4.14">0.4.14</a>
- 2025-09-30</h2>
<ul>
<li>Fixed use of <code>doc_cfg</code> when building on docs.rs.</li>
<li>Bumped MSRV to 1.71</li>
<li>Added <code>#[track_caller]</code> where locking implementations
could feasibly need to panic</li>
<li>Added <code>try_map_or_err</code> to various mutex guards (<a
href="https://redirect.github.com/Amanieu/parking_lot/issues/480">#480</a>)</li>
<li>Removed unnecessary build script and <code>autocfg</code> dependency
(<a
href="https://redirect.github.com/Amanieu/parking_lot/issues/474">#474</a>)</li>
<li>Added missing <code>into_arc(_fair)</code> methods (<a
href="https://redirect.github.com/Amanieu/parking_lot/issues/472">#472</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="d7828fff7b"><code>d7828ff</code></a>
chore: release</li>
<li><a
href="73365ad59b"><code>73365ad</code></a>
Merge pull request <a
href="https://redirect.github.com/Amanieu/parking_lot/issues/495">#495</a>
from mbrobbel/doc_auto_cfg</li>
<li><a
href="0b5585a17f"><code>0b5585a</code></a>
Replace <code>doc_auto_cfg</code> with <code>doc_cfg</code></li>
<li><a
href="c7b7dc730d"><code>c7b7dc7</code></a>
Merge pull request <a
href="https://redirect.github.com/Amanieu/parking_lot/issues/493">#493</a>
from a1phyr/windows_link</li>
<li><a
href="07c2d4020d"><code>07c2d40</code></a>
Update MSRV to 1.71</li>
<li><a
href="345cf7a0eb"><code>345cf7a</code></a>
Switch from <code>windows-targets</code> to
<code>windows-link</code></li>
<li><a
href="eeb186c48c"><code>eeb186c</code></a>
Merge pull request <a
href="https://redirect.github.com/Amanieu/parking_lot/issues/491">#491</a>
from AaronKutch/fix_assembly_on_miri</li>
<li><a
href="a7d328e9c4"><code>a7d328e</code></a>
do not use elision on Miri even if feature is enabled</li>
<li><a
href="739d370a80"><code>739d370</code></a>
Merge pull request <a
href="https://redirect.github.com/Amanieu/parking_lot/issues/487">#487</a>
from sola-contrib/replace-winapi</li>
<li><a
href="ed4ae932ce"><code>ed4ae93</code></a>
Replace winapi with windows-sys in benchmark crate</li>
<li>Additional commits viewable in <a
href="https://github.com/Amanieu/parking_lot/compare/parking_lot-v0.12.4...parking_lot-v0.12.5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=parking_lot&package-manager=cargo&previous-version=0.12.4&new-version=0.12.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-07 06:11:48 +00:00
Thomas Eizinger
89f0af3fd7 fix(gateway): remove exclamation mark from sysusers.conf (#10802) 2025-11-07 12:21:32 +11:00
Thomas Eizinger
024b1864b4 feat(linux): automatically add user to firezone-client group (#10787)
By checking various environment variables, we can automatically add the
current user to the `firezone-client` group which allows them to connect
to the IPC socket of the tunnel process. Unfortunately, they still have
to create a new login session / reboot for that to be reflected.

The docs update for this will follow once we have cut a release with
this code in it.

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-06 23:53:31 +00:00
Mariusz Klochowicz
470680cb1f chore(apple): Migrate to latest Xcode recommended settings (#10766)
Prompted by Xcode warning at project startup.

Most of the changes are simple migrations from entitlements files
to build settings, which is the recommended approach, and were done
automatically by Xcode.

new settings:
- REGISTER_APP_GROUPS - Automatically registers app groups with
provisioning
profile (I had to set this manually when setting up, so it's a welcome
change)
- STRING_CATALOG_GENERATE_SYMBOLS - type-safe localization (no
  regression, we're not doing any localization currently)
- ENABLE_USER_SCRIPT_SANDBOXING - sandboxing all the build scripts

Note: I had to turn off the recommended `ENABLE_USER_SCRIPT_SANDBOXING`
as it
would interfere with our building of connlib during the build.

Also: make Makefile more ergonomic to use (setup LSP config during first
build)
2025-11-06 22:45:56 +00:00
Thomas Eizinger
602844ae4a fix(gateway): always update translation table from DNS response (#10796)
For DNS resources, the Gateway maintains a per-peer NAT table from the
client-assigned proxy IPs to the real IPs of the domain. Whenever the
Client re-queries a DNS resource domain locally, we asynchronously ping
the Gateway to also re-query said domain. This allows us to detect
changes in the DNS records of DNS resources.

To avoid breaking existing connections, the mapping between proxy IPs
and real IPs is currently not updated if there are any active UDP or TCP
flows for a proxy IP.

This logic turns out to be unnecessarily restrictive as TCP flows can
linger around for up to 2h before they timeout if they are not closed
with a TCP RST. What we really need to do is always update the mapping
of proxy IP <> real IP but honor existing NAT table entries when we
route packets before creating new ones. This ensures that an existing
connection to a previously resolved IP remains intact, even if a later
DNS response for the same domain updates the mapping. At the same time,
new connections (i.e. with a different source port) will immediately use
the new destination IP.
2025-11-06 11:52:28 +00:00
Mariusz Klochowicz
b5048ad779 refactor(apple): Convert IPCClient from actor to stateless enum (#10797)
Refactors IPCClient from an actor to a stateless enum with static
methods, removing unnecessary actor isolation and instance management.

- IPCClient: Actor → enum with static methods taking session parameter
- Store: Removed IPCClient instance caching, added resource list caching
- Store: Moved resource fetching logic from IPCClient into Store
- All call sites: Updated to pass session directly to static methods

Store now directly manages resource list hashing and caching via
fetchResources() method, using SHA256 hash optimisation to avoid
redundant updates when resource lists haven't changed.
2025-11-05 21:58:20 +00:00
Mariusz Klochowicz
936b095391 chore(apple): Enable Swift 6.2 Approachable Concurrency features (#10799)
Enables SWIFT_APPROACHABLE_CONCURRENCY build setting which activates
a few key Swift 6.2 concurrency features, including:

1. NonisolatedNonsendingByDefault - Makes nonisolated async functions
run
   on the caller's executor instead of the global executor, providing
   more predictable performance and behaviour

2. InferIsolatedConformances - Protocol conformances automatically
   inherit global actor isolation, reducing annotation burden

Read more:
https://www.donnywals.com/what-is-approachable-concurrency-in-xcode-26/

Also bumps swift-tools-version from 6.0 to 6.2 in Package.swift to
enable newer Package Manager manifest APIs.

As a result of better type inference, removes 1 redundant @Sendable
annotation in Store.swift:
- vpnStatusChangeHandler: @MainActor closures are implicitly Sendable
2025-11-05 21:56:24 +00:00
Thomas Eizinger
72dd7187f4 revert: specify systemd-resolved dependency (#10798)
I can't make the CI smoke install work with this change.

Reverts firezone/firezone#10783
2025-11-05 12:54:54 +00:00
Mariusz Klochowicz
bf95dc45a3 refactor(apple): Upgrade to Swift 6.2 with concurrency checks (#10682)
This PR upgrades the Swift client from Swift 5 to Swift 6.2, addressing
all
concurrency-related warnings and runtime crashes that come with Swift
6's
strict concurrency checking.

## Swift 6 Concurrency Primer

**`actor`** - A new reference type that provides thread-safe, serialised
access to mutable state. Unlike classes, actors ensure that only one
piece of
code can access their mutable properties at a time. Access to actor
methods/properties requires await and automatically hops to the actor's
isolated executor.

**`@MainActor`** - An attribute that marks code to run on the main
thread.
Essential for UI updates and anything that touches UIKit/AppKit. When a
class/function is marked @MainActor, all its methods and properties
inherit
this isolation.

**`@Sendable`** - A protocol indicating that a type can be safely passed
across concurrency domains (between actors, tasks, etc.). Value types
(structs, enums) with Sendable stored properties are automatically
Sendable.
Reference types (classes) need explicit @unchecked Sendable if they
manage
thread-safety manually.

**`nonisolated`** - Opts out of the containing type's actor isolation.
For
example, a nonisolated method in a @MainActor class can be called from
any
thread without await. Useful for static methods or thread-safe
operations.

**`@concurrent`** - Used on closure parameters in delegate methods.
Indicates
the closure may be called from any thread, preventing the closure from
inheriting the surrounding context's actor isolation. Critical for
callbacks
from system frameworks that call from background threads.

**Data Races** - Swift 6 enforces at compile-time (and optionally at
runtime)
that mutable state cannot be accessed concurrently from multiple
threads. This
eliminates entire classes of bugs that were previously only caught
through
testing or production crashes.

## Swift Language Upgrade

- **Bump Swift 5 → 6.2**: Enabled strict concurrency checking throughout
the
  codebase
- **Enable ExistentialAny (SE-0335)**: Adds compile-time safety by
making
  protocol type erasure explicit (e.g., any Protocol instead of implicit
  Protocol)
- **Runtime safety configuration**: Added environment variables to log
concurrency violations during development instead of crashing, allowing
  gradual migration

## Concurrency Fixes

### Actor Isolation

- **TelemetryState actor** (Telemetry.swift:10): Extracted mutable
telemetry
state into a dedicated actor to eliminate data races from concurrent
access
- **SessionNotification @MainActor isolation**
(SessionNotification.swift:25):
  Properly isolated the class to MainActor since it manages UI-related
  callbacks
- **IPCClient caching** (IPCClient.swift): Fixed actor re-entrance
issues and
resource hash-based optimisation by caching the client instance in Store

### Thread-Safe Callbacks

- **WebAuthSession @concurrent delegate** (WebAuthSession.swift:46): The
  authentication callback is invoked from a background thread by
ASWebAuthenticationSession. Marked the wrapper function as @concurrent
to
  prevent MainActor inference on the completion handler closure, then
  explicitly hopped back to MainActor for the session.start() call. This
  fixes EXC_BAD_INSTRUCTION crashes at _dispatch_assert_queue_fail.
- **SessionNotification @concurrent delegate**
(SessionNotification.swift:131): Similarly marked the notification
delegate
method as @concurrent and used Task { @MainActor in } to safely invoke
the
  MainActor-isolated signInHandler

### Sendable Conformances

- Added Sendable to Resource, Site, Token, Configuration, and other
model
  types that are passed between actors and tasks
- **LogWriter immutability** (Log.swift): Made jsonData immutable to
prevent
  capturing mutable variables in @Sendable closures

### Nonisolated Methods

- **Static notification display** (SessionNotification.swift:73): Marked
showSignedOutNotificationiOS() as nonisolated since it's called from the
  Network Extension (different process) and only uses thread-safe APIs

Fixes #10674
Fixes #10675
2025-11-05 04:24:49 +00:00
Thomas Eizinger
bae38ec345 feat(connlib): add HTTP2 client with pluggable sockets (#10788)
Firezone's ability to tunnel all traffic on a particular Client (i.e.
the Internet Resource) means we have to ensure that traffic originating
from within the Firezone process does not get routed back into the
tunnel. On MacOS and iOS, this is automatically taken care of for us. On
all other platforms, we need to take steps to prevent these routing
loops.

This functionality is abstracted away using our `SocketFactory`. A
socket created with such a factory is guaranteed to route its traffic
outside of the tunnel. These sockets are used for the WebSocket
connection to the portal, as well as for recursive UDP and TCP DNS
queries.

In order to support DoH, we need to also be able to send HTTPS requests
without causing packet loops.

This PR adds a new crate `http-client` that does exactly that. It
composes together `hyper` and `rustls` such that the configured
`SocketFactory` is used to create the TCP socket for the underlying
HTTP2 connection. Consequently, HTTPS requests made with this library
will automatically be routed outside of the tunnel, assuming the
`SocketFactory` is adequately configured.

Right now, this crate just stands by itself. It will be integrated into
connlib at a later point.

Resolves: #10774
Related: #4668 
Related: #10272
2025-11-04 08:17:59 +00:00
Thomas Eizinger
b8b52c1f07 fix(portal): do not allow ports for upstream DNS servers (#10772)
DNS servers are standarised to be contacted on port 53. This is also
hard-coded within `connlib` when we contact an upstream server. As such,
we should disallow users inputting any custom port for upstream DNS
servers. Luckily - or perhaps because it doesn't presently work - no
users in production have actually put in a port.

Resolves: #8330
2025-11-04 04:44:57 +00:00
Thomas Eizinger
352a83bbb0 refactor(connlib): allow creating multiple layer 4 DNS servers (#10763)
Within Firezone, there are multiple components that deal with DNS
queries. Two of those components are the `l4-udp-dns-server` and
`l4-tcp-dns-server`. Both of them are responsible for receiving DNS
queries on layer 4, i.e. UDP or TCP. In other words, they do _not_
operate on an IP level (which would be layer 3) but instead use
`UdpSocket` and `TcpListener` to receive queries and sent back
responses.

Right now, the interfaces of these crates are designed for the usecase
of receiving forwarded DNS queries from the CLient on the Gateway's TUN
device. This is a special-case of DNS resolution. When receiving a TXT
or SRV query for a domain that is covered by a DNS resources, Firezone
Client's will forward that query to the corresponding Gateway and
resolve it in its network context. SRV and TXT records are commonly used
for service discovery and as such, should be resolved in the network
context of the service, i.e. the site that assigned to the resource.

For that usecase, it made sense to allow each DNS server to listen on 1
IPv4 and 1 IPv6 address. Since then, our event-loop has evolved a bit,
being able to handle multiple inputs at once. As such, we can simplify
the API of these crates to only listen on a single address and instead
create multiple instances of them inside `Io`. Depending on how the
design of our DNS implementation for the Clients evolves, this may be
used to listen on multiple IPs later (e.g. from the `127.0.0.0/8`
subnet).

Related: #8263
2025-11-04 03:45:49 +00:00
Thomas Eizinger
804ef7a3fb fix(connlib): retain order of system/upstream DNS servers (#10773)
Right now, connlib hands out a `BiMap` of sentinel IPs <> upstream
servers whenever it emits a `TunInterfaceUpdated` event. This `BiMap`
internally uses two `HashMap`s. The iteration order of `HashMap`s is
non-deterministic and therefore, we lose the order in which the upstream
/ system resolvers have been passed to us originally.

To prevent that, we now emit a dedicated `DnsMapping` type that does not
expose its internal data structure but only getters for retrieving the
sentinel and upstream servers. Internally, it uses a `Vec` to store this
mapping and thus retains the original order. This is asserted as part of
our proptests by comparing the resulting `Vec`s.

This fix is preceded by a few refactorings that encapsulate the code for
creating and updating this DNS mapping.

Resolves: #8439
2025-11-03 17:55:48 +00:00
Thomas Eizinger
1b7313622a feat(connlib): introduce l3-udp-dns-client (#10764)
With #8263, we will stop receiving UDP and TCP DNS queries on the tunnel
but use regular sockets instead. This means that for UDP DNS queries
that need to be sent _through_ the tunnel, we actually need to make new
IP packets again. For TCP, we already have a crate that does this for us
because there, we need to manage an entire TCP stack.

For UDP, the story is a bit simpler but there are still a few things
involved. In particular, we need to set a source address for the packets
and we need to sample a new random port for each query.

The crate added in this PR does exactly that. It is not yet used
anywhere but split out into a separate PR to reduce the reviewing burden
of the larger refactor.

Related: #8263
Related: #10758
2025-11-03 17:04:19 +00:00
Thomas Eizinger
9e33e514c4 chore(linux): specify systemd-resolved dependency (#10783)
On Ubuntu, this should be the default anyway and already be installed
but to be correct, we should list this dependency in the `depends`
section of our `.deb`. That way, it will automatically get installed
again if a user chooses to install the GUI client from our repository
and doesn't have `systemd-resolved` installed.
2025-11-03 15:11:45 +00:00