Tag Archives: raspberry pi

SSL PASSIVE FTP with virtual users on Raspberry Pi

I found this handy plugin to backup my blog: BackWPup
It has also an interesting feature which is the ability to backup remotely, for example on a FTP server.

So… here we go! 🙂

Few notes:

  • This uses vsftpd software
  • It will work ONLY over SSL
  • Due to SSL encryption, the FTP will also work ONLY in PASSIVE mode (ACTIVE mode is disabled)
  • This configuration has been made based of the fact that this raspberry pi is behind a router
  • This will use ONLY virtual users, chroot’ed, to increase the security (vsftpd will use a custom PAM auth file, which won’t lookup in /etc/passwd files – for this reason, any local user attempts to login will fail)
  • Virtual users usernames and credentials will be stored in a file
  • There is a workaround in place to avoid some common issues like “500 OOPS: Vsftpd: Refusing to Run With Writable Root Inside Chroot ()” – FYI, allow_writeable_chroot=yes does NOT work on vsftpd version 2.3.5.

Install required packets:

apt-get install vsftpd apache2-utils libpam-pwdfile

Create SSL certificate:

openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout /etc/ssl/certs/vsftpd.pem -out /etc/ssl/certs/vsftpd.pem
chmod 600 /etc/ssl/certs/vsftpd.pem

Add a local user with limited access (like no console) that vsfpd will use to run virtual users:

useradd --home /home/vsftpd --gid nogroup -m --shell /bin/false vsftpd

Create directory structures for the virtual users:

mkdir -p /space/ftpusers/
chmod a-w /space/ftpusers/
mkdir -p /space/ftpusers/ftp01/rw
chmod a-w /space/ftpusers/ftp01
chown -R vsftpd:nogroup /space/ftpusers/ftp01

Please note that all new virtual users added need its home directory manually created as per above. Also, due to the chroot option and the current limitation on vsftpd, if you want a user to be able to write in its home directory, you need to create an extra folder. Its root home folder has to be -w. This is a workaround that works 🙂

Setup PAM authentication

Create a new file /etc/pam.d/vsftpd.virtual and add the following:

auth required pam_pwdfile.so pwdfile /etc/vsftpd/vsftpd.users
account required pam_permit.so

Now, let’s reorder a bit vsftp files in a directory:

mkdir -p /etc/vsftpd
cd /etc/
mv vsftpd.conf vsftpd
ln -s /etc/vsftpd/vsftpd.conf .

Add new users (password max 8 characters):

htpasswd -c -d -b /etc/vsftpd/vsftpd.users ftp01 ftp01password

Use the flag -c only the first time to create the file. If you re-use it, the file will be overwritten!
Also the -d flag is required because vsftpd is unable to read MD5 hashed password (default if -d is not used). The downside of this is a password limited to 8 characters.
Openssl could be used to produce a MD5 based BSD password with algorithm 1 using # openssl passwd -1 (not tested)

Let’s configure vsftpd

vi /etc/vsftpd.conf

# Main Settings
listen=YES
listen_port=21
connect_from_port_20=NO
ftpd_banner=Welcome to my FTP :-)
use_localtime=YES
force_dot_files=YES

# FTP Passive settings
pasv_enable=YES
pasv_min_port=1100
pasv_max_port=1150
pasv_addr_resolve=YES
pasv_enable=YES
pasv_addr_resolve=YES
pasv_address=<span style="color: #ff0000;"><EXTERNAL IP or DYN DNS></span>

# Virtual user settings
local_enable=YES
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd/empty
virtual_use_local_privs=YES
guest_enable=YES
guest_username=vsftpd
pam_service_name=vsftpd.virtual
user_sub_token=$USER
local_root=/space/ftpusers/$USER
hide_ids=YES

# Anonymous settings
anonymous_enable=NO
anon_upload_enable=NO
no_anon_password=NO
anon_other_write_enable=NO
anon_mkdir_write_enable=NO

# Write permissions
write_enable=YES
local_umask=022
async_abor_enable=YES

# SSL
ssl_enable=YES
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH
rsa_cert_file=/etc/ssl/certs/vsftpd.pem

