WireGuard + Cloak

Cloak disguises a proxy or VPN server as a web server in order to evade deep packet inspection (DPI). The disguised server secretly implements Shadowsocks, OpenVPN, or Tor. This post describes an experimental implementation in which Cloak obfuscates a WireGuard server. WireGuard and Cloak run on a Debian 11 server. In the examples, we give the server IP address as 168.168.168.168. We end the tutorial by describing the procedure for setting up a Windows client.

1. Open Firewall

Firewalls are typically implemented with nftables, iptables, ufw, firewalld, or security groups. Whichever one you are using, you will need to open ports 80 and 443 for TCP input and persist your changes across reboots.

An example for iptables:

iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
apt install iptables-persistent

2. Install WireGuard on Server

Install WireGuard using the angristan script:

curl -O https://raw.githubusercontent.com/angristan/wireguard-install/master/wireguard-install.sh
chmod +x wireguard-install.sh
./wireguard-install.sh

Answer the questions that the script prompts you for. You can accept the defaults or enter your own values. In the example that follows, all the values were defaults except for the port number of 51820.

At the end of the script, enter your choices for the first WireGuard client:

The script creates a server configuration file /etc/wireguard/wg0.conf that looks like this:

[Interface]
Address = 10.66.66.1/24,fd42:42:42::1/64
ListenPort = 51820
PrivateKey = 8K/fTquVOSHxSmNnMY8dbvfpgbiXMEozf7WcPW8942o=
PostUp = iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i eth0 -o wg0 -j ACCEPT; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

### Client pc
[Peer]
PublicKey = 5w1dNTg10Nw1XXLmEn4+4SajwX7xgSftH8TayfFrdA8=
PresharedKey = 0fEJF/W0Rb6OhAdZ5/ptOXkNkRBk08OyVA0jiGvtFI0=
AllowedIPs = 10.66.66.2/32,fd42:42:42::2/128

The script also creates a first client configuration file /root/wg0-client-pc.conf that looks like this:

[Interface]
PrivateKey = eOh9TSSHqhkenmifQ9T8pNkSJ99lgSrBZ2Q1wqdLk0Q=
Address = 10.66.66.2/32,fd42:42:42::2/128
DNS = 94.140.14.14,94.140.15.15

[Peer]
PublicKey = LOOwb20PN1hQh0wKZ8qVZCE5EKlolsPwNI7IUOyR1EQ=
PresharedKey = 0fEJF/W0Rb6OhAdZ5/ptOXkNkRBk08OyVA0jiGvtFI0=
Endpoint = 107.161.24.219:51820
AllowedIPs = 0.0.0.0/0,::/0

You can check that the script has set the systemd service running with the command:

systemctl status wg-quick@wg0

3. Install Cloak on Server

3.1. Download Cloak

Open a browser on your PC and visit the GitHub Cloak releases page. Determine the version number of the latest release. For example, right now it is 2.6.0.

On your server, download the latest binary for 64-bit Linux. For example, for 2.6.0:

wget https://github.com/cbeuw/Cloak/releases/download/v2.6.0/ck-server-linux-amd64-v2.6.0

If this gives a temporary failure in name resolution, reboot and try again.

Copy the binary into a directory in your path with the name ck-server:

cp ck-server-linux-amd64-v2.6.0 /usr/local/bin/ck-server

Make ck-server executable:

chmod +x /usr/local/bin/ck-server

Allow Cloak to bind to privileged ports (i.e. TCP/IP port numbers below 1024):

setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/ck-server

3.2. Generate Public-Private Key Pair

Generate a public-private key pair:

ck-server -k

The public key and private key are delivered, separated by a comma. Here is an example of what the result might look like:

EjzZwdesObTyBWW9rI97uyztwK+4XFlDxxSrv9qyNFU=,cL2kY7rvneraJTyqbjy33rDAC/DQ3hyamRPAVolqgnI=

3.3. Generate Administrator Id

Generate a secret identifier for the administrator like this:

ck-server -u

It will produce a base-64 string that looks like this:

OuFKRCChbpTWrR1JXVg0ag==

3.4. Generate User Id

Generate an identifier for an ordinary user. We will make this user have no bandwidth or credit limit restrictions.

ck-server -u

The command will produce a base-64 string that looks like this:

JXD42BdCNynBeKq+G0KbFA==

3.5. Configure Cloak

For your reference, there is a sample configuration file on GitHub.

Create a directory for Cloak:

mkdir /etc/cloak

Edit your server’s configuration file for Cloak:

vi /etc/cloak/ckserver.json

Insert contents like the example below, substituting in your user id, private key, and administrator id:

