Create Surfshark wireguard connection on OpenWrt easily

Hi everyone,

I wrote a simple script that helps me create Surfshark's wireguard connection on my OpenWRT.
I'm sharing it with you in a hope that it hopefully will help someone else.
Please see

It needs curl and jq because it calls Surfshark API in order to get server's information and submit generated public key to Surfshark.

Right now it generates normal wireguard config file and the next step is to generate/emit set of uci commands to actually add it OpenWRT.

I will be happy to get any feedback from it

4 Likes

Hi @yazdan ,

once I have the .json files generated, how is the interface configured, with what values?

Thanks.

Hi @Gcholvi
After you run the script you should be able to see a folder named conf is created.

In that folder all classic Wireguard connection configs are generated.
Then if you cat one of these config files you see

[Interface]
PrivateKey=someprivatekey=
Address=10.14.0.2/8
MTU=1350

[Peer]
PublicKey=o07k/2dsaQkLLSR0dCI/FUd3FLik/F/HBBcOGUkNQGo=
AllowedIPs=172.16.0.36/32
Endpoint=wgs.prod.surfshark.com:51820
PersistentKeepalive=25

[Peer]
PublicKey=6dZGkg0iAMgQuOCGknAgBAqDEeJeBQ4Of5eblO4aNC8=
AllowedIPs=0.0.0.0/0
Endpoint=ae-dub.prod.surfshark.com:51820
PersistentKeepalive=25

use these information to create an interface using this guide

to have some sort of reference my folder structure is like this