# Logging
xferlog_enable=YES
log_ftp_protocol=NO
syslog_enable=NO
vsftpd_log_file=/var/log/vsftpd.log

Now, on your router, make sure that the module ip_conntrack_ftp is loaded using lsmod command.
This is required for FTP PASSIVE mode to work.
I’ve realised that this can be called also nf_conntrack_ftp.
A good way to check all the alias associated to that netfilter module is using the following command:

# modinfo nf_conntrack_ftp
filename: /lib/modules/3.3.7/kernel/net/netfilter/nf_conntrack_ftp.ko
alias: nfct-helper-ftp
alias: <span style="color: #ff0000;">ip_conntrack_ftp</span>
description: ftp connection tracking helper
author: Rusty Russell <[email protected]>
license: GPL
depends: nf_conntrack
intree: Y
vermagic: 3.3.7 mod_unload MIPS32_R1 32BIT
parm: ports:array of ushort
parm: loose:bool

Also, make sure to setup a port forwarding like as below:

$IPT -t nat -A PREROUTING -p tcp -i $EXTIF -d $EXTIP --dport 21 -j DNAT --to $FTPIP:21 # FTP connection port
$IPT -t nat -A PREROUTING -d $EXTIP -p tcp -m tcp --dport 1100:1150 -j DNAT --to-destination $FTPI # FTP PASS ports
$IPT -A FORWARD -i $EXTIF -d $FTPI -p tcp --dport 21 -j ACCEPT
$IPT -A FORWARD -i $EXTIF -d $FTPI -p tcp --dport 1100:1150 -j ACCEPT

Backup Raspberry Pi SD on your Mac… and restore.

Plug the SD in your Mac.

In the Terminal, as root, use diskutil to identify your SD.
Generally it’s the last in the list, if you’ve just plugged in.

root:~ # diskutil list

You will see something like this:
diskutil_list_pi_sd

In my case, the SD is /dev/disk4. For this reason, I run the following to unmount the whole disk.

root:~ # diskutil umountDisk /dev/disk4
Unmount of all volumes on disk4 was successful

Once done, you can create the backup using dd utility, but make sure to change the device from /dev/diskX to /dev/rdiskX, adding the “r“.

root:~ # dd if=/dev/<span style="color: #ff0000;">rdisk4</span> of=/path/to/mypibackup.img bs=1m

To restore, of course… invert if (input file) with of (output file)… 🙂

root:~ # dd if=/path/to/mypibackup.img of=/dev/rdisk4 bs=1m

Mac – Time Machine on a Raspberry Pi

Requirements

First of all, you need the following:

  • a raspberry pi installed with 1 USB port available,
  • 1 external USB drive (I’ve used a 3TB external USB drive), pre-formatted under your Mac in HSF+, labelled as TimeMachine
  • internet connection 🙂
  • …and some time to perform all the steps and the initial backup.

Installation of your pi

As root, run the following to upgrade the system and install the required packages:

apt-get update && apt-get upgrade && apt-get -y install hfsplus hfsutils hfsprogs avahi-daemon libavahi-client3 db-util libgcrypt11

Now all the required debian packages are installed. We will install netatalk from the source code, because the debian packages are very old.

Setup the hard drive

Create a mount point as root:

mkdir /TimeMachine

Connect your external USB drive to your pi and run as root the following:

blkid

The output should be something like this:

 # blkid
/dev/mmcblk0p1: SEC_TYPE="msdos" UUID="xxxx-xxxx" TYPE="vfat"
/dev/mmcblk0p2: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" TYPE="ext4"
/dev/sda1: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" TYPE="ext3"
/dev/sdb1: LABEL="EFI" UUID="xxxx-xxxx" TYPE="vfat"
/dev/sdb2: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" LABEL="TimeMachine" TYPE="hfsplus"

Please take note of the UUID where you can see your hard drive installed and add the following line in your /etc/fstab file:

UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" /TimeMachine hfsplus rw,force,exec,auto,users 0 0

Now your drive will be automatically mounted at each reboot of the machine.

Install and configure Netatalk demon

Here you have 3 options:

  1. You can follow this guide if you want to create a .deb package which is easier manageable, especially on Debian;
  2. (For the lazy ones) download my precompiled deb file of version 3.1.1 from here, or 3.1.7 version from here, unzip and install it using dpkg -i
  3. Otherwise… just follow the next steps 🙂
