Why:
* The current README in the `/elixir` directory is a circular reference
that does not explain much. This commit updates the README to give the
basics of how to get started with Firezone Elixir development.
This PR moves Gateway events to be triggered by the WAL broadcaster.
Some things of note that are cleaned up:
- The gateway `:update` event was never received anywhere (but in a
test) and so has been removed
- The account topic has been removed as it was also never acted upon
anywhere. Presence yes, but topic no
- The group topic has also been removed as it was only used to receive
broadcasted disconnects when a group is deleted, but this was already
handled by the token deletion and so is redundant.
This adds a feature that will email all admins in a Firezone Account
when sync errors occur with their Identity Provider.
In order to avoid spamming admins with sync error emails, the error
emails are only sent once every 24 hours. One exception to that is when
there is a successful sync the `sync_error_emailed_at` field is reset,
which means in theory if an identity provider was flip flopping between
successful and unsuccessful syncs the admins would be emailed more than
once in a 24 hours period.
### Sample Email Message
<img width="589" alt="idp-sync-error-message"
src="https://github.com/user-attachments/assets/d7128c7c-c10d-4d02-8283-059e2f1f5db5">
- Adds `http_test_server_image` to inputs so that it gets set properly
for CI (`debug`) and CD (`perf`)
- Updates `dev` -> `debug` in docker-compose.yml to fix pulls
- Fixes issue with seeds and relevant docs from #6205
Why:
* JumpCloud directory sync was requested from customers. JumpCloud only
offers the ability to use it's API with an admin level access token that
is tied to a specific user within a given JumpCloud account. This would
require Firezone customers to give an access token with much more
permissions that needed for our directory sync. To avoid this, we've
decide to use WorkOS to provide SCIM support between JumpCloud and
WorkOS, which will allow Firezone to then easily and safely retrieve
JumpCloud directory info from WorkOS.
---------
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
# Gateways
- [x] When Gateway Group is deleted all gateways should be disconnected
- [x] When Gateway Group is updated (eg. routing) broadcast to all
affected gateway to disconnect all the clients
- [x] When Gateway is deleted it should be disconnected
- [x] When Gateway Token is revoked all gateways that use it should be
disconnected
# Relays
- [x] When Relay Group is deleted all relays should be disconnected
- [x] When Relay is deleted it should be disconnected
- [x] When Relay Token is revoked all gateways that use it should be
disconnected
# Clients
- [x] Remove Delete Client button, show clients using the token on the
Actors page (#2669)
- [x] When client is deleted disconnect it
- [ ] ~When Gateway is offline broadcast to the Clients connected to it
it's status~
- [x] Persist `last_used_token_id` in Clients and show it in tokens UI
# Resources
- [x] When Resource is deleted it should be removed from all gateways
and clients
- [x] When Resource connection is removed it should be deleted from
removed gateway groups
- [x] When Resource is updated (eg. traffic filters) all it's
authorizations should removed
# Authentication
- [x] When Token is deleted related sessions are terminated
- [x] When an Actor is deleted or disabled it should be disconnected
from browser and client
- [x] When Identity is deleted it's sessions should be disconnected from
browser and client
- [x] ^ Ensure the same happens for identities during IdP sync
- [x] When IdP is disabled act like all actors for it are disabled?
- [x] When IdP is deleted act like all actors for it are deleted?
# Authorization
- [x] When Policy is created clients that gain access to a resource
should get an update
- [x] When Policy is deleted we need to all authorizations it's made
- [x] When Policy is disabled we need to all authorizations it's made
- [x] When Actor Group adds or removes a user, related policies should
be re-evaluated
- [x] ^ Ensure the same happens for identities during IdP sync
# Settings
- [x] Re-send init message to Client when DNS settings change
# Code
- [x] Crear way to see all available topics and messages, do not use
binary topics any more
---------
Co-authored-by: conectado <gabrielalejandro7@gmail.com>
- [x] Introduce api_client actor type and code to create and
authenticate using it's token
- [x] Unify Tokens usage for Relays and Gateways
- [x] Unify Tokens usage for magic links
Closes#2367
Ref #2696
- [x] make sure that session cookie for client is stored separately from
session cookie for the portal (will close#2647 and #2032)
- [x] #2622
- [ ] #2501
- [ ] show identity tokens and allow rotating/deleting them (#2138)
- [ ] #2042
- [ ] use Tokens context for Relays and Gateways to remove duplication
- [x] #2823
- [ ] Expire LiveView sockets when subject is expired
- [ ] Service Accounts UI is ambiguous now because of token identity and
actual token shown
- [ ] Limit subject permissions based on token type
Closes#2924. Now we extend the lifetime for client tokens, but not for
browsers.
This PR changes the protocol and adds support for DNS subdomains, now
when a DNS resource is added all its subdomains are automatically
tunneled too. Later we will add support for `*.domain` or `?.domain` but
currently there is an Apple split tunnel implementation limitation which
is too labor-intensive to fix right away.
Fixes#2661
Co-authored-by: Andrew Dryga <andrew@dryga.com>
Updates user-facing terminology to `One-Time Password` to more
accurately reflect this sign in method and match docs more consistently
Refs #2688
Refs #2021
Renaming it back to clients to reflect service accounts and headless
clients use cases in the terminology. Such a rename will be very painful
on live data so better if we do it early on.
---------
Co-authored-by: Jamil Bou Kheir <jamilbk@users.noreply.github.com>
Looks like it broke the staging WS connections. Getting a failure of
Liveview socket connection on `app.firez.one`:
```
insertId: 1o7nymzg12jh1k5
jsonPayload:
cos.googleapis.com/container_id: 89b4633e81432e43dfbaa3957324fd5ead3f2362737bac84648a8f839b6eb16c
cos.googleapis.com/container_name: klt-web-cpap
cos.googleapis.com/stream: stdout
message:
domain:
- elixir
erl_level: error
logging.googleapis.com/sourceLocation:
file: lib/phoenix/socket/transport.ex
function: Elixir.Phoenix.Socket.Transport.check_origin/5
line: 344
message: |+
Could not check origin for Phoenix.Socket transport.
Origin of the request: https://app.firez.one
This happens when you are attempting a socket connection to
a different host than the one configured in your config/
files. For example, in development the host is configured
to "localhost" but you may be trying to access it from
"127.0.0.1". To fix this issue, you may either:
1. update [url: [host: ...]] to your actual host in the
config file for your current environment (recommended)
2. pass the :check_origin option when configuring your
endpoint or when configuring the transport in your
UserSocket module, explicitly outlining which origins
are allowed:
check_origin: ["https://example.com",
"//another.com:888", "//other.com"]
severity: ERROR
time: '2023-08-26T21:24:36.002Z'
time: '2023-08-26T21:24:36.002628434Z'
logName: projects/firezone-staging/logs/cos_containers
receiveTimestamp: '2023-08-26T21:24:36.402398476Z'
resource:
labels:
instance_id: '8218473336234347240'
project_id: firezone-staging
zone: us-east1-d
type: gce_instance
timestamp: '2023-08-26T21:24:36.002628434Z'
```
This PR fixes issues with the iOS client connecting to the portal and
setting up the tunnel.
- portal IPv6 unique-local prefix typo
- Use `rustls-webpki-roots` instead of `rustls-native-roots` for tokio
tungstenite since the latter [only supports macOS, Linux, and
Windows](https://github.com/rustls/rustls-native-certs) while the former
seems to work on all platforms(?)
- Remove Multipath TCP entitlement for iOS since it's not relevant for
us.
@conectado After this is merged, we _almost_ have a working tunnel on
iOS. I believe the error we're hitting now is the 4-byte address family
header that we need to add and strip from each packet written to / read
from the tunnel. See below log for sample output when attempting to
connect to the `HTTPbin` resource:
```
dev.firezone.firezone.network-extension packet-tunnel debug 16:10:13.401705-0700 FirezoneNetworkExtensioniOS Adapter state changed to: tunnelReady
dev.firezone.firezone.network-extension packet-tunnel debug 16:10:13.401731-0700 FirezoneNetworkExtensioniOS Beginning path monitoring
com.apple.network path default 16:10:13.402211-0700 FirezoneNetworkExtensioniOS nw_path_evaluator_start [1ACDE975-615B-4557-BF7C-678F3594452E <NULL> generic, multipath service: 1, attribution: developer]
path: satisfied (Path is satisfied), interface: en0[802.11], scoped, ipv4, ipv6, dns
com.apple.network path info 16:10:13.402235-0700 FirezoneNetworkExtensioniOS nw_path_evaluator_call_update_handler [1ACDE975-615B-4557-BF7C-678F3594452E] scheduling update
com.apple.network path info 16:10:13.402261-0700 FirezoneNetworkExtensioniOS nw_path_evaluator_call_update_handler_block_invoke [1ACDE975-615B-4557-BF7C-678F3594452E] delivering update
com.apple.network debug 16:10:13.402286-0700 FirezoneNetworkExtensioniOS nw_path_copy_interface_with_generation Cache miss for interface for index 3 (generation 4574)
com.apple.network debug 16:10:13.402312-0700 FirezoneNetworkExtensioniOS nw_path_copy_interface_with_generation Cache miss for interface for index 31 (generation 141)
dev.firezone.firezone.network-extension packet-tunnel debug 16:10:13.402363-0700 FirezoneNetworkExtensioniOS Suppressing calls to disableSomeRoamingForBrokenMobileSemantics() and bumpSockets()
dev.firezone.firezone connlib debug 16:10:14.368105-0700 FirezoneNetworkExtensioniOS Reading from iface 76 bytes
dev.firezone.firezone connlib debug 16:10:15.369018-0700 FirezoneNetworkExtensioniOS Reading from iface 76 bytes
dev.firezone.firezone connlib debug 16:10:16.095618-0700 FirezoneNetworkExtensioniOS Reading from iface 76 bytes
dev.firezone.firezone connlib debug 16:10:16.370908-0700 FirezoneNetworkExtensioniOS Reading from iface 76 bytes
dev.firezone.firezone connlib debug 16:10:17.372035-0700 FirezoneNetworkExtensioniOS Reading from iface 76 bytes
dev.firezone.firezone connlib debug 16:10:18.373423-0700 FirezoneNetworkExtensioniOS Reading from iface 76 bytes
dev.firezone.firezone connlib debug 16:10:20.402863-0700 FirezoneNetworkExtensioniOS Reading from iface 76 bytes
dev.firezone.firezone connlib debug 16:10:24.381581-0700 FirezoneNetworkExtensioniOS Reading from iface 76 bytes
dev.firezone.firezone connlib debug 16:10:32.374566-0700 FirezoneNetworkExtensioniOS Reading from iface 76 bytes
dev.firezone.firezone connlib debug 16:10:38.137437-0700 FirezoneNetworkExtensioniOS Text("{\"ref\":null,\"topic\":\"phoenix\",\"event\":\"phx_reply\",\"payload\":{\"status\":\"ok\",\"response\":{}}}")
dev.firezone.firezone connlib debug 16:10:38.137757-0700 FirezoneNetworkExtensioniOS Phoenix status message
dev.firezone.firezone connlib debug 16:10:48.376339-0700 FirezoneNetworkExtensioniOS Reading from iface 76 bytes
dev.firezone.firezone connlib debug 16:11:08.148369-0700 FirezoneNetworkExtensioniOS Text("{\"ref\":null,\"topic\":\"phoenix\",\"event\":\"phx_reply\",\"payload\":{\"status\":\"ok\",\"response\":{}}}")
dev.firezone.firezone connlib debug 16:11:08.148654-0700 FirezoneNetworkExtensioniOS Phoenix status message
```
This is a result of our discussion with @conectado, this PR will add a
new message type which will allow reusing existing connections to the
gateway to access a new resource. We will also change the LB strategy to
be aware of the current device connection so that we will not pick a
different one if we have a connected gateway that can serve a new
resource.
---------
Co-authored-by: conectado <gabrielalejandro7@gmail.com>
TODO:
- [x] Cluster formation for all API and web nodes
- [x] Injest Docker logs to Stackdriver
- [x] Fix assets building for prod
To finish later:
- [ ] Structured logging:
https://issuetracker.google.com/issues/285950891
- [ ] Better networking policy (eg. use public postmark ranges and deny
all unwanted egress)
- [ ] OpenTelemetry collector for Google Stackdriver
- [ ] LoggerJSON.Plug integration
---------
Signed-off-by: Andrew Dryga <andrew@dryga.com>
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>