Categories
Weblogging

Weblogging: More Than Words

Two friends have stopped by to say hi since I turned comments back on.

Bill mentions the Radio Userland days,which puts us back in very ancient weblogging territory. So ancient that today’s TikTok kids weren’t even born when we got together in Userland pages.

I also used to have a Userland Manila weblog, but those days are permanently gone. The Manila weblogs were lost in the Wayback Machine because of a bot-killer Dave Winer implemented. Sad, but such is life.

AKMA also stopped by and discussed doing weblog  recovery for his space, but what about the comments? We can recover the words, but we can’t recover the comments.

Indeed this is the biggest loss when we’ve moved our spaces all about: we can move our words, but we’ve left the community behind.

Thankfully, Wayback Machine rode in and saved the internet. Not only does it preserve a page, it preserves the theme of the page, the look and feel and in-place context. It also frequently preserved the comments.

I may have recovered the words to Cheap Eats at the Semantic Web Cafe in this space, but the Wayback Machine saved everything else about that old posting in its space. And I’m eternally grateful for the gift it’s given us.

You see what I did there? I did weblogging.

Categories
Technology Weblogging

Web Server 101 for Ghost

update

I disabled the Ghost weblog because I don’t want to maintain two different weblogging software applications, and Drupal is my primary weblogging software.

The configuration listed here was sound and reliable for well over six months.

—-

Recently I installed Ghost on my server. Ghost is a Node.js weblogging tool that you can host yourself or have another organization host for you.

It’s not a complicated application to install. There’s even a How to Install Ghost web site, with handy instructions for installing Ghost in various environments.

Take my environment, which is Ubuntu Linux hosted on a Linode VPS. You could order a brand new VPS, but chances are your server is already set up, and you’re just looking to install Ghost.

You have to install Node.js first, of course. Then you download the Ghost source code, and install the application, using the following steps:

mkdir -p /var/www/
cd /var/www/
wget -O ghost.zip https://ghost.org/zip/ghost-latest.zip
unzip -d ghost ghost.zip
cd ghost
npm install --production
cp config.example.js config.js

Next you edit the configuration file, changing the default IP and port values to ones that allow people to access your new Ghost weblog:

host: '[your Linode public IP]',
port: '80'

Lastly, start that puppy up:

npm start --production

 

Now, you’re all set, good to go, blasting full ahead on all cylinders…

…right for that wall that is about to hit you, hard, in the face.

A reality check on that environment

Let’s back this sweet scenario up to, oh, step 1: your environment.

True, you could be installing Ghost in a brand new environment with nothing else installed. Chances are, though, you’re installing Ghost in an existing system that is already running a web server. Chances are also good the web server you’re running is Apache, which is running on port 80, the same as your new Ghost installation.

So what happens when you try to run Ghost on the same port you’re using with Apache?

If you try to start the application withnpm, you’ll get an almost immediate error response signaling that an unhandled error event has occurred, and to contact the Ghost author. If you try to start the Ghost application via another tool, such asforever, you may not see an immediate problem at the command line, but if you access the Ghost site via a browser, you’ll get a 503 “Service Temporarily Unavailable Error”.

You’re getting an error because you can’t run both web services at the same port. You then have two options to run your Ghost weblog. Option 1 is to shut down Apache or install Ghost on a machine where Apache is not installed, and then you can run Ghost at port 80. The second option is to find a way to get Apache (or other web server) and Ghost to co-exist.

Let’s take a look at that first option: running Ghost in a stand alone environment at port 80.

Running Ghost in a Stand Alone Environment

If you don’t have Apache installed, or no other web service running at port 80, you could follow the steps I gave earlier, and you might expect Ghost to start. You might, but you could be in for a surprise.

If you try to start Ghost with a line such as the following:

npm start --production

You’ll most likely get an error. If you try to start Ghost up directly, using Node, you’ll find that the error is EACCES, “permission denied”. The reason why is that port numbers below 1024 are what is known as privileged ports, requiring root permission. When you tried to start up Ghost as a normal user, you lacked the permissions to start the service.

You might be tempted to use sudo to start the Ghost application:

sudo npm start --production

And yes, Ghost should be alive and well and running on port 80. But this command just triggered a visceral response from security minded web developers, because now Ghost (which is currently in beta development and unlikely to be hardened) is now running with root privileges. Not even Apache, hardy veteran of the web wars that it is, responds to web requests with processes running with root privileges.

