This Page Was Served From Windows 3.11

… running on Uberspace using Windows httpd (based on NCSA HTTPd), the first web server for Microsoft Windows—created in the early 90s.

Taking screenshot…
Screenshot from Windows 3.11
Recent screenshot from the web server’s UI retrieved via /cgi-win/scrgrab.exe. The computer’s time zone is set to Europe/Berlin.

But Why?

I learned that someone is running Windows 95 and the included Personal Web Server on Uberspace—which made me think, “hold my beer,” and this is the result. Also, this was a fun ride through the history of the Internet—reminding me that most of the basics are still the same. And finally, this demonstrates the versatility of my web hoster Uberspace, which supports running all this nonsense in a shared(!) hosting environment.

And How?

I’m running QEMU on Uberspace that hosts a Windows 3.11 VM. Inside the VM, there’s Windows httpd running, along with a self-written utility to capture a screen shot via CGI.

You may call it cheating, but to prevent people from exploiting or overloading this tiny server, I’ve put an NGINX reverse proxy in front of it that does some filtering and caching. The expiry times are just 10 seconds though, as you may have noticed by looking at the clock in the screen shot above. So there is a high probabilty that this server response was generated just for you.

You can find the Ansible Playbook that sets up the Uberspace account on GitHub.

Challenges

There were a few challenges that I had to overcome.

Installing QEMU Without Root Access

After being unsuccessful with Homebrew, I found user-yum.sh. It’s a shellscript which retrieves RPMs, extracts them, and installs them into any location—no root access required. I just had to manually set some library paths, but then I was ready to boot Windows 3.11.

QEMU Process Eating 100% CPU

If I hadn’t fixed this one, I probably would have gotten a friendly email from my hoster after a few hours. By default, an emulated Windows 3.11 will cause a CPU utilization of 100% on the host (limited to one core, of course). Not nice. Luckily, there is a utility called DOSidle which I found in a thread at VOGONS. This reduces the CPU usage to an acceptable amount.

htop running on Uberspace, showing QEMU’s CPU usage
htop showing QEMU’s CPU usage at an acceptable amount of 4.0%. The one core that’s running at 100% isn’t me. I swear!

Clock Drift Issues

I noticed that the machine’s clock (shown on the screenshot above) loses sync over time. After the server had been running for a few days, the clock was lagging behind by a some seconds. Setting driftfix=slew option on the QEMU command-line didn’t fix this issue. Also, at the time of writing, Europe still observes daylight savings time which Windows 3.11 doesn’t respect.

Side note: Later Windows versions (such as Windows 95) added support for daylight saving time changes, but were cautious: they asked the user during system start-up to confirm whether automatic change had been performed correctly.

Die Uhr wurde sommerzeitbedingt umgestellt. Prüfen Sie, ob die Einstellungen der Uhr richtig sind.
Windows 98 telling the user to double-check whether it had correctly adapted to summer time.

So what do you do to keep our computer clock in sync? You use NTP! Oh, wait—even though RFC 958 was written in 1985, NTP wasn’t a thing in Windows 3.11. But, luckily, third-party tools would fill this gap. One of them is Tardis.

Tardis taking care of clock sync and daylight saving changes.

To my surprise, it almost worked out of the box. I just had to replace the pre-defined server (I chose de.pool.ntp.org) and set the protocol to “SNTP”. I’ve also ticked “Start minimized” and added it to the Startup folder. No more clock sync issues! And even daylight saving changes are supported. 🥳

More Challenges

There were more challenges, some of which I coudn’t solve yet. I’m going to amend this section over time.

Feedback, Comments, or Questions?

Contact me here.