TrackBack spam solved

Following up on the post I just made about the BotBlock plugin, I thought I should mention that the reason I'm getting comment spam is that I turned off the DisableComments plugin on LinLog. The reason I turned it off was to test out the TrackbackValidator plugin that comes standard with LnBlog 0.8.0.

The DisableComments plugin allows you to automatically turn off replies (TrackBacks and comments) on entries older than a given number of days. Since my big problem was TrackBack spam, and it was mostly on entries that were more than a month old, I "fixed" the problem by simply setting DisableComments to disable replies after 30 days. On the up side, this stopped the flood of TrackBack spam. On the down side, it stopped all legitimate replies too.

Well, it turns out that I don't really need the DisableComments plugin as much anymore, Happily, the new TrackbackValidator plugin, which only allows TrackBacks from URLs that actually link to you, has completely solved my comment spam problem. My server access logs will show lots of TrackBack pings, but not a single spam ping has gotten through.

The only down side is that now I need to worry about comment spam on old entries.

BotBlock plugin

I added a new plugin to the plugins page today. It's called BotBlock, and it's just simple attempt to keep robots from posting comments.

I wrote this because, for the past several days, I've been getting a lot of comment spam. The messages were comming in groups of two to six messages at a time, had varying content, and came from varying IP addresses. However, the general format of all the posts was the same (short fake greeting, followed by lines of URLs and two or three word descriptions) and they all targeted the same blog entry. So obviously these were either being posted by a robot or a very stupid human.

Thus I implemented this stop-gap solution. Basically, it just adds a hidden field to the comment form that contains a hash value based on your LnBlog configuration and the client IP address. When the client submits a comment, it checks this hash. If it's either missing or doesn't match the calculated value, the comment is rejected.

Of course, this depends on the bot being relatively stupid and the spammer not being motivated enough to figure out your specific configuration. A determined spammer could bypass this protection without too much effort, which is why I call this a stop-gap. However for small-time blogs like mine, which aren't worth the effort to crack, this solves the immediate problem.

Walk-through part 2: Making a blog

In this installment of the LnBlog walk-through, we'll be taking a look at the administration page and creating a new weblog. This will get you to the point of having a working, if empty, weblog.

Administration Page

When you access the main LnBlog URL again after your initial setup, you will be asked to log in and then taken to the administration page. LnBlog administration page This is where you will create new users, new blogs, and perform upgrade and administration functions.

Let's briefly go through the links you'll find on this page. In the "Add Features" section, the "configure site-wide plugins" link allows you to control the default plugin settings for your blogs. Plugins can be set up on a per-blog basis, so if you don't specifically change the plugin settings for a certain blog, the ones set here will be in effect. I'll cover plugin configuration in detail in a future installment.

The next link, "configure enabled plugins and load order" allows you to disable installed plugins and to change the order in which they are loaded. The defaults will probably be fine for a new installation, but if you want to, for example, put the blog sidebar panels in a different order, the easiest way to do it is by chaning the plugin load order. As with the plugin settings, loaded plugins are configurable on a per-blog basis.

The "edit system.ini file" and "edit group.ini file" links will simply let you edit the indicated files in a text area. Currently (as of version 0.8.0), the only reason to edit group.ini is to make other users administrators. The system.ini file, on the other hand, does have a few setting that you might be interested in. I'll save that for another day, though. Right now, we're still on the basics.

The "modify site-wide menubar" link is used to add custom links to the site map bar under the page banner. Note that this is also configurable on a per-blog basis, so use this link to create the default site map. Note that the site map is controled by the SiteMap plugin, which has several configuration options. If you do not change the settings, then the default behavior is to dynamically add a link in the sitemap to each blog you create, so you really only need this to add links to sections not managed by LnBlog.

The "add new user" link should be pretty self-explanatory. It just lets you create new users, just like you did in the last installment. The only difference is that any new users you create will not be administrators.

Creating Blogs

That brings us to the "add new blog" link. If you click that, you will be taken to the new blog screen. New blog screen Here you will enter the options for your first blog.

The first piece of information you need is the blog path. This is the root-relative URL of the blog and the path to the folder it will be created in. For example, if you give "myblog" as the blog path, then LnBlog will store this blog in a folder called "myblog" under the document root on your web server. The resulting URL of your blog would be http://yourhost.com/myblog/. Note that you can specify paths in this box as well, provided the beginning components of the path already exist. For example, you could give blogs/tech/linux as the path, so long as you already have a /blogs/tech/ on your server.

The blog owner is the username of whoever "owns" this blog. The blog owner is considered the administrator of this blog and can change any of the blog's settings. Note that site administrators, like your first user account, can also change any settings on any blog.

The "additional allowed writers" box lets you list specify a list of other usernames who can post new entries to this blog. You should separate the usernames by commas with no spaces. Note that these users will not be able to change any blog settings (unless they are also administrators).

The blog name and description boxes are pretty obvious - they're the name and description for your blog. These will be displayed in the page banner, the RSS feeds, and various other places. Note that the PageHeader plugin defaults to only show the blog name. There is an option to show the description as well.

The theme drop-down box allows you to select a theme for your blog. A theme is a set of templates, style sheets, images, and scripts that determine what your pages look like. Note that it is possible to customize your pages on a per-blog basis or to simply create your own theme, which can be either entirely original, or simply modifications to a few selected files. The themes use XHTML and CSS with a some inline PHP code to insert variables into templates and control display. Theming is a somewhat complicated topic, which I will, yet again, save for another day.

The "maximum number of entries" box determines how many blog entries to show on the front page of the blog. Likewise, the "maximum number of entries in RSS feeds" determines how many entries to show at once in the RSS feeds.

The "send Pingbacks when posting entries" box is used to enable or disable sending Pingback pings to pages your entries link to. By default, Pingback pings will be sent whether your entries accept Pingbacks pings or not. You can disable sending pings when you post your entry, but this sets the default.

The "allow enclosure for entries" box simply turns on and off the text box for entering an enclosure URL for blog entries. Enclosures are the feature of RSS by which podcasting is made possible. If you don't do any podcasting, then you can uncheck this box to remove the extraneous box from the post editor. If the extra text box doesn't bother you, can can safely ignore this option.

Lastly, the "default markup for entries and articles" box allows you to pick the default mode for writing your entries. You can override this on a per entry basis. The available choices are auto-markup (which is plain text with URLs made clickable), LBCode (which is a variant of BBCode), and raw HTML (no auto-generated code - not even line breaks). The default for new blogs is LBCode, as it is the easiest use, especially if you're familiar with web forums. You can read the LBCode documentation for the full list of supported tags.

When you have filled in all these boxes, click the submit button to create your blog. Note that the path and owner are the only fields that cannot be changed after you create the blog. (Well, technically they can be changed, there's just no graphical interface for it - you have to do it the old-fashioned way, with a text editor and an FTP client.)

You should now be looking at a nice blog page with no entries on it. Next time, we'll briefly go over the how LnBlog handles user security and then we'll move on to filling in that empty blog.

Walk-through: Initial setup

Welcome to te LnBlog walk-through! In this series of entries, I will be walking you through the process of setting up a weblog using LnBlog, from initial installation to advanced customization.

It is my hope that these articles will serve as a guide to help new users get up and running quickly and to help encourage people to try out LnBlog. If you have any questions or feedback, please feel free to post comments or e-mail me privately. I will do my best to answer all questions.

So, without further ado, let's get to it! Today's installment will cover installation and initial configuration. This will take you from zero to the main administration page.

Requirements

LnBlog doesn't have much in the way of requirements. In fact, that's half the point - it's meant to work well on both low-cost shared hosting accounts and full-featured hosting. The only hard and fast requirements are PHP 4.1, the standard Perl-Compatible Regular Expression extention (which nearly every installation should have), and the ability to write files, either through PHP's normal functions or via FTP. Support for the less-common gettext, CURL, and fileinfo or mime-magic extensions is recommended, but not required for proper operation. Things will work better if you have them, but don't worry about it if you don't.

Installation

After downloading a copy of LnBlog, the first order of business is to get it on your web server. To do this, simply extract the LnBlog-version.zip file to your hard drive and upload the resulting folder to your web host. You will probably want to rename the directory to remove the version number, so that upgrading to a newer version will be easier. Note that you need to upload the folder to someplace under your document root directory, i.e. somplace where you can get to it with a web browser.

Initial Configuration

To configure LnBlog, fire up your favorite web browser and point it to the URL corresponding to where you put the LnBlog folder, e.g. http://yourhost.com/LnBlog/. This will launch the file writing configuration screen, seen here. LnBlog file writing setup screenThe first section asks you to set the path to the document root directory on your web server. LnBlog will calculate a default value for this. The default should be right for your setup, but you can change it here if it's not. If you're not sure, try the "test document root" link to run a simple test.

The second section on this page asks you to configure file writing. Here, you have two choices. You can either use PHP's native file writing functions, or you can write files through FTP. For shared hosting accounts, especially cheap ones, the recommended setup is to use FTP file writing, because you won't have to worry about safe mode or directory permissions.

If you choose native file writing, no further configuration is required within LnBlog. However, there are a few things to keep in mind. First, native file writing won't work with PHP's safe_mode enabled, so you'll have to get your hosting provider to turn it off for your account. Also, you will have to check the file permissions on the web server and make your LnBlog/userdata folder writable to everyone. Keep in mind that when you create new blogs, you will also have to the directory where you create them writiable to all users. Because file permissions have to be handled manually, native file writing can be harder to manage, especially when using shared hosting accounts.

FTP file writing should not require many manual setup and it works just fine when safe_mode is enabled. However, it does require that you have FTP access to your web space. It also requires some extra configuration.FTP file writing configuration You will need to provide a username and password for a user account which can upload files to your site via FTP. LnBlog will assume that the FTP server is running on the same machine as the web server (hence the name localhost) and will attempt to calculate the root directory for FTP access automatically. This should work for most configurations, but you can also specify these manually if you need to. You can click the "test FTP root" link to get a simple test page that will attempt to connect to the FTP server and calculate the FTP root directory.

Once you have picked your file writing method, click the submit button. If all goes well, you will be taken to the user creation page. Create new administrator pageThis page allows you to create a new user who will serve as the system administrator. That means that this user will be able to create other user accounts, create new blogs, and make changes to any existing blog or post. In other words, an administrator is allowed to do anything that can be done in LnBlog.

As for the fields themselves, you can enter any username you like. The "real" name is the name that will be displayed as the author's name on posts you create, so it is recommended that you specify some name here. An e-mail address is required if you want to get e-mail notifications of replies (i.e. TrackBacks, Pingbacks, and reader comments). The homepage is purely for informational purposes. Lastly, the contact URL allows you to enter an HTML like that allows people to contact you. If you enter a link here, then that will be displayed in your profile instead of your e-mail address.

Once you have successfully created your account, you will be redirected to the login page. Note that this first user account will be automatically marked as the administrator, so you will be able to use this account to log in and administer LnBlog. This includes editing configuration files, creating new users, creating new blogs, and so forth. We'll take a look at the administration page and creating anew blog in the next installment.

LnBlog 0.8.0, "No Need for TrackBack"

Well, it's finally here: LnBlog 0.8.0 is now available. You can grab it here or go to the download page.

Several files have been removed in this release, so to upgrade, you should upload the new directory to your server and then copy/move your old userdata folder into it. Before that, though, you might want to take a look at the new system.ini file, just to see what the new options are. That part is optional, though.

Lots of changes and lots of bug fixes in this release. I won't bore you with all (or even most) of the specifics. That's what the changelog is for. However, for this version, I did do some extra testing and even documented the outstanding problems in this release. Fortunately, most of them are relatively small.

There are bunches of new features. First, LnBlog now has support for Pingbacks. You can turn on and off both the sending and receiving of Pingbacks on a per-entry basis. Note that there is an AllowLocalPingback setting in the entryconfig section of the system.ini file. If you set this to 0, then LnBlog will not send Pingback pings to enrties on your

Second, there's a new standard plugin: the TrackbackValidator. Basically, this checks the URLs of incoming TrackBack pings to see if they link to your blog. This works on the principle that legitimate TrackBacks almost always link to you, but TrackBack spam almost never does. So far, it seems to have completely eliminated my TrackBack spam problem.

Third, there's now a standard profile.ini file. This adds a custom "contact me" link field for your profile. This field takes an HTML link as its input. If this is given, then your e-mail address will not be displayed in your profile. You can use this with the ContactForm plugin.

Fourth, LnBlog now has simple Podcast support. Basically, this means you can add an enclosure URL to your entries and it will be included as an RSS enclosure in the RSS 2.0 feed (if you have one). You can either enter the RSS attributes directly, specifying url="http://somehost/file" length="12345" type="audio/mpeg", or, if the file in on the same server as LnBlog, you can give the URL and let LnBlog compute the file size and MIME type. Note that you can also use LBCode-style relative URIs, giving only the name for files in the entry directory, or a path relative to the blog root.

Last, I've reworked the post editor, including a lot more JavaScript. I've condensed the LBCode editor buttons, added a drop-down menu to add topics, and hidden the extra settings in an expandable box. I think it's much easier to use now. Also note that there's an EditorOnBottom setting to the entryconfig section of the system.ini file. Although it's not acutally in the default file, the default value is 0, which puts the editor buttons above the text area. Add this setting with the value of 1 to put them below.

I think that pretty much sums up the big things for this release. As usual, all forms of feedback are welcome. If you have any comments, find any bugs, or whatever, feel free to leave a comment, e-mail me, or whatever.

New post editor

Here's a little sneak preview of the New post editorchanges I've made to the post editor for the next release. I've cleaned it up a little and added a fair amount of "unobtrusive JavaScript" for enhancements. Here's a screenshot of the basic view.

The default view is simpler than in previous releases. Notice the drop-down topic list so you no longer have to type in existing topics. The LBCode editor controls are also closer to the content area, so you can actually get to them. They also disappear when the markup type is something other than LBCode, so they're not in the way.

The rest of the post settings are available by expanding the lower panel. Here's the shapshot. Post settings panel Of course, the default configuration only has one upload box, but that can be changed in your system.ini. The new features to note here are, of course, the box to allow Pingbacks and the enclosure URL. If you're not familiar with RSS enclosures, they're basically the mechanism by which "Podcasting" is made possible. As with other URLs in LnBlog, you can specify a relative URL in this box.

So far, I think the new setup is pretty good. More functionality, fewer distractions, and just generally better. This interface will be available in the next 0.8.0 prerelease, which I'll be putting up some time this week.

TrackbackValidator: sneak preview

I read an interesting article on TrackBack spam today, called Taking TrackBack Back (from Spam). The ideas seemed sensible to me, so I banged out a TrackbackValidator plugin to implement it.

The idea behind the paper and the plugin is simple: the sites linked to by TrackBack spam never contain a link back to your blog entry, but nearly every legitimate blog entry that pings you does. Therefore, rather than fancy content filter, we can eliminate TrackBack spam by simply fetching the URL in the ping and only accepting it if the page actually contains a link to your site.

This plugin implements that idea. It also includes options to white-list all pings coming from your domain and to allow ping that link to files under your entry (e.g. an uploaded file or the comments page) rather than just the permalink. My spam rates have been way up lately, so I'll be uploading this tonight and we'll see how it goes.

Release preview

It's time for a preview release. We'll call this one LnBlog 0.8.0-pre1. I don't really want to call it a beta release, because that would imply that the feature set is at least close to finalized. I'm actually still not sure if I want to release after a little more testing or add a few more features and call it version 1.0.0.

Since this is a testing release, I of course recommend keeping a backup copy of the previous version around. No blog upgrades are required, so just upload the new version and rename it after your old installation. Note a few old plugins are now redundant and have been removed and a file has been added in the userdata folder, so I the recommended starting with the fresh installation directory and copying over your old userdata folder rather than trying to upload the new files into your existing directory.

This is going to be a major feature addition release. The big one in this release is support for sending and receiving Pingbacks. If you're not already aware, Pingbacks are very similar to TrackBacks, in that they are used to send a notification to another blog that you've linked to them. The main differences are that 1) Pingbacks are significantly more complicated to implement and 2) Pingbacks don't suffer from the same spam problems as TrackBacks, due to the fact that the server, rather than the client, determines what data goes into them.

