Kerberos and LDAP on OpenBSD 6.2

I recently started setting up Kerberos and LDAP for my home network.  While I don’t have a ton of users, it’s handy to be able to centralize account information and do single sign-on.  So far all I really have for clients are a server computer, laptop, and Raspberry Pi, but I find it quite handy even if it was kind of a pain to set up.

I have an older PC in the basement I use mostly when I need to work on the network or some other project and just need to quickly grab a web page or SSH into something.  I had been running Ubuntu Mate on this, since I like the Mate desktop and wanted to give this distro a try.  It ran, but not well.  The desktop was slow,  and it would take a minute to start something like Firefox.  This machine is 3 GHz Pentium 4 dual core with 1 GB of RAM.

I also use OpenBSD on and off, and like it a lot.  Since I was curious about how it does on the desktop I decided to give it a try, using the Lumina desktop environment.  It works well, and it feels noticeably faster than Ubuntu did on this hardware.  Initially I got it going just to get a quick desktop, but then I started thinking about getting it into my Kerberos realm.

This turned out to be a little tricky.  For one thing, OpenBSD uses Heimdal Kerberos, as opposed to MIT Kerberos, which the rest of my setup uses.  For another, doesn’t use PAM, like all (most?) GNU/Linux distros do, as well as FreeBSD.  RedHat’s SSSD is also not present, which has been a godsend on the other platforms.  OpenBSD can authenticate to sources such as Kerberos and LDAP, however, though there isn’t a whole lot floating around online about it (though of course the man pages help out a lot).  There’s also no support for authorization (eg, group information, UID number) for anything besides local files and NIS, which presents a further challenge.

A Quick Little Guide

I thought I’d post this here in cases it helps someone down the line, or in case I have to do this again myself.  🙂  I’ve pieced this together from information found online, as well as man pages.  Note that this doesn’t cover setting up the Kerberos/LDAP server(s), which is another topic on which there are other guides.  I used a combination of this guide for Debian, and this one for Ubuntu (even though my KDC runs Debian).  At the moment the exact details of the setup aren’t terribly important, but you should have some kind of Kerberos/LDAP implementation that authenticates users.

I just want to point out here, that although Active Directory is in fact one Kerberos/LDAP implementation, I don’t really have much experience with it, and this guide will not directly concern it or any peculiarities it may have.  In theory a lot of what you see here should be applicable, and hopefully it will be helpful.  In my travels I found this, which may be helpful if that’s what you’re trying to do.

Aside from the server, you should obviously have an OpenBSD system you want to have as your authentication/authorization client.  Have some test users kicking around helps too, both some local users on your OpenBSD system as well as a couple configured in Kerberos/LDAP to test authentication there.

I’m using OpenBSD 6.2, i386, but I think this should work on other platforms as well(?), particularly amd64.  Now a word of caution: this guide requires modifying some system files.  I myself screwed up at one point, causing my system to boot but not allow anyone to log in.  I recommend not only making backups of relevant files, but also reading a bit about single user mode.  Take a look at the root password reset guide in the OpenBSD handbook; you can also use single user mode to fix system files.  For running an editor, you may also want to take a look at this if you get any errors in single user mode.

Kerberos

First, we’ll install Kerberos, which will handle authentication.  That is, this will check a user’s password and verify they are who they say they are.  I assume that you have a realm, EXAMPLE.COM, with a KDC/admin server kerberos.example.com.

Note that in this guide, in a code snippet meant to be run at the command line, # indicates the root prompt.  However, in a file, # will indicate a comment.

To start, we’ll need to install some packages.  From the command prompt:

# pkg_add heimdal heimdal-libs login_krb5

Next, you’ll want to modify your path so that you actually have access to the different Kerberos tools.  In .profile, look for that PATH line and add /usr/local/heimdal/bin like this:

PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/sbin:/usr/local/bin:/usr/local/heimdal/bin

You may want to make the same modification in /etc/skel/.profile, so that it’s propagated to new users.  Next, modify /etc/rc.conf.local and add teh shlib_dirs line.  I had made other modifications in setting up my desktop, so for me that file now looks like this:

portmap=YES
portmap_flags=
shlib_dirs=/usr/local/heimdal/lib
xenodm_flags=

The reason for that is that Heimdal is installed under /usr/local/heimdal, which is also where its shared libraries are.  This tells the rest of the system where they are.  (You may have to reboot after saving this change.)

