MoinMoin with NGINX and uWSGI

I’ve been moving much of my web infrastructure away from Apache and toward NGINX and uWSGI.  Goal: Ditch PHP like the bad habit it is and improve performance of my webapps.  (Yes, I know I said that on a WordPress, PHP based blog.)

MoinMoin is my wiki engine of choice.  It works very well under this setup and figuring that out was only a couple Google searches.  However, I could not attach files to my wiki pages under NGINX and uWSGI.  I kept getting the message:

“No file content. Delete non ASCII characters from the file name and try again.”

No other error messages, and my log files indicated nothing out of the ordinary.  I tracked this down in the MoinMoin code and discovered that this was the error produced when it checked the HTTP request object for the uploaded file content.  That content was the python special value None.

Turns out, this seems related to NGINX’s support of sendfile.  (Which improves performance of reading and writing from one file descriptor to another.)  I turned off sendfile support in /etc/nginx/nginx.conf and attaching files to wiki pages started to work

Now to figure out why that is.

NCSU FOSS Fair 2013

NC State’s University’s 5th annual FOSS Fair is in a little more than 2
weeks. Which means you have just a hair over a week to reserve your
lunch! Head over to our Wiki and reserve your food, and sign up to give
a session!

This year we are giving away a Raspberry Pi with enclosure, SD card, and
power adaptor. You must be present to win.

Gasp! The FOSS Fair has gone social. Like us on Facebook:

and join our Google Community!

Want to help out with this year’s FOSS Fair? Then tell others about the
Fair and encourage others to come give a talk. Blog about the FOSS
Fair. Tweet about the FOSS Fair. Spread the word. Forward this email.
Also, somebody to man the registration table would be awesome.

See you there!

Securing Puppet

I’m using Puppet’s Environments to separate out domains of control.  Each Environment is cloned from Git repository and starts out with our basic configuration, but each IT group needs the ability to add their own configuration which includes sensitive data that should not be exposed to other groups.

The problem is that Puppet uses x509 certificates to handle identify and authentication very well.  But authorization for specific environments is not present.  So, once one IT team sets up a Puppet client in their environment, there’s nothing to stop them from pointing at a different environment and potentially acquiring another group’s sensitive data. Puppet’s interface is a RESTful API so if you can figure the location of a configuration file its not hard to use the curl utility to fetch it.

I’m using Passenger via Nginx to run the Puppet Master in production.  I’ve recently been growing fond of Ruby and Rack.  Thanks to Google, I found the following presentation for securing and extending Puppet that lead me to learning more about Rack and how to shim in some of my own middleware.

http://rcrowley.org/talks/strange-loop-2010/#1

I starting modifying my config.ru file to implement authorization (with a Z) for environments.  The Puppet REST API always starts out with the environment and makes it easy to use a regular expression to grab.  I have a database of each machine what what access they should have. So I have all the information to determine if you are authorized for a specific environment and now the place to code that in.

This does depend on my Puppet certnames being of the form FQDN-UUID.  Where the UUID is a unique identifier given to each machine.  Makes it very handy to find things in the database.  Below is my config.ru for my Puppet Master.  I hope it might inspire others to extend Puppet for their own needs.

http://linuxczar.net/code/config.ru

 

Nginx and Passenger

I planned to setup an Nginx / Passenger install to run a Rack application.  A Puppet master actually.  I’m setting this up for production usage for a few thousand clients, so Puppet’s built in web server is right out.  It also gave me an oppertunity to learn Nginx which I’ve been meaning to look at for some time now.

I repeat, I’m setting this up for production.  As I was figuring out how to get everything setup I quickly became frustrated with so many sets of instructions to gem install this and passenger-install that.  These tools are great for setting up a development environment, especially as non-root.  But, frankly, I want RPMs.  I want a completely reproducible and automated configuration.  (Why else would I be installing Puppet?)  In fact, once I’m happy with the configuration I will reproduce it on a second server to have a redundant, load-balanced pair.

Fortunately, the folks at Phusion Passenger really want people to use their stuff.  Easily.  In development and production environments.  They support and document many ways to get Passenger installed.  With an extra Yum repository I have complete automation to setup a Rack environment.

I found an excellent blog post about configuring Nginx / Passenger to work with Puppet.  I skipped all the gem install and compiling and started with “Create rack directory structure” about half way into the post. Very handy.

Extending an LVM Volume to Its Max

Unless a System Administrator states a partitioning or LVM layout (which the junior level folks may not be able to do) I use a default layout in their Kickstarts.  It does a basic layout using about 20G and leaving the rest unallocated in a single Volume Group in LVM.  So what’s a common question I get?  You guessed it, how do you resize a volume.  How do you resize it to take up the rest of the available space?

Usually its the volume mounted at / that folks want to enlarge.

lvresize -l+100%FREE /dev/mapper/Volume00-root

The easy part to remember is how to do an on-line resize of that file system.

resize2fs /dev/mapper/Volume00-root

spacewalk-clone-by-date

The Red Hat Network (RHN) and RHN Satellites are part of my daily grind.  They have not always been the easiest to work with when deploying RHEL to a large university with many business, research, and education use cases.

Finally, Red Hat is shipping a tool to help clone RHN channels at a specific point in time and get them right. Pinpointing server to a specific patch set is not my preferred method of maintaining systems, but a lot of people depend on working in that manner.  This tool goes a long way to making that possible.

Altering KVM Virtual Disk Images

I wanted to alter a file that was a disk image for a KVM virtual machine.  With a physical machine I use dd fairly often to save and alter the partition table and boot loader.  I wanted to do that to a KVM image. The problem being that when you use dd to write to a file, when dd is done it truncates the file. So I would lay down a new partition table and boot loader on my KVM image and find the image was now only a few kilobytes long. It used to be 20 gigabytes in size!

To do this we need to use the loop device:

# dd if=/dev/zero of=/var/lib/libvirt/images/foo.img bs=1024 count=20971520
# losetup /dev/loop0 /var/lib/libvirt/images/foo.img
# dd if=/tmp/bar.img of=/dev/loop0

Now you can use fdisk or other tools to examine the hard disk image on /dev/loop0. When you are done, tear down the loopback.

# losetup -d /dev/loop0

Now boot your KVM.

Why do I like to do this? Think about automated ways to install DBan. Or to laydown a gPXE bootloader to reinstall or reprovision the machine.  Fixing a corrupt partition table or MBR.  Doing things this way allows for a high level of automation.