-
Notifications
You must be signed in to change notification settings - Fork 2
tor
Jesús Daniel Colmenares Oviedo edited this page Mar 6, 2025
·
2 revisions
Creating a VM is a good way to isolate applications, but in some cases isolating traffic is a necessity. In this case we will create a VM tunneled through TOR. The choice of TOR is for simplicity, but you can choose a VPN provider or use your own VPN server depending on your needs.
Before we continue, a few notes:
- If you think you are anonymizing by simply using the following settings, you are probably wrong. Anonymizing is much more complex and the tradeoff is that you must take into account what applications (aka processes) you plan to run and what they do, specifically what connections they made. The part you need to be aware of is when they use plaintext connections, which of course can reveal who you are. But even encrypted connections to protocols or applications (e.g. WWW browsers) can easily reveal patterns about who you are.
- If you plan to take it more seriously, use something like Tails Linux or Whonix.
- I recommend this method of isolating applications for when you plan to use an application and do not want to reveal your IP easily by malware. I guess an email client is a good example: a suspicious person who looks "legitimate" may send you an email with a suspicious attachment.
See also:
-
Create an environment file.
.env:
ENTRYPOINT=http://127.0.0.1:8888 TOKEN=<access token> TS_AUTH_KEY=<tailscale auth key> TIMEZONE=UTC SSH_KEY=<SSH public key> -
Create a deployment file for metadata.
torVM-metadata.yml:
kind: metadata datacenters: main: entrypoint: !ENV '${ENTRYPOINT}' access_token: !ENV '${TOKEN}' deployIn: labels: - desktop metadata: ts_auth_key: !ENV '${TS_AUTH_KEY}' resolv.conf: | options usevc nameserver 208.67.222.222 nameserver 208.67.220.220 timezone: !ENV '${TIMEZONE}' loader.conf: | nvme_load="YES" if_bridge_load="YES" bridgestp_load="YES" if_wg_load="YES" kern.racct.enable=1 ssh_key: !ENV '${SSH_KEY}' sshd_config: | # Ports Port 22 # Authentication PubkeyAuthentication yes AuthenticationMethods publickey PermitRootLogin prohibit-password PrintMotd no # Forwarding X11Forwarding no AllowAgentForwarding yes # Connection checks ClientAliveCountMax 3 ClientAliveInterval 15 # Compression Compression no # Limits LoginGraceTime 40 # Public keys AuthorizedKeysFile /etc/ssh/authorized_keys # SFTP Subsystem sftp internal-sftp sysctl.conf: | # A bit of hardening security.bsd.see_other_uids=0 security.bsd.see_other_gids=0 security.bsd.see_jail_proc=0 kern.randompid=1 # Allow packet filtering in if_bridge(4) net.link.bridge.pfil_member=1 net.link.bridge.pfil_bridge=1 pkg.conf: | FreeBSD: { url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest", mirror_type: "srv", signature_type: "fingerprints", fingerprints: "/usr/share/keys/pkg", enabled: yes }
-
Create a deployment file for the VM.
torVM.yml:
kind: vmJail datacenters: main: entrypoint: !ENV '${ENTRYPOINT}' access_token: !ENV '${TOKEN}' deployIn: labels: - desktop vmName: 'torVM' makejail: 'gh+DtxdF/vm-makejail --file Makejail.tor' template: loader: 'bhyveload' cpu: '4' memory: '2G' network0_type: 'virtio-net' network0_switch: 'public' wired_memory: 'YES' diskLayout: driver: 'nvme' size: '40G' from: type: 'components' components: - base.txz - kernel.txz osArch: amd64 osVersion: 14.2-RELEASE disk: scheme: 'gpt' partitions: - type: 'freebsd-boot' size: '512k' alignment: '1m' - type: 'freebsd-swap' size: '2g' alignment: '1m' - type: 'freebsd-ufs' size: '20g' alignment: '1m' format: flags: '-Uj' - type: 'freebsd-ufs' alignment: '1m' format: flags: '-Uj' bootcode: bootcode: '/boot/pmbr' partcode: '/boot/gptboot' index: 1 fstab: - device: '/dev/nda0p3' mountpoint: '/' type: 'ufs' options: 'rw,sync' dump: 1 pass: 1 - device: '/dev/nda0p2' mountpoint: 'none' type: 'swap' options: 'sw' dump: 0 pass: 0 script: | set -xe set -o pipefail sysrc -f /mnt/etc/rc.conf ifconfig_vtnet0="inet 192.168.8.2/24" sysrc -f /mnt/etc/rc.conf defaultrouter="192.168.8.1" sysrc -f /mnt/etc/rc.conf fsck_y_enable="YES" sysrc -f /mnt/etc/rc.conf clear_tmp_enable="YES" sysrc -f /mnt/etc/rc.conf dumpdev="NO" sysrc -f /mnt/etc/rc.conf moused_nondefault_enable="NO" sysrc -f /mnt/etc/rc.conf hostname=torVM if [ -f "/metadata/resolv.conf" ]; then cp -a /metadata/resolv.conf /mnt/etc/resolv.conf fi if [ -f "/metadata/loader.conf" ]; then cp /metadata/loader.conf /mnt/boot/loader.conf fi if [ -f "/metadata/ts_auth_key" ]; then pkg -c /mnt install -y tailscale ts_auth_key=`head -1 -- "/metadata/ts_auth_key"` echo "/usr/local/bin/tailscale up --accept-dns=false --auth-key=\"${ts_auth_key}\" && rm -f /etc/rc.local" > /mnt/etc/rc.local sysrc -f /mnt/etc/rc.conf tailscaled_enable="YES" fi if [ -f "/metadata/timezone" ]; then timezone=`head -1 -- "/metadata/timezone"` ln -fs "/usr/share/zoneinfo/${timezone}" /mnt/etc/localtime fi if [ -f "/metadata/sshd_config" ]; then sysrc -f /mnt/etc/rc.conf sshd_enable="YES" cp /metadata/sshd_config /mnt/etc/ssh/sshd_config fi if [ -f "/metadata/ssh_key" ]; then cp /metadata/ssh_key /mnt/etc/ssh/authorized_keys fi if [ -f "/metadata/sysctl.conf" ]; then cp /metadata/sysctl.conf /mnt/etc/sysctl.conf fi if [ -f "/metadata/pkg.conf" ]; then mkdir -p /mnt/usr/local/etc/pkg/repos cp /metadata/pkg.conf /mnt/usr/local/etc/pkg/repos/Latest.conf fi metadata: - resolv.conf - loader.conf - ts_auth_key - timezone - sshd_config - ssh_key - sysctl.conf - pkg.conf
-
Deploy.
overlord apply -f torVM-metadata.yml overlord apply -f torVM.yml
-
Once the VM is deployed, you should have a new node in your tailnet.
$ tailscale status tailscale status ... xxx.xx.xxx.xx torvm REDACTED@ freebsd - ...
-
Connect to the virtual machine and check if you can see your public IP address.
$ ssh root@xxx.xx.xxx.xx fetch -qo - http://ip-api.com/json | jq { "status": "success", "country": "Germany", "countryCode": "DE", "region": "BB", "regionName": "Brandenburg", "city": "Brandenburg", "zip": "14621", "lat": 52.6171, "lon": 13.1207, "timezone": "Europe/Berlin", "isp": "Stiftung Erneuerbare Freiheit", "org": "CIA TRIAD SECURITY LLC", "as": "AS60729 Stiftung Erneuerbare Freiheit", "query": "185.220.101.174" }
Attentive readers noted a few things:
- I have used Tailscale, but you can choose not to use it, however, your
pf.conf(5)configuration needs to differ to allow SSH connections. This is a bit more complicated than simply relying on Tailscale, Zerotier, Headscale or similar. - You may have noticed that I have used
options usevcwhich forces the FreeBSD DNS resolver to use TCP instead of UDP. You can opt not to use it and use the TOR DNS server, the problem is that it is limited to resolving only A, AAAA and PTR records, but records that may be needed such as SRV (thinkpkg(8)) or MX will fail. All TCP connections will be forwarded to TOR and UDP connections will be blocked, although there are some exceptions (see below). - CoreDNS (listen on
*:53) is installed and configured to forward DNS messages to TOR via its DNS server (listen on127.0.0.1:5353).pf.conf(5)is configured to allow both TCP and UDP connections when using the bridge's IPv4 address (currently192.168.8.1). - The
pf.conf(5)file is configured to allow connections to192.168.8.1:9050which is currently listening for connections to the socks proxy provided by the TOR service. This allows applications such as the Tor Browser to configure that node as the socks proxy instead of using the one installed on the system, thus avoiding sending packets through the TOR network twice and decreasing performance.