A Portable Web Server on a USB Stick

While doing some recent work on developing a WordPress theme for a friend, I found myself in need of a portable web server; something I could plug into a computer, start up, and continue my development work. Since this was for WordPress I needed PHP and a database. With no sense of whether or not this would be possible. I charged in.

I began by collecting the components.

I chose PostgreSQL simply because it was a 50mb download while MySQL was some 300mb. Also, I’d never used PostgreSQL so, why not? Then I found out WordPress doesn’t support PostgreSQL out of the box, but quickly found PostgreSQL for WordPress.

I avoided installers and took the appropriate ZIP file for my distribution so I could simply unzip it to my thumb drive. I unzipped each in turn into it’s own directory off the root of the thumb drive giving me the following directories:

  • Apache24
  • pgsql
  • php
  • wordpress

Apache

First up, getting Apache up and running. This is pretty straightforward except that I would need to use relative paths instead of absolute paths if this was going to be a truly portable solution. I didn’t find much online in the way of what relative paths in httpd.conf would be relative to, so trial-and-error it was. The answer: it depends. Some of the paths are relative to the directory where httpd.exe lives while others are relative to whatever ServerRoot is set to in httpd.conf. ServerRoot itself is relative to httpd.exe’s location and this is typically set to one directory up from the Apache bin directory.

ServerRoot "../"

Next is setting DocumentRoot. I stayed with the default htdocs directory under ServerRoot and the DocumentRoot directive is relative to ServerRoot. However the Directory directive is relative to httpd.exe. Don’t forget this one.

DocumentRoot "htdocs"
<Directory "../htdocs">

And with those changes in place, Apache started right up!

PHP

PHP probably presented the biggest challenge as I started to get buried under DLL dependencies because PHP’s directory was not in the PATH environment variable. I could append that path on-the-fly using a batch script, but I wanted to avoid that if possible and, with some jumping through hoops, it is possible. First is what I added to the end of my httpd.conf to get PHP loaded.

LoadFile "../php/libpq.dll"
LoadModule php5_module "../php/php5apache2_4.dll"
<IfModule php5_module>
    PHPIniDir "../php"
    AddHandler php5-script .php
    DirectoryIndex index.php index.htm index.html
    Alias /wp "../wordpress"
    <Directory "../../wordpress">
        AllowOverride All
        Require all granted
    </Directory>
</IfModule>

Using Apache’s LoadFile directive helps solve any missing DLL errors from PHP when starting up Apache. I’ve included the one DLL I got a missing DLL error for. Should you encounter others make similar use of the LoadFile directory to fix things up. All the relative paths here are relative to DocumentRoot except for the Directory directive as seen previously.

On the PHP side of things I made a copy of the supplied php.ini-development file and renamed it php.ini. I uncommented extension_dir and the two extensions for PostgreSQL.

extension_dir = "ext"
.
.
.
extension=php_pdo_pgsql.dll
extension=php_pgsql.dll

But then I ran into some problems. PHP wasn’t finding those pgsql DLL files. I used Process Monitor to see exactly what paths were being looked at and found there were all relative to httpd.exe. I modified extension_dir to be relative to httpd.exe, but I was still receiving the same DLL errors. I second check of ProcessMonitor confirmed not only was the right path being accessed, but the file was actually being opened. What gives?!

Out of frustration, I eventually created an “ext” directory in the same directory as httpd.exe and copied the DLLs over into that directory and, for reasons I’m not entirely sure of, Apache started up without a problem and PHP was working. If you have any idea why this is and what I can do to make it so I don’t have to create this ext directory, please let me know. For now all I care about is that it worked.

DLL Hell

The first time I booted up Apache with PHP on my portable server I got an error about a missing DLL, msvcr110.dll. This is part of the Visual C++ Redistributable for Visual Studio 2012 which can only be downloaded as an installable, not a ZIP. To get this missing DLL I installed the runtime and then copied the DLL from my C:\Windows\System32 directory over to my Apache24\bin directory.

That fixed the issue, eventually…

