I do not use the kuerig – here is why…

The kuerig device is a visually pleasing design. It appears to belong in the modern kitchen. A few months ago, I was given a kuerig first generation with a reusable filter and used it as my primary coffee consumption device. It gave me a sense of faster coffee delivery in the morning – I was happy until I discovered these flaws:

Flaw #1 – I spent more time making coffee than with a drip machine.

While it had a reservoir of water, that only lasted for about 6 tall glasses of coffee. I would have to switch out the K cup if I wanted a cup in the morning and one to take with – very common thing for me to do. This led me to another flaw.

Flaw #2 – the kuerig is designed for casual coffee drinkers.

By casual I mean 3-6 cups a month. Even with a refillable K cup, I was spending twice the amount on coffee and found myself adding 5 minutes to my normal routine just for use of the kuerig.

Flaw #3 – coffee dust

The coffee ground too much in store bought K cups and my refillable K cup often found itself in the bottom of my glass. This was disgusting and I could not stand throwing away the last sip of coffee because it had coffee dust at the bottom. To combat this, I had to cut filters in the shape of my K cup.

After 2 months of trouble with the kuerig, I got frustrated with drinking coffee. What was designed to be a pleasant, easy experience in making coffee turned out to be painful, time consuming, and more expensive. I evaluated my habit with the kuerig and found I was doing the same exact items with my old drip system, but spent more time affixing it to the kuerig. Once I realized that, I switched back to my old ways, sold the kuerig and bought more coffee with the money.

Debugging PHP web applications

In 2017, this topic seems a little dated and will probably not get me an opportunity to speak at a conference. While all of the elite programmers, cool kids, and CS grads are talking languages such as Go and Erlang – how to do tracing, performance testing, and the like – it seems very juvenile for me to write about PHP.

PHP is a language made specifically for the web. It is the first web language I learned after HTML 4/CSS. I learned it because it was easy. The syntax was easy, the variables – easy, running it – easy; however, when something broke, it was difficult as a beginner to troubleshoot. I would spend several hours looking at the code I just wrote only to find out I missed a semicolon or quote. This post is several things I wish I knew when I started with PHP. Continue reading Debugging PHP web applications

Few posts in the works

I have not posted in a few weeks. This was mainly due to getting a rest from posting every week of 2016! I have a few posts coming in the next few weeks. The first one will be about debugging PHP applications. The second one will be deploying a high availability MySQL cluster – what it looked like 10 years ago, and what it will look like 10 years from now. (HINT: Kubernetes + GlusterFS 😉 )

2016 behind, 2017 forward

With a year drawing to a close, I have a habit of looking back at my goals I set for myself, see how I have done, and set goals for the new year. My new year’s resolution for 2017 will be 1920×1080 (same as last year). I wish I could upgrade it to 5k, but it will have to do for now.

In 2016, I set a goal to post to my blog every week – I met that goal. I also planned to get more certs – of which I achieved my LFCE, COA, and Puppet Certified Professional. I also sharpened my ruby skills.

For 2017, I am not going to write on my blog every week. Instead I will write more lengthy blog posts and tutorials.

In 2016 we saw the Cubs win the world series, Microsoft join the Linux foundation, Google join the ASP.net foundation, and pigs actually flew. I can only imagine what 2017 will hold.

Easy unix epoch timestamps from CLI

While working on various projects and ultimately the need for a Unix timestamp for expiring swift objects in OpenStack, I needed a quick way to convert past, present, and future timestamps to the Unix epoch. Traditionally, I went to google, searched for a Unix timestamp converter, and retrieved my seconds that way. Unfortunately in exams, you are not allowed to visit external websites.

If you know how to read documentation, you will already know that the date command has this feature already built in. An excerpt from the docs is as follows:

 ...
       Show the local time for 9AM next Friday on the west coast of the US

              $ date --date='TZ="America/Los_Angeles" 09:00 next Fri'

DATE STRING
       The  --date=STRING  is  a mostly free format human readable date string
       such as "Sun, 29 Feb 2004 16:21:42 -0800" or "2004-02-29  16:21:42"  or
       even  "next Thursday".  A date string may contain items indicating cal‐
       endar date, time of day, time zone, day of week, relative  time,  rela‐
       tive date, and numbers.  An empty string indicates the beginning of the
       day.  The date string format is more complex than is easily  documented
       here but is fully described in the info documentation.
...

Further reading of the docs will point you in specifically formatting a return string by doing a date +%s. So when the time comes to expire an object from swift at 17:00 next Friday, you can do something like:

swift post container file -H 'X-Delete-On: `date +%s --date="17:00 next Friday"`'

OpenStack PS1 snippet

I have been studying for my OpenStack certification test (the COA) which is scheduled next week. One thing that was painful to keep track of was the user I was using to interface with OpenStack as the rc file you download from OpenStack does not update your PS1 prompt. I came up with the following solution and placed it in my ~/.bashrc:


function parse_os_user() {
    if [ ! "${OS_USERNAME}" == "" ]
    then
        echo "(${OS_USERNAME})"
    else
        echo ""
    fi
}

PS1='\u@\h \w `parse_os_user` \$ '

OpenStack certification

On Dec 20th, I am scheduled to take my COA exam. From the exam requirements page, it appears to be a somewhat moderately difficult exam. The few points I need work on are heat templates and swift object administration. A few things I know about the exam are what are publicly available via YouTube videos of the OpenStack summit sessions.

One of my troubles of studying for exams is creating content to test myself on the objectives of the exam. I look at the requirements and say to myself, “I know that,” and nothing gets written for that aspect. One thing I have done in the past is to search Github for exam prep questions. One I have found for OpenStack is AJNOURI/COA. He also made a nifty website for his test prep questions.

A key aspect that has helped me pass all of my open book exams is to recall the locations of my troubled areas. Looking at the docs/reading the manual has often come a best practice of mine. Most of the time, exam questions are covered in the docs as the exams expect you to have read them.

Docker is not a source to blame

I have been reading a few articles that have been published recently regarding the use of docker in production. Of the articles I read, all seem to complain about the instability of docker, the docker ecosystem, and they lament persistent storage. While I have not run docker in production for a lengthy amount of time, I can determine these issues are from operator error and are not entirely docker’s fault.

One article I read came out and boldly said that docker created a new file system in one year and it is not humanly possible to have created one in such a short amount of time. I think this article writer has never heard of the DevOps philosophy nor the minimum viability product (MVP). Basically, you do not need 100% of the features to have a working product. This makes it clearly possible to build a single file system – though not have all of the features – within a short time frame. It is also noted that a year in this development process, a second file system was created. Just like in real life, if you wait to ship a product with 100% of the features, you will never ship the product.

If you are losing data due to not properly mounting the volumes to a HA storage network (such as GlusterFS or DRBD) – you deserve to have lost the data. I know what it is like to lose 50TB of unique data due to a failed storage device, no current backups, and the shame and cost of having to send it over to DriveSavers (which they are!) for recovery. That is a painful experience and not worth repeating. If you do the same thing and expect different results, the issue lies with the operator and not the tool. Drastic changes were made when loss occurred including developing a new backup solution and having 1-to-1 replication of the data. It has also fine grained a permanent memory in my subsystem to not let that happen ever again.

Personally, I think running docker in a public cloud is a waste of company resources – there is no price difference between a VM and 1 docker image on AWS’ EC2 container platform of the same capacity. Even if you spun up an Atomic Host or similar, you still have to deal with networking constraints for your file storage. This is something best handled in house as you can scale your network infrastructure to match your workload.

The most important factor in all of this fuss about docker is that it is open source software. If you do not have the capacity to find flaws, make patches, and submit those patches for review to upstream, you are better off using a proprietary product that does not have such needs. Again, the issue lies in the operators and not the tools.

Day after Thanksgiving ritual

My wife and I adopted a tradition on the day after Thanksgiving – after a full night’s sleep – we visit stores and go shopping around 10am. Yes, the lines are still crazy, but the people who woke up at 5am to wait in line are already gone. With grandparents watching our children, it is one of our best stress-free shopping experiences. No doubt – we are doing it again today.

Using Puppet to host a private RPM repository

A repository is a place where files are stored, indexed, and available through a package manager to anyone who has the repository information. With rpm based systems, a repository is created with a tool called createrepo. Most of the time, publicly available repositories already offer the packages your server needs. When you have a custom application you want to deploy (or even rebuild an existing application with your patches), it is best to distribute that package with a repository rather than a file share or some other means. Often a folder structure is created so that differing client OS versions can connect to the same repository and access versions compiled to that specific release. In my example below, I am not creating this folder structure as I am only serving one major release – Centos 7 – and the packages I am generating are website directories which are just a collection of portable code.

