Skip to content

Linux: PORTAL of Pi

int0x80 edited this page Jan 2, 2016 · 3 revisions

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.

Arch Install

The Arch install is straightforward, hence this portion is essentially copypasta.

Partition

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

Format

The partitions need to be formatted with a filesystem. Pretty straightforward.

$ sudo mkfs.vfat -F 32 /dev/mmcblk0p1
$ sudo mkfs.ext2 /dev/mmcblk0p2

Mount

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

Download and unpack

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

Finish up

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

WiFi

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.

No Logs, No Crime

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.

/var/log

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

User history

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.

Changes

A few modifications remain to improve the hygiene of the Arch Linux install.

Passwords

You likely noticed the default credentials in the install process.

alarm:alarm
root:root

Change those with passwd on the Pi.

MAC Addresses

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

Hostname

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.

PORTAL Install

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

No HDMI, No Problem?

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.

Firewall

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

SSH

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.

SD Card Fun

To be documented later.