The expression for one of the rules was not able to be applied due to
invalid characters (`\n`) and even once the invalid characters were
removed there is a limit of 5 subexpressions, but the previous
expression contained 10.
Along with the expression change, the `deny(451)` is not allowed. The
only `deny` codes allowed are `403`, `404`, `502`
This PR reverts commit that moves out IPv6 address to a separate
subdomain (deploying that will cause a prod downtime) and simply removes
the check that causes redirect loops.
Based on testing and research it does not appear that Chrome will
reliably choose a consistent protocol stack for loading the initial web
page as it does for connecting the WebSocket when connecting over VPN
tunnels. If one or the other stacks experiences a slight delay or packet
loss causing retransmission, or QUIC simply doesn't play nicely with the
MTU (in our case 1280), it may fall back to IPv4 (which has less
per-packet overhead) or even a TCP connection.
Unfortunately this violates an assumption we have in token validation
logic. Namely, that the remote_ip used to create the token (via sign in)
is the same one used to the connect the WebSocket. I can see where this
logic comes from in a security context, but thinking through the attack
vector(s) that would be able to leverage this violation has me left
wondering if this check is worth the breakage we currently face in
#6511.
- Scenario 1: MITM - attacker steals token somehow via MITM (would need
to somehow break TLS) - the attacker is already in our network path and
can rewrite the remote_ip already with his/her own.
- Scenario 2: Malicious browser plugin stealing session token. It will
be harder to spoof the remote IP in this case, but if this is a
possibility, the plugin could presumably directly control the tab where
the user is logged in.
- Scenario 3: IdP is compromised leading to malicious redirect before
arriving to Firezone - if this is the case, the user could likely login
in directly and create his/her own valid session token anyhow.
Perhaps I'm missing other scenarios, open to feedback. If we want to
ensure the token used by the websocket originated from the same browser
as it was minted from, perhaps we could generate a small random key,
save it in local storage, and send that in a header when connecting the
WebSocket. I think cookies handle that for us already though.
Fixes#6511
I've managed to finally reserve enough e2 instances for our needs and
also used e2 for gateways to workaround the quota issues. The `web` app
still used n2 because quota doesn't allow additional n4's. Rollouts also
fixed to not go over the reservations/quotas.