Next, we’ll start putting in some Kerberos details.  In the file /etc/kerberos/krb5.conf, modify it to reflect your situation (ie, your own realm and kdc/admin server):


# $OpenBSD: krb5.conf,v 1.1 2014/07/13 14:10:13 ajacoutot Exp $
#
# See krb5.conf(5) and the heimdal info(1) page for more information.

[libdefaults]
# local realm(s)
default_realm = EXAMPLE.COM

[realms]
EXAMPLE.COM = {
# list of KDC(s) for this realm
kdc = kerberos.example.com

# admin server for this realm
admin_server = kerberos.example.com

default_domain = EXAMPLE.COM

}

[domain_realm]
.EXAMPLE.COM = EXAMPLE.COM

[kadmin]
# default salt string
default_keys = v5

[logging]
# log to syslog(3)
kdc = SYSLOG:INFO:DAEMON
kpasswdd = SYSLOG:INFO:AUTH
default = SYSLOG:INFO:DAEMON

By this point you should be able to use tools like kinit, klist, etc. on the OpenBSD client.  What we want to do now is set up a host principal for this machine, and a keytab for it.  At this point, I would like to mention that I had a problem with this on OpenBSD: normally I create the principal by logging into my KDC, then creating the principal in kadmin, then logging into the client and running kadmin as root.  Because of the krb5.conf configuration, you basically use kadmin to copy the principal from the KDC to the local keytab.  Unfortunately, when I tried to do this from my OpenBSD machine it hung.  I’m not sure what was going on, or if it was some kind of Heimdal vs MIT Kerberos issue, but I ended up having to copy the keytab over manually.

Log in to your KDC, and run the following.  Note that in the addprinc command I have the -x dn=”uid..” line – this is because my KDC uses LDAP as its backend (not just for authorization), and I keep the principal with other information about that computer.  (See the Ubuntu guide I linked earlier for more information.)  You can leave that out if you don’t do this.

The session should look something like this (again, my KDC is running MIT Kerberos):

root@kerberos:~/kdc# kadmin -p kerberosadminuser
Authenticating as principal kerberosadminuser with password.
Password for kerberosadminuser@EXAMPLE.COM: 
kadmin: addprinc -randkey -x dn="uid=openbsdclienthostname$,ou=computers,dc=example,dc=com" host/openbsdclienthostname.example.com
WARNING: no policy specified for host/openbsdclienthostname.example.com@EXAMPLE.COM; defaulting to no policy
Principal "host/openbsdclienthostname.example.com@EXAMPLE.COM" created.
ktadd -k /path/to/some/file.keytab host/openbsdclienthostname.example.com@EXAMPLE.COM
quit

The above copies the host principal to /path/to/some/file.keytab, which you need to then transfer to the client – rename it to /etc/heimdal/krb5.keytab.  Transfer it using a secure method, like SSH or a thumb drive.  Assuming you put it in /root:

# mv /root/file.keytab /etc/heimdal/krb5.keytab
# chown root:wheel /etc/heimdal/krb5.keytab
# chmod 600 /etc/heimdal/krb5.keytab

At this point, you should be able to get a Kerberos principal yourself:

# klist
klist: No ticket file: /tmp/krb5cc_0
# kinit krbuser
krbuser@EXAMPLE.COM's Password: 
# klist
Credentials cache: FILE:/tmp/krb5cc_0
 Principal: krbuser@EXAMPLE.COM

Issued Expires Principal
Mar 4 15:48:38 2018 Mar 5 15:48:38 2018 krbtgt/EXAMPLE.COM@EXAMPLE.COM

Next, we want to be able get that principal when we log in.  Earlier, we installed login_krb5, which will do this (along with of course letting us log into the system without a passwd entry).

Edit /etc/login.conf, and look for the default:\ section as shown below:

default:\
:path=/usr/bin /bin /usr/sbin /sbin /usr/X11R6/bin /usr/local/bin /usr/local/sbin:\
:umask=022:\
:datasize-max=512M:\
:datasize-cur=512M:\
:maxproc-max=256:\
:maxproc-cur=128:\
:openfiles-max=1024:\
:openfiles-cur=512:\
:stacksize-cur=4M:\
:localcipher=blowfish,a:\
:auth=-krb5-or-pwd:\
:tc=auth-defaults:\
:tc=auth-ftp-defaults:

The line to add is “:auth=-krb5-or-pwd:\” just above “:tc=auth-defaults:\”.  This line allows you to use Kerberos as a login mechanism, but falls back to checking local files if that fails.

This should be about it – you can test authentication to a Kerberos account, but note that we don’t have authorization.  In other words, the system still has to look to local files for things like user and group information.  To test now, create a local account with a home directory, group, etc. in OpenBSD (as root):

# useradd krbuser

Follow the prompts that come up.  The password doesn’t really matter, just use something different than what you set up for the Kerberos principal.  Then, log in to the console as that user using the Kerberos principal’s password.  After logging in, you should be able to run klist and see that user’s principal.  (If you get a “Command not found” or similar error, make sure that /usr/local/heimdal/bin is in your path, see above.)

LDAP

Assuming you got the Kerberos part working, now might be a good time to take a break, get a fresh coffee, etc.

As I mentioned before, LDAP is used for authorization, that is user info like groups, login shells, etc.  Unfortunately, OpenBSD doesn’t actually support using LDAP for authorization, only Network Information System (NIS, aka YellowPages or yp, which most of the tools are named for).  Luckily, there’s a translator we can use that comes with the base system, ypldap.  This basically makes the LDAP directory look like a YP (NIS) server.

I couldn’t find much online about using this with OpenBSD 6.2, but I think I got it working.  I found two pages on this, both of which are older.  Both of these start by talking about login_ldap, which I ended up installing, but which isn’t really needed.  That’s if you want to authenticate to LDAP (ie, if that’s where you’re storing your passwords).  In our case, that’s already taken care of by login_krb5.

To start, create /etc/ypldap.conf.  I recommend copying the example:

# cp /etc/examples/ypldap.conf /etc/ypldap.conf

There is another caveat – on my Linux clients, I use GSSAPI with the host principal to authenticate to the LDAP database.  On OpenBSD, ypldap does not support this (that I could tell).  This means you’ll need a user that can just bind to LDAP by itself, for instance using the userPassword attribute.  This user needs to be able to read through your directory to get user/group information.  Also, while I don’t have it set up here, you should probably be using SSL/TLS with your LDAP server.

Now, edit this file like the following (I’ve added some of my own comments) to reflect your own setup:

# $OpenBSD: ypldap.conf,v 1.1 2014/07/11 21:20:10 deraadt Exp $

domain "example.com" #This is just the name of your realm
interval 120 #How often to pull data from the LDAP database, in seconds
provide map "passwd.byname"
provide map "passwd.byuid"
provide map "group.byname"
provide map "group.bygid"
provide map "netid.byname"

directory "kerberos.example.com" { #This is the machine hosting your LDAP directory
# directory options
binddn "uid=openbsdclienthostname$,ou=computers,dc=example,dc=com" #User to bind to LDAP as
bindcred "mypassword" #Password for above user
basedn "dc=example,dc=com"
# starting point for groups directory search, default to basedn
groupdn "ou=groups,dc=example,dc=com" #Change to reflect your setup

# passwd maps configuration (RFC 2307 posixAccount object class)
passwd filter "(objectClass=posixAccount)"

attribute name maps to "uid"
fixed attribute passwd "*" #Can leave this as is, we check passwords with Kerberos
attribute uid maps to "uidNumber"
attribute gid maps to "gidNumber"
attribute gecos maps to "cn"
attribute home maps to "homeDirectory"
attribute shell maps to "loginShell"
fixed attribute change "0"
fixed attribute expire "0"
fixed attribute class ""

# group maps configuration (RFC 2307 posixGroup object class)
group filter "(objectClass=posixGroup)"

attribute groupname maps to "cn"
fixed attribute grouppasswd "*"
attribute groupgid maps to "gidNumber"
# memberUid returns multiple group members
list groupmembers maps to "memberUid"
}

Next, we configure the YP client.  I recommend taking a look at the relevant page in the FAQ, for reference.  Since we basically just set up an YP server, we want to tell the client where to find it:

# echo 'example.com' > /etc/defaultdomain
# echo '127.0.0.1' > /etc/yp/example.com

To have the system use the YP client, make the following changes to /etc/master.passwd and /etc/group:

# echo '+:*::::::::' >> /etc/master.passwd
# pwd_mkdb -p /etc/master.passwd
# echo '+:*::' >> /etc/group

