Skip to content

Instantly share code, notes, and snippets.

@izzyleung
Last active August 14, 2024 20:05
Show Gist options
  • Save izzyleung/98bcc1c0ecf424c1896dac10a3a4a1f8 to your computer and use it in GitHub Desktop.
Save izzyleung/98bcc1c0ecf424c1896dac10a3a4a1f8 to your computer and use it in GitHub Desktop.
Update your WireGuard public key in Mullvad via its public API

Generate a new pair of keys via wg

$ wg genkey | tee privatekey | wg pubkey > publickey

Rotate your public key via the same logic as in Mullvad's source code:

  • Step 1: Obtaining an access token:
$ curl -fsSL -X POST \
    -H 'Content-Type: application/json' \
    -H 'Accepts: application/json' \
    -d '{"account_number": "YOUR_ACCOUNT_NUMBER_HERE"}' \
    https://api.mullvad.net/auth/v1/token
{"access_token":"mva_c....","expiry":"2024-05-30T20:00:00+00:00"}
  • Step 2: List your devices, and find out which one needs a key rotation, using the access_token you obtained using the command above
$ curl -fsSL \
    -H 'Content-Type: application/json' \
    -H 'Accepts: application/json' \
    -H 'Authorization: Bearer mva_c....' \
    https://api.mullvad.net/accounts/v1/devices | jq
[
  {
    "id": "9315bf6d-7672-44db-9c09-2dd3212c9b0a",
    "name": "xxx xxx",
    "pubkey": "REDACTED",
    "hijack_dns": false,
    "created": "2024-05-30T20:00:00+00:00",
    "ipv4_address": "REDACTED",
    "ipv6_address": "REDACTED",
    "ports": []
  },
  {
    ...
  }
]
  • Step 3: Update/Rotate your new key
$ curl -fsSL -X PUT \
    -H 'Content-Type: application/json' \
    -H 'Accepts: application/json' \
    -H 'Authorization: Bearer mva_c...' \
    -d '{"pubkey": "CONTENT_OF_YOUR_NEW_PUBLIC_KEY"}' \
    https://api.mullvad.net/accounts/v1/<YOUR_DEVICE_ID_FOUND_ON_THE_LAST_STEP>/pubkey | jq
{
  "id": "<YOUR_DEVICE_ID_FOUND_ON_THE_LAST_STEP>",
  "name": "REDACTED",
  "pubkey": "CONTENT_OF_YOUR_NEW_PUBLIC_KEY",
  "hijack_dns": false,
  "created": "2024-05-30T20:00:00+00:00",
  "ipv4_address": "REDACTED",
  "ipv6_address": "REDACTED",
  "ports": []
}
  • Step 4: Update your config with the new ipv4_address and/or ipv6_address and profit.

The OLD way - NOT RECOMMENDED

Upload the newly generate key to Mullvad

$ curl https://api.mullvad.net/wg/ -d account=YOUR_ACCOUNT_NUMBER --data-urlencode pubkey="$(cat publickey)"

Revoke a previously uploaded key

  • Step 1: "Login" to Mullvad and get an autherization token
$ curl -fsSL https://api.mullvad.net/www/accounts/YOUR_ACCOUNT_NUMBER
{
  "auth_token": "xxyyzz",
  "account": {
    "token": "ACCOUNT_NUMBER",
    "pretty_token": "1234 4567 7890 0123",
    "active": true,
    "expires": "2100-01-01T12:00:00Z",
    "expiry_unix": 1234567890,
    "ports": [],
    "max_ports": 5,
    "can_add_ports": true,
    "wg_peers": [
      {
        "key": {
          "public": "PUBLIC_KEY_HERE",
          "private": ""
        },
        "ipv4_address": "10.0.19.123/32",
        "ipv6_address": "dead:beef:1337:1::5:2/128",
        "ports": [],
        "can_add_ports": true,
        "created": "2020-01-01"
      }
    ],
    "max_wg_peers": 5,
    "can_add_wg_peers": true,
    "subscription": {
      "method": "XX",
      "status": "ACTIVE",
      "unpaid": false
    }
  }
}

The token at the line "auth_token": "xxyyzz" is the one you should be using in the next step. Or if you have jq installed, you can just do

$ curl -fsSL https://api.mullvad.net/www/accounts/YOUR_ACCOUNT_NUMBER | jq -r '.auth_token'
  • Step 2: Revoke the previously uploaded key
$ curl -X POST \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Token THE_TOKEN_YOU_GOT_FROM_THE_STEP_ABOVE' \
    -d '{"pubkey": "CONTENT_OF_THE_PREVIOUSLY_UPLOADED_PUBLIC_KEY"}' \
    https://api.mullvad.net/www/wg-pubkeys/revoke/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment