Ed's Big Plans

Computing for Science and Awesome

Archive for the ‘Website Management’ Category

Fighting spam account registration (phpBB3)

with 3 comments

I was asked to deploy a means to fight spam account registration on a phpBB3 installation. I tried the advice posted by Nadav Samet, but the version of phpBB3 we use doesn’t seem to respond to changes made to profile_add_body.tpl. I settled on an approach that’s similar to the one posted by Steve Maury, but is slightly improved as you can request any exact string for an answer from the registrant.

This method should work with phpBB3 version 3.0.x.

This method results in a mandatory field to be completed by the registrant during registration time. You can assign it any question you like where the answer is a string of text that you decide. I’ve given a really simple question in this example. Use a more difficult question that a bot would have trouble with but that your typical registrants can answer.

We do this with a custom profile field in the registration screen as in the below screen capture.

The above is a screen capture of an example mandatory question (choose a more secure question).

There are two steps to setting this up.

First, set up a custom question that must be answered — you can find such a setting in the administrative control panel (ACP) as in the following screen capture.

Add a mandatory question in user and groupscustom profile fieldscreate new field.
Here, I’ve named mine guelph_question.

After you click Create new field, you will be presented with a screen where you can create the question of your choosing — be sure to make the field mandatory by using the radio button labelled Required field listed under Visibility options.

Second, add the following code indicated below in includes/ucp/ucp_register.php — Notice that I’ve placed my custom code after existing code to check for a valid password and e-mail. This is commented under validate custom profile fields ( — just checked — starts at line 247 in the 3.0.9 source code). Replace the simple question and answer I’ve placed there with your own question and answer. Notice that you also have full control over the error message that the registrant sees if they answer the question incorrectly.

// validate custom profile fields
$cp->submit_cp_field('register', $user->get_iso_lang_id(), $cp_data, $error);

if (!sizeof($error))
	if ($data['new_password'] != $data['password_confirm'])
		$error[] = $user->lang['NEW_PASSWORD_ERROR'];

	if ($data['email'] != $data['email_confirm'])
		$error[] = $user->lang['NEW_EMAIL_ERROR'];