The second bigish feature is support for enclosures. Basically, this means podcasting support. An enclosure is just a hint to an RSS reader that a post is related to a particular file so that it can be downloaded in the background. All you need to do is enter the URL of the file in the box and, provided it's on the same server, LnBlog will calculate the MIME type and file size to insert into the RSS feed. I also added a default profile.ini file that allows you to enter a "contact me" URL. Basically, you enter the HTML for the link you want and this will be displayed in your profile instead of your e-mail address. You can use that in ContactForm plugin.

There's a bunch of smaller stuff in this release too. Check the change log for the details. For starters, I did some cleanup to various plugins. For example, I added a "ban and delete" option to the IPBan plugin, added the "new standard" RSS icons to the sidebar, made the calendar look slightly less crappy, added a stylesheet to the RSS 2 feeds (so they look like something in a browser), and created RSS feeds for comments even when there are no comments yet.

There are also a number of small bug fixes. For example, TrackBacks finally work regardless of whether or not you have CURL. I also found a bug with receiving the response code when sending TrackBacks. I also fixed a few small display issues that were weird or didn't make sense.

Last, there's a bit of code cleanup and consolidation. For instance, the TrackbackNotifier and CommentNotifier plugins are now gone, replaced by a generic ReplyNotifier plugin that handles comments, TrackBacks, and Pingbacks. I also consolidated some functions in the utility library and a few things in the entry subclasses.