Compile and install Netatalk

Download the latest stable code from here.
I’ve personally used version 3.0.4 for a while, and now I’ve upgraded to version 3.1.7.

Decompress the file, enter the folder and run the following:

./configure --with-init-style=debian --with-zeroconf

If no errors:

make

As root:

make install
cd /etc/init.d/
update-rc.d netatalk defaults

Configure afp.conf

Based on your version, you could have the configuration files in different locations.
Use the command afpd -v | grep "afp.conf"  to locate your afp.conf file.

Edit afp.conf based on your network configuration:

I’ve setup also an extra bit called [Homes] which shares the user /home directory using the same protocol. Quite handy to move around files 🙂 But this last part is NOT required for the scope of this post.

[Global]
mimic model = TimeCapsule6,106
; Global server settings
; Name of your computer in apple devices network
hostname = <your raspberry pi HOSTNAME>
; IP of your Pi
afp listen = <your raspberry pi IP>
hosts allow = <your network or the Mac's IP, for example 192.168.1.0/24>
; logging config
log file = /var/log/netatalk.log
log level = default:warn

[TimeMachine]
; Our Time Machine volume
path = /TimeMachine
cnid scheme = dbd
file perm = 0660
directory perm = 0770
time machine = yes

[Homes]
basedir regex = /home
cnid scheme = dbd
; Display each user home directory in this format
home name = Home $u

Now we can mount the drive and restart the services:

mount /TimeMachine && /etc/init.d/netatalk restart && /etc/init.d/avahi-daemon restart

Now the disk should be visible from your Mac and Time Machine application 🙂

First Time Machine backup

For the first Time Machine backup, I would really recommend to connect the external drive directly to the USB port of your Mac and follow these steps.

Before disconnect the drive from your pi, make sure to stop the services and unmount properly the disk:

/etc/init.d/avahi-daemon stop && /etc/init.d/netatalk stop && umount /TimeMachine && mount

Make sure the output does NOT show /TimeMachine mounted.

Create a sparsebundle manually

Connect the USB drive to your Mac and from the Terminal do the following:

cd /Volumes/TimeMachine/
hdiutil create -size 1500g -fs HFS+J -volname "TMachine" NAME_XXXXXXXXXXXX.sparsebundle

NAME is the hostname
XXXXXXXXXX is your MAC Address without “:”
200g means 1.5 TB (1500 GB). Please make sure it’s big enough to contain the first backup. After it will expand automatically. But if you set it less than the space required for the first backup, Time Machine might ignore it and create a normal folder structure, typical of USB hard drives.
Best practise is set about 80% of the capacity of your hard drive 😉

Start the first backup

Then, add this disk to Time Machine and let’s the backup start and finish.
For the fist backup, if it’s around 1Tb, be ready to leave the PC on all day.

Make sure that NO directories are created in the USB disk.
Just check the size of the sparsebundle file during the initial backup process. If it increases, it’s working! 🙂

I have to admit that I was doing something else when I’ve launched the backup and I’ve realised (I guess) that the sparsebundle file got renamed by Time Machine in a format like <hostname>.sparsebundle. Not sure why but… well, all worked so… from now on, I will use this new name for that file. :-p

If the backup doesn’t start automatically using the sparsebundle file, you can try to force it following these steps:

1) double click on your file sparsebunle to mount it
2) From Terminal, as superuser, run

tmutil setdestination /Volumes/TMachine/

3) Now force to run a new backup

Once completed, just take notes of the current permission of that file. You can check via terminal running ls -l /Volumes/TimeMachine/.
Now unmount the hard drive and reconnect it to your Raspberry Pi.

Final setup on the Raspberry Pi

Before mounting, do a quick check running the following (/dev/sdb2 is my Time Machine drive – please review the output of blkid if unsure):

fsck.hfsplus -f /dev/sdb2

If all is fine, you can mount the drive:

mount /TimeMachine/

And now, do a little trick to make sure to avoid permissions issues, and allow Time Machine to be able to write into the sparsebundle “file” (you will realise on Linux that it’s in fact a directory tree with files).

