Linux: Fedora 22 major package versions

Fedora 22 has been released and I gathered the versions of some core packages:

Package Version
Perl 5.20.2
PHP 5.6.9
Vim 7.4.640
Apache 2.4.12
Kernel 4.0.4
Leave A Reply

Regexp: Splitting on unescaped delimiters

I need to split a string at a specific delimiter, but I also wanted to allow that delimiter in the string if it were escaped. The following string contains three parts separated by commas:

$str = 'Baker\, Scott,email@domain.com,https://www.perturb.org';

The first part is a full name, last name first, and then first name. The name portion has an escaped comma in it and should not be treated as a delimiter. To split on non-escaped delimiters you need to use negative look ahead assertion:

# Perl code
@p = split(/(?<!\\),/,$str);

This code snippet splits the string on all the commas that do not have a \ in front of them.

Special note: PHP requires the backslash delimiter to be escaped itself:

// PHP Code
$p = preg_split('/(?<!\\\\);/',$str);
Leave A Reply

Linux: Reverse path forwarding headaches

The Linux kernel has a security feature called Reverse Path Forwarding which is designed to ensure that incoming packets are valid for your network. It validates that a packet arriving via a given interface has a valid IP address for that interface. In some situations a packet can arrive on one interface, and leave on a separate interface. If you have a packet like this Reverse Path Filtering kicks in and drops that packet.