The first line sets the YP domain, while the second tells the YP client to look to our own host for the server (ypldap).  Next, enable some services:

# rcctl enable portmap
# rcctl start portmap
# rcctl enable ypldap
# rcctl start ypldap
# rcctl enable ypbind
# rcctl start ypbind

In some of the other guides online, it was said that you had to edit /etc/rc.local to make sure that ypldap starts before ypbind.  For 6.2, I didn’t have to do this.

Now, you can reboot and check to make sure you have the above running:

# ps aux | grep yp
_ypldap 3982 0.0 0.1 540 1488 ?? Ip 4:55PM 0:00.01 ypldap: dns engine (ypldap)
_ypldap 85354 0.0 0.2 584 1608 ?? Ssp 4:55PM 0:00.01 ypldap: parent (ypldap)
_ypldap 56536 0.0 0.2 628 1600 ?? Ip 4:55PM 0:00.01 ypldap: ldap client (ypldap)
root 23124 0.0 0.1 384 960 ?? Ss 4:55PM 0:00.00 /usr/sbin/ypbind

You can also test lookup up user information using the id command:

# id krbuser
uid=5555(krbuser) gid=5555(krbuser) groups=5555(krbuser)

In the above, 5555 would be whatever uid/gid you set it up for.  (If you have the user from before, the one which was using the local OpenBSD files, you may want to use a different one to make sure you’re actually pulling from LDAP.)

Next test logging in with a Kerberos/LDAP user from the console.  Note that I did not look into creating users’s home directories automatically, so you’ll have to do that yourself.  (If I figure this out, I’ll post it, or if someone else knows, feel free to comment.)

Final Remarks

I like OpenBSD a lot, but this was kind of a pain.  Actually, it was a good learning experience, and it’s good to know that it’s possible.  I got to learn a little more about the internals, and once I started looking into it it wasn’t too bad, just different from what I’d been used to on Linux.  Let me know if you have any trouble with this, or if I missed anything (I’m putting this down partly from memory, after working on it on and off over a couple weeks.).

I did not manage to get Kerberized SSH working, that is being able to SSH to/from the OpenBSD client without entering a password.  I think this is because the builtin sshd doesn’t support it.  This might be something that could be changed by recompiling it, I’ll have to look into it in the future.

Posting from Hurd!

Nothing’s really occured to me to post in a while, so here’s something kind of random.  I’m actually posting this from GNU/HURD (specifically, the Debian distribution).  I played around with it, installed some software, and eventually got Xorg and Mate running, and then Midori:

Midori on a GNU/Hurd desktop.
Even Midori was kind of sluggish, but it was usable until it crashed.

So how is it?  Slow, for one thing.  Not terribly while just using the terminal, but the install process took hours.  The installer is the basic Debian installer, but things like copying files to the hard drive took longer than it seems like they would under GNU/Linux.  The same is true of just installing packages.  The desktop is of course noticeably sluggish as well, although using something like Openbox might improve things here.  This machine is an old Dell Optiplex, with a 1.6 GHz P4 and 2 GB of RAM (only 768 MB were picked up according to htop).  The graphics are Intel, which I think requires a kernel module on Linux, which of course isn’t supported here.  This probably explains the X slowness, but otherwise while this machine is old it’s felt faster on other OSes.

As far as applications, there are quite a few Debian packages ported over, and while not everything works very smoothly (I tried getting Apache and PHP going, only to have mod-php give an error about allocating shared memory) a lot of familiar programs are available and do run.  I dare say that there’s enough here to run an almost-functional desktop, although there is no sound or USB support (although keyboards/mice may work due to BIOS emulation).

So what’s the point of it then?  The concept of HURD, as in how it runs on top of a microkernel, is interesting.  Basically, this means that most of the services provided are run as a set of servers in userspace on top of a very minimal kernel (Mach in this case).  This is in contrast to Linux, in which these are all part of the kernel.  So, a fault in one of these servers doesn’t necessarily bring down the entire operating system.  In fact, these programs don’t even have to run as root.  This modularity may not be that much of a big deal on a normal desktop or server, considering how mature monolithic kernels like Linux are these days, but one could imagine an embedded or remote system where this could be desirable.  (Think some diagnostic that restarts one of the servers should it crash, so your entire space probe doesn’t have to reboot.)  Some other interesting features in GNU/HURD are the ability for a process to have more than one UID associated with it, as well as translators, which can expose things as part of the filesystem.  (For example, they can be used to mount an FTP share on a directory, similar to Fuse.)