We’re going to create the same user and group that we have on the Mac on our Raspberry Pi.
Run a handy ls -l /TimeMachine and take note of the UID and GID.
If the group shows as numeric value, as root, you can run groupadd -g GID MACGROUP .

NOTE:GID is the value that you’ve seen with the previous command and MACGROUP is the name of the group that you saw running ls -l /Volumes/TimeMachine/ on you Mac Terminal.

Now, as root, create a new user that matches with the Mac user.

useradd -u UID -g GID MACUSER -m

NOTE: Same as before, UID is the value that you’ve seen with the previous command and MACUSER is the name of the user that you saw running ls -l /Volumes/TimeMachine/ on you Mac Terminal.

Now check again with ls -l /TimeMachine and you should see something like this: drwxr-xr-x 1 macuser staff 11 Apr 2 10:22 HOSTNAME.sparsebundle

NOTE: The group might be displayed as ‘dialout’ (or something else) instead of ‘staff’ as on your Mac. This is not a problem, as long as the numeric GID matches. If the group still shows as numeric value, it groupadd -g GID ‘staff’

All good? Then let’s restart netatalk:

/etc/init.d/netatalk restart

And now, we’re ready to:

  1. Add the remote disk “TimeMachine” to Time Machine;
  2. Initialise a second backup, just to make sure that all works fine (this will be probably less than 1GB);
  3. Have a drink as reward after all this work 🙂

Sources:
http://garmoncheg.blogspot.com.au/2012/11/time-capsule-for-25.html
http://administeria.com/?s=time+machine
http://buffalo.nas-central.org/wiki/Time_Machine_&_Time_Capsule_support_on_your_LinkStation

Raspberry Pi Emulator on Ubuntu 12.04 LTS

You have two options:

  1. Use a Ubuntu Desktop version with Gnome environment already preinstalled (do you really need all that crap?!)
  2. Install a brand new Ubuntu server 12.04 x64 LTS, basic, without Gnome or any super fancy packages… just a basic installation with SSH (suggested but not required). And after, just follow the post here to install a “Minimal X server”.If you want to change a bit the look of the login screen, you can have a look to this post.
    This is what I’ve done 🙂

Please note that a graphic environment is REQUIRED for this emulator to work.

Compile and install QEMU

Packages:

sudo apt-get install git zlib1g-dev libsdl1.2-dev libpixman-1-dev

Working directory:

mkdir ~/raspidev && cd ~/raspidev/
git clone git://git.qemu-project.org/qemu.git

It will take a while

Once done:

cd qemu
./configure --help

Read the output carefully (options of interest highlighted):

Usage: configure [options]
Options: [defaults in brackets after descriptions]

Standard options:
--help                   print this message
<span style="color: #0000ff;">--prefix=PREFIX          install in PREFIX [/usr/local]</span>
--interp-prefix=PREFIX   where to find shared libraries, etc.
use %M for cpu name [/usr/gnemul/qemu-%M]
<span style="color: #0000ff;">--target-list=LIST       set target list (default: build everything)</span>
Available targets: i386-softmmu x86_64-softmmu
<span style="color: #0000ff;">arm-softmmu</span> cris-softmmu lm32-softmmu m68k-softmmu
microblaze-softmmu microblazeel-softmmu mips-softmmu
mipsel-softmmu mips64-softmmu mips64el-softmmu
ppc-softmmu ppcemb-softmmu ppc64-softmmu sh4-softmmu
sh4eb-softmmu sparc-softmmu sparc64-softmmu
s390x-softmmu i386-linux-user x86_64-linux-user
alpha-linux-user <span style="color: #0000ff;">arm-linux-user</span> armeb-linux-user
cris-linux-user m68k-linux-user
microblaze-linux-user microblazeel-linux-user
mips-linux-user mipsel-linux-user ppc-linux-user
ppc64-linux-user ppc64abi32-linux-user
sh4-linux-user sh4eb-linux-user sparc-linux-user
sparc64-linux-user sparc32plus-linux-user
unicore32-linux-user s390x-linux-user

