Using OS X to Image an SD Card with Debian for BeagleBone Black

The latest revision of the BeagleBone Black is shipping with a 4GB eMMC, and it’s now possible to get it pre-imaged with Debian Wheezy, a more broadly useful production-isn environment than Angstrom. If you have a rev. B BeagleBone Black, you might want to run Debian on yours as well.

BeagleBoard.org only provides instructions for using a Windows machine to set up an SD card with the Debian Wheezy image, so I wanted to document a parallel set of directions and utilities for OS X users.

Get the Compressed “Wheezy” Image

wget https://rcn-ee.net/deb/microsd/wheezy/bone-debian-7.6-console-armhf-2014-08-13-2gb.img.xz

Check the MD5 hash, just to make sure that we’ve gotten the correct image. On OS X, the md5 command works similarly to md5sum on other systems.

$ md5 bone-debian-7.6-console-armhf-2014-08-13-2gb.img.xz
MD5 (bone-debian-7.6-console-armhf-2014-08-13-2gb.img.xz) = f925d35517b3938e67d9108f6abd3c4b

Uncompress the Image

Images for the BeagleBone Black (and other small devices) tend to come in 7zip format, and there’s no built-in support for unpacking 7zip files in OS X. However, Dag Ågren, the author of the Mac utility the UnArchiver, has made some free command line tools available which will handle 7zip files.

Install unar wherever it’s convenient to in your $PATH (Homebrew users will probably want to move it to /usr/local/bin). Unpack the image file with the command

unar bone-debian-7.6-console-armhf-2014-08-13-2gb.img.xz

Install the Image On an SD Card

Without the SD card inserted in your Mac, run the command

df -h

You’ll get a list of the disk volumes mounted on your system. Now, insert the SD card, and run the df -h command a second time. Note the device identifier for the SD card, which should now appear at the end of the list, showing an identifier that wasn’t previously present (you can also check the volume names, at the end of each output line.) In my case, it’s /dev/disk5s1.

The "df -h" command

Start by unmounting the SD card so that it can be completely rewritten.

sudo diskutil unmount /dev/disk5s1

We have to write to the raw disk, which has a slightly different identifier. In this example, since our SD card was /dev/disk5s1, the corresponding raw disk is /dev/rdisk5; if your SD card showed up at /dev/disk3s1, you’d use /dev/rdisk3, and so on.

Issue the dd command to write the image to the SD card. Be very certain you’re using the correct raw disk identifier here, or you’re liable to overwrite something you didn’t want to!

sudo dd bs=1m if=bone-debian-7.6-console-armhf-2014-08-13-2gb.img of=/dev/rdisk5

This command will take several minutes to run, be patient. When it completes, it will output something like the following:

1700+0 records in
1700+0 records out
1782579200 bytes transferred in 366.464955 secs (4864256 bytes/sec)

Now, eject the SD card, and you’re ready to reboot your BeagleBone into Debian Wheezy.

sudo diskutil eject /dev/rdisk5

With the BeagleBone connected to a monitor and a keyboard, but not connected to power, insert the SD card. While holding down the “BOOT” button, connect the board to power, and continue to hold the “BOOT” button down until you see the USR LEDs light up. You should be able to log in using the user name “debian” and password “temppwd”.

The Micro Python pyboard Arrived!

The version 1.0 pyboard that I ordered from the Micro Python project arrived in the mail today. It’s amazingly small.

IMG_1115-0.JPG

The board supports a REPL shell, accessible via the same USB cable that provides power, and has a number of LEDs, timers, a user-assignable switch, and an accelerometer framework. I’ll be putting together a review pretty shortly, but there are a million things going on, suddenly.

Stay tuned.

The Most Recent Batch of Inept Hackers

WordPress is very popular. Very easy to install. Very easy to install incorrectly if you’re not entirely clear on how things operate on your hosting, and in my experience, even a lot of ISPs seem to not be entirely clear on that.

This is just a screenful’s worth of the security scan — I’m using the free WordFence plugin on that site, which is one of the better free ones out there — from one of the WordPress sites I run. Pretty typical.

If you’re not running some sort of live traffic and file system scanner on your WordPress site, you’re probably asking for trouble. If your administrative account has a name like “admin”, “Administrator”, or “«PASTE SOME PORTION OF YOUR SITE’S DOMAIN NAME HERE»”, or if you expose your admin account name in other ways (like via an “?author=” page, or by using your admin account as an author), you’re walking down dark alleys with twenty-dollar bills hanging out of your pockets.

If you’re using an account name like that and an easily-guessed (or duplicated) password, you’re probably already in trouble.

I’m going to have more to say on this when I get it all organized…

Set Up Your WordPress Site to Use Password-Free SFTP For Better Security

This turns out to be a pretty easy trick to do. In order to accomplish this, you will need:

  1. to be able to ssh (or, heaven forbid, telnet) into a command line on your server and operate as root or a “sudoer”;
  2. to be able to edit the wp-config.php file for your WordPress installation;
  3. to be able to stop and restart your web server.

Assumptions: You’re running CentOS or something like it. If you’re running Debian, or something like it, you’ll need to use apt-get instead of yum, and your directory layout will be different.

Enabling SSH for PHP

