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
.
IPv4 or IPv6 public address: 168.168.168.168
Public interface: eth0
WireGuard interface name: wg0
Server's WireGuard IPv4: 10.66.66.1
Server's WireGuard IPv6: fd42:42:42::1
Server's WireGuard port [1-65535]: 51820
First DNS resolver to use for the clients: 94.140.14.14
Second DNS resolver to use for the clients (optional): 94.140.15.15
At the end of the script, enter your choices for the first WireGuard client:
Client name: pc
Client's WireGuard IPv4: 10.66.66.2
Client's WireGuard IPv6: fd42:42:42::2
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=
- The base-64 string before the comma is the public key, to be given to users
- The base-64 string after the comma is the private key, to be kept on the server
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 }
ProxyBook
tells Cloak where to forward authenticated proxy traffic to, which for us is WireGuard on portudp/51820
BindAddr
is a list of addresses Cloak will bind and listen to, which for us is443
BypassUID
is a list of UIDs that are authorised without any bandwidth or credit limit restrictionsRedirAddr
is the redirection address when the incoming traffic is not from an authenticated Cloak clientPrivateKey
is the static curve25519 Diffie-Hellman private key encoded in base-64AdminUID
is the user id of the admin user in base-64DatabasePath
is the path touserinfo.db
(ifuserinfo.db
doesn’t exist in this directory, Cloak will create one automatically)StreamTimeout
is the number of seconds of no sent data after which the incoming Cloak client connection will be terminated
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 }
Transport
can be either direct or CDNProxyMethod
is the name of the proxy method you are usingEncryptionMethod
is the name of the encryption algorithm you want Cloak to use, over and above the encryption in the proxy methodUID
is your user id in base-64PublicKey
is the static curve25519 public key, given by the server adminServerName
is the domain you want to make your ISP or firewall think you are visitingNumConn
is the amount of underlying TCP connections you want to useBrowserSig
is the browser you want to appear to be usingStreamTimeout
is the number of seconds of no sent data after which the incoming proxy connection will be terminated
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.
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
- For Cloak issues, post in the Issues section for Cloak on GitHub
- For WireGuard, the best place to get help is the #wireguard IRC channel on libera.chat
Updated 2022-06-09