Behind the scenes, when you start Apache as root, it spawns a worker thread that handles a web request. This worker thread runs with the privileges of a non-root user, typicallywww-data. If you’re running a Linux server, you can issue the following command and see that one Apache process is running as root, while other child processes are running as the Apache user (www-data).

ps -ef | grep apache

Other web servers, such as Nginx, operate under the same principle.

So, what do you do if you want to run Ghost at port 80?

Well, you can start Ghost up on port 2368 (the default port) and then go where most folks don’t dare to go by tweaking iptables to redirect port 80 to port 2368, or something similar. Bottom line, though, is you just don’t run Ghost as a stand alone web server/application, period.

In an issue thread at github the architects behind Ghost have stated that they see Ghost as an application, not web server. As such, they don’t recommend that people run it directly, as a web server. Instead, they recommend using Ngnix or Apache as the web server, and then reverse proxy to Ghost. Both Nginx and Apache are hardened from a security perspective, and both do a better job providing other services the Ghost folks won’t be providing.

The Ghost folk recommend using Ngnix,and you can use Ngnix as reverse proxy for both Apache and Ghost if you’re hosting Apache applications. For myself, I don’t need the extra level of complexity or the performance boost that Ngnix can provide for static files, so I decided to go with Apache as reverse proxy. I’ll cover the steps I took, but first, let’s return to that running instance of Ghost.

Running Ghost Forever

My Ghost weblog is currently running at Shelley’s Toy Box. Shelley’s Toy Box is my hack and trash domain where I’ll try new things. I thought about getting a separate VPS for it, but can’t really afford it at this time, so I’m making do with a virtual host for now.

Ghost is running at port 2368, the default. Yes, this means you could also access the Ghost weblog at http://burningbird.net:2368, and completely bypass Apache doing so, but we’ll get to that in a little bit. For now, I have started Ghost usingforever:

forever start  -l forever.log -o out.log -e err.log index.js

If Ghost crashes and burns,forevershould start it back up. However, if the server, itself, gets re-booted, Ghost isn’t restarted. Luckily, since I’m running Ubuntu, I can use Ubuntu’s Upstart to re-start Ghost withforever.

I created a simple file named ghost.conf in /etc/init, with the following text:

# /etc/init/ghost.conf
description "Ghost"

start on (local-filesystems)
stop on shutdown

setuid your-userid
setgid your-grpid

script
    export HOME="path-to-ghost"
    cd path-to-ghost
    exec /usr/local/bin/forever -a -l path-to-logfiles/forever.log --sourceDir path-to-ghost index.js

end script

Now when my system re-boots, the Ghost weblog restarts. And it restarts as my non-privileged user thanks to thesetuidandsetgid.

Using Apache as reverse proxy

Apache has a good description of forward and reverse proxies, but simply stated, a reverse proxy allows web users to access both Apache and Ghost in our servers, seemingly on the same port 80.

I’ve not used Apache as a reverse proxy before, so this is new territory for me. After going through variations that left my server crawling on its knees, I found a routine that seems to work well, or at least, not work badly.

First, I had to enable bothmod_proxyandmod_proxy_http:

sudo a2enmod proxy
sudo a2enmod proxy_http

I’m not turning on forward proxying, so didn’t uncomment any of the lines within the proxy.conf file in Apache’s mods-available subdirectory.

I already have several virtual hosts configured, so it was a simple matter of creating another for Shelley’s Toy Box. In the settings, I turnProxyRequestsoff, just because I’m paranoid (it shouldn’t be on), and then add myProxyPassandProxyPassReversesettings:

<VirtualHost ipaddress:80>
    ServerAdmin shelleyp@burningbird.net
    ServerName shelleystoybox.com

    ErrorLog path-to-logs/error.log
    CustomLog path-to-logs/access.log combined

    ProxyRequests off

    <Location />
            ProxyPass http://ipaddress:2368/
            ProxyPassReverse http://ipaddress:2368/
    </Location>
</VirtualHost>

I specify my ip address for the virtual host, because I have used two IP addresses in the same server in the past, and may again in the future.

Once I enable the site and reload Apache, I’m good to go.

