For the Masochists (or the truly paranoid)

(This article is written for BrewPi Legacy Remix version 0.5.2.0, it likely applies to other versions but there may be some differences.)

You’re here for one of a few reasons:

  • You’re just curious about how things work
  • You hate easy things and want to do this the most difficult way possible
  • You are exceeding (perhaps justifiably) paranoid and refuse to run scrips as root. Maybe starting at the bottom of this article is a good place to start?
  • You are one of those people that find some twisted satisfaction in running something named BrewPi on something other than a Raspberry Pi

We’re not here to judge (or am I silently judging you right now?), we’re just here to help. Just like the government. Here’s what you have to go through to replicate most of the scripting in the BPR tool set. Note that this only addresses a single-chamber setup. I’m not sure I feel like describing what has to be done to do multi-chamber but a smart person can figure it out from the information that’s out there for the Legacy BrewPi.

Finally before we dig in, these instructions are written for Debian-based Linux distributions (of which Raspbian is one.) If you use something else, chances are you already understand the differences.

Prerequisites

The bootstrap especially does some checking which may not specifically be strictly required, but is highly recommended:

  • Check to see if the default password of ‘raspberry’ is still current for the ‘pi’ user. If so, prompt to change it.
  • Prompt to set the proper timezone. Since BrewPi works on schedules and the graph is of course time-based, having the proper system time is important. Yes, I could do some work to allow UTC and display in the user time zone … but why?
  • If the hostname is still ‘raspberrypi’, prompt to change it. More than a few folks have more than one Raspberry Pi, and being able to use a nice name like “brewpi.local” to get to the system is handy. Plus, you should never have two machines with the same name on the same network segment. It confuses anything with an ARP table (like your router.)

APT Repositories

Manipulation of APT repositories is required to support this product. This obviously needs to be done as root, however the repos are GPG signed so in theory there’s an added level of security.

As with any other apt packages, it is always good practice to refresh your local apt indexes before doing any installs, updates, or uninstalls. This command will re-synchronize the package index files from their sources. The indexes of available packages are fetched from the location(s) specified in /etc/apt/sources.list.

sudo apt update

There are some packages known to conflict with the solution as well; namely nginx and anything related to php5. This should not be a surprise since we use apache2 as a web server and nginx is a web server itself. Yes a crafty person can make them coexist, if you’re that crafty you don’t need my tutorials. Some of the packages I suggest to reinstall will be reinstalled again with apache2 and that’s fine. The process may also suggest removing other packages which are included by dependency; remove those as well. To uninstall nginx, use the following command:

sudo apt remove libgd-tools, fcgiwrap, nginx-doc, ssl-cert, fontconfig-config, fonts-dejavu-core, libfontconfig1, libgd3, libjbig0, libnginx-mod-http-auth-pam, libnginx-mod-http-dav-ext, libnginx-mod-http-echo, libnginx-mod-http-geoip, libnginx-mod-http-image-filter, libnginx-mod-http-subs-filter, libnginx-mod-http-upstream-fair, libnginx-mod-http-xslt-filter, libnginx-mod-mail, libnginx-mod-stream, libtiff5, libwebp6, libxpm4, libxslt1.1, nginx, nginx-common, nginx-full

To uninstall php5, I could give you a script but you’re here because you either don’t trust my scripts or you can’t use them for some reason. You can use the following command to find php5 packages which may be installed:

dpkg --get-selections | awk '{ print $1 }' | grep 'php5'

You would have to uninstall each of the returned package names with:

sudo apt remove {package name}

Now you need to install a series of APT repos. Here’s the command you would run to install all repos used in this product:

sudo apt get git arduino-core git-core pastebinit build-essential apache2 libapache2-mod-php php-cli php-common php-cgi php php-mbstring python-dev python-pip python-configobj php-xml

Pip Installs Packages (pip)

In addition to the apt packages, several additional python packages will be necessary. These are installed with pip:

 sudo pip install pyserial psutil simplejson configobj gitpython --upgrade 

User Setup

BrewPi runs as its own (now passwordless) user. Here we create the brewpi user and add it to the dialout, sudo and www-data groups:

useradd brewpi -m -G dialout,sudo,www-data

