11 Feb

Emulating Raspbian for the Raspberry Pi on Linux using QEMU

I’ve recently been trying to emulate Raspbian for the Raspberry Pi on my desktop computer so that I can try a few things out when I don’t have my Pi to hand.

Some of the guides on the internet are a bit outdated and since I wanted to use the latest Jessie build some where not relevant.

Below you will find instructions for emulating Raspbian on a desktop PC.

Install QEMU

sudo pacman -S qemu

Download the latest Raspbian image from https://www.raspberrypi.org/downloads/. At the time of writing the latest version was Raspbian Jessie with a kernel version 4.4.

Download this QEMU compatible kernel from https://github.com/dhruvvyas90/qemu-rpi-kernel.

The image file needs to be slightly modified as the /etc/fstab file is referencing /dev/mmcblk0, which is the SD Card device. Inside the emulation environment, the disk will have device id /dev/sda.

Attach the image file on the loop device:

sudo losetup -Pf 2017-01-11-raspbian-jessie-lite.img
mkdir partition2
sudo mount /dev/loop0p2 partition2
vi partition2/etc/fstab

Inside vi change references to mmcblk0 to sda.

Now unmount and detach the image from the loop device:

sudo umount partition2
rm -rf partition2
sudo losetup -d /dev/loop0

We can finally run up the system:

qemu-system-arm -kernel kernel-4.4.34.img -cpu arm1176 -m 256 -M versatilepb -serial stdio -append "root=/dev/sda2 rootfstype=ext4 rw" -hda 2017-01-11-raspbian-jessie-lite.img

Hopefully after the system has booted you will see a similar screen to this:

15 Dec

Create a WiFi hotspot and modify HTTP requests using the Raspberry Pi 3

Recently I was demonstrating the dangers of public WiFi, or indeed any untrusted network. Regardless of whether the WiFi has a password or not, the owner of the wireless access points can read, inspect and modify all the data you send over the connection.

To best demonstrate this I set up a rogue WiFi hotspot using a Raspberry Pi 3. The Raspberry Pi was setup to do 4 things:

  1. Act as a WiFi hotspot broadcasting a wireless network that did not have a password.
  2. Respond to DNS requests from all clients connected to it’s WiFi and had DNS server information obtained by DHCP.
  3. Return the access points IP address when a client requested the IP address of a well known website.
  4. Run a web server that returns a modified version of the well known website.

Below I take you through the installation and configuration steps necessary to achieve this.

I used Arch Linux on the Raspberry Pi 3 and so it is necessary to follow the ARMv7 installation instructions at https://archlinuxarm.org/platforms/armv8/broadcom/raspberry-pi-3 before continuing.