Because if you’re mixing 32 and 64 bits then the location of this DLL after install might be different. If you’re running the 64-bit version of Apache and PHP, then you need the 64-bit DLL which, on a 64-bit Windows system, is located in C:\Windows\System32. If you’re running the 32-bit version of Apache and PHP on a 64-bit system, the 32-bit version of this DLL is in C:\Windows\SysWOW64. On 32-bit system it’s in C:\Windows\System32.

Good luck with that one.

PostgreSQL

I hadn’t worked with PostgreSQL before and had no clue how to create a database let alone start and stop it. I’m still not sure I do, but here’s what I did. First I needed to create a database. I opened up a command prompt and positioned myself inside pgsql directory and ran this command:

bin\initdb.exe --username <username> --pwprompt -A md5 -D data

This creates a data directory where all information and data about your database server will be stored. You could also think of it as initializing a database server instance. <username> will the the username of the superuser for the database. This can be anything you want. I used “postgres”. During the creation process you will be prompted to provide a password for the superuser account. Note: if you do not provide the username PostgreSQL will use the username of the account you’re logged into Windows under.

When the initialization completes you’ll be told exactly how to start the server.

"bin\pg_ctl" -D "data" -l pgsql.log start

This will start PostgreSQL as a background process. To stop it, use the same command, but change “start” to “stop”. With the database up and running, create a user for WordPress. This can also be done from the command line as follows:

bin\createuser.exe -U <superuser> -W -P wordpress

This creates a user called “wordpress”. You will be prompted to enter the password for the account. Don’t forget it.

Next you need to create the database that will store the data for WordPress. Again, from the command line:

bin\createdb.exe -O wordpress -U <superuser> -W wordpress

This creates a database called “wordpress” and assigns the user “wordpress” as the database’s owner.

We’re nearly there. Just one more step to go.

WordPress

With Apache and PostgreSQL running (start up Apache just by running httpd.exe from the Apache bin directory) it’s time to get WordPress running. In the configuration for Apache I gave above I alised my WordPress directory to “/wp” so open up a browser and go to http://localhost/wp. If you haven’t already installed PosgreSQL for WordPress you should see an error message that PHP is missing the MySQL extensions. No problem!

PostgreSQL for WordPress

You’ll find a readme.txt file inside the PG4WP ZIP file which will walk you through the process. Basically take the pg4wp directory that’s in the ZIP file and copy it into the wp-content directory of your WordPress install. Then make a copy of the db.php file located in the pg4wp directory and place it one level up, inside the wp-content folder. Your folder structure will look something like this:

  • wordpress
    • wp-admin
    • wp-content
      • pg4wp
      • plugins
      • themes
      • db.php
      • index.php
    • wp-includes

With that taken care of, go back to your web browser and go to http://localhost/wp. You’ll now be warned about a missing wp-config.php file. You can try the web interface or just make a copy of the wp-config-sample.php file and name it wp-config.php. You’ll need to then edit your newly created wp-config.php file to define the database name (wordpress), the database user (wordpress), and the password. Save the file and reload http://localhost/wp.

If all goes well you’ll finally see the WordPress install page. You will also (most likely) see a PHP warning message at the top about pg_query having failed. Ignore it. Fill out the form and press that install button. With luck you’ll get a success message. You’ll also get yet more PHP warnings. Again, ignore them, it’s okay. Login to your new, minty-fresh, WordPress site.

Starting and Stopping With Ease

At this point everything is up and running and everything is portable! All that’s really left is to find some way to easily start and stop the server with the click of a button. To do that I use a batch script.

@echo off
pgsql\bin\pg_ctl.exe start -D pgsql\data -l pgsql\pgsql.log
cd Apache24\bin
httpd.exe
cd ..\..
pgsql\bin\pg_ctl.exe stop -D pgsql\data

This will open a command prompt window and start PostreSQL first, followed by Apache. The window will remain open while the server is running. When I’m finished bring the command window up and press CTRL-C to tell Apache to shut down. I’m then prompted whether or not I want to terminate the batch job. I say NO which lets the script continue and shut down the PostgreSQL database.