{
  "ProxyBook": {
    "wireguard": [
      "udp",
      "127.0.0.1:51820"
    ]
  },
  "BindAddr": [
    ":80",
    ":443"
  ],
  "BypassUID": [
    "JXD42BdCNynBeKq+G0KbFA=="
  ],
  "RedirAddr": "www.bing.com",
  "PrivateKey": "cL2kY7rvneraJTyqbjy33rDAC/DQ3hyamRPAVolqgnI=",
  "AdminUID": "OuFKRCChbpTWrR1JXVg0ag==",
  "DatabasePath": "/etc/cloak/userinfo.db",
  "StreamTimeout": 300
}

Save the Cloak server configuration file.

3.6. Configure Systemd for Cloak

Create a systemd service file, so that we can make Cloak start after every reboot and run continually as a service:

vi /usr/lib/systemd/system/cloak.service

Insert contents like this:

[Unit]
Description=Cloak Server
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/ck-server -c /etc/cloak/ckserver.json
Restart=on-failure

[Install]
WantedBy=multi-user.target

Save the file.

3.7. Run Cloak

Make Cloak start after every reboot and run continually as a service:

systemctl enable cloak
systemctl start cloak

Check the status of the Cloak service:

systemctl status cloak

The above command should show that Cloak is active (running). Type q to quit the status display. Check that Cloak server is listening:

ss -tulpn | grep ck

The above command should show that Cloak (ck-server) is listening on ports 80 and 443.

Your work on the server is done for now, so exit your SSH session with the server:

exit

4. Set Up Windows Client

Now work on your PC, which in this tutorial is running Windows.

4.1. Download Cloak Client

In your browser, visit GitHub and determine the latest version of Cloak. We will use version 2.6.0 as our example.

Download ck-client-windows-amd64-v2.6.0.exe from GitHub to your PC’s Downloads directory.

4.2. Configure Cloak Client

For your reference, there is a sample client configuration file on GitHub.

In the Downloads folder, create a client configuration file for Cloak named ckclient.json. You can use Notepad or Notepad++ to edit the file. Insert contents like the example below, substituting in your UID and PublicKey.

This example has EncryptionMethod as plain for simplicity, but in the real world you would change it to aes-gcm or chacha20-poly1305.

{
  "Transport": "direct",
  "ProxyMethod": "wireguard",
  "EncryptionMethod": "plain",
  "UID": "JXD42BdCNynBeKq+G0KbFA==",
  "PublicKey": "EjzZwdesObTyBWW9rI97uyztwK+4XFlDxxSrv9qyNFU=",
  "ServerName": "www.bing.com",
  "NumConn": 4,
  "BrowserSig": "firefox",
  "StreamTimeout": 300
}

Save the file.

4.3. Install WireGuard for Windows Client

Download WireGuard for Windows installer from https://www.wireguard.com/install.

Run the installer.

Add a new tunnel like the one below. Note that the endpoint has been changed to be localhost (127.0.0.1) port 1984, not the remote server!

[Interface]
PrivateKey = eOh9TSSHqhkenmifQ9T8pNkSJ99lgSrBZ2Q1wqdLk0Q=
Address = 10.66.66.2/32,fd42:42:42::2/128
DNS = 94.140.14.14,94.140.15.15

[Peer]
PublicKey = LOOwb20PN1hQh0wKZ8qVZCE5EKlolsPwNI7IUOyR1EQ=
PresharedKey = 0fEJF/W0Rb6OhAdZ5/ptOXkNkRBk08OyVA0jiGvtFI0=
Endpoint = 127.0.0.1:1984
AllowedIPs = 0.0.0.0/0,::/0

Uncheck the Block untunneled traffic (kill-switch) checkbox.

Configuring WireGuard for Windows tunnel to pass through Cloak on localhost

4.4. Add Route to Server

Open a Windows command prompt with Run as administrator. Click Yes to allow. Add a route to your server via your main interface’s gateway. For example, if your server is at 168.168.168.168 and your primary gateway is at 192.168.122.1:

route ADD 168.168.168.168 MASK 255.255.255.255 192.168.122.1

4.5. Run Cloak Client

Open a Windows Command Prompt window.

Change into your Downloads directory:

cd Downloads

Run Cloak, pointing to your configuration file ckclient.json and your server 168.168.168.168, and specifying -u for UDP:

ck-client-windows-amd64-v2.6.0.exe -u -c ckclient.json -s 168.168.168.168

You will see a message, Listening on UDP 127.0.0.1:1984 for wireguard client. Leave the command prompt window open, with Cloak running in it.

4.6. Connect WireGuard Client to Server

Activate your WireGuard tunnel.

In the Cloak window, you will see messages Attempting to start a new session and Session 123456789 established.

4.7. End-to-End Test

Check the end-to-end functionality to confirm that TunSafe and Cloak are both configured correctly. Visit IP Chicken. You should see the IP address of the server, not your local client.

4.8. Disconnect

Deactive your tunnel in WireGuard for Windows client.

Terminate the Cloak client process with Ctrl+c.

Delete the static route to your server:

route DELETE 168.168.168.168 MASK 255.255.255.255 192.168.122.1

5. Get Help and Report Issues

Updated 2022-06-09