a2ensite shelleystoybox.com
service apache2 reload

The only issue left is the fact that people can also access the Ghost weblog directly using other domains and the 2368 port (i.e. http://burningbird.net:2368). Since I’m running Ubuntu and am using iptables, I add the following rule:

iptables -A input -i eth0 -p tcp --dport 2368 -j DROP

This prevents direct access of port 2368, while still allowing Apache to proxy requests to the port. I maintain it between boots using iptables-persistent. However, it is modifying iptables, so you have to balance modifying iptables against people accessing the site via another site domain and direct access of the port.

Ghost as Weblog

Ghost is an important addition to the Node.js community because weblogging software appeals to a broad range of interests and experience levels. That latter is particularly important because we’re now seeing with Ghost the issues people face when running a Node.js web application, particularly in a world where Apache is so ubiquitous. Ghost is a learning experience, and not just for the Ghost developers or users.

Having said that, at this time I don’t recommend Ghost for people who are only looking for a weblogging tool. Ghost is still in the early stages of development and lacks much of the basic functionality we’ve come to associate with weblogging software. However, if you’re interested in Node.js development and are looking to get in on the ground floor of a weblogging application (before all the complex bells and whistles are added), Ghost can be a fun and educational alternative to Drupal or WordPress.

Whatever you do, though, don’t run Ghost with root privileges. It’s no fun to get your butt bitten off.

Categories
Burningbird Technology Weblogging

Another year, another web server

Drupal 7 is right around the corner, and my efforts to see how it would work on my existing server made me decide it is time to move to another hosting company. I need more control over my own space, and what is, or is not, installed. After discussions with the inestimable Laura Scott (@lauras), my go-to person for anything Drupal, I’ve decided on a Linode VPS account.

Linode has attracted a good Drupal community, which is important to me. In addition, it provides an extremely easy to use interface, which makes it quite simple to manage the space. I also like the fact that the company provides a good selection of documentation on how to do things geared to its own environment.

Since I’m making a major Drupal upgrade and moving to a new server, now is the time to look seriously at how my web sites are configured and designed, and make changes. I think this is one of the advantages to major releases—they provide a time to stop, think, and decide if you want to keep what you, or if now is the time to make all those other little changes you’ve been thinking about.

Since I’ve designed my own Drupal themes, I need to upgrade them to Drupal 7, as well as incorporate new HTML5/RDFa features. I may even do a re-design, not sure yet. I don’t like web site designing, so I may just grab one of the existing Drupal themes, and tweak it.

Several of my sites haven’t been updated in a donkey’s age, so I need to figure out if I’m going to continue writing at the sites. I probably will keep most, if not all, but I may do some major re-organizing.

I’ve not been taking many photos this year, as some of you have noticed. I need to re-design my photo pages to incorporate Drupal 7 changes and also my changed photography habits.

I’ve become much more interested in eBooks and the ePub format this last year. I was looking at creating an ePub module for Drupal, but someone already started this effort(Drupal ePub Module). However, there’s been little work on the module, and I’m thinking that an extension to the Print Module is a better approach. Or perhaps the best thing to do is just create an ePub friendly XHTML theme, and do a wget or curl on a book’s pages and use one of the many existing ePub publishing tools to create an ePub eBook. It’s better to be a smart developer than a clever one, and smart developers use what exists. Plus the same pages can be used to create a Kindle book, a Nook, and others.

I have been thinking of incorporating Disqus into some of my web sites. I’ve used this service at other sites, and I like how it works. Commenters can edit their comments, track their discussions across many sites, and they don’t have to provide a username and password for each web site (*cough* Gawker) to expose to hackers. Plus, if I turn comments off, the people still have access to their own writing. And Drupal has a module for Disqus, though I’ve not been able to get it to work with my theme (another reason to re-design my pages).

One thing I really like about Drupal 7 is if you don’t like the new administration interface, you can turn off all the new bits. You can turn off the overlay (don’t like), the page-top toolbar (still considering), and the new Dashboard (a keeper). I also like the fact that all the modules I use now are either incorporated directly into Drupal 7, or the developers have guaranteed a first day Drupal 7 release. Most of the modules have also committed to accessibility—that’s something you don’t often see with content management systems. Or W3C specifications.

Categories
Burningbird Technology Weblogging

My first attempt at Drupal 7 upgrade fails

I made my first attempt to use the new Drupal 7 beta to upgrade my existing module experiment site. Unfortunately, I quickly ran into a fatal error:

DatabaseSchemaObjectExistsException: Table cache_path already exists. in DatabaseSchema->createTable() (line 621 of /home/myname/public_html/books/includes/database/schema.inc).

I submitted a bug for the error at the time it happened. Checking back later, though, I couldn’t find the bug. I assumed I had mucked it up somehow when submitting, so re-submitted it. However, when I checked a couple of minutes later, I couldn’t find the second bug. I noticed then that when you access My Issues, it only shows open bugs. When I adjusted to show all bugs, I found that my bugs had been quickly closed out by someone saying they were duplicates of another.

I can understand the enthusiasm the developers have with wanting to close out bugs quickly, but unfortunately, my bug was not a duplicate of the bug so noted. What caused the problem, though, is known, but the error message I received was inaccurate.

Drupal 7 is dependent on the PHP Data Objects (PDO) extension that is now in PHP core. Previously, we could add PDO via PECL—the PHP Extension Community Library. However, the PECL PDO is out of date and Drupal 7 now only supports the core PDO.

One problem with this, though, is that cPanel, the site management tool popular with many Shared Hosting companies, disabled PHP core PDO because of compatibility issues. It’s only been recently that the application has stopped disabling PDO, but hosting companies like mine are still in the process of upgrading to the PHP core PDO. Until these companies make this upgrade, we can’t upgrade to Drupal 7.

The problem is further compounded by the fact that the Drupal 7 upgrade doesn’t test for the appropriate version of PDO, and we get bizarre errors such as the one I described earlier. Luckily, there is now a patch, which I ended up testing yesterday and that should give people the appropriate error. The problem with it, though, is that it recommends people check out the requirements page for Drupal, which, among other things, informs people that they can install PDO with PECL.

screenshot of Drupal requirements page with PECL PDO instruction highlighted

Hopefully, the disconnects will soon be corrected, and most folks are in environments where the PDO is from PHP core, rather than PECL. I was impressed at how fast everyone did jump on this after the initial duplicate bug mistake was discovered. Once the patch is in place, and the documentation updated, people will at least now know why they can’t upgrade and can chat with their hosting provider about the necessary upgrade.

Until my own shared environment is upgraded, though, I’ll have to stay in 6.x land. Many thanks to Everett Zufelt for his help in pulling all the Drupal pieces together for me.

Categories
Technology Weblogging

WordPress attacks

I’m usually good about reminding (nee nagging) my friends about updating their WordPress weblogs, but in case any of you missed the last upgrade, there’s a good chance your weblog may have been seriously compromised. Lorelle covers the exploit and how you can tell if your site has been compromised.

From other discussions, I gather that if your site has been compromised, it’s going to be a mess to try to fix the problem, because the hacked software is now a part of the database, so exporting your data and re-building won’t help.

It’s not unusual for CMS to develop security problems that need fixing, but I am a little surprised that there’s been no official statement from the WordPress folks and the parent company, Automattic about this issue. Regardless of notification, it’s really important to always update your sites when security releases are issued, no matter what software you use. When I get an update notice for my Drupal sites, I update immediately. If updating is too much of a hassle, or you’re intimidated by the process, then you need to hire someone to help you with upgrades, go with a hosted solution, or change your software.

update Robert Scoble’s site was one that was hacked. There’s an interesting discussion on this at FriendFeed though how long that link will be viable, is hard to say.

I found it disingenuous of Matt Mullenweg to blame Rackspace for the problem Scoble had because of the WordPress exploit. Having said that, security updates rarely impact on plug-ins, and if a plug-in is broken, disable it and do the security update, anyway. I don’t know of any module in Drupal, outside of core, that I am so dependent on that I can’t upgrade Drupal based on a security release. But then, the modularization architecture with Drupal is different than that for WordPress.

As for Scoble, I feel for him, but he’s got plenty of free support. I feel worse for the folks who have to go it alone when trying to fix their sites. Hopefully some of the new articles on this story will provide the help you need, including one just released by Matt at WordPress. I’d offer to help, but I don’t run WordPress now, and I’m becoming less familiar with the tool with each new release. Still, if you’re desperate, holler, and I’ll see what I can do.