A couple things to note. I found that I needed to be within the Apache24\bin directory before running httpd.exe to get around some missing DLL errors. I also have found that PostgreSQL seems to shut down some times for reasons I don’t know. When this happens I just stop and restart the server and everything is back up and running.

Finale

Congratulations, you have a portable web server. Go forth and develop!

Offset Column Chaos

I’m tired of confusing myself trying to write up a description of the layout. Here it is, make of it whatever you will.

Offset Column Chaos (Download)

The primary design idea was two columns where the widths of the columns had a maximum width, but the background color for each column would extend beyond the content to the edges of the viewport while the content, as a whole, remains centered to the viewport.

I took a few different approaches and eventually landed on using media queries to apply different approaches to the same problem depending on the situation with the viewport (are we at max-width yet, or not?) It works. I perhaps made it more complicated than most people really need it to be, but you can pick out the bits you don’t need to keep things simpler.

The CSS is heavily commented with variables and formulas to help keep everything pixel-perfect. It’s a layout like this one that makes me wish CSS had some kind of built-in support for variables. It’d make creating these kinds of layouts a lot easier.

Work is In Progress

I was asked to create a WordPress theme for a friend’s web site. I’ve since created the layout and theme and intend to release a stripped-down version of this layout sometime soon. In preparation for this I dusted off the blog and even found a new template that is more to my liking.

I also started doing what was never intended to be, but has since become an exhaustive write-up about what this new layout does and how it works. This has been a great exercise because it forced me to revisit certain design choices and I’ve discovered new ways to approach certain issues with the mechanics of the layout. I’ve found new solutions to problems whose original fix I wasn’t quite pleased with and also solved some minor bugs that I was initially willing to ignore.

I think I’m at the point where I started, which is cleaning up the CSS, adding comments, and writing about how it all works.

So I’ve got a new layout to give you soon. It’s not terribly complex, it has just two columns, but how those two columns function is something I think will interest others than just myself.

Texture & Transparent Maths

This is the kind of post that would benefit greatly from the addition of screenshots, but I’m far too lazy so you’re going to have to put a lot of this into your head and create your own screenshots.

Now that’s out of the way, let’s talk about a situation that came up over the weekend. I was looking at a particular layout I’ve developed and lamented that the solid color background felt a little too empty. What it needed was some kind of texture to make it more visually interesting, but no so much that it takes attention away from the actual content of the page. What immediately came to mind were the linoleum tiles of an old grocery store I went to years ago which had solid color tiles with little dots of black and white color. I thought something like that might just pull off the trick of making things a little more visually interesting without taking away focus from the content of the page. So I needed to make some dots.

Continue reading

SharePoint Designer

I recently installed Office 2010 and, along with it, SharePoint Designer 2010.

SharePoint Designer was a child of Microsoft’s WYSIWYG HTML editor FrontPage. Many people cut their teeth in HTML with FrontPage and were promptly told (rightly so) to ditch it for something better. But SharePoint Designer 2007, which is free for any Windows user to download, might actually not completely suck! What a bargain then, a nice WYSIWYG HTML editor that was free for anyone who operates on a Windows OS.

But SharePoint Designer was not the only child of FrontPage to come out of Redmond. There is another WYSIWYG HTML editor called Expression Web. However one must purchase Expression Web; it is not free. I wonder why. SharePoint Designer 2010 answers this question.

SharePoint is a product from Microsoft that tries to solve a lot of business problems. It is perhaps best to think of it as a business intranet on a single server. It handles collaboration, web publishing, portals, wikis, blogs, etc. It’s not a product, it’s a platform. And SharePoint Designer is intended to be used to develop content on SharePoint servers. But SharePoint Designer 2007 lets you create and edit standalone web pages. In essence you could replace FrontPage with SharePont Designer 2007. And don’t forget that it’s free! So that’s what a lot of people did.

Enter SharePoint Designer 2010 which comes with it a very large, very problematic restriction. It only lets you develop content for SharePoint servers. No longer can you manage just any old HTML content; if it’s not on a SharePoint server you can’t touch it with SharePoint Designer 2010.