Advanced options (experts only):
--source-path=PATH       path of source code [/home/shift/openembedded/qemu]
--cross-prefix=PREFIX    use PREFIX for compile tools []
--cc=CC                  use C compiler CC [gcc]
--host-cc=CC             use C compiler CC [gcc] for code run at
build time
--extra-cflags=CFLAGS    append extra C compiler flags QEMU_CFLAGS
--extra-ldflags=LDFLAGS  append extra linker flags LDFLAGS
--make=MAKE              use specified make [make]
--install=INSTALL        use specified install [install]
--python=PYTHON          use specified python [python]
--static                 enable static build [no]
--mandir=PATH            install man pages in PATH
--datadir=PATH           install firmware in PATH
--docdir=PATH            install documentation in PATH
--bindir=PATH            install binaries in PATH
--sysconfdir=PATH        install config in PATH/qemu
--enable-debug-tcg       enable TCG debugging
--disable-debug-tcg      disable TCG debugging (default)
--enable-debug           enable common debug build options
--enable-sparse          enable sparse checker
--disable-sparse         disable sparse checker (default)
--disable-strip          disable stripping binaries
--disable-werror         disable compilation abort on warning
--disable-sdl            disable SDL
<span style="color: #0000ff;">--enable-sdl             enable SDL</span>
--disable-vnc            disable VNC
--enable-vnc             enable VNC
--enable-cocoa           enable COCOA (Mac OS X only)
--audio-drv-list=LIST    set audio drivers list:
Available drivers: oss alsa sdl esd pa fmod
--audio-card-list=LIST   set list of emulated audio cards [ac97 es1370 sb16 hda]
Available cards: ac97 es1370 sb16 cs4231a adlib gus hda
--block-drv-whitelist=L  set block driver whitelist
(affects only QEMU, not qemu-img)
--enable-mixemu          enable mixer emulation
--disable-xen            disable xen backend driver support
--enable-xen             enable xen backend driver support
--disable-brlapi         disable BrlAPI
--enable-brlapi          enable BrlAPI
--disable-vnc-tls        disable TLS encryption for VNC server
--enable-vnc-tls         enable TLS encryption for VNC server
--disable-vnc-sasl       disable SASL encryption for VNC server
--enable-vnc-sasl        enable SASL encryption for VNC server
--disable-vnc-jpeg       disable JPEG lossy compression for VNC server
--enable-vnc-jpeg        enable JPEG lossy compression for VNC server
--disable-vnc-png        disable PNG compression for VNC server (default)
--enable-vnc-png         enable PNG compression for VNC server
--disable-vnc-thread     disable threaded VNC server
--enable-vnc-thread      enable threaded VNC server
--disable-curses         disable curses output
--enable-curses          enable curses output
--disable-curl           disable curl connectivity
--enable-curl            enable curl connectivity
--disable-fdt            disable fdt device tree
--enable-fdt             enable fdt device tree
--disable-check-utests   disable check unit-tests
--enable-check-utests    enable check unit-tests
--disable-bluez          disable bluez stack connectivity
--enable-bluez           enable bluez stack connectivity
--disable-slirp          disable SLIRP userspace network connectivity
--disable-kvm            disable KVM acceleration support
--enable-kvm             enable KVM acceleration support
--disable-nptl           disable usermode NPTL support
--enable-nptl            enable usermode NPTL support
--enable-system          enable all system emulation targets
--disable-system         disable all system emulation targets
--enable-user            enable supported user emulation targets
--disable-user           disable all user emulation targets
--enable-linux-user      enable all linux usermode emulation targets
--disable-linux-user     disable all linux usermode emulation targets
--enable-darwin-user     enable all darwin usermode emulation targets
--disable-darwin-user    disable all darwin usermode emulation targets
--enable-bsd-user        enable all BSD usermode emulation targets
--disable-bsd-user       disable all BSD usermode emulation targets
--enable-guest-base      enable GUEST_BASE support for usermode
emulation targets
--disable-guest-base     disable GUEST_BASE support
--enable-user-pie        build usermode emulation targets as PIE
--disable-user-pie       do not build usermode emulation targets as PIE
--fmod-lib               path to FMOD library
--fmod-inc               path to FMOD includes
--oss-lib                path to OSS library
--enable-uname-release=R Return R for uname -r in usermode emulation
--sparc_cpu=V            Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9
--disable-uuid           disable uuid support
--enable-uuid            enable uuid support
--disable-vde            disable support for vde network
--enable-vde             enable support for vde network
--disable-linux-aio      disable Linux AIO support
--enable-linux-aio       enable Linux AIO support
--disable-attr           disables attr and xattr support
--enable-attr            enable attr and xattr support
--enable-io-thread       enable IO thread
--disable-blobs          disable installing provided firmware blobs
--enable-docs            enable documentation build
--disable-docs           disable documentation build
--disable-vhost-net      disable vhost-net acceleration support
--enable-vhost-net       enable vhost-net acceleration support
--enable-trace-backend=B Set trace backend
Available backends: nop simple stderr ust dtrace
--with-trace-file=NAME   Full PATH,NAME of file to store traces
Default:trace-<pid>
--disable-spice          disable spice
--enable-spice           enable spice
--enable-rbd             enable building the rados block device (rbd)
--disable-smartcard      disable smartcard support
--enable-smartcard       enable smartcard support
--disable-smartcard-nss  disable smartcard nss support
--enable-smartcard-nss   enable smartcard nss support
--disable-usb-redir      disable usb network redirection support
--enable-usb-redir       enable usb network redirection support
--disable-guest-agent    disable building of the QEMU Guest Agent
--enable-guest-agent     enable building of the QEMU Guest Agent