// Anti-spam code below ...
if (!sizeof($error)) {
	if (!isset($_POST['pf_guelph_question']) ||
	$_POST['pf_guelph_question'] != 'Gryphon') {
		$error[] = 'Incorrect answer to Guelph question.';
// ... EOAnti-spam code

And you’re done.

I hope this works for you! Enjoy 😀

Eddie Ma

December 29th, 2011 at 4:49 pm

Move a Subdirectory to a Subdomain (Apache mod_alias)

without comments

In this post, I’m going to explain how to move resources located at a subdirectory of your domain to its own subdomain. The reason why I came across this was because I decided to move my MediaWiki installation to better separate the URLs corresponding to my blog and my notebook — this is paired with better separation of the actual files and directories corresponding to my blog and notebook as they exist on my server. I’ll assume that you’re running Apache; I’ll further assume that you’ve already gotten your A-RECORD set up with your domain registrar or name server provider (DNS) — if you don’t know what that means, ask me.

I’ll use my MediaWiki move as my running example for this post.

Here are some properties we want a redirect to satisfy — I’ll lead you through to making a redirect such that each of these conditions are met.

  1. Moving the subdirectory to a subdomain corresponds to moving files on the server filesystem.
    • (URL) http://eddiema.ca/wiki = ~/Sites/eddiema/notebook (server filesystem)
    • (URL) http://wiki.eddiema.ca = ~/Sites/notebook (server filesystem)
  2. Requests to the subdomain must work.
    • http://wiki.eddiema.ca
  3. Requests to the subdirectory must be forwarded to the subdomain.
    • http://eddiema.ca/wiki →
    • http://wiki.eddiema.ca
  4. Requests to subdirectories of the former subdirectory must be forwarded to subdirectories of the subdomain.
    • http://eddiema.ca/wiki/index.php/Special:AllPages
    • http://wiki.eddiema.ca/index.php/Special:AllPages
  5. URLs with GET requests to the subdirectory must be forwarded to the subdomain without losing the GET requests.
    • http://eddiema.ca/wiki/?search=Notes+CIS+6050
    • http://wiki.eddiema.ca/?search=Notes+CIS+6050

Let’s meet each of our above properties.

Changing the URL corresponds to a physical move (Property 1)

Move your subdirectory on the server to its target location on the server.

For my example, I moved my notebook out of my main site directory.

mv ~/Sites/eddiema/notebook ~/Sites/notebook

(If you’re moving a MediaWiki installation like me, there’s one more thing you have to do — this is explained at the end.)

Requests to the subdomain must work (Property 2)

Update your Apache httpd.conf configuration file with a new VirtualHost entry. This new entry stipulates a new document root for your target subdomain.

#<VirtualHost *:80>
#    ServerName {full URL to your new subdomain}
#    DocumentRoot {full path to your new document root}

# Example ...
<VirtualHost *:80>
    ServerName wiki.eddiema.ca
    DocumentRoot /Users/eddiema/Sites/notebook

Requests to the subdirectory must be forwarded to the subdomain (Properties 3~5)

There are two ways to accomplish this task — you can either modify Apache’s httpd.conf file, or you can create a new .htaccess file. I chose the latter because I wanted to keep all of the changes related to this move localized.

To accomplish this task, you must perform two steps.

First, you must recreate the subdirectory on your server filesystem that you have just moved elsewhere. We do this so that a request for that directory causes Apache to look there for a .htaccess file in the correct place. This .htaccess file will tell Apache to redirect to your new subdomain instead.

For my example, I recreated the subdirectory with…

mkdir ~/Sites/eddiema/notebook

Second, Create a new plaintext .htaccess file in the recreated subdirectory with a RedirectMatch rule.

#RedirectMatch 301 ^/{subdirectory}/(.*)$ http://{full subdomain URL}/$1

# Example ...
RedirectMatch 301 ^/wiki/(.*)$ http://wiki.eddiema.ca/$1

RedirectMatch is part of mod_alias. If you’re doing something more sophisticated than just forwarding URLs, then you will need to use mod_redirect which has the ability to manipulate query strings.

The number 301 tells browsers and search engines that the URL pointing at your subdirectory is no longer valid and has permanently moved to the one pointing at your new subdomain. The next part is a PERL style regular expression. Let’s break it apart.

  • ^ and $ match the start of, and end of the string respectively.
  • .* means we want to match zero or more characters in a string.
  • (.*) means we want to save the matched string as an autovariable $1.

The last string is appended with $1 to push the tail of any URL of your subdirectory onto the tail of your subdomain.

A final note for moving a MediaWiki installation

In order to stop MediaWiki from appending the subdirectory “wiki” to the tail of your new subdomain (“http://wiki.{your domain}.*/wiki“), you can change the variable $wgScriptPath to the empty string in LocalSettings.php found in the root directory of your MediaWiki installation.

#$wgScriptPath       = "/wiki";
$wgScriptPath       = "";

Note that MediaWiki doesn’t seem to like this idea — but they don’t really say explain why.

After this step, you can use Short URLs (same as above link) to get rid of index.php appearing in the URL, but I won’t go into that today.

That’s everything 😀

Eddie Ma

February 23rd, 2011 at 12:36 pm

Apache Optimized Finally! (Firebug, YSlow)

without comments

I didn’t realize I hadn’t added the mod_expires.c and mod_deflate.c items to my httpd.conf file in Apache yet– Andre clued me in!

Andre noticed my blog was taking a while to load, even when the browser cache should have significantly dented the page weight. He used Firebug and Yahoo’s YSlow to make a diagnosis and told me to do the same– this page ended up taking a whopping 17 seconds to load which is … very … sad. After I added these lines to my httpd.conf file, things were looking better (roughly 1.5 seconds — not perfect, but it’s far better).

The mod_expires.c chunk specifies that files displayed on a webpage ought to live in the browser cache. The caching information is sent as part of the file header by Apache to the client browser. Without this, files were apparently expiring instantly meaning that each refresh required downloading every single file again including including the images comprising this theme’s background.

The mod_deflate.c chunk specifies that file data should be gzipped before transmitting– this is again handled by Apache. The trade off between compressing a few text files (even dynamically generated ones) versus sending uncompressed text is more than fair.

<IfModule mod_expires.c>
    FileETag MTime Size
    ExpiresActive On
    ExpiresByType image/gif "access plus 2 months"
    ExpiresByType image/png "access plus 2 months"
    ExpiresByType image/jpeg "access plus 2 months"
    ExpiresByType text/css "access plus 2 months"
    ExpiresByType application/js "access plus 2 months"
    ExpiresByType application/javascript "access plus 2 months"
    ExpiresByType application/x-javascript "access plus 2 months"

<IfModule mod_deflate.c>
    # these are known to be safe with MSIE 6
    AddOutputFilterByType DEFLATE text/html text/plain text/xml

    # everything else may cause problems with MSIE 6
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/ecmascript
    AddOutputFilterByType DEFLATE application/rss+xml

I’ve also removed the custom truetype font files specified in the CSS… they aren’t handled correctly for whatever reason– even after I added ‘font/ttf’ entries to the mod_expires.c chunk above. Finally, I tried completely removing background images from the site and restoring them again– it doesn’t make things any faster after images have been cached (correctly, finally).

I am very happy.

Eddie Ma

December 24th, 2009 at 5:19 pm