-
Notifications
You must be signed in to change notification settings - Fork 3
Linux: PORTAL of Pi
The Personal Onion Router To Assure Liberty is designed to protect the user by isolating their computer behind a router that forces all traffic over the Tor network. The PORTAL of Pi is a build script by the grugq to create a PORTAL with a Raspberry Pi using an Arch Linux install.
The scenario is that your attack device connects to the PORTAL via wired ethernet. The PORTAL connects to the internet via USB device (WiFi adapter, 3G/4G modem, etc). All traffic coming in on the wired ethernet port is forced into the Tor network as it departs the PORTAL headed for the internet. This setup aims to protect you from Tor information leaks.
This is a physical implementation of a Tor middlebox; e.g. the Tails project. The problem with a virtualized middlebox is that once an operator (you) has been compromised via client-side exploit, an adversary can leverage a VM break out to then access the host OS and reveal the identity of the operator. Identity disclosure of couse is in complete contradiction to the desired anonymity of using Tor. The PORTAL as a standalone device continues to force all traffic through Tor, regardless of host OS compromise on the operator attack device.
The Arch install is straightforward, hence this portion is essentially copypasta.
The micro/SD card needs two partitions: a W95 FAT32 (LBA) partition for /boot, and a Linux partition for the root filesystem. It should look something like this:
$ sudo parted /dev/mmcblk0 unit b print
Model: SD SU32G (sd/mmc)
Disk /dev/mmcblk0: 31914983424B
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1048576B 105906175B 104857600B primary fat32 lba
2 105906176B 31914983423B 31809077248B primary ext2
The partitions need to be formatted with a filesystem. Pretty straightforward.
$ sudo mkfs.vfat -F 32 /dev/mmcblk0p1
$ sudo mkfs.ext2 /dev/mmcblk0p2
Next step is to mount the partitions so that files can be written to the device.
$ mkdir boot root
$ sudo mount /dev/mmcblk0p1 ./boot
$ sudo mount /dev/mmcblk0p2 ./root
The root Arch Linux filesystem for Raspberry Pi can be downloaded at http://archlinuxarm.org/os/ArchLinuxARM-rpi-latest.tar.gz. The regular tar
utility finishes with errors, so the bsdtar
utility is used as per the original documentation.
$ wget http://archlinuxarm.org/os/ArchLinuxARM-rpi-latest.tar.gz
$ sudo bsdtar -xpf ArchLinuxARM-rpi-latest.tar.gz -C root
$ sudo sync
The last steps are to populate the SD card's /boot partition, and unmount.
$ mv ./root/boot/* ./boot
$ sudo umount ./boot ./root
At this point the SD card can be inserted into the Pi and powered on. The default credentials are:
alarm:alarm
root:root
Using WiFi requires some additional configuration. First install the wireless-tools
and wpa_supplicant
packages.
# pacman -Syu
# pacman -S wireless-tools wpa_supplicant
The adapter should show up in iwconfig
.
$ iwconfig
wlan0 IEEE 802.11abgn ESSID:off/any
Mode:Managed Access Point: Not-Associated Tx-Power=0 dBm
Retry short limit:7 RTS thr:off Fragment thr:off
Encryption key:off
Power Management:off
Here is an example to configure credentials for an access point at the local coffee shop that uses WPA2 and has the SSID Cafe WiFi.
$ wpa_passphrase "Cafe WiFi"
# reading passphrase from stdin
network={
ssid="Cafe WiFi"
#psk="Password123"
psk=6de652791b9f1582dff5d4e0ec495d008debe35b5915f231ce5041cefedd3d34
}
Here is a basic config file for wpa_supplicant
. I renamed the original /etc/wpa_supplicant/wpa_supplicant.conf
and left this in its place.
update_config=1
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
network={
ssid="Cafe WiFi"
#psk="Password123"
psk=6de652791b9f1582dff5d4e0ec495d008debe35b5915f231ce5041cefedd3d34
}
All that's left is to start wpa_supplicant
and collect an IP address.
# wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
# dhcpcd wlan0
You can check the status of the adapter with iwconfig
and ifconfig
.
For this portion, I have removed the SD card from the Pi and am interfacing with it via my operator device.
The Arch Linux install looks to have two sets of logs. The standard /var/log
set, and the user history files.
Clean up here is easy. Find the logs, shred them, and symlink them to /dev/null
. Note that I'm operating from the mount point of the Pi's SD card (hence the .
in ./var/log
) and all of these changes are happening on the Pi SD card, not my operator device.
$ sudo find ./var/log/ -type f | while read log; do sudo shred -u -n 1 "${log}" && sudo ln -s /dev/null "${log}"; done
The default shell is bash so I have prepended the following to all .bashrc
files and the SD card's /etc/bash.bashrc
.
unset HISTFILE
export HISTSIZE=0
export HISTCONTROL=ignoreboth
The HISTCONTROL=ignoreboth
prevents command entries starting with a space from being logged. Old habits die hard.
A few modifications remain to improve the hygiene of the Arch Linux install.
You likely noticed the default credentials in the install process.
alarm:alarm
root:root
Change those with passwd
on the Pi.
Another old favorite of mine is to randomize MAC addresses before the device comes up. Create two files in /etc/systemd/network
.
# touch /etc/systemd/network/00-{eth,wlan}0.link
Grab the MAC address for each interface; use ifconfig
or ip link show <interface>
if you're not sure. Now edit each of the two new files to look like the following (replace permanent MAC with your interface's MAC):
[Match]
MACAddress=permanent MAC
[Link]
MACAddressPolicy=random
NamePolicy=kernel database onboard slot path
This is an optional step. The PORTAL build script sets the hostname to portal
. If you want to change that every time the Pi boots, you can generate a new hostname. In this example, I will use the installed cracklib dictionary at /usr/share/dict/cracklib-small
but you can wrangle any data source of your choosing to create a new hostname.
Next I wrote a short script to generate a new hostname at /usr/local/bin/newhostname
.
#!/bin/bash
# -----------------------------------------------------------
# newhostname: generate a new hostname and set it using sed
# on /etc/hosts and the hostnamectl utility
# -----------------------------------------------------------
old=$(hostname)
new=$(sort -R /usr/share/dict/cracklib-small | head -n 1 | tr -cd '[:alpha:]')
hostnamectl set-hostname "${new}"
sed -i -e "s/${old}/${new}/g" /etc/hosts
The last part is to setup and enable a systemd service file; mine is /etc/systemd/system/newhostname.service
.
[Unit]
Description=Set hostname at OS load
[Service]
ExecStart=/usr/local/bin/newhostname
[Install]
WantedBy=multi-user.target
Enable the service with systemctl enable newhostname
.
Installing PORTAL on the Raspberry Pi is a breeze. The only needed items are git and an internet connection.
# pacman -S git
# git clone https://github.com/grugq/PORTALofPi
# cd PORTALofPi
# ./build.sh
The normal facilities of an external display and HDMI cable may not be available while freedom fighting on the go. The need for additional configuration of the Pi may however be present, such as WiFi configuration. To accommodate this, two minor adjustments can be made to expose SSH on the Pi to the operator device. Undo these changes before commencing any operational activities.
One rule is needed in the PREROUTING
chain, and one rule is needed in the INPUT
chain on the Pi to accommodate new SSH connections from the operator device. You could probably tighten this with source and destination address ranges if desired but it seems overly verbose.
-A PREROUTING -i eth0 -m conntrack --ctstate NEW -p tcp -m tcp --dport 22 -j REDIRECT --to-ports 22
-A INPUT -i eth0 -m conntrack --ctstate NEW -p tcp -m tcp --dport 22 -j ACCEPT
The PREROUTING
rule can be inserted into /etc/iptables/iptables.rules
just before the line -A PREROUTING -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT --to-ports 9040
. The INPUT
rule can be inserted into /etc/iptables/iptables.rules
just before the line -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
. To manually delete the rules, simply:
# iptables -t nat -D PREROUTING -i eth0 -m conntrack --ctstate NEW -p tcp -m tcp --dport 22 -j REDIRECT --to-ports 22
# iptables -D INPUT -i eth0 -m conntrack --ctstate NEW -p tcp -m tcp --dport 22 -j ACCEPT
A simple change to /etc/ssh/sshd_config
will restrict the listener. The normal SSH hardening and config recommendations apply here, as well, but are out of scope.
ListenAddress 172.16.0.1
Once SSH access is no longer needed, delete the firewall rule then terminate SSH service with systemctl stop sshd.service
.
To be documented later.