Using Puppet + Augeas to turn off usb ports

no usb

Augeas and Puppet can team up to modify the modprobe config files

My blog posts always seem to start with a question asked on stackexchange or ask.puppetlabs.com. This is no exception.

Danilo asked if puppet was able to block access to usb ports on linux machines. I decided to flex the Augeas muscle.

 

tl;dr Here is a working solution

class blockusb {

   augeas {'block usb-storage':
    context   =>"/files/etc/modprobe.d/blacklist.conf/",
    changes =>["set blacklist[last()+1] usb-storage",],
    onlyif =>"match blacklist[.='usb-storage'] size == 0 ",
  }
}
include blockusb

 

The match functionality in augeas is very non intuitive. Instinct would suggest that the following solution should work:

onlyif =>"match blacklist not_include 'usb-storage' ",

However as pointed out by Dominic in the user list, match returns a list of paths, not the values of those paths.  While you *can* see the values of the path when using augtool from the command line, those values are not included in Augeas’s API call.

 augtool> match /files/etc/modprobe.d/blacklist.conf/blacklist
/files/etc/modprobe.d/blacklist.conf/blacklist[1] = evbug
/files/etc/modprobe.d/blacklist.conf/blacklist[2] = usbmouse
/files/etc/modprobe.d/blacklist.conf/blacklist[3] = usbkbd
....
/files/etc/modprobe.d/blacklist.conf/blacklist[16] = amd76x_edac
/files/etc/modprobe.d/blacklist.conf/blacklist[17] = usb-storage

 

By requesting the actual usb-storage value in the tree and then checking it’s length we are able to return a boolean. The result is that puppet will only modify the blacklist.conf file once.

 

Share single .bashrc across multiple linux machines

Often I manage many servers and find myself wishing I had the same shortcuts available on my workstation, also present on the server.

Normally I’d use puppet to manage the .bashrc or .bash_profile, but my workstations don’t have a puppet master. To work around this, I store my .bash_profile on github, and have a script to update it automatically.

Here is the script to update my bash_profile

    #!/bin/bash
       curl -L https://gist.github.com/spuder/11360474/raw/ > ~/.bash_profile

https://gist.github.com/spuder/11360474

The actual bash profile is located here

    alias ls='ls -G'
    alias sl='ls -G'
    alias up='cd ..'
    alias redo='sudo \!-1'
    alias sdou='sudo'
    alias suod='sudo'
    alias sodu='sudo'
    alias tailf='tail -f'
    # Open sublime text editor with command subl
    if [ ! -f /usr/local/bin/subl ]; then /bin/ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/local/bin/subl; fi;

https://gist.github.com/spuder/11360447

Now on every machine I manage, I run the following command just once

    curl -L https://gist.github.com/spuder/11360474/raw/ | bash -x

After that, I can just execute the bashupdate alias to pull down the latest version.

    spuder@Spuders-MacBook-Pro:~$ bashupdate

Open a new terminal, or source your ~/.bash_profile and you will instantly have the new changes. Pretty slick right?

Recovering from lost git commit messages

I posted a question and answer to stack overflow that explains how to undo the dangerous -c flag in git. 

 

http://stackoverflow.com/questions/22768695/how-do-you-undo-a-mistakenly-overwiten-git-commit-message

If ever you accidentially overwrite a commit message using git commit –amend, you can easily undo it by search the .git/logs directory. There will still be a hash that points to the previous object which will contain the original message. 

 

 

git pre-receive hooks.

In my attempts to block users from committing code as root users which I mentioned in my previous blog post; I’ve identified an unusual behavior in git.

 

Git pre-receive hooks do not have any parameters passed in, but rather query stdin for parameters.

To demonstrate, create the following file on your git server

some_repository/.git/hooks/pre-receive

set -x

echo "$# parameters have been passed in"

 

Then try and push code

 

spencer@workstation:/tmp/hooktest3$ git push
Counting objects: 11, done.

Delta compression using up to 4 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (9/9), 731 bytes | 0 bytes/s, done

remote: + echo '0 parameters have been passed in'

The correct way to evaluate the incoming commit is with

read
some_repository/.git/hooks/pre-receive

while read oldsha newsha refname; do
    case $oldsha,$newsha in
    *,$NULL_SHA1) # it's a delete
        echo "delete request received";;
    $NULL_SHA1,*) # it's a create
       echo creating $newsha";;
    *,*) # it's an update
        echo "updating with $newsha";;
    esac
done

So why is this important?
This is the only way to parse an incoming git commit. You can then evaluate the commit to see who the author is, what type of commit ect..