.
├── LICENSE
├── README.md
├── conf
│   ├── ae-dub.prod.surfshark.com.conf
│   ├── al-tia.prod.surfshark.com.conf
│   ├── ar-bua.prod.surfshark.com.conf
│   ├── at-vie.prod.surfshark.com.conf
│   ├── au-adl.prod.surfshark.com.conf
│   ├── au-bne.prod.surfshark.com.conf
│   ├── au-mel.prod.surfshark.com.conf
│   ├── au-per.prod.surfshark.com.conf
│   ├── au-syd.prod.surfshark.com.conf
│   ├── az-bak.prod.surfshark.com.conf
│   ├── ba-sjj.prod.surfshark.com.conf
│   ├── be-anr.prod.surfshark.com.conf
│   ├── be-bru.prod.surfshark.com.conf
│   ├── bg-sof.prod.surfshark.com.conf
│   ├── br-sao.prod.surfshark.com.conf
│   ├── ca-mon.prod.surfshark.com.conf
│   ├── ca-tor.prod.surfshark.com.conf
│   ├── ca-van.prod.surfshark.com.conf
│   ├── ch-zur.prod.surfshark.com.conf
│   ├── cl-san.prod.surfshark.com.conf
│   ├── co-bog.prod.surfshark.com.conf
│   ├── cr-sjn.prod.surfshark.com.conf
│   ├── cy-nic.prod.surfshark.com.conf
│   ├── cz-prg.prod.surfshark.com.conf
│   ├── de-ber.prod.surfshark.com.conf
│   ├── de-fra.prod.surfshark.com.conf
│   ├── dk-cph.prod.surfshark.com.conf
│   ├── dz-alg.prod.surfshark.com.conf
│   ├── ee-tll.prod.surfshark.com.conf
│   ├── es-bcn.prod.surfshark.com.conf
│   ├── es-mad.prod.surfshark.com.conf
│   ├── es-vlc.prod.surfshark.com.conf
│   ├── fi-hel.prod.surfshark.com.conf
│   ├── fr-bod.prod.surfshark.com.conf
│   ├── fr-mrs.prod.surfshark.com.conf
│   ├── fr-par.prod.surfshark.com.conf
│   ├── ge-tbs.prod.surfshark.com.conf
│   ├── gr-ath.prod.surfshark.com.conf
│   ├── hk-hkg.prod.surfshark.com.conf
│   ├── hr-zag.prod.surfshark.com.conf
│   ├── hu-bud.prod.surfshark.com.conf
│   ├── id-jak.prod.surfshark.com.conf
│   ├── ie-dub.prod.surfshark.com.conf
│   ├── il-tlv.prod.surfshark.com.conf
│   ├── in-chn.prod.surfshark.com.conf
│   ├── in-idr.prod.surfshark.com.conf
│   ├── in-mum.prod.surfshark.com.conf
│   ├── is-rkv.prod.surfshark.com.conf
│   ├── it-mil.prod.surfshark.com.conf
│   ├── it-rom.prod.surfshark.com.conf
│   ├── jp-tok.prod.surfshark.com.conf
│   ├── kr-seo.prod.surfshark.com.conf
│   ├── kz-ura.prod.surfshark.com.conf
│   ├── lu-ste.prod.surfshark.com.conf
│   ├── lv-rig.prod.surfshark.com.conf
│   ├── md-chi.prod.surfshark.com.conf
│   ├── mk-skp.prod.surfshark.com.conf
│   ├── mx-mex.prod.surfshark.com.conf
│   ├── my-kul.prod.surfshark.com.conf
│   ├── ng-lag.prod.surfshark.com.conf
│   ├── nl-ams.prod.surfshark.com.conf
│   ├── no-osl.prod.surfshark.com.conf
│   ├── nz-akl.prod.surfshark.com.conf
│   ├── pa-pac.prod.surfshark.com.conf
│   ├── pe-lim.prod.surfshark.com.conf
│   ├── ph-mnl.prod.surfshark.com.conf
│   ├── pl-gdn.prod.surfshark.com.conf
│   ├── pl-waw.prod.surfshark.com.conf
│   ├── pt-lis.prod.surfshark.com.conf
│   ├── pt-opo.prod.surfshark.com.conf
│   ├── ro-buc.prod.surfshark.com.conf
│   ├── rs-beg.prod.surfshark.com.conf
│   ├── ru-mos.prod.surfshark.com.conf
│   ├── se-sto.prod.surfshark.com.conf
│   ├── sg-sng.prod.surfshark.com.conf
│   ├── si-lju.prod.surfshark.com.conf
│   ├── sk-bts.prod.surfshark.com.conf
│   ├── th-bkk.prod.surfshark.com.conf
│   ├── tr-ist.prod.surfshark.com.conf
│   ├── tw-tai.prod.surfshark.com.conf
│   ├── ua-iev.prod.surfshark.com.conf
│   ├── uk-gla.prod.surfshark.com.conf
│   ├── uk-lon.prod.surfshark.com.conf
│   ├── uk-man.prod.surfshark.com.conf
│   ├── us-ash.prod.surfshark.com.conf
│   ├── us-atl.prod.surfshark.com.conf
│   ├── us-bdn.prod.surfshark.com.conf
│   ├── us-bos.prod.surfshark.com.conf
│   ├── us-buf.prod.surfshark.com.conf
│   ├── us-chi.prod.surfshark.com.conf
│   ├── us-clt.prod.surfshark.com.conf
│   ├── us-dal.prod.surfshark.com.conf
│   ├── us-den.prod.surfshark.com.conf
│   ├── us-dtw.prod.surfshark.com.conf
│   ├── us-hou.prod.surfshark.com.conf
│   ├── us-kan.prod.surfshark.com.conf
│   ├── us-las.prod.surfshark.com.conf
│   ├── us-lax.prod.surfshark.com.conf
│   ├── us-ltm.prod.surfshark.com.conf
│   ├── us-mia.prod.surfshark.com.conf
│   ├── us-nyc.prod.surfshark.com.conf
│   ├── us-orl.prod.surfshark.com.conf
│   ├── us-phx.prod.surfshark.com.conf
│   ├── us-sea.prod.surfshark.com.conf
│   ├── us-sfo.prod.surfshark.com.conf
│   ├── us-sjc.prod.surfshark.com.conf
│   ├── us-slc.prod.surfshark.com.conf
│   ├── us-stl.prod.surfshark.com.conf
│   ├── us-tpa.prod.surfshark.com.conf
│   ├── ve-car.prod.surfshark.com.conf
│   └── za-jnb.prod.surfshark.com.conf
├── config.json
├── config.json.sample
├── gen_wg_config.sh
├── selected_servers.json
├── surf_servers.json
├── token.json
└── wg.json