SSH into the Raspberry Pi using the alarm user with password alarm, change both root and alarm user passwords. (See https://wiki.archlinux.org/index.php/Users_and_groups for those unfamiliar with Arch Linux).

For convenience and security it is recommended to disable password authentication and enable public key authentication. (see https://wiki.archlinux.org/index.php/Secure_Shell#Force_public_key_authentication for those unfamiliar with Arch Linux)

Prepare the Raspberry Pi by executing the following commands as root (using su, see here for more information for those unfamiliar with su).

NOTE: Confirm any prompts that you receive

pacman -Syu
groupadd sudo
usermod -aG sudo alarm
pacman -S --needed base-devel
pacman -S git-core nodejs npm dnsmasq hostapd screen wget

At this point logout and log back in and you should be able to prefix commands that need root privileges with sudo

Create a directory called wifi

mkdir wifi
cd wifi/

create a file called hostapd.conf, in the current directory and populate it’s contents with the following:

beacon_int=100
ssid=Public-Hotspot
interface=wlan0
driver=nl80211
channel=1
ignore_broadcast_ssid=0
ap_isolate=0
hw_mode=g
logger_stdout=-1
logger_stdout_level=0

create a file called dnsmasq.conf, in the current directory and populate it’s contents with the following:

# Configuration file for dnsmasq.

port=53
domain-needed
bogus-priv
server=8.8.8.8
server=8.8.8.4
address=/example.com/192.168.30.1
interface=wlan0
dhcp-range=192.168.30.2,192.168.30.253,255.255.255.0,60m
dhcp-option=vendor:MSFT,2,1i
log-queries
log-dhcp
log-facility=/var/log/dnsmasq.log

NOTE: Replace line 8 with whatever website you wish to redirect to the Pi for modification.

Now we need to update the system to use our local DNS server

sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
sudo rm /etc/resolv.conf
sudo touch /etc/resolv.conf

modify /etc/resolv.conf so it’s contents are as follows:

nameserver 127.0.0.1
nameserver 8.8.8.8

modify hostapd.conf and dnsmasq.conf to suit your needs and then you’re almost ready.

create a file called start_ap.sh in the current directory and make it executable. Populate it’s contents with the following:

#!/bin/bash

ip link set up dev wlan0
ip addr add 192.168.30.1/24 broadcast 192.168.30.255 dev wlan0

hostapd ./hostapd.conf &

sysctl net.ipv4.ip_forward=1

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -P FORWARD ACCEPT
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -I INPUT -p udp --dport 67 -i wlan0 -j ACCEPT
iptables -I INPUT -p udp --dport 53 -s 192.168.30.0/24 -j ACCEPT
iptables -I INPUT -p tcp --dport 53 -s 192.168.30.0/24 -j ACCEPT

dnsmasq -C ./dnsmasq.conf

cd example.com/
node server.js &
cd ..

Optionally now download an example modified page for the example.com:

wget https://lanphier.co.uk/wp-content/uploads/2016/12/example.tar.gz
tar -xzvf example.tar.gz
cd example.com/
npm install
cd ..

You can now start the wifi hotspot using the following:

#start the WiFi
sudo ./start_ap.sh

As soon as you disconnect from the SSH then the processes launched to create the AP and node server will be terminated. To prevent this run the start wifi command inside of a screen session:

screen -S wifi
sudo ./start_ap.sh

You can detach from the screen by pressing ctrl+a and then ctrl+d. To reattach to the screen at a later date then SSH onto the Raspberry Pi and type

screen -x wifi

Protect against rogue hotspots

Any websites that use HTTPS should create a secure channel that the hotspot cannot read, however the hotspots will still be able to see that you are connecting to those secure sites though they will not be able to see the data you exchange.

The best possible protection is to use a VPN. This creates a secure tunnel to a third party and so all your traffic is secure against the hotspot owner.

20 Mar

Boot ArchLinux from USB on the Raspberry Pi

If you have ever wanted to store your root file system on a USB stick rather than an SD card then the following will describe how to do so.

You can’t get rid of the SD card completely as the Raspberry Pi is designed to boot from an SD card however you only need to store the “boot” files on the SD card as this is what the Raspberry Pi will attempt to load when powered on.

The usual instructions for installing Arch on the Raspberry Pi is to format the SD card with two partitions using a DOS (MBR) partitioning format. The first partition is recommended to be 100 MB in size and is formatted using the FAT file system. The second partition takes up the rest of the space on the SD card and is formatted using the standard Linux Ext4 file system.

Once the partitions are created and file systems formatted then we download the latest Arch Linux package for the Raspberry Pi (I’m using the Raspberry Pi 2 package here) (http://archlinuxarm.org/os/ArchLinuxARM-rpi-2-latest.tar.gz). Extract this archive to the main Ext4 partition on the SD card and then move the “boot” files from /mnt/p2/boot/ to /mnt/p1 assuming that the 100 MB FAT partition is mounted at /mnt/p1 and the Ext4 partition is mounted at /mnt/p2.

This works because the “boot” files on the first partition point to the second partition containing the root file system.

All we need to do is install the root file system on a USB drive and change the “boot” files on the SD card to point to our root file system partition on the USB drive.

The following assumes that on the Linux system used to prepare the USB and SD card that /dev/sdb is the USB drive and /dev/sdc is the SD card.

  1. Start fdisk to partition the SD card:
    fdisk /dev/sdc
  2. At the fdisk prompt, delete old partitions and create a new one:
    1. Type o. This will create a new MBR partition table at the beginning of the SD card.
    2. Type n to create a new partition.
    3. Make it a primary partition by typing p.
    4. Type 1 for the first partition on the SD card and press ENTER twice to accept the default first and last sector.
    5. Type t, then c to set the first partition to type W95 FAT32 (LBA).
    6. Save the changes and exit by typing w.
  3. Start fdisk to partition the USB drive:
    fdisk /dev/sdb
  4. At the fdisk prompt, delete old partitions and create a new one:
    1. Type o. This will create a new MBR partition table at the beginning of the USB drive.
    2. Type n to create a new partition.
    3. Make it a primary partition by typing p.
    4. Type 1 for the first partition on the USB drive and press ENTER twice to accept the default first and last sector.
    5. Save the changes and exit by typing w.
  5. Create and mount the FAT filesystem:
    mkfs.vfat /dev/sdc1
    mkdir boot
    mount /dev/sdc1 boot
  6. Create and mount the ext4 filesystem:
    mkfs.ext4 /dev/sdb1
    mkdir root
    mount /dev/sdb1 root
  7. Download and extract the root filesystem (as root, not via sudo):
    wget http://archlinuxarm.org/os/ArchLinuxARM-rpi-2-latest.tar.gz
    bsdtar -xpf ArchLinuxARM-rpi-2-latest.tar.gz -C root
    sync
  8. Move boot files to the first partition:
    mv root/boot/* boot
  9. Modify the file boot/cmdline.txt so that the root= kernel option specifies the first partition on the USB device. It should look similar to this:
    root=/dev/sda1 rw rootwait console=ttyAMA0,115200 console=tty1 selinux=0 plymouth.enable=0 smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 kgdboc=ttyAMA0,115200 elevator=noop

    If no other USB drives are to be plugged into the Raspberry Pi then the USB device is likely to get assigned /dev/sda.

  10. Unmount the two partitions:
    umount boot root
  11. Insert the SD card and USB drive into the Raspberry Pi and switch it on

The problem with the above is that you cannot guarantee that the USB drive will be assigned /dev/sda and this is especially the case when using more than one USB drive with the Pi.

To make this more reliable then when partitioning the USB drive in the above you should use gdisk to create a GPT based partition table. This way the partition can be referenced using a UUID and then modifying cmdline.txt so that the root kernel option is in the form root=PARTUUID=4673c3fe-9bab-476c-88c5-65e2c842f72a.