I’m probably not going to be installing a GNU/HURD desktop on my main computer anytime soon.  In fact, I would guess that most people won’t be.  (There are probably exceptions, like people who work on GNU/HURD.)  For day-to-day use, it’s similar enough to a normal Debian (in this case, there are other HURD distributions) system that it’s not really worth the effort compared to the ease of the mainstream alternatives.  However, I’ll be keeping an eye on this project now and then.  Of course, there aren’t many people working on it compared to say Linux, so development isn’t exactly snappy.  But, depending on how it matures it could hold promise in some applications.  (Again I’m thinking of embedded systems.)

It’s also nice to have alternatives.  This is part of the reason I use GNU/Linux, and experiment with other OSes.  Even if HURD really isn’t ready now, it can actually be somewhat useable.  So, I consider it worth checking out, if only as an educational experience.  (And hopefully not as a cuationary tale.)

Easytether and Networkmanager

Easytether is a nice application you can use to tether your Android phone regardless of restrictions put in place by your carrier.  It consists of an app for the phone, as well as a program you run on your computer.  The two then talk to each other using the phone’s USB debugging abilities (ie, through ADB, which is integrated).  On the computer-side, Linux, Windows, and OS X are supported, and you can even use it with a Raspberry Pi.

I use this to occasionally tether my laptop, which runs Xubuntu.  On GNU/Linux, the PC-side application works by creating a tun (virtual) interface.  You start it from the command line like this ($ indicating the command prompt):

$ sudo easytether-usb

When I first did this (must have been a few years ago), Networkmanager would immediately detect the interface and manage it, so I didn’t really have to do anything else.  As soon as I started the program, I’d have a network connection.   This does not work with Xubuntu 16.04, however – the interface comes up, but I have to configure it manually.  No big deal, but now after running the above I have to do this:

$ sudo dhclient easytether-tap

Or this instead of dhclient, to do it manually:

$ sudo ifconfig easytether-tap 192.168.117.2
$ sudo route add default gw 192.168.117.1$ sudo sh -c ‘echo “nameserver 8.8.8.8” >> /etc/resolv.conf’

That works fine, but it’s kind of a pain.  Networkmanager is fairly capable these days, and it would be nice to make it do some of this for us again.  The reason it doesn’t is that, with the current version (1.2.0-0ubuntu0.16.04.2 on this machine), virtual interfaces that it didn’t create itself are ignored by default.  Luckily, there is a way we can make a new connection and automate things.  Unfortunately, this doesn’t seem to be possible with the panel applet in Xubuntu, but we can do it from the command line using nmcli.

In the above lines, easytether-tap is the default name of the virtual interface that the PC application creates.  First, let’s create a new connection named ‘phone’ that uses this interface.  Then, we’ll add a DNS server.  (Note that the below lines can be done as a normal user, no sudo needed.)

$ nmcli connection add ifname easytether-tap con-name phone type tun mode tap ip4 192.168.117.2 gw4 192.168.117.1
$ nmcli con mod phone +ipv4.dns 8.8.8.8

You could of course name it something other than phone.  Note that that configures the interface manually, which I just did for simplicity.  Also, 8.8.8.8 is Google’s public DNS, and you could substitute a different server IP.  Now, assuming you have easytether-usb started like in the first command in this post, you can bring the interface up like this:

$ nmcli connection up phone

And then bring it down like this:

$ nmcli connection down phone

And that’s it!  But, we still have to start easytether-usb when we plug the phone in.  It’s possible to automate that, too, using Networkmanager’s dispatcher scripts.  I created the following script, and saved it as 90easytether.sh:

#!/bin/bash

IFACE=$1
STATUS=$2

if [ “$IFACE” == “easytether-tap” ]
then
case “$STATUS” in
pre-up)
logger -s “Starting easytether-usb daemon”
easytether-usb
;;
down)
logger -s “Stopping easytether-usb daemon”
killall easytether-usb
;;
esac
fi

Now, move the script into the dispatcher.d directory, then change the ownership and permissions, and create a symlink to the script in the pre-up directory:

$ sudo mv 90easytether.sh /etc/NetworkManager/dispatcher.d/
$ cd /etc/NetworkManager/dispatcher.d
$ sudo chown root:root 90easytether.sh$ sudo chmod 755 90easytether.sh
$ cd pre-up.d/
$ sudo ln -s /etc/NetworkManager/dispatcher.d/90easytether.sh ./

Now, we need to start the dispatcher service, an enable it on boot:

$ sudo systemctl start NetworkManager-dispatcher.service
$ sudo systemctl enable NetworkManager-dispatcher.service

I also found I needed to restart Networkmanager itself:

$ sudo systemctl restart network-manager.service

Basically, that script is triggered by the pre-up and down actions, and starts and kills easytether-usb for us.  The symlink was necessary because Networkmanager needs anything that acts on this to be in the pre-up.d directory.  Now, you plug in your phone, then use the nmcli commands from above to bring the interface up and down, and that’s it!

One caveat: You need to be able to use USB debugging on your phone.  Also, you may have to confirm on your phone that you want to be able to connect from your PC or laptop first.  I also find that I have to mount my phone (IE, click on the icon on the desktop and browse to it in the file manager) before easytether-usb will connect.  Make sure you get Easytether working manually like at the beginning of this post, and you should be fine.  Have fun!

OwnCloud Client Won’t Remember Account…

I use ownCloud on a few of my machines for keeping some folders synced via the desktop syncing client.  I’m fairly happy with it, at least for smaller files like documents and pictures.  (Part of this is because I’m running the server on a Raspberry Pi, which is a little slow, but for my purposes works fine.)  Recently, however, I ran into a problem with  version 1.8.1 of the desktop client, running on a laptop with Xubuntu 15.10.  Basically, every time I started the  client it would ask me for my username, password, and folder list, as if I were configuring it for the first time.  This happened when just logging in (when I have it set to start automatically), or if I killed it and restarted it.

The fix turned out to be relatively simple.  First, the desktop client stores its configuration files (on Linux) here:

$HOME/.local/share/data/ownCloud/

In that directory I found the following:

cookies.db folders owncloud.cfg socket

But when I tried to display the file owncloud.cfg, I got an Input/Output error.  I could list the folders directory; this just contained a file with conf info for each of the folder I sync.  On a hunch I deleted owncloud.cfg, and restarted the client.  It asked for my login information again, and then I told it to skip the folder configuration.  It worked, and even picked up the folders I had set up to sync (as those configuration files were readable).  I’m not sure what caused this, but after doing this I can view the new owncloud.cfg file that was created.

Hopefully this save someone some time.  It’s a little aggrivating  that I did have to poke around in the terminal, but not too bad – at least it’s possible.  I’m not sure if this could be a bug in the client, but if this happens again I’ll reevaluate.

Inverters and Isolation

Take a look at the picture blow, of a 400 watt inverter I garbage picked a while ago:

Common mode voltage on the inverter output.

The inverter is running off a 12 volt battery, and is switched on.  Notice anything interesting, particularly with how the meter is connected and what it’s reading?  (You may have to click to embiggen, so you can see the display.)

The meter is connected between the negative (black) battery post, and one of the legs of the 120 volt output, and is reading about 67 volts AC.  This works between that post and either leg of the output, as well.  Going between the two legs gives 117 volts, which is the output we want.

So what’s going on here?  The problem has to do with grounding and isolation.  Inside the inverter, there’s a circuit that looks something like this:

Simple H-bridge inverterThat’s an H-bridge, a switching arrangement that lets you supply a load (on what I have labeled here as the AC out wires) with either normal or reversed polarity, or none at all.  This is very simplified; you’d want to drive the switches (MOSFETs in this case, could be something else like an IGBT) with some sort of switching scheme of some sort.  However, this is the basic mechanism by which the inverter makes alternating current.  (There are other ways to do this, including one with just two switches, but this is the basic idea.)

Notice the ground symbol on the low-side of the H-bridge?  That’s our problem – imagine that the MOSFET just above it (the lower left-hand one) is on, as is the one diagonal from it in the upper-right.  The other two are off.  If we measured between the AC out leg from the left-hand side of the bridge to the ground node, we’d see 0 volts, because it’s the same node – the transistor shorted that leg to ground.  But, milliseconds later (about 8.3 if we’re at the beginning of the cycle) the transistors switch – now, that same leg of the AC out is at the voltage of the DC source (could be battery voltage, or could be from a DC-DC converter), and that’s what we’d read on the meter.  It would be in this state half the time, and with the meter set to AC voltage we’d read something like the 67 volts in the first picture.  The AC output is floating with respect to the ground point.

