We can assume that any state actor will be able to;
Sufficiently DPI (Deep Packet Inspect) any and all outgoing network traffic.
Have established a supply chain injection where their own root CA will be added to the system's keychain, legally if required.
As such, we can assume that HTTPS traffic can/will be MITM'd silently by a state firewall.
To counter this, we need to add a TLS-level check for the connection, to figure out if the connection is truly intercepted, or if the connection is unterminated.
One thing we could do is leverage exported authenticators to detect when our TLS connection has been MITM'd.
We do this by adding a sequence number, encrypted by the EA, to the Handshake procedure between the relay and client (and/or Control and the client).
With the relay, the handshake messages (session messages) are encrypted and decrypted using a shared key derived from the client's session private key and the relay's public key. To MITM these, the state actor would require to;
Know the relay's public key (likely, if application-level attacks are done)
Have rootkit-level access to the VM, system, phone, or other device that is initiating the connection, to grab the session key from memory (not unlikely in some circumstances, but with some care, could be made nearly impossible)
To the handshake procedure, a small struct is added;
{
init: bool
seq: int64
}
The client and the server start their first message with init: true, and a random sequence number. This struct is then encrypted using the EA of the TLS connection, and added to every handshake message.
When this field cannot be decrypted properly, we know that the TLS connection has been terminated and recreated early; a MITM attack.
A similar handshake procedure could be done with Control and the client, just with using the node private key and control's key for the same handshake messages.
Following this, we could have the client halt activity and inform/alert the user. The MITM means that the cyphertext of the session messages are readable, and any wireguard frames, should we not re-encrypt them.
The client can be configured to automatically stop dialing control/the relay if the MITM is detected, or inform the user of the risks and continue, albeit possibly with the WG frames encrypted using the TLS EA.
Relay information distributed by the server can contain fields that inform the relay is capable of MITM EA sequence numbers.
Clients will not attempt peer-to-peer connections if a relay is detected, independent of a user's "OK" to continue connecting.
Clients can configure;
wether to abort on detected MITM
to only connect to relays with MITM EA sequence numbers.
On the control/relay side, to enable this feature, it'd require the program to be exposed directly to the internet, or at least, have its TLS connection unterminated by a reverse proxy / TLS terminator.
This may mean that automatic certificate management and refresh (to allow the use of certbot and the likes to refresh domain certificates without downtime) would also need to be implemented, and the security of directly exposing golang's TLS module to the internet also be checked.
We can assume that any state actor will be able to;
As such, we can assume that HTTPS traffic can/will be MITM'd silently by a state firewall.
To counter this, we need to add a TLS-level check for the connection, to figure out if the connection is truly intercepted, or if the connection is unterminated.
One thing we could do is leverage exported authenticators to detect when our TLS connection has been MITM'd.
We do this by adding a sequence number, encrypted by the EA, to the Handshake procedure between the relay and client (and/or Control and the client).
With the relay, the handshake messages (session messages) are encrypted and decrypted using a shared key derived from the client's session private key and the relay's public key. To MITM these, the state actor would require to;
To the handshake procedure, a small struct is added;
The client and the server start their first message with
init: true
, and a random sequence number. This struct is then encrypted using the EA of the TLS connection, and added to every handshake message.When this field cannot be decrypted properly, we know that the TLS connection has been terminated and recreated early; a MITM attack.
A similar handshake procedure could be done with Control and the client, just with using the node private key and control's key for the same handshake messages.
Following this, we could have the client halt activity and inform/alert the user. The MITM means that the cyphertext of the session messages are readable, and any wireguard frames, should we not re-encrypt them.
The client can be configured to automatically stop dialing control/the relay if the MITM is detected, or inform the user of the risks and continue, albeit possibly with the WG frames encrypted using the TLS EA.
Relay information distributed by the server can contain fields that inform the relay is capable of MITM EA sequence numbers.
Clients will not attempt peer-to-peer connections if a relay is detected, independent of a user's "OK" to continue connecting.
Clients can configure;
On the control/relay side, to enable this feature, it'd require the program to be exposed directly to the internet, or at least, have its TLS connection unterminated by a reverse proxy / TLS terminator.
This may mean that automatic certificate management and refresh (to allow the use of certbot and the likes to refresh domain certificates without downtime) would also need to be implemented, and the security of directly exposing golang's TLS module to the internet also be checked.