tempalias.com – sysadmin work
This is yet another episode in the development diary behind the creation of a new web service. Read the previous installment here.
Now that I made the SMTP proxy do its thing and that I'm able to serve out static files, I though it was time to actually set up the future production environment so that I can give it some more real-world testing and to check the general stability of the solution when exposed to the internet.
So I went ahead and set up a new VM using Ubuntu Lucid beta, running the latest (HEAD) redis and node and finally made it run the tempalias daemons (which I consolidated into one opening SMTP and HTTP ports at the same time for easier handling).
I always knew that deployment will be something of a problem to tackle. SMTP needs to run on port 25 (if you intend to be running on the machine listed as MX) and HTTP should run on port 80.
Both being sub 1024 in consequence require root privileges to listen on and I definitely didn't want to run the first ever node.js code I've written to run with root privileges (even though it's a VM - I don't like to hand out free root on a machine that's connected to the internet).
So additional infrastructure was needed and here's what I came up with:
The tempalias web server listens only on localhost on port 8080. A reverse nginx proxy listens on public port 80 and forwards the requests (all of them - node is easily fast enough to serve the static content). This solves another issue I had which is HTTP content compression: Providing compression (Content-Encoding: gzip) is imperative these days and yet not something I want to implement myself in my web application server.
Having the reverse proxy is a tremendous help as it can handle the more advanced webserver tasks - like compression.
I quickly noticed though that the stable nginx release provided with Ubuntu Lucid didn't seem to be willing to actually do the compression despite it being turned on. A bit of experimentation revealed that stable nginx, when comparing content-types for gzip_types checks the full response content-type including the charset header.
As node-paperboy adds the ";charset: UTF-8" to all requests it serves, the default setting didn't compress. Thankfully though, nginx could live with
gzip_types "text/javascript; charset: UTF-8" "text/html; charset: UTF-8"
so that settled the compression issue.
Update: of course it should be "charset=UTF-8" instread of "charset: UTF-8" - with the equal sign, nginx actually compresses correctly. My patch to paperboy has since been accepted by upstream, so you won't have to deal with this hassle.
Next was SMTP. As we are already an SMTP proxy and there are no further advantages of having incoming connections proxied further (no compression or anything), I wanted clients to somehow directly connect to the node daemon.
I quickly learned that even the most awesome iptables setup won't make the Linux kernel accept on the lo interface anything that didn't originate from lo, so no amount of NATing allows you to redirect a packet from a public interface to the local interface.
Hence I went by reconfiguring the SMTP server component of tempalias to listen on all interfaces, port 2525 and then redirect the port of packets on the public port from 25 to 2525.
This of course left the port 2525 open on the public interface which I don't like.
A quickly created iptables rule rejecting (as opposed to dropping - I don't want a casual port scanner to know that iptables magic is going on) any traffic going to 2525 also dropped the redirected traffic which of course wasn't much help.
In comes the MARK extension. Here's what I've done:
# mark packets going to port 25 iptables -t mangle -A PREROUTING -i eth0 -p tcp --dport 25 -j MARK --set-mark 99 # redirect packets going to port 25 to 2525 iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 25 -j REDIRECT --to-ports 2525 # drop all incoming packets to 2525 which are not marked iptables -A INPUT -i eth0 -p tcp --dport 2525 -m mark ! --mark 99 -j REJECT |
So. Now the host responds on public port 25 (but not on public port 2525).
Next step was to configure DNS and tell Richard to create himself an alias using
curl --no-keepalive -H "Content-Type: application/json" \ --data-binary '{"target":"t@example.com","days": 3,"max-usage": 5}' \ -qsS http://tempalias.com/aliases |
(yes. you too can do that right now - it's live baby!)
Of course it blew up the moment the redis connection timed out, taking the whole node server with it.
Which was the topic of yesterdays coding session: The redis-node-client library is very brittle what connection tracking and keeping is concerned. I needed something quick, so I hacked the library to provide an additional very explicit connection management method.
Then I began discussing the issues I was having with redis-node-client's author. He's such a nice guy and we had one hell of a nice discussion which is still ongoing, so I will probably have to rewrite the backend code once more once we found out how to do this the right way.
Between all that sysadmin and library-fixing time, unfortunately, I didn't yet have time to do all too much on the public facing website: http://tempalias.com at this point contains nothing but a gradient. But it's a really nice gradient. One of the best.
Today: More redis-node-client hacking (provided I get another answer from fictorial) or finally some real HTML/CSS work (which I'm not looking forward to).
This is taking shape.
New MacMini (early 09) and Linux
The new MacMinis that were announced this week come with a Firewire 800 port which was reason enough for me to update shion yet again (keeping the host name of course).
All my media she's serving to my various systems is stored on a second generation Drobo which is currently connected via USB2, but has a lingering FW800 port.
Of course the upgrade to FW800 will not double the transfer rate to and from the drobo, but it should increase it significantly, so I went ahead and got one of the new Minis.
As usual, I entered the Ubuntu (Intrepid) CD, hold c while turning the device on and completed the installation.
This left the Mini in an unbootable state.
It seems that this newest generation of Mac Hardware isn't capable of booting from an MBR partitioned harddrive. Earlier Macs complained a bit if the harddrive wasn't correctly partitioned, but then went ahead and booted the other OS anyways.
Not so much with the new boxes it seems.
To finally achieve what I wanted I had to do the following complicated procedure:
- Install rEFIt (just download the package and install the .mpkg file)
- Use the Bootcamp assistant to repartition the drive.
- Reboot with the Ubuntu Desktop CD and run parted (the partitioning could probably be accomplished using the console installer, but I didn't manage to do it correctly).
- Resize the FAT32-partition which was created by the Bootcamp partitioner to make room at the end for the swap partition.
- Create the swap partition.
- Format the FAT32-partition with something useful (ext3)
- Restart and enter the rEFIt partitioner tool (it's in the boot menu)
- Allow it to resync the MBR
- Insert the Ubuntu Server CD, reboot holding the C key
- Install Ubuntu normally, but don't change the partition layout - just use the existing partitions.
- Reboot and repeat steps 7 and 8
- Start Linux.
Additionally, you will have to keep using rEFIt as the boot device control panel item does not recognize the linux partitions any more, so can't boot from them.
Now to find out whether that stupid resistor is still needed to make the new mini boot headless.
Ubuntu 8.04
I'm sure that you have heard the news: Ubuntu 8.04 is out.
Congratulations to Canonical and their community for another fine release of a really nice Linux distribution.
What prompted me to write this entry though is the fact that I have updated shion from 7.10 to 8.04 this afternoon. Over a SSH connection.
The whole process took about 10 minutes (including the download time) and was completely flawless. Everything kept working as it was before. After the reboot (which also went flawlessly), even OpenVPN came back up and connected to the office so I could have a look at how the update went.
This is very, very impressive. Updates are tricky. Especially considering that it's not one application that's updated, not even one OS. It's a seemingly random collection of various applications with their interdependencies, making it virtually impossible to test each and every configuration.
This shows that with a good foundation, everything is possible - even when you don't have the opportunity to test for each and every case.
Congratulations agin, Ubuntu team!
VMWare Server 2.0
Now that the time has come to upgrade shion's hardware, and now that I'm running a x86 based platform (well, it's the 64 bit server install of Ubuntu Gutsy), I guessed it was time to have a look at my current bittorrent solution.
Of all the torrent clients out there, so far, I had the most painless experience with uTorrent: Acceptable download speeds, a very nice web interface and a nice looking user interface. The only drawback is that it requires Windows to run and I had no constant-running Windows-PC at home.
In fact, I didn't even have a Windows-PC at all. VMWare Fusion came to the rescue as it allowed me to install Windows on a virtual machine and run that on my main mac at home. I chose fusion as opposed to parallels because I always knew that I was going to update shion sooner or later, so I wanted the portability of the VMWare virtual machines (they run everywhere VMWare runs on - no conversion, no nothing).
And now that I did replace shion, I've installed the latest beta version of VMWare Server 2.0 and moved the virtual machine over to the newly born shion 2.0 which means that I now have a constantly running "Windows-PC" at home.
The move was painless as expected, but the whole process of installing VMWare server or the web interface was not as painless. VMWare Server feels exactly like every other proprietary Unix application I ever had to deal with. Problems with shared libraries (PAM, Gentoo, 32bit emulation and vmware server 1.0 is pure hell), problems with init-scripts not working, problems with incomprehensible error messages, you name it.
And once I actually got the thing to run, the first thing I had to do was to configure a whole bunch of iptables-rules because it seems impossible to bind all the 7 ports the web interface opens to localhost only (shion also is my access router, so I certainly don't want the vmware-stuff exposed on eth1).
And actually using the web interface means forwarding all the 7 ports. In VMWare Server 1, it sufficed to forward the one port the console application used.
All this to finally end up without a working console access - the browser plugin they use for this seems not to work with Mac OS X and adding all the 7 ports to putty in my client windows VM, frankly, was more complicated than what I could get out of it.
Before this goes final with the expectation of being as useful as version 1 was, they need to give us back a native client and a smaller number of ports to forward.
Closed Source on Linux
One of the developers behind the Linux port of the new Flex Builder for Linux has a blog post about how building closed source software for linux is hard
Mostly, all the problems boil down to the fact that Linux distributors keep patching the upstream source to fit their needs which clearly is a problem rooted in the fact that open source software is, well, open sourced.
Don't get me wrong. I love the concepts behind free software and in fact, every piece of software I've written so far has been open source (aside of most of the code I'm doing for my eployer of course). I just don't see why every distribution feels the urgue to patch around upstream code, especially as this issue applies to both open- and closed source software projects.
And worse yet: Every distribution adds their own bits and pieces - sometimes doing the same stuff in different ways and thus making it impossible or at least very hard for a third party to create add-ons for a certain package.
What good is a plugin system if the interface works slightly different on each and every distribution?
And think of the time you waste learning configuration files over and over again. To make an example: Some time ago, SuSE delivered an apache server that was using a completely customized configuration file layout, thereby breaking every tutorial and documentation written out there because none of the directives where in the files they are supposed to be.
Other packages are deliberately broken up. Bind for example often comes in two flavors: The server and the client, even though officially, you just get one package. Additionally, every library package these days is broken up in the real library and the development headers. Sometimes the source of these packages may even get patched to support such breaking up.
This creates an incredible mess for all involved parties:
- The upstream developer gets blamed for bugs she didn't cause because they were introduced by the packager.
- Third party developers can't rely on their plugins or whatever pluggable components to work across distributions if they work upstream
- Distributions have to do the same work over and over again as new upstream versions are released, thus wasting time better used for other improvements.
- End users suffer from the general disability of reliably installing precompiled third-party binaries (mysql recommends the use of their binaries, so this even affects open sourced software) and from the inability to follow online-tutorials not written for the particular distribution that's in use.
This mess must come to an end.
Unfortunately, I don't know how.
You see: Not all patches created by distributions get merged upstream. Sometimes, political issues prevent a cool feature from being merged, sometimes clear bugs are not recognized as such upstream and sometimes upstream is dead - you get the idea.
Solution like FHS and LSB tried to standardize many aspects of how linux distributions should work in the hope of solving this problem. Bureaucracy and idiotic ideas (german link, I'm sorry) are causing quite the bunch of problems lately, making it hard to impossible to implement the standards. And often the standards don't specify the latest and greatest parts of current technology.
Personally, I'm hoping that we'll either end up with one big distribution defining the "state of the art", with the others being 100% compatible or with distributions switching to pure upstream releases with only their own tools custom-made.
What do you think? What has to change in your opinion?
VMWare Server, chrony and slow clocks
We have quite many virtual machines running under VMWare server. Some for testing purposes, some for quite real systems serving real webpages.
It's wonderful. Need a new server? Just cp -r the template I created. Need more RAM in your server? No problem. Just add it via the virtual machine configuration file. Move to another machine? No problem at all. Power down the virtual machine and move the file where you want it to be.
Today I noticed something strange: The clocks on the virtual machines were way slow.
One virtual second was about ten real seconds.
This was so slow that chrony which I used on the virtual machines thought that the data sent from the time servers was incorrect, so chrony was of no use.
After a bit of digging around, I learned that VMware server needs access to /dev/rtc to provide the virtual machines with an usable time signal (usable as in "not too slow").
The host's /var/log/messages was full of lines like this (you'll notice that I found yet another girl from a console RPG to name that host):
Dec 15 16:12:58 rikku /dev/vmmon[6307]: /dev/rtc open failed: -16 Dec 15 16:13:08 rikku /dev/vmmon[6307]: host clock rate change request 501 -> 500
-16 means "device busy"
The fix was to stop chrony from running on the host machine so VMWare could open /dev/rtc. This made the error messages vanish and additionally it allowed the clocks of the virtual machines to work correctly.
Problem solved. Maybe it's useful for you too.
ServeRAID – Fun with GUI-Tools
We've recently bought three more drives for our in-house file server. Up until now, we had a RAID 5 array (using a IBM ServeRAID controller) spawning three 33GB drives. That array recently got very, very close to being full.
So today, I wanted to create a second array using the three new 140GB drives.
When you download the ServeRAID support CD image, you get access to a nice GUI-tool which is written in Java and can be used to create Arrays on these ServeRAID controllers.
Unfortunately, I wasn't able to run the GUI at first because somehow, the Apple X11 server wasn't willing/able to correctly display the GUI. I always got empty screens when I tried (the server is headless, so I had to use X11 forwarding via ssh).
Using a Windows machine with Xming (which is very fast, working perfectly and totally free as in speech) worked though and I got the GUI running.
All three drives where recognized, but one was listed as "Standby" and could not be used for anything. Additionally, I wasn't able to find any way in the GUI to actually move the device from Standby to Ready.
Even removing and shuffling the drives around didn't help. That last drive was always recognized as "Standby", independant of the bay I plugged it into.
Checking the feature list of that controller showed nothing special - at first I feared that the controller just didn't support more than 5 drives. That fear was without reason though: The controller supports up to 32 devices - more than enough for the server's 6 drive bays.
Then, looking around on the internet, I didn't find a solution for my specific problem, but I found out about a tool called "ipssend" and there was documentation how to use it in an old manual by IBM.
Unfortunately, newer CD images don't contain ipssend any more, Forcing you to use the GUI which in this case didn't work for me. It may be that there's a knob to turn somewhere, but I just failed to see it.
In the end, I found a very, very old archive at the IBM website which was called dumplog and contained that ipssend command in a handy little .tgz archive. Very useful.
Using that utility solved the problem for me:
# ./ipssend setstate 1 1 5 RDY
No further questions asked.
Then I used the Java-GUI to actually create the second array.
Now I'm asking myself a few questions:
- Why is the state "Standby" not documented anywhere (this is different from a drive in Ready state configured as Standby drive)?
- Why is there no obvious way to de-standby a drive with the GUI?
- Why isn't that cool little ipssend utility not officially available any more?
- Why is everyone complaining that command line is more complicated to use and that GUIs are so much better when obviously, the opposite is true?
podcast recommendation
I haven't been much into podcasts till now: The ones I heard were boring, unprofessional or way too professional. Additionally, I didn't have a nice framework set up to get them and to listen to them.
That's because I don't often sync my ipod. Most of the time, it's not connected to a computer: About once every two months, I connect it to upload a new batch of audiobooks (I can't fit my whole connection on the nano). So podcasting was - even if I had found one that I could interest myself in, an experience to have while behind the computer monitor.
Now two things have changed:
- I found the Linux Action Show. They guy doing that podcast are incredibly talented people. The entries sound very professionally made, while still not being on the obviously commercial side of things. They cover very, very interesting topics and they are everything but boring. Funny, entertaining and competent. Very good stuff.
-
At least since the release of SlimServer 6.5, my Squeezebox is able to tune into RSS feeds with enclosures (or podcast for the less technical savy people - not that those would read this blog). Even better: The current server release brought a firmware which finally gives the Squeezebox the capability of natively playing ogg streams.
Up until now, it could only play FLAC, PCM and MP3, requiring tools like sox to convert ogg streams on the fly. Unfortunately, that didn't work as stable as I would have liked, but native OGG support helped a lot
So now, whenever a new episode of the podcast is released (once per week - and each episode is nearly two hours in length), I can use my Squeezebox to hear it via my home stereo.
Wow... I'm so looking forward to do that in front of a cozy fire in my fireplace once I can finally move into my new flat.
ripping DVDs
I have plenty of DVDs in my possession: Some movies of dubious quality which I bought when I was still going to school (like "Deep Rising" - eeew) and many, many episodes of various series (Columbo, the complete Babylon 5 series, A-Team and other pearls).
As you may know, I'm soon to move into a new flat which I thought would be a nice opportunity to reorganize my library.
shion has around 1.5TB of storage space and I can easily upgrade her capacity (shion is the only computer I own I'm using a female pronoun for - the machine is something really special to me - like the warships of old times) by plugging in yet another USB hub and USB hard drives.
It makes totally sense to use that unlimited amount of storage capacity to store all my movies - not only the ones I've downloaded (like video game speed runs). Spoiled by the ease of use of ripping CDs, I thought, that this would be just another little thing to do before moving.
You know: Enter the DVD, use the ripper, use the encoder, done.
Unfortunately, this is proving to be harder than it looked like in the first place:
- Under Mac OS X, you can try to use the Unix tools with fink or some home-grown native tools. Whatever you do, you either get outdated software (fink) or not really working freeware tools documented in outdated tutorials. Nah.
-
Under Windows, there are two kinds of utilities: On one hand, you have the single-click ones (like AutoGK) which really do what I initially wanted. Unfortunately, they are limited in their use: They provide only a limited amount of output formats (like no x264) and they hard-code the subtitles into the movie stream. But they are easy to use. On the other hand, you have the hardcore tools like Gordian Knot or MeGUI or even StaxRip. These tools are frontends for other tools that work like Unix tools: Each does one thing, but tries to excel at that one thing.
This could be a good thing, but unfortunately, it fails at things like awful documentation, hard-coded paths to files everywhere and outdated tools.
I could not get any of the tools listed above to actually create a x264 AVI or MKV-File without either throwing a completely unusable error message ("Unknown exception ocurred") or just not working at all or missing things like subtitles.
- Linux has dvd::rip which is a really nice solution, but unfortunately, no solution for me as I don't have the right platform to run it on: My MCE machine is - well - running Windows MCE, my laptop is running Ubuntu (no luck with the debian packages and no ubuntu-packages). shion is running Gentoo, but she's headless, so I have to use a remote X-connection which is awfully slow and non-scriptable.
The solution I want works on the Linux (or MacOS X) console, is scriptable and - well - works.
I guess I'm going the hard-core way and use transcode which is what dvd::rip is using - provided I find good documentation (I'm more than willing to read and learn - if the documentation is current enough and actually documents the software that I'm running and not the software at the state of two years ago).
I'll keep you posted on how I'm progressing.
Intel Mac Mini, Linux, Ethernet
If you have one of these new Intel Macs, you will sooner or later find yourself in the situation of having to run Linux on one of them. (Ok. Granted: The situation may be coming sooner for some than for others).
Last weekend, I was in that situation: I had to install Linux on an Intel Mac Mini.
The whole thing is quite easy to do and if you don't need Mac OS X, you can just go ahead and install Linux like you would on any other x86 machine (provided the hardware is sufficiently new to have the BIOS emulation layer already installed - otherwise you have to install the Firmware Update first - you'll notice by the mac not booting from the CD despite holding c during the initial boot sequence).
You can partition the disk to your liking - the Mac bootloader will notice that there's something fishy with the parition layout (the question-mark-on-a-folder icon will blink one or two times) before passing control to the BIOS emulation which will be able to boot Linux from the partitions you created during installation.
Don't use grub as bootloader though.
I don't know if it's something grub does to the BIOS or if it's something about the partition table, but grub can't launch stage 1.5 and thus is unable to boot your installation.
lilo works fine though (use plain lilo when using the BIOS emulation for the boot process, not elilo)
When you are done with the installation process, something bad will happen sooner or later though: Ethernet will stop working.
This is what syslog has to say about it:
NETDEV WATCHDOG: eth0: transmit timed out sky2 eth0: tx timeout sky2 eth0: transmit ring 60 .. 37 report=60 done=60 sky2 hardware hung? flushing
When I pulled the cable and plugged it in again, the kernel even oops'ed.
The macs have a Marvel Yukon ethernet chipset. This is what lspci has to tell us: 01:00.0 Ethernet controller: Marvell Technology Group Ltd. 88E8053 PCI-E Gigabit Ethernet Controller (rev 22). The driver to use in the kernel config is "SysKonnect Yukon2 support (EXPERIMENTAL)" (CONFIG_SKY2)
I guess the EXPERIMENTAL tag is warranted for once.
The good news is, that this problem is fixable. The bad news is: It's tricky to do.
Basically, you have to update the driver with the version that is in the repository of what's going to be kernel 2.6.19
Getting a current version of sky.c and sky.h is not that difficult. Unfortunately though, the new driver won't compile with the current 2.6.18 kernel (and upgrading to a pre-rc is out of the question - even more so considering the ton of stuff going into 2.6.19).
So first, we have to patch in this changeset to make the current release of sky compile.
Put the patch to /usr/src/linux and patch with patch -p1
Then fetch the current revision of sky2.c and sky2.h and overwrite the existing files. I used the web interface to git for that as I have no idea how the command line tools work.
Recompile the thing and reboot.
For me, this fixed the problem with the sky2 driver: The machine in question is now running for a whole week without any networking lockups - despite heavy network load at times.
While happy to see this fixed, my statement about not buying too new hardware (posting number 6 here on gnegg.ch - ages ago) if you intend to use Linux on it seems to continue to apply.