So all those folks who have looked to SharePoint Designer as their FrontPage replacement are in for a rude awakening.

What’s the Microsoft solution? Expression Web 2010, on sale now at the cut-rate price of US$149.00.

So what free alternatives are available? Well, SharePoint Designer 2007 is still available for download. Maybe stick with that for now. Or you could experiment with Apatana or KompoZer. Or stick to a plain text editor (my preferred choice).

But this post isn’t about evaluating alternative WYSWYG HTML editors. This post is a simple warning to those of you who thought you had found your FrontPage replacement in SharePoint Designer. You didn’t.

The Petition Against IE6

There’s a petition that’s getting some attention in the media asking the British government to end its endorsement of Internet Explorer 6. The petition explains that IE6 is vulnerable to exploits and so encouraging users to continue using IE6 makes the users more vulnerable than if they had a more modern browser.

I’m no fan of IE, especially the broken rendering engine that has plagued the browser since its creation. Although with that said, I feel IE 8, from the a CSS and rendering engine perspective, is very nearly where it should be.

And I certainly would encourage all users to upgrade to a modern browser, be it IE 8 or Firefox or Opera or Safari or any of their countless derivatives. (I am intentionally leaving Chrome out of the list because I believe there are some deep flaws with the philosophy of its creators that doom the browser to always be problematic, but that is for another blog post.)

However I don’t agree with this petition.

The Register article states the petition’s author is the managing director of a web publishing company that recently nixed IE 6 from its support list. I’m guessing the author’s intent may not be focused solely on the safety of UK citizens, but perhaps a bit influenced by the fact that his company can not be contracted by the UK government since their company no longer supports IE6.

Perhaps I am being cynical.

The reason I do not agree with the petition is I believe any web site should be accessible in every web browser that conforms to basic HTML standards. At the end of the day a web site should work on plain text. That’s exactly what the web was made for. The whole “Rich Internet Application” junk that has spawned since is more a product of the need to “out flash” (no pun intended) the next guy. It’s the kind of design philosophy responsible for atrocities like the BLINK and MARQUEE tags.

I’m not saying that every web site should be nothing but plain text and maybe a few 8-bit images. Far from it. I’m all for incorporating new technologies, such as Flash or Javascript, to help improve the user experience. However I strongly believe that web site functionality should not rely on such technologies. You have existing standards such as the HTTP protocol’s GET and POST methods allow a web site to be interactive. If you wish to hide these operations behind some AJAX calls so users do not experience the traditional page load (because it feels more like a “real” and “interactive” computer application) that’s fine. But support for those basic methods of submitting and receiving data from your web site should still function for those who, by choice or by limitation of software, do not support HTTP/HTML extension technologies.

So I question the intent of this petition. If your web site is simply not compatible with IE6 it is because you have decided to employ newer technologies that are not compatible. You have, by choice, made your web site less accessible.

You could argue that I am contradicting myself a bit with the various CSS-based layouts I have created that, unless CSS hacks are employed, make them completely unusuable in browsers like IE6. My response is that A) part of my goal was to show people it was possible to develop web pages that DID work with older browsers while still employing newer technologies for those browsers that support it and B) I wanted to explore the limits of CSS and such exploration requires that we break older browsers if we are to find the new limits.

And every layout I do offer up for download and say “here, use it” I include vast amounts of documentation on the hacks employed, why they were employed, and I showcase that these layouts ARE compatible with the incompatible browsers. Hopefully with the work I’ve shared with my layouts I’ve been able to show at least one person that it’s really possible to make a modern web site while still being able to support older browsers; I think it’s a very important lesson for any web developer to learn. And it’s a lesson I think the author of this petition and those that have signed it need to learn.

Interacting With SSL

Sometimes I find it useful to do a quick telnet session to port 80 of my web server and throw at it a few requests to see how it responds. However, how do you do this with an SSL connection? Obviously Telnet doesn’t do SSL, so is there something else that’s quick and dirty?

Why yes, there is!

