vmask.sh (short for vnc mask) is a shell script utility for deploying and managing sockpuppets, which we will also refer to here as masks.
Using Docker, each mask is given its own dedicated web browser and VPN profile. This lets you easily set aside compartmentalized environments (with their own unique sets of cookies, sessions & bookmarks) for each of your sockpuppets, ensuring that no two sockpuppets connect to the internet from the same IP address.
The web browser is linuxserver.io's Firefox image, which is encased in KasmVNC and accessed via the desired port on any other web browser. This means you can store all your masks in the cloud, on any server or VPS that has Docker installed. (Direct X11/Wayland access not available. I am working on a companion script with a different browser image for that.)
The VPN connection is implemented by forcing the browser to go through Gluetun. By default, our configuration uses Wireguard, but all other Gluetun-compatible VPN modes are supported as well. (See: Configuring Wireguard and Other VPN Options, below.)
The way this is set up, it lets us use a single browser image as the base, which in turn is cloned into a unique container environment when the mask is "put on." Upon taking the mask off, only the mask's settings/cookies/bookmarks/etc are saved, and the rest of the container is Permanently Erased. Putting the mask back on generates a fresh instance of the browser container, with that masks's personal data preserved. This keeps disk space consumption at a minimum, while still providing the opsec benefits of containerization.
- bash (or compatible)
- sed
- Docker
Docker should ideally be running in rootless mode, since running a web browser as root is a very bad idea.
cd $HOME/.config
git clone https://github.com/HumphreyBoaGart/vmask
chmod u+rx vmask/vmask.sh
ln -s vmask/vmask.sh $HOME/.local/bin/vmask
Make sure your environment's $HOME
variable is set to your home directory, or you're going to have a hard time with, well, everything. You can check if it is set by running printenv HOME
.
The following commands are built into vmask.sh:
vmask list
vmask on MASKNAME
vmask off MASKNAME
vmask new
Or, to bypass interactive mode:
vmask new MASKNAME PORT
New masks are saved in an inactive state by default. To use a freshly-generated mask, you will need to first Configure Wireguard, and then run vmask on
.
Do not put two masks on the same port! If you are only pulling one mask out of storage at a time, this is not a big deal. HOWEVER, if you are planning on activating multiple masks at once, you will run into problems if more than one mask is configured to use the same port.
vmask del MASKNAME
If you are using rootless Docker (as you should be), the persistent storage directory for the browser will be chown'd to a different userid than your own. This means you need sudo permissions to delete any saved masks. (You do not need to run sudo yourself, it is baked into the script on this one command.)
vmask help
(vmask -h
and vmask --help
will also work)
If you are running vmask locally, you can access your mask's browser instance by going to http://localhost:PORTNUMBER, where PORTNUMBER is the port you told vmask to use.
For remote vmask installs, replace localhost with your server's IP address.
IMPORTANT: I highly recommend using HTTPS for remote use. (See: Enabling SSL, below.)
The default settings profile for all new masks is stored in skel/compose.yaml
. When you create a new mask with vmask new
, it creates a new directory for that mask in data/
. Then it creates a copy of this file, saves it to that new directory, and populates it with the attibutes you define.
This means there are two types of compose.yaml
files: One for new masks in skel/
, and another for existing masks in data/
.
To edit the default profile from which all new masks will be derived, just edit skel/compose.yaml
with your favorite text editor.
To edit existing profiles on a case-by-case basis, edit data/MASKNAME/compose.yaml
.
The following customizations can be made to both types of files:
Wireguard is only partially configured by default. You will need to edit the following variables on Lines 13-17 in compose.yaml
to finish the setup for each mask:
- WIREGUARD_ENDPOINT_IP
- WIREGUARD_ENDPOINT_PORT
- WIREGUARD_PUBLIC_KEY
- WIREGUARD_PRIVATE_KEY
- WIREGUARD_ADDRESSES
Eventually I may add Wireguard configuration to the vmask new
command, but I wanted to leave things flexible enough for end-users to implement all the other Gluetun VPN options that I personally do not use. (See: Other VPN Options, below.)
Gluetun supports a myriad of VPN options and providers, all of which can be implemented in compose.yaml
. For a full list of other VPN options you can implement, see the Gluetun wiki.
By default, Firefox is accessed via HTTP on a port of your choosing, mapped to port 3000 within the container. However, linuxserver.io provides the option for HTTPS access on internal port 3001, which is highly recommended if you are not using this on a local machine.
To use HTTPS, replace '3000' with '3001' on Line 8 in compose.yaml
.
Timezones for the Gluetun and Firefox containers are defined on Lines 10 & 25 in compose.yaml
respectively. By default they are set to America/New_York
to match the AMI server this script is promoted through. To throw off spies and other vultures, you may wish to define different timezones for each of your masks.
See this list of valid timezones for a complete list of options.
For an analytical rundown of best practices when engaging in sockpuppetry online, read my guide about Identity Management at the Anonymous Military Insitute.