Ghost
- The GHOST Vulnerability, from the The Laws of Vulnerabilities blog at Qualys.
- CVE-2015-0235 at Mitre, at Red Hat Bugzilla (Bug 1183461), at Novell, at Debian, at Red Hat Knowledge Base, at SANS ISC Youtube Channel.
- Discussions at Hacker News, Reddit, Slashdot, Stack Exchange.
- Qualys Security Advisory CVE-2015-0235, and cross-posted at the Open Source Software Security Mailing List.
- Articles at ZDNet, Ars Technica, Security Week (#1), Security Week (#2), Yahoo News, TechRepublic.
- Glibc Adventures: The Forgotten Chunks
- 'Ghost' Not So Scary After All
Clone a remote repository with GitPython
Example code:
{% highlight python %} import git
remote = 'https://github.com/gitpython-developers/GitPython.git' local = '/home/marios/Tests/gitpython'
git.Repo.clone_from(remote, local) {% endhighlight %}
mysqlhotcopy
mysqlhotcopy is a Perl script for backing up MySQL tables stored in either the MyISAM or ARCHIVE engines. It works very fast because it doesn't dump the contents of the tables. Instead it takes advantage of the fact that MyISAM tables are contained in separate files, and simply locks the tables and copies the flat files.
Example Setup
Create a user in MySQL for running
mysqlhotcopy
. The user will need to be granted theSELECT
,RELOAD
andLOCK TABLES
privileges on the databases that will be backed up. In this example, I want all databases to be backed up:mysql> CREATE USER `mysqlhotcopy`; mysql> GRANT SELECT, RELOAD, LOCK TABLES ON *.* TO `mysqlhotcopy`@`localhost`;
Create a daily cron job to backup every database, except for
information_schema
, which is a dynamic schema created my the MySQL server itself and does not exist as files on the filesystem. An example script is:#!/bin/bash for database in $(mysql --user mysqlhotcopy \ --batch \ --skip-column-names \ --execute 'SHOW DATABASES;' | \ grep -v '^information_schema$') do mysqlhotcopy $database /root/mysql-dumps/ --allowold --keepold --user=mysqlhotcopy done
This script maintains one previous copy of the databases, by renaming the directory, appending the suffix
_old
to the name.
See also
PostgreSQL
Replication
This is the nicest guide for streaming replication that I've found: Zero to PostgreSQL streaming replication in 10 mins. It is written for Ubuntu, but it only needs a couple of steps done differently on CentOS, which I have noted in the comments of that article. This guide is not as clear (for my preference), but it includes some commands to verify that the replication is running: How To Setup PostgreSQL Replication On CentOS.
BackupPC
Random tips for BackupPC:
On your client systems (those that will be backed up by BackupPC), rotate your logs (whether compressed or not) with dates in the filenames, instead of appending prefixes such as
.1
,.2
,.3
, etc. The benefit from this is that BackupPC will ignore old logs on new runs, since they will have the same name and the same checksum. If you rotate logs with numbered names, BackupPC will transfer them again, since the name will have changed. This configuration is achieved with thedateext
parameter set inlogrotate
configuration file, which on CentOS 6 is at/etc/logrotate.conf
, by default.If
mlocate
is installed on the BackupPC system, you should exclude the backup directory from being indexed by the nightly run ofupdatedb
, otherwise/var/lib/mlocate/mlocate.db
will become enormous. To exclude the backup directory, edit/etc/updatedb.conf
and append the directory path to the end of the line for thePRUNEPATHS
variable.
See Also
- BackupPC Archive is a Perl script that maintains archive copies of backups taken with BackupPC. Fork on GitHub.
- A BackupPC Windows Client used to live at michaelstowe.com/backuppc/ but that project seems dead (last checked 2020-12-23)
- Stale NFS Mount Causes BackupPC
fileListReceive()
Failure

Raspberry Pi Security Bootstrap
These are my notes on the first steps of improving security on a new Raspberry Pi. The default configuration that an RPi comes with might be suitable for a development environment in a private or isolated network, but if you intend on exposing your RPi to the world then you need to tweak that configuration to be more robust. The commands mentioned here have been tested on a Raspberry Pi B+, running a fresh installation of Raspbian.
Disclaimer
Security is fluid and open-ended. The following are mere suggestions. Taking these steps will hopefully reduce your exposure, but does not guarantee complete safety. Nothing does.
User configuration
This goes without saying: Change the default user's password. By default, the RPi user is
pi
and her password israspberry
. Change that as soon as you get your operating system runnning, either by runningpasswd
as thepi
user, or by runningsudo raspi-config
and selecting the option for password change.Change the default user's
sudo
configuration. By default, thepi
user can execute anything withsudo
, without providing a password. As thepi
user, do:sudo visudo
...and the change the line:
pi ALL=(ALL) NOPASSWD: ALL
...to:
pi ALL=(ALL) ALL
Additionally, you might want to disable the default
pi
user altogether, and create another user that you will use on your RPi. As the userpi
, do:sudo adduser myuser
...and answer the questions. Only the password question is important, the rest can be left blank. Then, to make the new user a sudoer, do:
sudo visudo
...and add this line in the end of the file:
myuser ALL=(ALL) ALL
Additionally, since login will be disabled for
pi
, you might as well comment out the line in/etc/sudoers
that refers to that user. Finally, to disable login for the defaultpi
user, logout frompi
and login as the new user that you created, and do:sudo usermod --lock pi sudo usermod --shell /sbin/nologin pi
SSH Configuration
Forbid SSH login for user
root
. If your RPi is exposed to the world, it will get attacked with SSH attempts for common usernames and passwords, which is yet another reason to disable the defaultpi
username. Another username that your RPi will be hammered with isroot
. Now, you can't disable the root account, but you can disallow logins for it. To do that, edit the file/etc/ssh/sshd_config
, and change the line:PermitRootLogin yes
...with:
PermitRootLogin no
...and then restart the SSH daemon:
sudo service ssh restart
Restrict Incoming IPs for SSH, using entries in
/etc/hosts.allow
and/etc/hosts.deny
. For example, I allow SSH on my RPi from my internal LAN subnets (192.168.x.x), and from one public IP only (1.2.3.4 in this example). To achieve that, put in/etc/hosts.allow
:sshd: 192.168. 1.2.3.4
...and in
/etc/hosts.deny
:sshd: ALL
Attempting to login to the RPi from a restricted host will return an error to the client:
[email protected] ~ $ ssh [email protected] ssh_exchange_identification: Connection closed by remote host
...and will also create a log in
/var/log/auth.log
:Dec 13 11:40:48 rpi sshd[3456]: refused connect from 172.16.1.2 (172.16.1.2)
Firewall Configuration with iptables
On my RPi running a freshly installed Raspbian OS, iptables
was already
installed, and it was running with an empty rule set, i.e. all traffic was
allowed in all directions. Furthermore, Raspbian does not include a SysV
script for the iptables
service, but this functionality is offered by the
iptables-persistent
package.
Install
iptables-persistent
, to help make theiptables
rules survive a reboot:sudo apt-get install iptables-persistent
If you accept the defaults during the installation, the currently running empty rule set of
iptables
will be saved in/etc/iptables/rules.v4
. After the installation, you can manage your firewall with:service iptables-persistent {start|restart|reload|force-reload|save|flush}
Here are the contents of that file, with the default configuration of the firewall:
# Generated by iptables-save v1.4.14 on Sat Dec 13 14:23:03 2014 *filter :INPUT ACCEPT [1291:113154] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [828:105910] COMMIT # Completed on Sat Dec 13 14:23:03 2014
Next, you will need to add some rules to the
iptables
configuration, to start blocking some traffic. There are two methods that you can apply:A. Replace the line
:INPUT ACCEPT
that defines a default policy to accept all incoming traffic), with:INPUT DROP
, and then define rules that will only allow selected traffic through the firewall.B. Keep the default
:INPUT ACCEPT
policy for incoming traffic, but have one last rule that rejects all incoming traffic.I'm going with the second option, simply because of the convenience of copying rules from one of my CentOS machines :) Here it is then, my rules file, implementing only the restriction to SSH port to the same IPs that I mentioned earlier:
*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --source 192.168.0.0/16 --dport 22 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --source 1.2.3.4/32 --dport 22 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT
Summary
With these measures taken to improve the security of my Raspberry Pi, I am now more confident that I can assign it a public IP and expose it the the world, without it being a very easy target.