NOTE: The object files are built at the place where configure is launched

Easiest way:

./configure --help | egrep -i "PREFIX|everything|arm-softmmu|arm-linux-user|SDL"

Then, compile and install:

make
sudo make install

Check that all is fine:

qemu-system-arm -cpu ?

The output should contain ‘arm1176‘. If all is good, go to the next steps. 😉

 

Create the emulation environment

cd ~
mkdir raspemu && cd raspemu

Get the linux kernel:

wget http://xecdesign.com/downloads/linux-qemu/kernel-qemu

Download a raw image of Raspberry Pi from here and save in the same folder

wget http://downloads.raspberrypi.org/raspbian_latest

If you want to play a bit with it, you might need to pre-expand the file size, in order to have some extra space (by default you have only 200 Mb free on the current image).
For this, you can use the following commands, to add 2GB to the image:

dd if=/dev/zero bs=1M count=2048 >> path/your_image.img

Then, launch your qemu, and inside the console, try to useraspi-config script to automatically expand the filesystem.
Otherwise, try the following to do it manually (not tested):

PART_START=$(parted /dev/sda -ms unit s p |grep “^2? | cut -f 2 -d:)
echo $PART_START # (to be sure that it’s not empty).
fdisk /dev/sda <<EOF
p
d
2
n
p
2
$PART_START
p
w
EOF

Then reboot and launch resize2fs /dev/root
Now, you’re ready for the first boot.
Create a script called first_boot.sh with the following:

qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw init=/bin/bash" -hda <strong>$1</strong>

Remember to setchmod +xto this file and do not try to use more than 256 MB of RAM, the value is hard-coded in and QEMU will not work correctly.

After you can easily use this syntax to start your image:

./first_boot.sh path/your_image.img

Comment the line/usr/lib/arm-linux-gnueabihf/libcofi_rpi.soin the file/etc/ld.so.preloadand reboot.
Alternatively create a file/etc/udev/rules.d/90-qemu.ruleswith the following content:

KERNEL=="sda", SYMLINK+="mmcblk0"
KERNEL=="sda?", SYMLINK+="mmcblk0p%n"
KERNEL=="sda2", SYMLINK+="root"

The kernel sees the disk as /dev/sda, while a real pi sees /dev/mmcblk0. This will create symlinks to be more consistent with the real pi.

Once done, you can create a new script called start.sh with the following content:

qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" -hda <strong>$1</strong>

And now, finally, we can run our image of Raspberry Pi running:

./start.sh path/your_image.img

NOTE: use first_boot.sh script ONLY with a brand new image. If you’re using a copy of your Pi, maybe made using dd command, just use start.sh script.

Sources:

http://xecdesign.com/compiling-qemu/
http://xecdesign.com/qemu-emulating-raspberry-pi-the-easy-way/