We’re going to set up WordPress to enable uploads via SFTP; for that, we’ll first need to build and install the ssh2 extension to PHP. At your server’s command line, execute the following to load all of the infrastructure you’ll need:

$ yum install php-devel php-pear gcc gcc-c++ make automake autoconf pcre-devel re2c libssh2 libssh2-devel

Next, have pecl install the ssh2 extension.

$ pecl install ssh2-0.12

Turn on ssh2 by creating an ini file for PHP:

$ echo "extension = ssh2.so" > /etc/php.d/ssh2.ini

Restart your web server:

$ service httpd restart

At this point, the SSH2 PHP extension should be installed and activated; you can use

$ php -i | grep ssh2

to verify this.

Setting Up WordPress for SFTP

First thing to do is to generate a key pair. YOU MUST BE LOGGED IN AS THE USER WHO WOULD BE DOING THE UPLOADING TO WORDPRESS. At the command line, execute

$ keygen-ssh

When prompted to enter a file name, we’ll call the key pair “~/wp_rsa”, so as not to accidentally overwrite any other keys we have around. Once your key pair has been generated, execute the following commands in that user’s home directory:

$ cat wp_rsa.pub >> .ssh/authorized_keys
$ mv wp_rsa* .ssh/

For reasons that aren’t immediately clear to me, WordPress required both the public and private key to be available to it. Set the access protections appropriately:

$ chmod 755 .ssh/
$ chmod 644 .ssh/*

Next, edit wp-config.php, and add the following lines to the end, making the appropriate substitutions for your own site «where indicated»:

define('FTP_HOST', 'localhost');
define('FTP_USER', '«your user name goes here»');
define('FTP_PUBKEY', '«full path to user's home directory»/.ssh/wp_rsa.pub');
define('FTP_PRIKEY', '«full path to user's home directory»/.ssh/wp_rsa');

Finally, set the protections and ownership on the wp-content directory to allow Apache to create things in there (assumption — I have ownership of my wp-content directory set to «site owner»:apache; you may need to adjust this to suit your specific situation:

$ chmod 775 «full path to WordPress directory»/wp-content

You should be good to go.

[This posting is an adapted excerpt from the upcoming book “McFate’s Indispensible and Comprehensive Guide to Building Bullet-Proof Servers”]

The Correct Way to Lock Out an IP Address From Your Server

I’ve been getting something like a one-person DoS attack overnight, it seems — a single IP address hitting port 80 hundreds of times a minute, generating endless 404s, and chewing up noticeable bandwidth — so I had to add a rule to my iptables to block the IP address at fault. Here’s how to do it:

First, list your current iptable rules, with line numbers, for easy reference:

$ sudo iptables -L -n --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    fail2ban-SSH  tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22 
2    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
3    REJECT     all  --  0.0.0.0/0            127.0.0.0/8         reject-with icmp-port-unreachable 
4    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
5    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:25 
6    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:587 

etc...

Add a new rule to block the offending IP address (“xxx.yyy.zzz.www”).

$ sudo iptables -I INPUT 1 -s xxx.yyy.zzz.www -j DROP

This will insert the new rule at position 1, just prior to the rule that accepts TCP incoming traffic on port 22 for SSH and passes it to fail2ban.

Save the updated table and restart the service.

$ sudo service iptables save
$ sudo service iptables restart
$ sudo iptables -L -n --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    DROP       all  --  200.85.152.75        0.0.0.0/0           
2    fail2ban-SSH  tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22 
3    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
4    REJECT     all  --  0.0.0.0/0            127.0.0.0/8         reject-with icmp-port-unreachable 
5    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
6    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:25 
7    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:587 

etc...

Some suggestions for doing this that turn up on Google have used the “-A” (Add) flag rather than the “-I” (Insert) flag. This will not work in most cases, it would add the new rule to the end of the INPUT chain, after the rule that accepts (for instance) HTTP packets. If the banned IP address were attempting to access port 80, if would be ACCEPTed by that rule before it could get DROPped by the new rule.

The position of the rule is important: if it follows a rule which would accept the traffic otherwise, the new rule will have no effect. Placing it before the rules for general public traffic ensures that the annoyance in question can’t consume resources by trying to do things like load non-existent web pages. In fact, by checking first, the IP address is effectively firewalled from the server.

LEARN YOU SOME GIT! A git Resource List

If you’re working on code, whether you’re doing it on your own or collaboratively, you really want to be using a version control/source code management system, and the one most widely used these days is Linus Torvalds’ program git.

Git can be a little difficult to get your head around, but luckily, there are a lot of excellent (and free!) resources available to get you up to speed.

First, there’s TryGit, a collaboration between Github and Code School. TryGit walks you through fifteen guided experiments that will introduce you to the basics of git.

When you’ve worked through that, Code School’s “Git Real” course is available for free, no sign-up or credit card needed.

Another great resource is Git Immersion, from EdgeCase, a web-based guided tutorial that you can download to your own desktop.

Atlassian also provides an extensive set of git tutorials.

Finally, the text of the entire book “Pro Git”, written by Scott Chacon and published by Apress, is available online for free.

There’s no good reason not to use git, and lots of excellent reasons to do so. Do yourself a favor, save yourself some headaches, and check it out.

(SEE WHAT I DID THERE?)