Uncle Deadly Image

Hi there. Welcome to blog.oddbit.com! I post articles here on a variety of technical topics. Mostly I’m posting for myself (writing things up helps me remember them in the future), but I always hope the content I put here is helpful to someone else. If you find something here useful and want to say thanks, feel free to buy me a coffee!

Git fetch, tags, remotes, and more

I’ve been playing around with Git, Puppet, and GPG verification of our Puppet configuration repository, and these are some random facts about Git that have come to light as part of the process.

If you want to pull both changes and new tags from a remote repository, you can do this:

$ git fetch
$ git fetch --tags

Or you can do this:

$ git fetch --tags
$ git fetch

What’s the difference? git fetch will leave FETCH_HEAD pointing at the remote HEAD, whereas git fetch --tags will leave FETCH_HEAD pointing at the most recent tag.

[read more]

Capturing Envoy Data

Pursuant to my last post, I’ve written a simple man-in-the-middle proxy to intercept communication between the Envoy and the Enphase servers. The code is available here.

What it does

As I detailed in my previous post, the Envoy sends data to Enphase via http POST requests. The proxy intercepts these requests, extracts the XML data from the request, and writes it to a local file (by default in /var/spool/envoy). It then forwards the request on to Enphase, and returns the reply to your Envoy.

[read more]

Enphase Envoy XML Data Format

We recently installed a (photovoltaic) solar array on our house. The system uses Enphase microinverters, and includes a monitoring device called the “Envoy”. The Envoy collects data from the microinverters and sends it back to Enphase. Enphase performs monitoring services for the array and also provides access to the data collected by the Envoy product.

I’m interested in getting direct access to the data provided by the Envoy. In pursuit of that goal, I set up a man-in-the-middle proxy server on my home network to intercept the communication from the Envoy to the Enphase servers. I’m documenting the results of my exploration here in case somebody else finds the information useful.

[read more]

Rate limiting made simple

I use CrashPlan as a backup service. It works and is very simple to set up, but has limited options for controlling bandwidth. In fact, if you’re running it on a headless system (e.g., a fileserver of some sort), your options are effectively “too slow” and “CONSUME EVERYTHING”. There is an open request to add time-based limitations to the application itself, but for now I’ve solved this using a very simple traffic shaping configuration. Because the learning curve for “tc” and friends is surprisingly high, I’m putting my script here in the hopes that other people might find it useful, and so that I can find it when I need to do this again someday.

[read more]

Puppet, scope, and inheritance

I note this here because it wasn’t apparent to me from the Puppet documentation.

If you have a Puppet class like this:

class foo {
  File {  ensure  => file,
          mode    => 600,
          }
}

And you use it like this:

class bar {
  include foo

  file { '/tmp/myfile': }
}

Then /tmp/myfile will not be created. But if instead you do this:

class bar inherits foo {
  file { '/tmp/myfile': }
}

It will be created with mode 0600. In other words, if you use inherits then definitions in the parent class are available in the scope of your subclass. If you include, then definitions in he included class are “below” the scope of the including class.

[read more]

Fixing RPM with evil magic

Fixing rpmsign with evil magic

At my office we are developing a deployment mechanism for RPM packages. The general workflow looks like this:

  • You build a source rpm on your own machine.
  • You sign the rpm with your GPG key.
  • You submit the source RPM to our buildserver.
  • The buildserver validates your signature and then builds the package.
  • The buildserver signs the package using a master signing key.

The last step in that sequence represents a problem, because the rpmsign command will always, always prompt for a password and read the response from /dev/tty. This means that (a) you can’t easily provide the password on stdin, and (b) you can’t fix the problem using a passwordless key.

[read more]

Installing CrashPlan under FreeBSD 8

This articles describes how I got CrashPlan running on my FreeBSD 8(-STABLE) system. These instructions by Kim Scarborough were my starting point, but as these were for FreeBSD 7 there were some additional steps necessary to get things working.

Install Java

I had originally thought that it might be possible to run the CrashPlan client “natively” under FreeBSD. CrashPlan is a Java application, so this seemed like a possible solution. Unfortunately, Java under FreeBSD 8 seems to be a lost cause. I finally gave up and just installed Java under Linux.

[read more]

Signing data with ssh-agent

This is follow-up to my previous post, Converting OpenSSH public keys.

OpenSSH allows one to use an agent that acts as a proxy to your private key. When using an agent – particularly with agent forwarding enabled – this allows you to authenticate to a remote host without having to (a) repeatedly type in your password or (b) expose an unencrypted private key to remote systems.

If one is temtped to use SSH keys as authentication credentials outside of ssh, one would ideally be able to take advantage of the ssh agent for these same reasons.

[read more]

Converting OpenSSH public keys

I’ve posted a followup to this article that discusses ssh-agent.

For reasons best left to another post, I wanted to convert an SSH public key into a PKCS#1 PEM-encoded public key. That is, I wanted to go from this:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD7EZn/BzP26AWk/Ts2ymjpTXuXRiEWIWn
HFTilOTcuJ/P1HfOwiy4RHC1rv59Yh/E6jbTx623+OGySJWh1IS3dAEaHhcGKnJaikrBn3c
cdoNVkAAuL/YD7FMG1Z0SjtcZS6MoO8Lb9pkq6R+Ok6JQjwCEsB+OaVwP9RnVA+HSYeyCVE
0KakLCbBJcD1U2aHP4+IH4OaXhZacpb9Ueja6NNfGrv558xTgfZ+fLdJ7cpg6wU8UZnVM1B
JiUW5KFasc+2IuZR0+g/oJXaYwvW2T6XsMgipetCEtQoMAJ4zmugzHSQuFRYHw/7S6PUI2U
03glFmULvEV+qIxsVFT1ng3pj lars@tiamat.house

To this:

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA+xGZ/wcz9ugFpP07Nspo6U17l0YhFiFpxxU4pTk3Lifz9R3zsIsu
ERwta7+fWIfxOo208ett/jhskiVodSEt3QBGh4XBipyWopKwZ93HHaDVZAALi/2A
+xTBtWdEo7XGUujKDvC2/aZKukfjpOiUI8AhLAfjmlcD/UZ1QPh0mHsglRNCmpCw
mwSXA9VNmhz+PiB+Dml4WWnKW/VHo2ujTXxq7+efMU4H2fny3Se3KYOsFPFGZ1TN
QSYlFuShWrHPtiLmUdPoP6CV2mML1tk+l7DIIqXrQhLUKDACeM5roMx0kLhUWB8P
+0uj1CNlNN4JRZlC7xFfqiMbFRU9Z4N6YwIDAQAB
-----END RSA PUBLIC KEY-----

If you have a recent version of OpenSSH (where recent means 5.6 or later), you can just do this:

[read more]

Python ctypes module

I just learned about the Python ctypes module, which is a Python module for interfacing with C code. Among other things, ctypes lets you call arbitrary functions in shared libraries. This is, from my perspective, some very cool magic. I thought I would provide a short example here, since it took me a little time to get everything working smoothly.

For this example, we’ll write a wrapper for the standard statvfs(2) function:

[read more]