A private repository is not a tricky feat – all you have to do is serve the repository via https and require http basic authentication. You then configure the clients to connect to the repository with the basic authentication in the URL string (i.e. baseurl=https://user:pass@repo.example.com/). The HTTPS protocol is not required to serve a repository, but it does prevent network snoopers from seeing your repository credentials.

Now that we know what is needed for a private repository, we can then define it in our puppet code.

node 'repo.example.com' {

  file { '/var/yumrepos':
    ensure => directory,
  }

  createrepo { 'yumrepo':
    repository_dir => '/var/yumrepos/yumrepo',
    repo_cache_dir => '/var/cache/yumrepos/yumrepo',
    enable_cron    => false, #optional cron job to generate new rpms every 10 minutes
  }

  package { 'httpd':
    ensure => installed,
  }

  httpauth { 'repouser':
    ensure    => present,
    file      => '/usr/local/nagios/etc/htpasswd.users',
    password  => 'some-long-password',
    mechanism => basic,
    require   => Package['httpd'],
  }

  file { '/usr/local/nagios/etc/htpasswd.users':
    ensure => file,
    owner  => 'nginx',
    mode   => '0644',
  }

  class{'nginx':
    manage_repo    => true,
    package_source => 'nginx-mainline',
  }

  nginx::resource::vhost{"$::fqdn":
    www_root             => '/var/yumrepos/yumrepo',
    index_files          => [],
    autoindex            => 'on',
    rewrite_to_https     => true,
    ssl                  => true,
    auth_basic           => 'true',
    auth_basic_user_file => '/usr/local/nagios/etc/htpasswd.users',
    ssl_cert             => "/etc/puppetlabs/puppet/ssl/public_keys/$::fqdn.pem",
    ssl_key              => "/etc/puppetlabs/puppet/ssl/private_keys/$::fqdn.pem",
    vhost_cfg_prepend    => {
      'default_type'     => 'text/html',
    }
  }

}

For the above code to work, we need the required modules:

mod 'palli/createrepo', '1.1.0'
mod "puppet/nginx", "0.4.0"
mod "jamtur01/httpauth", "0.0.3"

We can then use the following declaration on our nodes to use this repository.

yumrepo {'private-repo':
  descr           => 'My Private Repo - x86_64',
  baseurl         => 'https://repouser:some-long-password@repo.example.com/',
  enabled         => 'true',
  gpgcheck        => 'false',
  metadata_expire => '1',
}

You now have a fully functional private repository – deploy your awesome software.

Website protection

There are several factors that go into securing a web application. Most are second nature to seasoned system administrators, but it is still too common to talk to someone who does not know how to properly secure a web application. Here is the common checklist I go through when I determine if a website is secured.

  • Is it using a firewall?
  • Am I using unique passwords that are over 20 characters?
  • Are passwords required to alter data?
  • Is my codebase up to date?
  • Are the only public facing ports HTTP and HTTPS?
  • Do I protect data in transit from the user to my site by enforcing HTTPS?
  • Do I protect data from my website to the database with SSL?
  • Is my database only accessible to my application?
  • Do I have my database and application on different servers?
  • Can a malicious user drop/delete/alter data from my database from a form/switch/button that is publicly accessible on my website or do they need to login to perform that operation?
  • Do I have separate connections and users to the database for writing and reading data?
  • Do I rate limit connections via web application firewall or utility like fail2ban?
  • Am I reading and blocking malicious inputs via web application firewall or mod_security?
  • Can anyone brute force a login or am I blocking it after 5 tries?

So the Cubs won the world series

I am still in shock that the Chicago Cubs won the World Series in Baseball which ended their 108 year drought. Last time the Cubs won the world series, they won it back-to-back. I can expect nothing less this time around. 😀

GlusterFS overview

GlusterFS is a distributed file system. Think of it as a replacement of traditional file storage (a single NFS/samba server), an alternative to Microsoft’s DFS, or a modern implementation of SAN. It really shines when you have multiple locations and need a file server which must have the same data and be continually in sync. It is also superb for virtual machine disks as they will then become highly available.

You can use GlusterFS in a replica, distributed, and distributed-replica models. Replica is where a copy of file a is located on all GlusterFS hosts. Distributed is where file a is on some hosts and file b is on the other hosts. Distributed-replica is a combination of both – in other words a subset of two distributed hosts in a parent of replicas.

To get started with GlusterFS, all you need is commodity hardware. Nothing has to match – not even the harddrive space. GlusterFS will configure the storage allocation pool automatically. I do recommend at least a 1GB NIC connection and a large internet pipe between locations. Partitioning your system appropriately must also be considered – have a separate mount for /var/log and /data. Keeping /data as the location of your shares makes adding and removing nodes consistent with the documentation.

You need at least a multiple of 2 GlusterFS hosts to experience replica, distributed (minimum of 2 hosts), and (minimum of 4) distributed-replica. If you plan on serving Virtual machines off of the GlusterFS volume, multiples of 3 are recommended. Clusters can also be geographically bound so that if one node fails, your clients will connect to another gluster server in that region rather than just any gluster node.

The quick start documentation goes over setting up two nodes, pairing them together, connecting via the GlusterFS protocol on your client, and creating 100 files. In total, this is about 6 commands.

For managing a large cluster of GlusterFS servers, one may want to take a look at heketi which manages the lifecycle of GlusterFS. Facebook also developed a tool called AntFarm, but it is currently closed source.

A journey to LFCE

I began my Linux hobby in 1999. I was given a CD of RedHat Linux which I installed on an old computer. At first use, it was slow and buggy and uninstalled in favor of Windows 98. I installed Debian a few months later and discovered I could install a different desktop environment – KDE which looked like Windows, but was different. After playing with it for a few weeks, I discovered Knoppix – a live CD that didn’t overwrite my hard drive and let me play around without grave consequences. A friend then introduced me to Gentoo which allowed for complete customization for my 1ghz single core processor. After a few failed misconfigurations and a desire to get back to binary installs, I switched to Fedora Core 1 and used it on my desktop. Another friend showed me a new distribution called Ubuntu – similar to Debian, but more up to date. This was then installed on my laptop that I used for college. I switched completely to Ubuntu after the release of Fedora core 4 as I got frustrated with yum.

After college, I started working in a help desk position. It was mainly servicing Windows desktops and a few OSX machines. I then received a task from my boss to create a simple lookup website. I got to choose the server OS, create the VM on a Hyper-V host, and use any tools I could muster to perform this simple task. The project was a success and I received another – parse a text file and output it to a standard CSV. At the time, I only knew PHP and none of the cool features of sed and awk. PHP turned out to be a good choice for this project as I was later informed a user would use my creation every day to convert a text file to this new format. I simply had to create a web front end, parse the uploaded file, and give the user an option to download this file.

I began to develop more skills in Linux as my various work tasks involved more and more Enterprise level responsibility – such as LDAP authentication for websites, Active Directory maintenance, converting databases from Access to MySQL with a front end, Migration of Exchange 2003 to 2007, and introducing Google Apps for Education to about 700 students. 

When my boss left the organization, I assumed his role and provided oversight for network connectivity (switch/router config), overseeing two, 6 figure technology budgets, and also my regular responsibilities. I was able to attend training events as well as attend online courses regarding Linux. At that time, I began reading more books on tech practices, management, and Linux. I felt I learned enough to prove my skills with certification – even though I was doing the work successfully without being certified. The Linux Foundation released their equivalent to Red Hat’s RHCSA – the Linux Foundation Certified SysAdmin (LFCS). The domains and competencies covered described all the tasks I have done since setting up my first Linux box – create users, partitions, edit text files, etc. I took the introduction to Linux course offered by the Linux Foundation on edx, and scheduled an exam for my LFCS. On my first try, I misconfigured RAID, and rebooted the server. (Whoops!) The Linux Foundation was gracious to allow a free retake which I passed. I kept going around to my co-workers (after being certified) and quoting my favorite Dilbert comic: “Step away from that network server… I AM CERTIFIED!”

At this time, my skilled co-workers left (not all at once) and my team turned out to be just me for a period of eight months to cover 1,100 network attached devices and 1,300 users. It was about this time I researched CMEs (Chef, CFEngine, and Puppet) to help do tasks. I eventually picked puppet and successfully deployed RPi-wayfinding with it. A year and a half later, I passed the Puppet Certified Professional exam. With that out of the way, I turned my attention to the LFCE – especially since the Linux Foundation had a sale on the course and test for less than the test amount. 

The LFCE was the easiest certification test of all the ones I took. I scored an 88 out of 100, and I think the things I missed were saving the iptables rules :/

My next step is to take an AWS certificate test as I have been using AWS for nearly 2 years, but I will probably take an OpenStack cert first as I was given a discounted rate for the cert + course from the Linux Foundation.

Deploying Puppet Open Source

In this guide we will go over best practices to deploy Puppet Open Source using the recommended workflow (r10k), PuppetDB, and the foreman. You can deploy Puppet server on any of their supported *nix distributions. In this tutorial we will assume it to be on CentOS 7 as this seems to have the best support. Continue reading Deploying Puppet Open Source