Also refactored to extract an auth state machine. The auth logic
previously was scattered throughout the GUI module, which would make it
hard to audit. Because of the refactoring I was able to add some simple
unit tests.
the way we were checking for subdomains in the gateways completely
broke, didn't detect it before because the deployed staging version for
gateways is too old.
~~Added a few CI tests so this doesn't' happen again.~~ seems like
github runners [doesn't support pinging the outside
world](https://github.com/actions/runner-images/issues/1519) so I'm
putting that off for now.
This will fix#3114 and save about 13 seconds at startup, compared to
shelling out to Powershell.
I'm not 100% sure it works for IPv6 routes - I'm setting port, flowinfo,
and scope to 0 and just assuming that it's fine.
For some reason Windows wants a socket address in this API even though I
don't think the port is used for anything.
Bumps
[org.jetbrains.kotlin:kotlin-stdlib](https://github.com/JetBrains/kotlin)
from 1.9.21 to 1.9.22.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/JetBrains/kotlin/releases">org.jetbrains.kotlin:kotlin-stdlib's
releases</a>.</em></p>
<blockquote>
<h2>Kotlin 1.9.22</h2>
<h2>Changelog</h2>
<h3>JavaScript</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63719"><code>KT-63719</code></a>
KJS: Test results ignored for ES module kind</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63808"><code>KT-63808</code></a>
compileTestDevelopmentExecutableKotlinJs failed in
JsIntrinsicTransformers</li>
</ul>
<h3>Native</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-64139"><code>KT-64139</code></a>
Weird bug with while and coroutine in Kotlin Native</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63471"><code>KT-63471</code></a>
linkDebugTestIosX64 Failed to build cache: NoSuchFileException
bitcode_deps</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63789"><code>KT-63789</code></a>
Native: Incremental compilation problem with compose</li>
</ul>
<h3>Tools. CLI</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-64485"><code>KT-64485</code></a>
CLI: cache and optimize parsing of command-line arguments</li>
</ul>
<h3>Tools. Gradle</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63990"><code>KT-63990</code></a>
"Cannot query the value of property 'buildFlowServiceProperty'
because it has no value available" with Isolated Projects</li>
</ul>
<h3>Tools. Gradle. Native</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63363"><code>KT-63363</code></a>
Kotlin Gradle Plugin:
<code>KotlinNativeHostSpecificMetadataArtifact</code> breaks
configuration cache, implicitly includes output file as configuration
cache input</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63742"><code>KT-63742</code></a>
Gradle wrongly caches Kotlin/Native compiler flags</li>
</ul>
<h3>Tools. JPS</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-64305"><code>KT-64305</code></a>
Kotlin JPS builder requests chunk rebuild with graph implementation</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-64112"><code>KT-64112</code></a>
Avoid using IJ's JPS mappings in Kotlin JPS tests</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63799"><code>KT-63799</code></a>
Make plugin classpath serialization path agnostic</li>
</ul>
<h2>Checksums</h2>
<table>
<thead>
<tr>
<th>File</th>
<th>Sha256</th>
</tr>
</thead>
<tbody>
<tr>
<td>kotlin-compiler-1.9.22.zip</td>
<td>88b39213506532c816ff56348c07bbeefe0c8d18943bffbad11063cf97cac3e6</td>
</tr>
<tr>
<td>kotlin-native-linux-x86_64-1.9.22.tar.gz</td>
<td>c2b0a6481ced5401db4a7028661c039b7466996efaa554bbcc6a3d421ac5e7d4</td>
</tr>
<tr>
<td>kotlin-native-macos-x86_64-1.9.22.tar.gz</td>
<td>4646c9bc289d48a228064f565f3a968dde3dcccd7821f403717c708f6ffa8285</td>
</tr>
<tr>
<td>kotlin-native-macos-aarch64-1.9.22.tar.gz</td>
<td>8a95c0e0eb46b41b6d02a1942dc7dfe8c70082a2a26679490a77cd486f0ec8dd</td>
</tr>
<tr>
<td>kotlin-native-windows-x86_64-1.9.22.zip</td>
<td>a9d7bcf38a41a84002ba7a733b08e97b554225a39656d5158fc31dc6d0acede4</td>
</tr>
</tbody>
</table>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md">org.jetbrains.kotlin:kotlin-stdlib's
changelog</a>.</em></p>
<blockquote>
<h2>1.9.22</h2>
<h3>JavaScript</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63719"><code>KT-63719</code></a>
KJS: Test results ignored for ES module kind</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63808"><code>KT-63808</code></a>
compileTestDevelopmentExecutableKotlinJs failed in
JsIntrinsicTransformers</li>
</ul>
<h3>Native</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-64139"><code>KT-64139</code></a>
Weird bug with while and coroutine in Kotlin Native</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63471"><code>KT-63471</code></a>
linkDebugTestIosX64 Failed to build cache: NoSuchFileException
bitcode_deps</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63789"><code>KT-63789</code></a>
Native: Incremental compilation problem with compose</li>
</ul>
<h3>Tools. CLI</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-64485"><code>KT-64485</code></a>
CLI: cache and optimize parsing of command-line arguments</li>
</ul>
<h3>Tools. Gradle</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63990"><code>KT-63990</code></a>
"Cannot query the value of property 'buildFlowServiceProperty'
because it has no value available" with Isolated Projects</li>
</ul>
<h3>Tools. Gradle. Native</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63363"><code>KT-63363</code></a>
Kotlin Gradle Plugin:
<code>KotlinNativeHostSpecificMetadataArtifact</code> breaks
configuration cache, implicitly includes output file as configuration
cache input</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63742"><code>KT-63742</code></a>
Gradle wrongly caches Kotlin/Native compiler flags</li>
</ul>
<h3>Tools. JPS</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-64305"><code>KT-64305</code></a>
Kotlin JPS builder requests chunk rebuild with graph implementation</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-64112"><code>KT-64112</code></a>
Avoid using IJ's JPS mappings in Kotlin JPS tests</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KT-63799"><code>KT-63799</code></a>
Make plugin classpath serialization path agnostic</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="44ed2e94f5"><code>44ed2e9</code></a>
Add changelog for 1.9.22</li>
<li><a
href="b7b0397d2c"><code>b7b0397</code></a>
[Gradle] Made klib unpacked for native metadata compile task</li>
<li><a
href="262697dc38"><code>262697d</code></a>
[K/JS] Fix file extension inside the JS KGP to run tests with ES modules
^KT-...</li>
<li><a
href="87c8aa1037"><code>87c8aa1</code></a>
[K/JS] Fix case with boxing/unboxing inside the BlockDecomposerLowering
^KT-6...</li>
<li><a
href="316df8d032"><code>316df8d</code></a>
[CLI] Add cache for reflection lookup of CLI arguments</li>
<li><a
href="b0cc245beb"><code>b0cc245</code></a>
Avoid throwing exception when BuildFusService can't be injected</li>
<li><a
href="cfbb957e02"><code>cfbb957</code></a>
[IR] Correct handling of loops in liveness analysis</li>
<li><a
href="204cecd5d9"><code>204cecd</code></a>
[box-tests] Added a reproducer for #KT-64139</li>
<li><a
href="9c7aac2ec0"><code>9c7aac2</code></a>
[gradle] Use more fine grained directory for K/N incremental
compilation</li>
<li><a
href="9012e67fdb"><code>9012e67</code></a>
Add KotlinBuilder 'dumb mode' flag</li>
<li>Additional commits viewable in <a
href="https://github.com/JetBrains/kotlin/compare/v1.9.21...v1.9.22">compare
view</a></li>
</ul>
</details>
<br />
[](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>
Initial version of the `firezone-connection` crate. To begin with, we
only establish a connection in a LAN, i.e. no hole-punching, no STUN or
TURN servers, just host candidates. As such, a lot of this PR is just
scaffolding for setting up the test environment and the actual
`ConnectionPool` implementation.
For the curious, I've left some TODOs where I am going to attempt
extending the implementation once we start dealing with STUN and TURN
servers.
I also extended CI to run these tests.
... and move its methods into ResourceDescription.
This was a TODO from some pull request in the last few days. I assume
the goal is to share this function between all clients if needed. It
doesn't reduce the number of lines of code, since I could have removed
ResourceDisplay and done this on-the-fly when building the systray menu,
as an alternative.
Fix for #2956 this is achieved by refreshing access to every resource
every 5 minutes.
There's still an open question for this PR:
When the gateway resolves an ip the gateway allows access to a DNS
resource it resolves the address and allow access to that ip for that
client.
Right now, until the access for that resource doesn't expire that access
isn't revoked.
We could change it so that we require the client to refresh such
access(with this PR those refresh queries are already being made every 5
minutes) every x minutes on top of the `expires_at` or we can keep
`expires_at` as to mean "allow access until `expires_at` for whatever
this resource resolves to".
cc @jamilbk @AndrewDryga
Previously, we just assumed that the domain in the query is a subdomain
of the resource but a malicious actor can hijack that field to access
domains that doesn't correspond to that resource.
With this patch we don't even resolve the address for unrelated domains.
Fixes#2470, now for linux it looks like:
```
Alpine Linux/3.19.0 (x86_64;5.15.133.1-microsoft-standard-WSL2;) connlib/1.0.0
```
For macos it looks like:
```
Mac OS/13.4.1 (arm64;22.5.0;) connlib/1.0.0
```
and this is how it looks on android:
```
Android/Unknown 6.1.23-android14-4-00257-g7e35917775b8-ab9964412 connlib/1.0.0
```
note: seems like in android emulator at least we can't get the
architecture so easily
Should fix#2880
The way I do it is after ~10 seconds dropping the
`gateway_awaiting_connection` and let the client try the connection
again, depending on upper layer, I think this is fine since the cases
where this happens is unlikely.
It's hard to test thoroughly but I'll test with bad-condition
simulators, [pumba](https://github.com/alexei-led/pumba) seems
promising. In the meantime I'm still creating the PR so that I can have
it reviewed.
Edit: Using Pumba with different % of packet loss things seems to go
well, and connections are actually established even if the packets are
loss. (Making a note that we should integrate pumba with our CI)
Partially fixes#2920
As explained in
https://github.com/firezone/firezone/issues/2920#issuecomment-1861642550
in the future we should change the way we resolve DNS queries in the
gateway to properly handle HTTPS record types.
With this patch this is what happens to an HTTPS query while firezone is
running:
```
kdig -t HTTPS ifconfig.net
;; ->>HEADER<<- opcode: QUERY; status: NXDOMAIN; id: 15773
;; Flags: qr rd; QUERY: 1; ANSWER: 0; AUTHORITY: 0; ADDITIONAL: 0
;; QUESTION SECTION:
;; ifconfig.net. IN HTTPS
;; Received 30 B
;; Time 2023-12-18 18:34:23 -03
;; From 100.100.111.1@53(UDP) in 0.6 ms
```
Fixes#2948
So it seems that it's easiest just to use an old-fashioned semver
string. This means we'll need to keep a version matrix in the docs of
which components are supported and for how long, but it's better than
having different version schemes for different Firezone components
altogether.
Automatically write the wintun.dll file on startup and then detect
whether we need to elevate to admin privileges.
I check for privileges by making a test tunnel, so I did #2758 as part
of this, which bundles the DLL inside the exe, and then the exe deploys
it.
---------
Signed-off-by: Reactor Scram <ReactorScram@users.noreply.github.com>
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
Prevent the edge case where our DNS sentinel could be used as a fallback
resolver. I didn't observe this in the wild, but we should avoid it in
case.
---------
Co-authored-by: Gabi <gabrielalejandro7@gmail.com>
This fixes#2503
Also:
* decouples data-plane and control-plane on the gateway
* fixes a thing were a client would stop retrying connecting to a
resource if it failed too many times
* add all routes on start instead of on a per-route basis
This reduces the failover time by depending on webrtc's keepalive
instead of wireguard's.
We have much more control over that, since boringtun doesn't bubble up
any of the keepalives timeout(only a trace warning).
In the a next commit, when things are more stable, we should just get
rid of wireguard's keep alive. When we remove webrtc we will build our
own.
Events based on `keepalive` timeouts are key to our failover system, so
we **need** it.
Draft because it's built on top of #2891 (which is completely separate
code but without that the failover just doesn't work correctly)
<img width="1552" alt="Screenshot 2023-12-12 at 11 29 43 PM"
src="https://github.com/firezone/firezone/assets/167144/d517c830-64a8-462d-8cb5-c41835fa2059">
Found a reliable way to return default system DNS resolvers on iOS and
macOS. Even if this method is not perfect, I think it's still worth
pursuing because:
* Many administrators will set an upstream resolver in the portal anyway
(bypassing client system resolvers)
* It unifies our Split DNS approach across platforms (assuming we can
query the default system resolvers on Windows), allowing connlib to
intercept all DNS queries on all platforms. This opens the door for some
interesting feature possibilities in the area of malicious query
blocking. This also makes DNS bugs easier to investigate because there's
only one codepath for packets to take. See
https://github.com/firezone/firezone/issues/2859
Draft because it needs more testing and I need to figure out the
`RustVec<RustString>` type for the Swift -> Rust FFI.
Refs #2713
When a peer expired the os might have cached the old internal ips that
we used, then with a new peer we were assigning new ips and that cached
ip might have been wrong, then the tunnel would be in state where it
would send the wrong response to this ips.
With this PR we try to always reuse the old ip if there's any available.
Previously, we just expected the portal to disconnects us and 401 on the
retry, right now we harden that behaviour by also just disconnecting
when token expiration.
This seems to work, there's another part to this which is not only
handling the replies but also handling the message generated by the
portal, I'll implement that when I can easily test expirying tokens, for
now this makes the client much more stable.
just silly but important mistake 😛fixes#2858 and #2859 (though there might be an additional edge case in
#2859 where the upstream server is set as a dns, though it seems to work
some further testing would be good)
At present, the definition of `Device` is heavily nested with
conditional code. I've found this hard to understand and navigate.
Recent refactorings now made it possible to remove a lot of these layers
so we primarily deal with two concepts:
- A `Device` which offers async read and non-blocking write functions
- A `Tun` abstraction which is platform-specific
Instead of dedicated modules, I chose to feature-flag individual
functions on `Device` with `#[cfg(target_family = "unix")]` and
`#[cfg(target_family = "windows")]`. I find this easier to understand
because the code is right next to each other.
In addition, changing the module hierarchy of `Device` allows us to
remove `async` from the public API which is only introduced by the use
of `rtnetlink` in Linux. Instead of making functions across all `Tun`
implementations `async`, we embed a "worker" within the `linux::Tun`
implementation that gets polled before `poll_read`.
---------
Co-authored-by: Gabi <gabrielalejandro7@gmail.com>