Thanks go to torek for pointing this out on my stack overflow question here: http://stackoverflow.com/questions/22546393/can-git-pre-receive-hooks-evaulate-the-incoming-commit/22547375?noredirect=1#comment34541940_22547375

Changing the author on git commits

Some of the users at my company have been accidentally creating and pushing git commits as the root user.

Image

While trying to setup a script to block these commits, I found an interesting quirk of git.

Many guides online suggest amending the git author like so:

git commit --amend --author

This unfortunately only changes the author, and not the committer. To prove this I created the following test.

Set the user name and email

git config user.name "bad user" --replace-all
git config user.email "bademail@localhost.com"

Now make a commit and check the  output of git log.

git log
commit bf4343f6a41978ef5c1236c558aeab9415d17601
Author: bad user <bademail@localhost.com>
fooy

Change the author

git commit --amend --author "good guy <goodguy@aol.com>"

Check the full output of the last commit. You will notice that while the author is correct, the committer is incorrect.

git log --format=full
commit 52ee52afde053b5c2102760011359dd4ad7fea47
Author: good guy <goodguy@aol.com>
Commit: bad user <bademail@localhost.com>

fooy

The correct way to change the author *and* the committer is with the following command:

git config user.name "good guy" --replace-all
git config user.email "goodguy@aol.com"

git commit --amend --reset-author

Now everything works properly

commit 52ee52afde053b5c2102760011359dd4ad7fea47
Author: good guy <goodguy@aol.com>
Commit: good guy <goodguy@aol.com>

fooy

Navigate linux ‘info’ command

The command ‘info’ can provide additional information that isn’t present in the man pages. Unfortunately it isn’t easy to navigate.

A trick is learned is to add the following to your ~/.bashrc file


function infos () {
info --vi-keys --subnodes -o - "$@" | less;
}

Now you can call infos (with an s), to be able to navigate the info page.

Example

$ infos ls

Thanks to Evan Teitelman for pointing this out on unix.stackexchange

http://unix.stackexchange.com/questions/82357/what-do-the-symbols-displayed-by-ls-f-mean

Setting up puppet board with Apache

PuppetDB appears to be the way of the future. By leveraging PuppetDB, some enterprising individuals have written a web interface that knocks the socks off of the regular puppet dashboard. It is called puppetboard

Clean and elegant – puppetboard

View of a node

Puppetboard with Apache

Normally puppet board requires Passenger. Here is how to configure puppet board to work with Apache instead.

You can install puppet board on cent with apache using the mod_wsgi plugin

Clone & install  puppetboard

git clone https://github.com/nedap/puppetboard.git /var/www/puppetboard
sudo yum install python-pip
Install mod_wsgi yum install mod_wsgi.x86_64

(You can see what was installed with the following)
rpm –query –list mod_wsgi.x86_64

Verify that /etc/httpd/confi.d/wdgi.conf exists and has the following content

LoadModule wsgi_module modules/mod_wsgi.so

Add a vhost to /etc/httpd/

$sudo vim /etc/httpd/conf/httpd.conf
<VirtualHost *>
 ServerName foo.bar
WSGIDaemonProcess puppetboard user=apache group=apache threads=5
 WSGIScriptAlias / /var/www/puppetboard/wsgi.py
<Directory /var/www/puppetboard>
 WSGIProcessGroup puppetboard
 WSGIApplicationGroup %{GLOBAL}
 Order deny,allow
 Allow from all
 </Directory>
 </VirtualHost>

 Restart Apache
 sudo apachectl -k stop
 sudo /etc/init.d/httpd start

If you are running CentOS/RHEL You get the following errors, it is because the WSGI root path is incorrect.

[Fri Jan 03 16:53:13 2014] [error] [client 10.1.5.231] (13)Permission denied: mod_wsgi (pid=2029): Unable to connect to WSGI daemon process 'puppetboard' on '/etc/httpd/logs/wsgi.2024.0.1.sock' after multiple attempts.

Solution
Add this to /etc/httpd/conf/httpd.conf *before* the vhost

WSGISocketPrefix ../../var/run/wsgi

Restart Apache and puppet board should be installed

Additional Resources

https://uwsgi.readthedocs.org/en/latest/Configuration.html

https://groups.google.com/forum/#!topic/modwsgi/UmNPV-2nQMM

https://www.digitalocean.com/community/articles/how-to-set-up-apache-virtual-hosts-on-centos-6

https://code.google.com/p/modwsgi/wiki/ConfigurationIssues

https://code.google.com/p/modwsgi/issues/detail?id=291

Follow

Get every new post delivered to your Inbox.