Hi, I'm Chris Moyer's Blog.

Peace of Mind, Moving /etc into Subversion

Having recently moved my various projects to a virtual private server1, I've been spending a fair amount of time mucking about in various files under /etc. Being a programmer, and not a sysadmin, at heart, I have a tendency to make my edits and test them out in a rapid-fire fashion. Most of the time, this is fine, I don't run any high availability services and am fairly careful. But, it does occasionally leave me wondering why or how I changed something… and how to put things back the way they were.

Being a programmer, I tend to live and breathe in version control, so my first thought was to version my config files. My primary concerns were twofold:

  • Security. I don't want to accidentally expose my /etc directory to the world via the anonymous subversion server I run for projects.
  • Breakage. I know many programs (well, at least sshd) are picky about the permissions and ownership of their config files, and didn't want to break things by managing to munge them all.

In my previous usage of subversion, the process of importing a new project has gone something like:

> svn import -m"Initial commit of project foo" foo file:///opt/svn/trunk/

> mv foo foo_back

> svn checkout file:///opt/svn/trunk/foo

> # look around, make sure everything is OK

> rm -rf foo_back

My concern with this was with the process of checking out a whole new copy, worried that the permissions and ownership would change. I understand that subversion is supposed to preserve permissions, but was still concerned. As far as security, it decided to simply create a whole new repository, owned and readable only by root (and outside the path served by svnserve). A short bit of googling later led me to the Subversion FAQ's “How can I do an in-place ‘import'”. The process turned out to be entirely painless:

> sudo svnadmin create /opt/svn_etc

> cd /opt

> sudo chmod -R go-rwx svn_etc/

> svn mkdir file:///opt/svn_etc/etc -m"make empty dir for etc"

> cd /etc

> sudo svn checkout file:///opt/svn_etc/etc .

> sudo svn add *

> sudo svn commit -m"Initial commit of all /etc"

And, done. To ensure that I never leave some changes dangling, I whipped up a quick shell script and added it to /etc/cron.daily/.2

#!/bin/bash



SENDMAIL=/usr/sbin/sendmail

EMAIL=chris@inarow.net



OUT=` svn status -q /etc `

echo -n "${OUT}" | grep "" > /dev/null && \

	echo -e "To: ${EMAIL}\nSubject: /etc locally modified\nContent-type: text/plain\n\n${OUT}\n" |\

	${SENDMAIL} "${EMAIL}"

For a final check, I verify the local security:

> whoami

cdmoyer

> cd /etc

> svn status passwd

> svn log passwd

svn: Unable to open an ra_local session to URL

svn: Unable to open repository 'file:///opt/svn_etc/etc/passwd'

svn: Can't open file '/opt/svn_etc/etc/passwd/format': Permission denied

> svn diff passwd

> svn diff -r1 passwd

svn: Unable to open an ra_local session to URL

svn: Unable to open repository 'file:///opt/svn_etc/etc/passwd'

svn: Can't open file '/opt/svn_etc/etc/passwd/format': Permission denied

> cd /opt/svn

svn/     svn_etc/

> cd /opt/svn_etc/

-bash: cd: /opt/svn_etc/: Permission denied

> ls /opt/svn

svn/     svn_etc/

> ls /opt/svn_etc/

ls: /opt/svn_etc/: Permission denied

> sudo svn log passwd

[sudo] password for cdmoyer:

------------------------------------------------------------------------

r2 | root | 2007-11-29 21:49:41 -0500 (Thu, 29 Nov 2007) | 1 line

All told, this took about 20 minutes, including the googling and monitoring script. Certainly a worthwhile investment.

1 I'll have to review my new host, Linode, at some point. (OneWordReview: Wow!)

2 And, look at that, running sudo /etc/cron.daily/etctattler and I have a new email.



Back to Blog Home »