The problem, then, is if at any point in your AC wiring the ‘neutral’ conductor is tied to ground, and that ground is also tied to Battery-, you have a short-circuit path!  This depends on the design of the inverter as far as whether or not it’s a pure short circuit (the DC source would have some impedance to it, so it might not necessarily be like a dead short on the battery), but it could still damage your inverter.  Not to mention that having a voltage between Battery- and the AC neutral or ground would be a safety hazard.

So, how much of a problem is this, really?  Well, in the picture the inverter is running a laptop charger, which is encased in plastic and I think actually provides isolation between its input and the laptop.   So, here I’m not worried about it.  However, say you wanted to provide some backup power to your house in a power failure.  It’s not uncommon for people with a generator to backfeed their circuit breaker panel (either with into a normal outlet with an aptly-named suicide cable or with a proper receptacle and transfer switch).  So what if we did this with this inverter instead?

In the US homes typically have the neutral and ground bonded together in the circuit breaker panel.  Now, say you have a little system with some solar panels and a big battery to run the inverter, and you happen to have the negative side of the battery grounded on a watter pipe in your basement, or maybe even the ground wire in your house wiring…  Even if you drive in a separate ground rod for the DC side, you’ll wind up with a current path, and a potential safety issue.

Now, a 400 watt inverter is a little small for backing up your whole house, but there are larger, cheapy inverters like this one that probably have a similar design.  If you find a 2000-3000 watt inverter at your local hardware store for a few hundred dollars, this is probably the case.

So, how can this be fixed?  Take a look at this update to the schematic from above:

Inverter with a transformerNotice that there’s a transformer on the output of the bridge – now the AC output is isolated from the DC side!  So you can use the same ground on the DC and AC sides.  There isn’t an electrical connection, there’s a magnetic one, so we just transfer the energy across.  There is a small section where the AC is floating, but it can be safely enclosed in the inverter chassis, and insulated appropriately.  Of course, there are other solutions; the DC source could be fully isolated itself, and the low-side of the H-bridge could remain ungrounded.  This way you could still reference the output to the inverter’s DC input safely.

You could also get an isolation transformer and put it between the inverter and your loads.  This would solve the problem, but would give you a little drop in efficiency – it’s not the same as if the transformer is designed into the inverter.  Also, the cheap inverters that don’t isolate input from output tend to be modified sine wave (really modified square wave), and so could cause an off-the-shelf isolation transformer to run with even less efficiency.  (A true sine wave inverter could also have this problem; the difference is in how the switching is done.  But, a lot of high-end sine wave inverters tend to take the isolation problem into account, it seems.)

On another note, those working with renewable energy will tell you that building a solar power system just for the off chance your grid power is out for a few hours a few times a year isn’t very economical.  This is true, but I imagine that there are people out there who will think of attaching a big, cheap inverter to their home’s wiring, which is why I threw this together.  The moral of the story is, if you’re going to distribute the AC from your inverter in a more complex fashion than an extension cord and power strip, check for voltage between each AC leg and the negative DC input.  If you’re looking at buying an inverter, see if you can go to the store and try this with a multimeter.  Or, call the manufacturer, and see what they say about hardwiring it.  If it’s designed to be wired into an electrical system, there’s a good chance they’ve thought of this problem.

Second Post!

Somehow, I had expected to post here a few more times this year, not sure what I was thinking.  But, better late than ever.  Now for something Halloween-related:

IMG_7560

And here’s a picture in the light:

IMG_7558Good-sized pumpkin, and I also made sure to save the seeds:

IMG_7557Basically, you pick the seeds out of the pumpkin guts and rinse them out well.  Then you can let them dry for about a week, and save them in an envelope.  I’ve got the ones above from the big pumpkin, as well as some from a smaller one.  I’m not sure I’ll have the space to plan them in the spring, as they do kind of take over, but I’ll see.

Anyways, I mentioned an homebrew inverter project before.  I’m still tossing this around, but I think I’ve thought of a way to simplify part of it.  More information will come, sometime.

In the mean time, Happy Halloween!