This manifests in that you can see the packet arrive (via tcpdump) but nothing after that (i.e. the packet doesn't leave). The Linux IP stack drops the packet before any routing or service can act upon the packet. To log affected packets to syslog you can run:

echo 1 > /proc/sys/net/ipv4/conf/<interfacename>/log_martians

To disable this check completely you can run the following command:

for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do
    echo 0 > $i 
done

Valid options for rp_filter are:

0 - No source validation.
1 - Strict mode as defined in RFC3704 Strict Reverse Path - Each incoming packet is tested against the FIB and if the interface is not the best reverse path the packet check will fail. By default failed packets are discarded.
2 - Loose mode as defined in RFC3704 Loose Reverse Path - Each incoming packet’s source address is also tested against the FIB and if the source address is not reachable via any interface the packet check will fail.

You can view the current settings for each interface on your box with this command:

sysctl -a | grep -E "net.ipv4.*\.rp_filter"

To make any changes permanent across a reboot set them in /etc/sysctl.conf

net.ipv4.conf.default.rp_filter = 0

Keywords: route, loop, egress, ingress, alien

Leave A Reply

Perl: Working with columnar data

I have a text file of data that is in whitespace separated columns that I need to work with. Perl has a command line option -a to enable auto-splitting the input into an array called @F. Using a Perl one-liner you can automatically split at whitespace separation like this:

cat /tmp/file_list.txt | perl -lane 'print "mv $F[3] $F[1]"'

This will output mv commands to rename the file in the 4th column to the 2nd column.

More information available in perlrun.

Leave A Reply

Linux: Debian 8 major package versions

Debian 8 has been released and I gathered the versions of some core packages:

Package Version
Perl 5.20.2
PHP 5.6.7
Vim 7.4.488
Apache 2.4.10
Kernel 3.16.0
Leave A Reply

Vim: Creating a portable copy of your configuration

If you use Vim on any regular basis you've probably created your own custom .vimrc file, and maybe installed a plugin or two. This config is machine specific and is not the easiest thing to move from one machine to another. I found this cool project called myvim that packages up your entire Vim installation into a single portable file. This file is a self-extracting archive of your Vim config that you can transfer to a new machine.

myvim -j /tmp/vim.bakers

This will create a file /tmp/vim.bakers which you can transfer and then run on a new machine.

Leave A Reply

Fedora: Force memcached to only listen on 127.0.0.1

I've been toying with memcached lately and wanted to ensure that it was only listening on 127.0.0.1. On Fedora this is controlled by the file /etc/sysconfig/memcached. Make sure that the OPTIONS line contains -l 127.0.0.1.

$ cat /etc/sysconfig/memcached 

PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 127.0.0.1"
Leave A Reply

Linux: Count CPU instructions

Zend published this infographic and it got me thinking about CPU instructions. According to the graphic, the Wordpress homepage required 9.4 billion machine instructions to render, but they've optimized PHP7 and it's now down to 2.6 billion. To count CPU Instructions on a Linux box you can use the perf command:

perf stat -e instructions <my_command>

In comparison, some very simple Linux commands take a significant amount of instructions:

# Approximately 640,000 instructions
perf stat -e instructions echo '' 

# Approximately 2 million instructions
perf stat -e instructions cd ~

# Approximately 700,000 instructions
perf stat -e instructions clear
Leave A Reply

Linux: Parallel file compression

Compressing files on Linux has gone through many iterations over the years. The three main methods to compress a file on Linux are: gzip, bzip2, and xz. All of these compression methods are single threaded, and can be "slow" on todays multi-core CPUs because they do not fully utilize all the cores. Fortunately the community has addressed this and created parallel implementations of each:

Single Threaded Parallel Version
gzip pigz
bzip2 pbzip2
xz pxz

All of these are available via Yum in Fedora and CentOS.

Leave A Reply

PHP: flat_var_export()

I needed to log a nested array to a file. To do this I needed to convert the array to a single line. After some searching I found improved_var_export() that converts a PHP array/object to a single line textual representation. I cleaned up some of the formatting and this is the result.

function flat_var_export($variable, $return = false) {
    if ($variable instanceof stdClass) {
        $result = '(object) ' . flat_var_export(get_object_vars($variable), true);
    } elseif (is_array($variable)) {
        $array = array();
        foreach ($variable as $key => $value) {
            $array[] = var_export($key, true) . ' => ' . flat_var_export($value, true);
        }
        $result = 'array(' . implode(', ', $array) . ')';
    } else {
        $result = var_export($variable, true);
    }

    if ($return) {
        return $result;
    } else {
        print $result;
    }
}
Leave A Reply

RSYSLOG: Send email notifications

I want to monitor my log files for a specific line, and if found send an e-mail alert. Rsyslog has this built in, and it works great. I put the following config in /etc/rsyslog.g/dhcp-watch.conf and now I get an email if a specific DHCP subnet is used.

# If we give out DHCP for a specific network send an alert email
$ModLoad ommail

$ActionMailSMTPServer mail.domain.com
$ActionMailFrom       rsyslog@domain.com
$ActionMailTo         me@domain.com

$template mailSubject,"DHCP Poll activity on %hostname%"
$template    mailBody,"DHCP Activity on the VLAN 873 pool\r\n\r\n%msg%"

$ActionMailSubject mailSubject

# Only send an email every 15 minutes
$ActionExecOnlyOnceEveryInterval 900

# This if/then must all be on one line
if $msg contains 'DHCPOFFER on 10.1.9.' then :ommail:;mailBody
Leave A Reply

PHP: Quote Word

I needed a function similar to Perl's qw. If you pass a string to this function it will return an array of the words, stripping any separating whitespace. If you pass true as the second parameter you will instead get a hash returning each word in a key/value pair.

function qw($str,$return_hash = false) {
    $str = trim($str);

    // Word characters are any printable char
    $words = str_word_count($str,1,"!\"#$%&'()*+,./0123456789-:;<=>?@[\]^_`{|}~");

    if ($return_hash) {
        $ret = array();
        $num = sizeof($words);

        // Odd number of elements, can't build a hash
        if ($num % 2 == 1) {
            return array();
        } else {
            // Loop over each word and build a key/value hash
            for ($i = 0; $i < $num; $i += 2) {
                $key   = $words[$i];
                $value = $words[$i + 1];

                $ret[$key] = $value;
            }

            return $ret;
        }
    } else {
        return $words;
    }
}

This is useful in the following scenarios:

$str  = "Leonardo    Donatello    Michelangelo    Raphael";
$tmnt = qw($str);

$str = "
    Leonardo       Blue
    Donatello      Purple
    Michelangelo   Orange
    Raphael        Red
";
$turtles = qw($str,true);
Leave A Reply

Books of 2015

Also see the list of 2014. The date indicated denotes the date I started reading the book.

2014-01-08 - Ogre, Ogre - 307 pages
2014-01-14 - Divergent - 489 pages
2014-01-23 - Protector - 218 pages
2014-02-09 - Gone Girl - 415 pages
2014-02-23 - Night Mare - 307 pages
2014-03-06 - Ender in Exile - 464 pages
2014-03-26 - Harry Potter and the Goblet of Fire - 734 pages
2014-04-15 - Interview with the Vampire - 346 pages
2014-05-06 - Fahrenheit 451 - 179 pages
2014-05-15 - Dragon on a Pedastal - 306 pages

Leave A Reply

Linux: CentOS 6.6 Major Package versions

CentOS 6.6 ships with these versions of some core packages:

Package Version
Perl 5.10.1 (bleh)
PHP 5.3.3
Vim 7.2.411
Firefox 31.2.0
Apache 2.2.15
Leave A Reply

ISC DHCP: Specific lease time for a given host

I needed to test lease timeout for a specific host. Rather than lowering the lease time globally for all clients I was able to target a specific MAC address using the following configuration block:

host shortlease_9b7d {
    hardware ethernet 00:5f:16:36:9b:7d;

    default-lease-time 900;
    max-lease-time 900;
    min-lease-time 900;
}
Leave A Reply