I tend to keep a copy of OpenSSL installed on whatever machine I’m working. Usually it’s for the DLLs to let wget work with SSL connections or to split and splice SSL certs. But it turns out you can also use OpenSSL as a command-line client to open SSL connections to remove servers. It’s quite simple, just drop to a command line/terminal session and use the following command:

openssl s_client -host <server> -port 443

Now work the HTTP magic like you would were you using telnet. Let’s see that in action!

>openssl s_client -host www.microsoft.com -port 443

GET / HTTP/1.0
host: www.microsoft.com

HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: text/html
Last-Modified: Mon, 16 Mar 2009 20:35:26 GMT
Accept-Ranges: bytes
ETag: "xxxxxxxxxxxx"
Server: Microsoft-IIS/7.5
VTag: xxxxxxxxxx
P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"
X-Powered-By: ASP.NET
Date: Mon, 25 Jan 2010 14:51:15 GMT
Connection: keep-alive
Content-Length: 1020

Cool stuff.

More exploits. Sun responds.

Intevydis blog has another exploit or two up today for Sun Java System Web Server.

Yesterday Sun posted an alert regarding the exploits and possible temporary solutions until a patch can be released.

Their solution is to disable WebDAV and all digest authentication.

But what if I use digest authentication? Do I really need to disable it? Possibly not. The HEAD, GET and POST methods do not seem to be affected by the overflow exploits. Therefore if I block all the other methods EXCEPT those three, I should still be able to do digest authentication. Only problem is knowing every other possible method available in Sun’s web server.

Well, maybe you don’t need to know them all. You might try this:

<If $method="(GET|POST|HEAD)"></If><Else>
AuthTrans fn="set-variable" remove-headers="transfer-encoding" set-headers="content-length: -1" error="501"
</Else>

What this does is if the method being handled is GET, POST or HEAD then nothing happens here. But if it’s something else, it gets rejected with a “method not implemented (501)” error. I couldn’t find a logical not wildcard pattern operator in the administrator’s guide (“!=” is a numercial not and will not work on strings), which is why there’s an empty IF block. Hey, it works, and remember it’s only temporary.

So if your a SJSWS person, I hope this helps a little bit.

It makes me wonder if I should ditch SJSWS entirely.

A Third SJSWS Exploit Released This Week!

Intevydis blog has released yet another exploit for Sun Java System Web Server. This one attacks diguest authentication. “Well, I don’t use digest auth, so I’m safe, right?” Wrong! Any client can trigger digest auth handling even if the web site doesn’t require a password.

I know this, not because I am clever and well versed in SJSWS. I know this because I ran the code against a test server and successfully crashed it.

So then, you and I are vulnerable to this exploit.

However there is a workaround. One that we’ve already used to prevent the previous two exploits. It requires that you manually add a couple lines to every virtual server config file in your deployment.

That code is:

<If $method="PROPFIND" or $method="OPTIONS" or $method="PUT" or $method="DELETE" or $method="MOVE" or $method="MKDIR" or $method="RMDIR">
AuthTrans fn="set-variable" remove-headers="transfer-encoding" set-headers="content-length: -1" error="501"
</If>

This disables all the methods you probably don’t really use. OPTIONS and PUT have already been used to exploit SJSWS. Why wait for another method to be exploited? Let’s disable them all. At least until Sun comes out with a patch.

I’d like to point out one thing. When I did crash my SJSWS test deployment, it came back up within 10-15 seconds. Sun’s watchdog process keeps tabs on your server process and, should it crash, immediately starts up another. That is really handy. Granted it’d be trivial to still execute a DoS against a vulnerable server (just send the malicious request every 30 seconds), but if someone’s just trying to muck around with your server, it won’t cause any lengthy amount of downtime.

Another SJSWS Exploit

Looks like the people behind Intevydis blog have revealed another Sun Java System Web Server exploit. This one attacks WebDAV. Not a problem for me as I have WebDAV disabled across all our web servers. However it will be a problem for people who rely on WebDAV. If I were in that position I would try to get away with disabling WebDAV until Sun releases a new patch. I don’t think disabling the OPTIONS method is possible; I believe it’s needed for WebDAV. So if you’re stuck in that situation, good luck!