1 directory, 123 files

Hi @yazdan ,


I've been all afternoon and I can't connect to Surfshark.
See attached image.
To what is due?

It seems that your public key is not registered with surfshark servers

Can you run my scripts again and send me the output?
It will not change your configs and just retry the key registration if it is needed

Hi,

The script works perfectly. In my router the speed with Openvpn 35M with Wiregurd 120M.
@yazdan thanks for the help

2 Likes

Happy to hear that

I think I evaluated Surfshark a year or so ago. If I remember right, I didn't go with them because they do not provide the WG configs to users so they can set it up themselves. Hence the need for this script, is that correct? Nice to see this is an option.

Right now they still don't officially provide WG configs.

I saw in github that there are some repositories in other languages that say they generate wireguard configs, and what I've done is just converting them to shell scripts so we can run/use it on OpenWRT.

1 Like

Hi @yazdan and @Gcholvi

I tried your script and I’m having the same problem where my public key is not registered with the Surfshark servers. Do you mind sharing what you did to make it work? Thanks in advance for your help and for making this script! Cheers!

Hella @yazdan,

I find myself in a similar situation here as well - Peer One handshake, Peer Two never sees a handshake.

I added some echo commands to the script to allow me to track function returns and variables, and added -v switch to the curl calls to track what might be failing here.

First I rm -rf the existing folder, pulled the latest wg_gen_config.sh from the repo, and restored my wg.json and config.json. Essentially my existing public/private key pair and authentication credentials.

Everything runs fine until the script hits the

VALIDATE PUBKEY Function - output below

Unnecessary use of -X or --request, POST is already inferred.
> POST /v1/account/users/public-keys/validate HTTP/1.1
> Host: api.surfshark.com
> User-Agent: curl/7.79.1
> Accept: */*
> Authorization: Bearer eyJ0eXAiOiJ -Truncated
> Content-Type: application/json
> Content-Length: 58
> 
< HTTP/1.1 404 Not Found	<------------:Note Response

< Date: Fri, 03 Dec 2021 14:57:01 GMT
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive```

and then of course the next function REG PUBKEY fails also, but it also sets the $register value = 0

Running a second instance without changing the folder files generated by the first run script yields the below output.
Note the HTTP/1.1 200 OK on this instance.

    LOGIN
	we have an existing "token.json"
	token value = "eyJ0eXAiOiJ -Truncated"
	renwToken value = "eyJ0eXAiOiJ -Truncated"
	END LOGIN

./surf_servers.json
servers list already exist

	GEN KEYS
	wg keys already exist
	Existing keys pub = "EwKu -Truncated- ZoHtbBU=" / prv = gLL -Truncated- CVlc=

VALIDATE PUBKEY
~~~~~~~~~~~~~~~
> POST /v1/account/users/public-keys/validate HTTP/1.1
> Host: api.surfshark.com
> User-Agent: curl/7.79.1
> Accept: */*
> Authorization: Bearer eyJ0eXAiOiJ -Truncated
> Content-Type: application/json
> Content-Length: 58
> 
< HTTP/1.1 200 OK	<------------:*Note Response*

< Date: Fri, 03 Dec 2021 15:03:55 GMT
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive

But, because

$register value returns 0, the previously failed registration function gets bypassed and the public key never seems to get registered with SS.

REG PUBKEY
register value = 0
No need to register pubkey

The script populates the .conf files absolutely correctly imo. Correct public/private keys, IP's,MTU, and required peer values.