I'm debating whether to hold off on the next release, add some features, and go straight to version 1.0. Before that, I want to at least add a simple theme editor. My plan is to do something very simple and hacky: a stylesheet editor. Basically, just a GUI to automatically generate a stylesheet based on settings entered by the user. The idea is that this stylesheet will just be inserted into the page last, thus overriding the default settings for the theme.

Other possibile features include more granular security, support for draft entries, and Atom feeds, among other cleanup. If I'm going to go straight to version 1.0, then I'll probably try to do some of these first. Anyone have any thoughts on other features for 1.0 or opinions on the release schedule?

Even lower: userconfig.php and setting the timezone

In an earlier post, I talked about low-level customization with userconfig.cfg. Well, there's actually an even lower level. That would be userconfig.php.

The principle is simple: userconfig.php is a PHP file that, if it exists, is loaded and executed before anything else. So, in other words, this is the place to put any code you need to modify your PHP configuration or things of that manner.

One handy use of this is setting the time zone. You might want to do that if you're like me and use a web host that's in a different time zone than you are. Sadly, PHP 4 doesn't provide an easy way to format dates to a different time zone. However, if you're using a typical Linux/Apache server, you can simply set an environment variable to take care of this.

To do this, you can just create a userconfig.php file in your userdata and add the following text to it (substituting your own timesone, or course):
<?php
putenv("TZ=US/Eastern");
?>

If you need to add any other special PHP code, such as ini_set() calls, it would go between the PHP tags. Just keep in mind that you can't have any characters or blank space (including blank lines) outside the PHP tags.

Of course, since this file is raw PHP code, it's not a good idea to mess with it too much unless you really know what you're doing. In fact, it's probably a bad idea to use it if you don't have a working knowledge of PHP. It's really only there to make things easier for those rare occasions where you really, genuinely do need to add some code when a page loads.

New plugin: HideSidebar

I've uploaded a new plugin to the plugins page. It's called HideSidebar and it, well, hides the sidebar. The idea came from this comment and the plugin is a sort of proof of concept. I don't know how useful it will be, but it's a good demonstration of the power of the plugin system.

For the curious, it works by injecting an inline JavaScript into the page when it loads. It has PHP code to add a link to the menubar and insert the JavaScript into the page. The JavaScript then manipulates the DOM to hide the sidebar when the link is clicked. It's really quite simple. In fact, the JavaScript portion took me longer to write than the rest of the plugin.