$ 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/oripv6_address
and profit.
$ curl https://api.mullvad.net/wg/ -d account=YOUR_ACCOUNT_NUMBER --data-urlencode pubkey="$(cat publickey)"
- 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/