Next we add the ‘pi’ user (or whatever user you normally use to the www-data and brewpi groups:

usermod -a -G www-data,brewpi pi

Clone git Repositories

There’s four repositories that make up this product:

  • BrewPi-Tools-Remix – The toolset that this article replaces, so we won’t clone it here
  • BrewPi-Script-Remix – The core Python scripts which communicate with the Arduino and website
  • BrewPi-WWW-Remix – The PHP website which forms the user interface
  • BrewPi-Firmware-Remix – This repository does not need to be cloned, one need only download the current compiled firmware

Make sure the /home/brewpi directory exists and is empty. Clone the scripts as the brewpi user with the following command:

sudo -u brewpi git clone -b master --single-branch https://github.com/brewpi-remix/brewpi-script-rmx.git /home/brewpi

The web root should be /var/www/html but new versions may change that. Clean out that directory (it probably has a default index.html file there) and clone the website as the www-data user with the following command:

sudo -u www-data git clone -b master --single-branch https://github.com/brewpi-remix/brewpi-www-rmx.git /var/www/html 

Set Permissions

One of the more common solutions to a whole slew of issues is setting the permissions correctly. There is a script for this in:

/home/brewpi/utils/doPerms.sh

If you are still needing or wanting to proceed manually, the following commands are issued:

chown -R www-data:www-data /var/www/html
find /var/www/html -type d -exec chmod 2770 {} \;
find /var/www/html -type f -exec chmod 640 {} \;
find /var/www/html/data -type f -exec chmod 660 {} \;
find /var/www/html -type f -name ".json" -exec chmod 660 {} \;
chown -R brewpi:brewpi /home/brewpi
find /home/brewpi -type d -exec chmod 775 {} \;
find /home/brewpi -type f -exec chmod 660 {} \;
find /home/brewpi -type f -regex "..(py|sh)" -exec chmod 770 {} \;
find /home/brewpi/logs -type f -iname "*.txt" -exec chmod 777 {} \;
find /home/brewpi/settings -type f -exec chmod 664 {} \;

Arduino Firmware

You can download the precompiled firmware (sorry, not going to go into how to compile it on your own here) from the GitHub repo. For instance here’s how to download the latest Arduino Uno firmware:

curl -O https://github.com/brewpi-remix/brewpi-firmware-rmx/releases/download/0.2.10/brewpi-arduino-uno-revC-0_2_10.hex

You would now flash your connected Arduino with the following command. Be sure to update the port (following the ‘-P’) with the port where your Arduino resides:

avrdude -F -e -p atmega328p -c arduino -b 115200 -P /dev/ttyACM1 -U flash:w:"brewpi-arduino-uno-revC-0_2_10.hex" -C /usr/share/arduino/hardware/tools/avrdude.con

Daemon Unit Files

BrewPi and a checker for the WiFi connection run as a systemd daemon. The following files must be placed in the /etc/systemd/system directory. The first is named brewpi.service and contains the following text:

[Unit]
Description=BrewPi service for: brewpi
After=multi-user.target

[Service]
Type=simple
Restart=on-failure
RestartSec=1
User=brewpi
Group=brewpi
ExecStart=/bin/bash /home/brewpi/utils/doBrewPi.sh -d
SyslogIdentifier=brewpi

[Install]
WantedBy=multi-user.target

Change permissions on the file, enable and start the service with the following commands:

sudo chown root:root /etc/systemd/system/brewpi.service
sudo sudo chmod 0644 /etc/systemd/system/brewpi.service
sudo systemctl daemon-reload
sudo systemctl enable brewpi
sudo systemctl start brewpi

The (optional) WiFi check file should be saved as wificheck.service and it contains:

[Unit]
Description=BrewPi service for: wificheck
After=multi-user.target
[Service]
Type=simple
Restart=on-failure
RestartSec=1
User=root
Group=root
ExecStart=/bin/bash /home/brewpi/utils/doWiFi.sh -d
SyslogIdentifier=wificheck
[Install]
WantedBy=multi-user.target

And as with the brewpi daemon, set permissions, install and start it with the following commands:

sudo chown root:root /etc/systemd/system/wificheck.service
sudo sudo chmod 0644 /etc/systemd/system/wificheck.service
sudo systemctl daemon-reload
sudo systemctl enable wificheck
sudo systemctl start wificheck

Work Complete & Final Thoughts

In theory, you should now have a working BrewPi Remix running in single chamber mode. I will however leave you with some final thoughts.

If you are one of those folks who got here and followed these instructions out of some sense of increased security by not running my install scripts I’ve got bad news for you. You are still running scripts from some random person on the Internet and some start as root.

With thanks to the folks at Sandstorm.io, I’m going to paraphrase a few of their sentences:

Using curl|bash or curl|sudo bash certainly seems insecure. To anyone with a basic understanding of Unix, the construction makes it really obvious: This command will give the named web site direct access to your system, with the ability to do anything that you could do. This feels very wrong: We should be able to install software without giving the developers full access to our systems, right?

I would be the first to agree that software you install should not be automatically fully trusted. Unfortunately, however, traditional Unix software is always granted the full authority of the user who runs it (and in the case of a stock Raspbian OS this implies passwordless sudo). When you install software on Linux, no matter what package manager you use, you are giving that software permission to act as you. Most package managers will even execute scripts from the package at install time – as root. So in reality, although curl|bash looks scary, it’s really just laying bare the reality that applies to every popular package manager out there: anything you install can pwn you.

If you wish to install any software without giving it full access to your system, you must install it on a dedicated machine, VM, or (perhaps, with caveats) an isolated user account. In truth it’s more work than a lot of people want to deal with and in my experience people spend a lot more time complaining about it than actually taking steps to be secure.

The reality is this:

  • This is free software and you are invited to not run it if you are that concerned. I’d argue however that even the most paranoid among you have downloaded and run applications from the Internet with no additional security. At best, maybe you scanned it for viruses, but I’d be willing to bet a normal home user would not perform a source-code scan. If you are a person who really does a source-code scan, this is all written in bash, PHP, Python and the firmware in a proprietary C-ish language. It’s all there and all able to be downloaded freely and handled however you wish under the terms of the GNU General Public License.
  • This is intended to be run on dedicated hardware. A Raspberry Pi is really perfect for this and a Pi Zero W is about $20. There’s no reason to try to run this on some other rig on which you do other things that could be compromised by rogue code.
  • The last significant vector at risk here is the network to which the BrewPi machine is attached. If you have IoT devices, surely you have a separate wireless LAN segment for them? Put this there. Tom has a great article about IoT security. You can also choose to not have your BrewPi connected to your home network at all. Sure you lose some functionality, but you can always disconnect the network and just use it with a local keyboard, mouse and monitor.

I’m not making fun of people displaying a healthy dose of paranoia. At last count I am tracking 552 website credential pairs, all using unique highly complex passwords. Yes that’s right, I have over 500 passwords to keep track of. In addition I use two-factor whenever possible. Believe me when I say I am a fan of security. Sometimes though you gotta pick your fights and mitigate risk when you do.

One last word: As a fan of security I do have several ideas how to make this application more secure. I don’t have a schedule and nobody is paying for this so who knows what I’ll get done. Stay tuned though, surely the battle will be won in small skirmishes.