summaryrefslogtreecommitdiffhomepage
path: root/docs/security.md
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2019-11-28 16:01:52 +0100
committerLinus Färnstrand <linus@mullvad.net>2020-01-07 21:50:38 +0100
commitfd3e46574ffd2bfd489675e3e60a800e0c4e7cf0 (patch)
tree9b3a4d67b9b3689f2cd00013c060d54f943d6ec5 /docs/security.md
parentdf1c08b5a6ecfbc51e6b06c18481d16c614e494f (diff)
downloadmullvadvpn-fd3e46574ffd2bfd489675e3e60a800e0c4e7cf0.tar.xz
mullvadvpn-fd3e46574ffd2bfd489675e3e60a800e0c4e7cf0.zip
Add security documentation describing app states
Diffstat (limited to 'docs/security.md')
-rw-r--r--docs/security.md133
1 files changed, 133 insertions, 0 deletions
diff --git a/docs/security.md b/docs/security.md
index af2d8f5f3d..52ea21ee81 100644
--- a/docs/security.md
+++ b/docs/security.md
@@ -6,25 +6,158 @@ platforms and their differences.
This document does not describe *how* we reach and uphold these properties, just what they are.
See the [architecture](architecture.md) document for details on how this security is implemented.
+The main purpose of the app is to allow the user to make all network/internet traffic to and
+from the device travel via an encrypted VPN tunnel.
## App states
+At the core of the app is a state machine called the "tunnel state machine". The following
+sub-sections will describe each state and what security properties hold and what network activity
+will be blocked and allowed during them.
+
+Except what's described as allowed in this document, all network packets should be blocked.
+
+The following network traffic is always allowed to flow. It's never blocked, regardless of state:
+
+1. All traffic on loopback adapters
+
+1. DHCPv4 and DHCPv6 requests to go out and responses to come in:
+ * Outgoing from `*:68` to `255.255.255.255:67` (client to server)
+ * Incoming `*:67` to `*:68` (server to client)
+ * Outgoing from `[fe80::]/10:546` to `[ff02::1:2]:547` and `[ff05::1:3]:547` (client to server)
+ * Incoming from `[fe80::]/10:547` to `[fe80::]/10:546` (server to client)
+
+1. Router solicitation, advertisement and redirects (subset of NDP):
+ * Outgoing to `ff02::2``, but only ICMPv6 with type 133 and code 0.
+ * Incoming from `[fe80::]/10`, but only ICMPv6 type 134 or 137 and code 0.
+
+1. If the "Allow LAN" setting is enabled, the following is also allowed:
+ * Outgoing to, and incoming from, any IP in an unroutable network, that means:
+ * `10.0.0.0/8`
+ * `172.16.0.0/12`
+ * `192.168.0.0/16`
+ * `169.254.0.0/16`
+ * `fe80::/10`
+ * Outgoing to any IP in a local, unroutable, multicast network, meaning these:
+ * `224.0.0.0/24` (local subnet IPv4 multicast)
+ * `239.255.255.250/32` (SSDP)
+ * `239.255.255.251/32` (mDNS)
+ * `ff02::/16` (Link-local IPv6 multicast. IPv6 equivalent of `224.0.0.0/24`)
+ * `ff05::/16` (Site-local IPv6 multicast. Is routable, but should never leave the "site")
+ * Incoming DHCPv4 requests and outgoing responses (be a DHCPv4 server):
+ * Incoming from `*:68` to `255.255.255.255:67`
+ * Outgoing from `*:67` to `*:68`
+
### Disconnected
+This is the default state that the `mullvad-daemon` starts in when the device boots, unless
+"Launch app on start-up" and "Auto-connect" are both active. Then the app will proceed to the
+[connecting](#connecting) state immediately.
+
+The disconnected state behaves very differently depending on the value of the
+"block when disconnected" setting. If this setting is enabled the disconnected state behaves
+like, and has the same security properties as, the [blocked](#blocked) state. If the setting is
+disabled (the default), then it is the only state where the app does not enforce any firewall.
+rules. This state behaves the same as if the `mullvad-daemon` was not even running. It lets
+network traffic flow in and out of the computer freely.
+
+The disconnected state is not active while the app changes server or if the VPN tunnel goes down
+unexpectedly. See the [connecting](#connecting) state and [kill switch](#kill-switch)
+documentation for these unexpected network issues. The only time this state is active is
+initially when the daemon starts and later
+when the user explicitly clicks the disconnect/cancel button to intentionally disable the VPN.
+
### Connecting
+This state is active from when the app decides to create a VPN tunnel, until said tunnel has
+been established and verified to work. Then it transitions to the [connected](#connected) state.
+
+In this state network traffic to and from the IP and port that the VPN tunnel is established
+towards. Meaning the IP of the VPN relay server and the selected OpenVPN or WireGuard port.
+In the case where a bridge/proxy is used this IP/port combo becomes the IP of the bridge
+and the port of the used proxying service.
+
+If connecting via WireGuard, this state allows ICMP packets to and from the in-tunnel IPs
+(both v4 and v6) of the relay server the app is currently connecting to. That means the private
+network IPs where the relay will respond inside the tunnel.
+
### Connected
+This state becomes active when [connecting](#connecting) has fully established a VPN tunnel. It
+stays active until the user requests a disconnect, quit, server change, change of other setting
+that affects the tunnel or until the tunnel goes down unexpectedly.
+
+In this state, all traffic in both directions over the tunnel interface should be allowed. Minus
+the DNS requests (TCP and UDP port 53) not to a gateway IP for that interface. Meaning we can
+*only* request DNS from the relay server itself.
+
+This state allows traffic to and from the IP and port combo that the tunnel runs over. See the
+[connecting](#connecting) state for details.
+
### Disconnecting
+This state becomes active if there is a VPN tunnel active but the app decides to close said
+tunnel. This state is active until the tunnel has been properly closed.
+
+This state does not apply its own security policy on the firewall. It just keeps what was already
+active. Usually all states transitioning into this state, and all states this state later
+transitions into, have their own security policies. This state is just a short transition between
+those, while the app waits for a running tunnel to come down and clean up after itself.
+
### Blocked
+This state is only active when there is a problem/error. As described in other sections, the app
+will never unlock the firewall and allow network traffic outside the tunnel unless a
+disconnect/quit is explicitly requested by a user. At the same time there might be situations
+when the app can't establish a tunnel for the device. This includes, but is not limited to:
+* Account runs out of time,
+* The computer is offline,
+* the TAP adapter driver has an error or the adapter can't be found,
+* Some internal error parsing or modifying system routing table, DNS settings etc.
+
+In the above cases the app gives up trying to create a tunnel, but it can't go to the
+[disconnecte](#disconnected) state, since it can't unlock the firewall. Then it enters this state.
+This state locks the firewall so no traffic can flow (except the always active exceptions) and
+informs the user what the problem is. The user must then explicitly click disconnect in order
+to unlock the firewall and get access to the internet again.
+
+## Kill switch
+
+The app has an always on kill switch that can't be disabled. There is no setting for it.
+This means that whenever the app changes server or temporarily loses tunnel connectivity it will
+ensure no network traffic leaks out unencrypted.
+
+We usually don't like the term "kill switch". Because it makes it sound like a big red button
+that the VPN client pushes when it detects a problem. Maybe that's how the clients who coined
+the term implemented it, but this app is much more proactive about it. This app applies
+strict firewall rules directly when it leaves the [disconnected](#disconnected) state
+and keeps those rules active and enforced until the app comes back to the disconnected state.
+Said rules unsure that packets can only leave or enter the computer in a few predefined ways,
+most notably to the selected VPN server IP and port. If the tunnel were to come down and your
+operating system tries to route packets out via the normal network rather than through the VPN,
+these rules would block them from leaving. So rather than failing open, meaning if the tunnel
+fails your traffic leaves in other ways, we fail closed, meaning if the packets don't leave
+encrypted in the way the app intends, then they can't leave at all.
+
+### Block when disconnected
+
+The "block when disconnected" setting in the app is regularly misunderstood as our kill switch.
+This is not the case. The "block when disconnected" setting only changes whether or not the
+[disconnected](#disconnected) state should allow traffic to flow freely or to block it. The
+disconnected state is not active during intermittent network issues or server changes, when
+a kill switch would normally be operating.
+
+The intended use case for this setting is when the user want to only switch between no internet
+connectivity at all and using VPN. With this setting active, the device can never communicate
+with the internet outside of a VPN tunnel.
## Firewall
The states above should probably explain what can and can't be reached in the different states.
But we might need/want this section in case there is something that does not fit above.
+
+
## DNS
Where are DNS requests sent?