2010
07.24

Again another long time between posts, this one is partly a small tutorial and partly about a small issue I encountered and workaround. This post discusses form validation using a cool jQuery form validation plugin created by Jörn Zaefferer, which I highly recommend, you can download the plugin from here. The plugin allows you to quickly and easily validate your html forms using the power of jQuery, the basic principle is that you specify the rules for validation on the fields of your form and submitting the form will be disabled until all fields are valid, where validation rules are broken the user is informed with messages next to the invalid fields. I wouldn’t be surprised if this plugin became part of jQuery directly since so many people are using it already.

Lets have a look at a quick simple example, lets say I have a form with 3 input fields, name, email and website, we want to have the name and email fields required, we want to check the email is valid and because we are storing these fields in a database with a character limit we need to check the fields are not too long. Below is the html form code and the javascript for the validation.

<script type="text/javascript">
$(function(){
    $("#subscribe_test").validate({
        rules: {
            fullname: { required: true, maxlength: 64 },
            email: { maxlength: 32 },
            website: { maxlength: 32 }
        }
    });
});
</script>

<form id="subscribe_test" action="save_subscriber.php" method="POST">
<table>
<tbody>
<tr>
<td><label for="fullname">Full name: *</label></td>
<td><input id="fullname" type="text" /></td>
</tr>
<tr>
<td><label for="email">Email: *</label></td>
<td><input id="email" class="email required" type="text" /></td>
</tr>
<tr>
<td><label for="website">Website:</label></td>
<td><input id="website" type="text" /></td>
</tr>
<tr>
<td><input type="submit" /></td>
<td></td>
</tr>
</tbody>
</table>
</form>

In the above example you can see that you can apply the validation rules both in javascript and also using the predefined rule names as the css class for the input. E.g. the email input field is using classes email and required, the validation plugin will look for any class names on the inputs and apply the validation rule if there is one. I could have defined the email rule solely in the script but I wanted to show that there is a quicker way using classes. The working example for the above code is below.

You can also do remote validation. For example, lets say in our example we did not want someone with the same email address to be subscribed twice. You can use a special validation rule remote which points to a script which should output true or false based on the form input value. We will also give a special message for when the email address is already in use. The changed script code is then:

<script type="text/javascript">
 $(function(){
     $("#subscribe_test2").validate({ rules: {
         fullname: { required: true, maxlength: 64 },
         email: { maxlength: 32, remote: "check_subscribed.php" },
         website: { maxlength: 32 }
     },
    messages: {
        email:{ remote: "Already subscribed" }
    } });
 });
</script>

The running example now will not allow you to enter the email test@example.com, for this example there is a script called check_subscribed.php which is hard coded to look for the POST email variable and return false if it equals test@example.com.

So that is all good everything seems to be validating fine. Now I will show you a small case to watch out for. Lets assume that the subscribe form needs to be submitted using ajax and only accepts a required email address which should be remotely validated. Below is the code and the working example, if you simply enter the already subscribed email test@example.com and submit you see it does not work properly, the form gets submitted even though the validation fails. Code and example below.

<script type="text/javascript">
jQuery(function($){
       $("#subscribe_test3").submit(function(e){
          if ($(this).valid()){
               $.ajax( {
                   type: "POST",
                   url: "save_subscriber.php",
                   data: "email="+$("#subscribe_test3_email").val(),
                   success: function(data){
                        $("#submit_result").html("Ajax submit results:<br />" + data);
                   }
               });
          }
          return false;
    });
    $("#subscribe_test3").validate({ rules: {
         email: { maxlength: 32, remote: "check_subscribed.php" }
     }, messages: {
        email: { remote: "Already subscribed"}
     }
     });
});
</script>

<form id="subscribe_test3" action="save_subscriber.php" method="POST">
<table>
    <tr>
        <td><label>Email: *</label></td>
        <td><input id="subscribe_test3_email" class="email required" remote="check_subscribed.php" name="email" type="text"/>
        </td>
    </tr>
    <tr>
        <td><input type="submit"/></td>
    </tr>
</table>
<div id="submit_result"></div>
</form>

The reason the above example did not work properly is because the remote validation checking is done asynchronously, as is the ajax request. In the above code, the form submit event binding function checks first if the form is valid before doing the ajax submit. The trouble is that the remote validation is done asynchronously. So the valid check is just returning true instead of false. In order to solve this the remote validation needs to be done synchronously instead (or async: false). Below is the relevant fix and the fixed example.

$("#subscribe_test3").validate({ rules: {
         email: { maxlength: 32, remote: { url: "check_subscribed.php", async: false } }
     }, messages: {
        email: { remote: "Already subscribed"}
     }
});

2010
05.08

Very recently I decided to clean my home FreeBSD server  and start from scratch, meaning deleting everything and reinstalling FreeBSD. The fact that I happened to do this after completely messing up my ports system is purely coincidence… ;)

I took the time to try out the new FreeBSD release 8.0, so I downloaded the iso from the FreeBSD site, burned it and installed it on my home server (the server I’m referring to is in this post). After reinstalling all the ports I had on it previously (Apache, MySQL, PHP5, PHP5-extensions, Java 1.6, Openfire etc.), I decided to go one step further and try something I hadn’t done before, get email working.

DNS settings

To be able to receive email I needed a domain, now it happens that I purchased chrismcdonald.co.uk at some point last year, got it very cheap for 2 years from 123-reg. The domain wasn’t really doing anything and was just being used to forward to this blog (and still is), so I decided to get more use out of it and use a subdomain to point to my home server. I set the hostname of my FreeBSD server to server.chrismcdonald.co.uk by adding hostname=”server.chrismcdonald.co.uk” to /etc/rc.conf and added an entry in /etc/hosts so that it would resolve locally. So my hosts file now contained:

127.0.0.1               localhost server.chrismcdonald.co.uk

To get the domain to point to my home server I changed my dns records for chrismcdonald.co.uk and added a CNAME record pointing server.chrismcdonald.co.uk to my dynamic dns host chris.is-a-geek.net. I also added an MX record for the root domain which directs email to chrismcdonald.co.uk to chris.is-a-geek.net. Dynamic DNS allows users with a non-static IP (most home internet users) to use a host name to refer to your system’s ip address, which might change whenever you connect to your ISP. It works by having your home system contact the dynamic dns provider every so often to make sure the ip address mapping is kept up to date. I use dyndns.com, you can create a free account with them where you can create some free host names to use. You get to pick your own subdomain from any one of the domains they allow you to use, I chose the domain is-a-geek.net and my subdomain chris. My wireless router has built in support to work with dyndns.com and keep my host ip address updated, but if yours does not, there are some instructions also in my older post to get this working on FreeBSD.

Receiving mail

To ensure I could send and receive email past my wireless router, I added some port forwards for ports 25 (smtp), 465 (secure smtp) and 993 (secure imap), I already have existing port forwards set up for web and ssh access. Sendmail is configured by default to only allow sending of email and receiving mail only from localhost. To enable sendmail to receive mail externally I added this line to /etc/rc.conf and started sendmail again.

sendmail_enable="YES"

/etc/rc.d/sendmail stop
/etc/rc.d/sendmail start

OK so with the domain name sorted out and sendmail set to receive external mail I tried testing it out. I logged into another remote server, which was located outside of my local network on the internet. I used telnet to attempt to manually send an email. Below is the transcript, my commands are in bold, square brackets are for your server name and email.

telnet server.chrismcdonald.co.uk 25
Connected to chris.is-a-geek.net.
Escape character is '^]'.
220 server.chrismcdonald.co.uk ESMTP Sendmail 8.14.4/8.14.3; Sat, 8 May 2010
12:08:15 +0100 (BST)
HELO [remote server name]
250 server.chrismcdonald.co.uk Hello [remote server name and ip] , pleased
to meet you
MAIL FROM: [user@remoteserver]
250 2.1.0 [user@remoteserver]... Sender ok
RCPT TO: [user@server - in this case chris at chrismcdonald.co.uk]
550 5.7.1 [user@server]... Relaying denied
QUIT
221 2.0.0 server.chrismcdonald.co.uk closing connection

So it appeared that my server was not accepting email for my domain. To fix this I created the file /etc/mail/local-host-names and added the following lines, you would add your own hostnames.

chrismcdonald.co.uk
server.chrismcdonald.co.uk

Then when I tried again:

telnet server.chrismcdonald.co.uk 25
Connected to chris.is-a-geek.net.
Escape character is '^]'.
220 server.chrismcdonald.co.uk ESMTP Sendmail 8.14.4/8.14.3; Sat, 8 May 2010
12:08:15 +0100 (BST)
HELO [remote server name]
250 server.chrismcdonald.co.uk Hello [remote server name and ip], pleased
to meet you
MAIL FROM: [user@remoteserver]
250 2.1.0 [user@remoteserver]... Sender ok
RCPT TO: [user@server - in this case chris at chrismcdonald.co.uk]
550 5.7.1 [user@server]... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Subject: test email again
Just testing
.
250 2.0.0 o48BLo6R001500 Message accepted for delivery
QUIT
221 2.0.0 server.chrismcdonald.co.uk closing connection

Sure enough I had the new email in my local mailbox (checked by running mail).

IMAP access

So now I could receive mail from outside, I looked around for a few guides to get started on setting up secure IMAP and secure SMTP sending. I needed a program that would provide IMAP access to mail and came across this blog post on Dovecot on freebsddiary.org, this is a great site with loads of tutorials and info on FreeBSD. I followed the steps in the guide to install Dovecot with some minor adjustments.

cd /usr/ports/mail/dovecot
make install clean

Below are the make options I used:

Dovecot make options

Dovecot make options

You can follow those steps from freebsddiary if you are starting from scratch. I ignored the certificate stuff because I already had a self signed one created, I also chose to use PAM authentication, which uses your user account password to authenticate. The important bits which I changed from /usr/local/etc/dovecot.conf are below, change them where they occur in the file:

protocols = imaps
ssl_cert_file = /etc/ssl/certs/server.chrismcdonald.co.uk.cert
ssl_key_file = /etc/ssl/private/server.chrismcdonald.co.uk.key
ssl_key_password = ******************
mail_location = mbox:~/mail/:INBOX=/var/mail/%u
protocol imap {
listen = *:143
ssl_listen = *:993
# Login executable location.
...
}
auth default {
  # Space separated list of wanted authentication mechanisms:
  #   plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp skey
  #   gss-spnego
  # NOTE: See also disable_plaintext_auth setting.
  mechanisms = plain login
...
}

Then add the following to /etc/rc.conf and start dovecot.

dovecot_enable="YES"

/usr/local/etc/rc.d/dovecot start

Now I access my mail using imap securely over port 993. So far the server is able to receive mail, send mail (only from localhost) and has secure imap access to read mail, if this is suitable for what you need you can stop here. If you want to be able to send mail from another machine using your secure smtp read on.

SMTP sending

I found a couple more guides on having secure smtp authentication here and here. I did not follow those steps but borrowed some from both guides. The common setup appears to use cyrus sasl (Simple Authentication and Security Layer) for the authentication and to configure sendmail to use it. SASL SASL support is not build into sendmail by default, the guides said to recompile sendmail from its source /usr/src/usr.sbin/sendmail which I couldn’t find, I guess these things are all done using the ports system now, so here’s what I installed.

cd /usr/ports/security/cyrus-sasl2
make install clean
cd /usr/ports/security/cyrus-sasl2-saslauthd
make install clean
cd /usr/ports/mail/sendmail-sasl
make install clean

Then I needed to enable the sasl daemon by editing /etc/rc.conf and adding this line and starting the sasl daemon.

saslauthd_enable="YES"

/usr/local/etc/rc.d/saslauthd start

Finally sendmail needed to be configured to use secure smtp authentication, I also copied my certificate files that I generated a while back into /etc/mail/certs. I copied the default freebsd.mc and freebsd.submit.mc files located in /etc/mail to server.chrismcdonald.co.uk.mc and server.chrismcdonald.co.uk.submit.mc and edited server.chrismcdonald.co.uk.mc. Then following bits from both guides I added the following:

dnl set SASL options
TRUST_AUTH_MECH(`GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN')dnl
define(`confAUTH_MECHANISMS', `GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN')dnl
dnl Offer SMTP AUTH only after encryption (STARTTLS) has been negotiated
define(`confAUTH_OPTIONS',`p,y')dnl

define(`CERT_DIR', `/etc/mail/certs')dnl
define(`confCACERT_PATH', `CERT_DIR')dnl
define(`confCACERT', `CERT_DIR/server.chrismcdonald.co.uk.cert')dnl
define(`confSERVER_CERT', `CERT_DIR/server.chrismcdonald.co.uk.cert')dnl
define(`confSERVER_KEY', `CERT_DIR/server.chrismcdonald.co.uk.key')dnl
define(`confCLIENT_CERT', `CERT_DIR/server.chrismcdonald.co.uk.cert')dnl
define(`confCLIENT_KEY', `CERT_DIR/server.chrismcdonald.co.uk.key')dnl
DAEMON_OPTIONS(`Port=smtps, Name=TLSMTA, M=s')dnl

The lines starting with dnl are comments and those backticks ` are not typos, the opening quote is a backtick and the closing one a normal apostrophe. Finally after running the following in /etc/mail I had secure smtp authentication working:

make
make install
make restart

Well, that’s it for another post, sorry it was such a long one. I am buying a couple of real servers on eBay that wer e going pretty cheap, the kind they use in datacentres. I will probably have a go at getting internal dns working, so that I won’t be restricted to a single server working at home. If it works I will do another post on it.

2010
03.26

Today I came across an annoying problem involving the RegExpValidator class in Flex. In flex app for one of our projects StickyWorld, we allow users to upload images, pdfs, 3d models and most recently, reference YouTube movies inside a virtual room where people can comment on them, adding sticky notes in context. In our upload window, users can choose what type of media they want to add to the room, in the case of a YouTube video only the video id is required. To make it a bit more flexible we decided to allow the users to specify a url to a video as well as just the video id. The app needed to handle urls in several different formats, e.g.

  • http://www.youtube.com/watch?v=[videoid]
  • http://www.youtube.com/v/[videoid]
  • http://www.youtube.com/[userchannel]/[somepath]/[videoid]

Sounds like a job for a regular expression right? Since we also wanted to do some validation on the field to make sure we were given a valid YouTube video url or video id, it seemed that the RegExpValidator class was perfect for the job. However after adding the RegExpValidator in MXML I had a problem that took a good while to figure out what was wrong.

Below is the snippet of code containing the regular expression string, its use in the validator and a validation handler function, apologies for the wrapping of the regular expression, I have split it below where the main formats are separated by pipes.

[Bindable]
private var youtubeRegExp:String
"^(?:http:\/\/(?:www\.)?youtube\.com\/watch(?:\?|#!)v=(.\{11\})(?:&.*)?
|(.\{11\})
|http:\/\/(?:www\.)?youtube\.com\/(?:v|[A-Za-z0-9#\/_\-]*)\/(.\{11\}))$"
;

private function youtubeValid(ev:ValidationResultEvent):void
{
    if (ev.type == ValidationResultEvent.VALID) {
        for (var i:int = 0;
                i < ev.results[0].matchedSubstrings.length;
                i++
        ) {
             if (ev.results[0].matchedSubstrings[i] != null)
                  youtubeVidId = ev.results[0].matchedSubstrings[i];
        }
        txtName.text = youtubeVidId;
        btnSubmit.enabled = txtYouTube.text.length>0;
    } else {
         btnSubmit.enabled = false;
    }
}

<mx :RegExpValidator id="youtubeValidator"
    source="{txtYouTube}" property="text"
    expression="{youtubeRegExp}" valid="youtubeValid(event)"
    invalid="youtubeValid(event)"
    noMatchError="YouTube video url/id invalid"
    trigger="{txtYouTube}"/>

The problem was, nothing was coming out as valid, not even the videoid just by itself. So wrote a test using the regular expression, creating a RegExp object using the expression and testing some urls using the exec function and it appeared to be working fine, so why not with the validator? In the end it turned out to be that the problem was down to several characters needing to be escaped. The correct expression that worked is below:

youtubeRegExp =
"^(?:http:\/\/(?:www\.)?youtube\.com\/watch(?:\\?|#!)v=(.\{11\})(?:&;.*)?
|(.\{11\})
|http:\/\/(?:www\.)?youtube\.com\/(?:v|[A-Za-z0-9#\/_\-]*)\/(.\{11\}))$"
;

Since the regular expression used in RegExpValidator needs to be a String and the String is used as a bound property in MXML the curly brackets need to be be preceded with a backslash, because without them in MXML it means a data binding. That didn’t make much sense to me, since I was binding a String variable which contained the expression, but ok, I can kind of see the problem. What made even less sense was that I needed to double escape the ? when I actually wanted to include a literal ? in the expression. So I suppose since it is a string and I want to include the backslash character before the question mark I need to escape the backslash itself, leaving \\?, but then shouldn’t I have to do that for all the other times I need to include a backslash in the expression? Well it turns out the answer is no, I do not really understand it and only figured this out after a lot of debugging.

Another pitfall to avoid, if you are binding on a condition in MXML and you need to use logical operators, you will need to encode the logical AND && should be &amp;&amp;, the less than < should be &lt; or greater than signs > should be &gt;, logical OR || works fine. However in those cases you should really be binding to a function which returns the boolean result you are looking for.

Working with MXML is cool because you can create data-bindable UI components quickly and easily, but it really isn’t when you have to worry about silly issues like wondering why your regular expressions are not working.

2010
03.12

It has been another long time between posts, but here is as promised, but very delayed, the second part to this post.

Working with git repositories in trac

It is incredibly simple to use a git repository instead of svn with trac, you just need to have the right plugin installed and enabled. Once again I’ll give install details for FreeBSD and Ubuntu.

Firstly we need to install the trac git plugin. For FreeBSD there is as usual a dedicated port install for what we need. As of writing the plugin version is 0.11.0.2 r7034. As the root user run:

cd /usr/ports/www/trac-gitplugin
make install clean

Ubuntu users, as root or using sudo:

apt-get install trac-git

With the trac git plugin installed, all we need to do is create a new git repository if we haven’t got one already and create a new trac project pointing to the git repository (or edit the trac.ini config file of an existing trac project). So following from the FreeBSD logic in the previous post, lets create a new git repository in /usr/local/git as root.

cd /usr/local
mkdir git
cd git
mkdir MyGitProject
git init MyGitProject

The git repository above was created by the root user, if you are accessing the git repository over ssh and want to be able to push changes to it, you will need to make sure that the user has read and write access to the folder and everything in the .git folder. What I have done in the past is create a group on the system called developers and add all the user accounts to the group. Then change the group of the git repository to developers and give it group write access. You have to make sure the whole folder and all files are writable by this group or you will get errors trying to push to the repository. An alternative is to just create the git repository using one user account or change the owner of the whole repository to a specific user account and only use that user account to push and pull to the server.

With the repository created, we can now create a new trac project, this is the same steps as in the previous post but we change the repository type from svn to git.

cd /usr/local/trac
mkdir MyTracGitProject
trac-admin MyTracGitProject initenv

The trac-admin program runs in interactive mode and will ask you questions to set up your repository, example questions and responses are given below.

Project Name [My Project]> My Trac Git Project
Database connection string [sqlite:db/trac.db]>
Repository type [svn]> git
Path to repository [/path/to/repos]> /usr/local/git/MyGitProject/.git

Now we just need to edit the trac.ini, this is in the trac project folder, so in our case /usr/local/trac/MyTracGitProject/conf/trac.ini. Make sure that under the [trac] section repository_type is git and the repository_dir is correctly pointing to the .git folder. Also FreeBSD gets the location of the git binary wrong, under the [git] section change git_bin from /usr/bin/git to /usr/local/bin/git. Finally, add the following if your trac.ini file does not already have it.

[components]
tracext.git.* = enabled

Now we just need to change the owner of the new trac project to the web user and edit the apache config for the new trac project location. See the previous post for how to do that.

Adding Mylyn support for trac

Mylyn for Eclipse is great, if you are not using it already, you should be. It basically allows you to create tasks, those tasks you can activate and work on, whilst a task is activated it looks at what files you have open and have been working on. So that the next time you activate the task, you see only the files that are most relevant to the task, for more info on Mylyn go here. Mylyn is integrated in the more recent editions of Eclipse, but there is a Mylyn trac plugin that allows you to create and view tickets in your trac repository. How nice is that? If someone reports a new bug, you can see it appear right in your IDE, work on it and close it, all from within Eclipse.

To get the Mylyn support working in trac you need to install and enable the xml-rpc plugin. As usual FreeBSD has a port for it.

cd /usr/ports/www/trac-xmlrpc
make install clean

Ubuntu users can run:

easy_install -Z -U http://trac-hacks.org/svn/xmlrpcplugin/trunk # 0.11

At the end of the install process keep a look out for the location where the python egg was installed, we need to copy that file to our plugins folder in the trac project. This was /usr/local/lib/python2.6/site-packages/TracXMLRPC-1.0.6-py2.6.egg on FreeBSD.

Edit the trac.ini file, under the [component] section add:

tracrpc.* = enabled

Now when you go to the admin section of your trac site you should see the xml-rpc plugin available under Plugins.

Close and comment on trac tickets in your SVN commit messages

You can have trac close and add comments to your tickets simply by including certain text triggers in your SVN commit messages, such as fixes #231, refs bug:29. To get this working you need to include a special script in your svn repository location. First download this python script from the trac web site. Save it in a location which is easily accessible, on FreeBSD I put the script in the trac share folder /usr/local/share/trac.

Now go to your svn repository location in the hooks folder you should see a lot of files with a .tmpl extension. One of them is post-commit.tmpl, we need to copy this and edit it as follows:

cp post-commit.tmpl post-commit
edit post-commit

Ignore all the comments, at the end make sure the file reads as below:

TRAC_ENV="/usr/local/trac/[TracProjectName]"
REPOS="$1"
REV="$2"

/usr/local/bin/python /usr/local/share/trac/trac-post-commit.py -p "$TRAC_ENV" -r "$REV"
#mailer.py commit "$REPOS" "$REV" /path/to/mailer.conf

Replace [TracProjectName] with your trac project name or change the path if yours is different. I specified the full path to the python command, on freebsd when this shell script is triggered the script does not inherit you environment PATH, so absolute paths to commands need to be specified, at least on FreeBSD anyway. Change the path of the trac-post-commit.py file to wherever you saved it. I commented out the mailer.py script, this is another post-commit script that you can run which sends an email detailing the commit. This script should be shipped with your subversion installation, on FreeBSD it is in /usr/local/share/subversion/hook-scripts/mailer/mailer.py.

Finally we need to make sure that the python script is executable and owned by the web user like everything else in the svn repository.

chmod 755 post-commit
chown www post-commit

Now when you do your next commit to the repository try closing or referencing one of the trac tickets. You can refer to a ticket by prefixing the ticket number with #, ticket:, issue: or bug:. You can close a ticket using by using a command prefix close, closed, closes, fix, fixed, fixes before the ticket reference. To comment on a ticket but not close it use any of these command prefixes: addresses, re, references, refs or see.

You can customise these commands or ticket references, just edit the trac-post-commit.py file, the following is what you’ll need to change:

ticket_prefix = '(?:#|(?:ticket|issue|bug)[: ]?)'

    _supported_cmds = {'close':      '_cmdClose',
                       'closed':     '_cmdClose',
                       'closes':     '_cmdClose',
                       'fix':        '_cmdClose',
                       'fixed':      '_cmdClose',
                       'fixes':      '_cmdClose',
                       'addresses':  '_cmdRefs',
                       're':         '_cmdRefs',
                       'references': '_cmdRefs',
                       'refs':       '_cmdRefs',
                       'see':        '_cmdRefs'}

So, thats all for now. Apparently you can also do git post-commit hooks as well, but as I am not using git that much I haven’t tried it out yet. Happy coding with your svn/git trac repositories.

2010
01.08

It has been way too long since the last post, so here is something you might find useful.

A couple of months back we noticed that our commercially hosted svn and trac repositories were becoming quite unresponsive and slow, which held up development albeit only slightly. Time is money as they say, so we decided to cancel our commercial hosting and go for a local svn set up on our development server (just an old networked dell laptop, not very high specs at all). Our dev server is just a freebsd 7.1 install on an old dell laptop, which already had Apache, MySQL and PHP installed (FAMP server). For this guide you will need to have at least Apache installed (plus a few other port installs which I will detail below), but if you’re going to install Apache you might as well go all the way and have MySQL and PHP, see here and here posts on this. This guide is mainly for FreeBSD, although steps should be similar for Ubuntu, although your installs are very different, where appropriate I’ll put the ubuntu alternative installation steps.

Assuming you have already set up your FAMP server, next steps are as follows:

Install subversion

Use the make options as defined below. At the time of writing I am installing subversion 1.6.6

cd /usr/ports/devel/subversion
make install clean
Subversion make options

Subversion make options

This might take a while depending on how many dependencies need to be installed.

Install trac

Leave the options as they are or copy from below. At time of writing I am installing trac 0.11.5

cd /usr/ports/www/trac
make install clean
trac make options

trac make options

Install mod_python for apache

From /usr/ports/www/mod_python3. Trac runs on python, the trac website neds to be handled by python so we need to install this apache module for the trac website(s) to work

cd /usr/ports/www/mod_python3
make install clean

Apache needs to be set up to enable the new mod_python module, so edit the httpd.conf file located in /usr/local/etc/apache22/httpd.conf add the following to the end of the LoadModule section if it is not there already.

LoadModule python_module libexec/apache22/mod_python.so

Install Git (optional)

There is a trac plugin to work with git repositiories if you prefer that to svn. I will not go into git now, see my next post for integrating trac with a git repository.

cd /usr/ports/devel/git
make install clean
git make options

git make options

You do not need perforce or cvs support unless you want it. I have never used either, only subversion. You will not be able to install the GUI Tools without install the X11 windowing system. If you have already got X11 installed, then I would recommend installing the GUI tools as they can help with visualising the current branch on the development tree, but if not then do not bother as X11 takes AGES to install and will bloat your system with hundreds of dependencies.

Install the trac git plugin (optional)

You can install the trac git plugin if you want to work with git repositories rather than svn.

cd /usr/ports/www/trac-gitplugin
make install clean

Ubuntu install steps for the all of the above are below(they are a lot simpler and quicker! Ubuntu uses pre-compiled files binary files and automatically sets up apache with the relevant modules loaded):

sudo apt-get install subversion
sudo apt-get install libapache2-mod-python
sudo apt-get install libapache2-svn
sudo apt-get install trac
sudo apt-get install git-core
sudo apt-get install trac-git

Now that we have all the programs we need lets go on to set up an svn repository.

Create an SVN repository

First we need to decide where we are going to have our svn repository, where ever you decide to keep it, you will need to make sure it is readable (and writable if you want to make checkins) by the apache user. For this example I am storing all my svn repositories under one location, /usr/local/svn. Make sure you are root and run the following:

cd /usr/local
mkdir svn
cd svn
mkdir repositories
cd respositories
mkdir Test
svnadmin create Test
cd /usr/local/svn
htpasswd -c .passwd [Username]
[Enter password, and again]
chown -R www /usr/local/svn

Ok, the steps above we created a location where we are going to store our svn repositories, we created one respository called Test, then we created an apache basic authentication access file which the svn server will use to authenticate the users. Finally we changed the owner of the entire svn directory over to the apache web user. Ubuntu users can perform the same steps, feel free to choose a different location than /usr/local, this is common practice in a freebsd system.

Setup Apache to serve our SVN repository

Now we need to tell apache which directory contains our svn repository. As root create the following file by running:

touch /usr/local/etc/apache22/Includes/svn.conf

Ubuntu users:

touch /etc/apache2/conf.d/svn.conf

Then edit that file and save the following in it:

<Location /svn>
DAV svn
SVNParentPath /usr/local/svn/repositories
AuthType Basic
AuthName "Subversion access"
AuthUserFile /usr/local/svn/.passwd
Require valid-user
</Location>

Now if you restart your apache webserver (apachectl restart) and navigate to http://[server address]/svn/Test you should be asked for your username and password. Once you have logged in you should see your empty repository!

Create a trac repository

Now we will create a trac repository, I will follow the same logic as for the svn repositories and keep all the trac repositories under /usr/local/trac. As root again run:

cd /usr/local
mkdir trac
cd trac
mkdir Test
trac-admin Test initenv

trac-admin is an interactive program and you will be asked a series of questions to set up the trac repository. You will have to enter or accept the default value (by pressing return) at the following prompts:

Project Name [My Project]> Test
Database connection string [sqlite:db/trac.db]>
Repository type [svn]>
Path to repository [/path/to/repos]> /usr/local/svn/repositories/Test

When you have finished change the owner of the trac folder to the apache web user:

chown -R www /usr/local/trac

The steps are again the same for Ubuntu users.

Setup apache to serve our trac repository

Apache needs to serve the trac repository using the mod_python module we installed earlier. To set this up, create the configuration file by running the following as root:

touch /usr/local/etc/apache22/Includes/trac.conf

Ubuntu users:

touch /etc/apache2/conf.d/trac.conf

Save the following text in the new file:

<Location /trac/MyRepoName>
SetHandler mod_python
PythonHandler trac.web.modpython_frontend
PythonOption TracEnv /usr/local/trac/Test
PythonOption TracUriRoot /trac/Test
AuthType Basic
AuthName “trac access”
AuthUserFile /usr/local/svn/.passwd
Require valid-user
</Location>
<Location /trac/MyRepoName>
SetHandler mod_python
PythonHandler trac.web.modpython_frontend
PythonOption TracEnv /usr/local/trac/Test
PythonOption TracUriRoot /trac/Test
AuthType Basic
AuthName "trac access"
AuthUserFile /usr/local/svn/.passwd
Require valid-user
</Location>

Now if you restart apache again by running apachectl restart and navigate to http://[server address]/trac/Test you should be asked to authenticate and see your trac site!

Testing the SVN repository

To test the repository we will checkout a working copy, in your users home directory, try the following:

mkdir svnworkingcopy
cd svnworkingcopy
svn checkout http://[server address]/svn/Test . --username [username]
[Enter password]
svn mkdir trunk branches tags
svn commit -m "Checking in svn directory structure"

Now if you go back to the trac site and click the Timeline button you should see the first commit with the message. Click on Browse source to see the directory structure we just created. You now have everything you need to work with your trac and svn repository and to start adding and committing your project code.

Look out for the next post which will detail a few more steps to get more out of your trac server setup including:

  • Using a git repository instead by using the trac git plugin
  • A few extras steps that will help integrating your trac repository with the Eclipse Mylyn trac connector
  • A svn post-commit hook to automatically add comments or close your trac tickets, simply by referring to a ticket number in your svn commit messages
2009
10.20

It has been a very long time since I posted anything so I thought I would share this small snippet.

Recently I had to extract some data which was stored as xml in a field within a mysql database table. To explain briefly, this data was actually saved as part of an XMPP (jabber) chat message by an openfire server. Openfire is a real time collaboration server which includes jabber functionality. To store the chat history Openfire records the chat message as an xml chunk in a field named body in a particular database table ofMucConversationLog. I needed to extract certain data that our system had communicated as a chat message through openfire, to do this I used a combination of regular expressions and string manipulation.

Ok, lets say I have messages that are either in format A or B as below:

<messageformata>
  <child1>some text</child1>
  <child2>some more text</child2>
</messageformata>

<messageformatb>
  <child1>some text</child1>
  <child2>some more text</child2>
</messageformatb>

Each row in the database can contain xml in the format of A or B and there are many rows. If I need to extract only the contents of the first child of message format a, I could use the following SQL code to do it (assuming I’ve created a temporary table called temptable to store these values):

INSERT INTO temptable (child1value)
SELECT
SUBSTRING(body, LOCATE(‘<child1>’, body)+8,
  LOCATE(‘</child1>’, body) - LOCATE(‘<child1>’, body) - 8)
FROM ofMucConversationLog WHERE body REGEXP ‘<messageformata>*’;

Unfortunately the REGEXP operator can only be used for testing true or false and so is probably only useful in a WHERE clause. There are no capturing options like in other languages (php, perl java etc.), however you can use it in combination with the substring and locate functions to get the job done, although it is admittedly tedious.

2009
09.23

After updating my debugger version of Adobe Flash Player to 10.0.32.18 I noticed that Mouse Events were no longer working correctly.

There appears to be a bug in the more recent flash player which appears to break the mouse events. It only appears to affect Macs, I am having the problem on both Safari 4.0.3 and FireFox 3.5.3. I made a test app below which adds a few mouse event listeners to the white box and informs you of the events being received. Try it out below and comment on your results.

Get Adobe Flash player

If you do not have a problem, do not upgrade your flash player or you will. This has been reported as a bug to Adobe here and here, more people are starting to notice it, hopefully Adobe will fix it soon.

Update 25/09/09

So far the results of people trying out the above test on a mac have been varied. The problem seems to be occuring in Snow Leopard 1.6, with most people FireFox being the only browser experiencing the bug. I have witnessed someone running Leopard with the same versions of FireFox and Safari as myself with no problems at all. Most people who are running Snow Leopard appear to only experience the bug in FireFox with safari working fine. However, as I mentioned above,  I am having the bug appear both in Safari and FireFox. I don’t know what is so different about my set up, apart from that I have installed the latest debugger version of the Flash Player and that my system is 32-bit only.

If you do try out the test above and want to report your results, please provide as much information as you can, what versions of browser you are using, what is your flash player version, what OS version, 32 or 64-bit etc? Some people think the problem is with FireFox but I am not so sure.

Update 06/10/09

Ok, I am pretty sure now that this problem is not to do with a flash player upgrade, it is to do with Snow Leopard!

Recently my hard disk died, I reinstalled Snow Leopard and then restored my files from a time machine backup, I did not restore my applications.

Upon reinstalling Flex Builder I noticed that my flash player was now at version 9, which gave me an opportunity to test if this bug was still happening and it is, both in Safari and FireFox for Flash Player 9,0,124,0 as well. This almost definitely means the problem is down to the operating system, either Apple needs to fix it or Adobe need to come up with a fix in Flash Player. I can not run my demo test app above using flash 9 as the demo is set to require 10, but in other test apps I am getting the same broken behaviour with mouse events being lost after loading the FileReference browser. Looks like we will need to put a warning for Snow Leopard users on our flash apps.

Update 22/11/09

Adobe Labs have recently released Flash Player 10.1, which has fixed the issue detailed above. I have tried out the new player, but while the problems above have been fixed, many others new problems are present. For example, it appears that key events are duplicated, every keystroke entered appears twice and filtering by file type does not appear to work with FileReference. I realise this is a pre-release version constantly being improved, so hopefully these will be fixed soon. Unfortunately there is no debugger version of the new player, which is quite strange since the people who are going most likely to try out a pre-release are developers who would require the debugging features.

So far it appears I am the only one that has experienced these problems with the latest player, I think this is somehow related to my system being 32 bit only. It appears that most of the development efforts into Flash on the Mac are on 64 bit support, which makes sense since Apple is shifting eveything to 64 bit. If you too try out the new beta flash player and experience other bugs please report them here and on the adobe bug reporting site. This new flash player update proves that an active Flash community can get flash bugs fixed quicker and help improve the flash platform for all. Thanks to all who commented on their issues experienced with the demo.

You can try out the new 10.1 player at the Adobe Labs site.

2009
09.14

Ok, in my previous post, which was a while ago now (I must make an effort to post more often), I wrote about installing FreeBSD and setting up your home router to give a fixed ip address for your server and forward some relevant ports on your router to make it accessible from outside of your local network. Up until now you should have a working FreeBSD server that you can ssh into using its local address. Your server so far does not do very much, lets install some software to make it a useful server.

Installing Apache

We are now going to install apache from the ports collection, remember I said the ports collection was important and that you definitely wanted to include it in the install process? The ports collection is a massive collection of free software, mostly source code which has been specifically ported to work on FreeBSD. You install a port by compiling the source code and copying the compiled binary files to the relevant places. Fortunately you don’t have to do this manually, the ports have a Makefile which will do most if not all the work for you.

Let’s start by installing the latest version of apache 2.2 which is located in /usr/ports/www/apache22, you will see there is a Makefile. You can install almost any port with a make file by just running make install clean, in some cases you can run make config to set any configuration options before actually compiling and installing, this applies here, run make config,  you will be presented with a window with some configuration options, you can change these if you want if you already know there are certain Apache requirements you want, otherwise accept the defaults, press the tab key so OK is selected and press enter. Then run make install clean, it will then go about downloading,  compiling the source code, install the files and any required dependencies. Make a cup of tea, this might take a while. Whenever you are installing software on your FreeBSD server it is always best to do it via the ports collection, firstly because you are getting the software that is most likely to work on your system. Secondly when you install a port, other ports will know about the installed software, thereby the installed port can be used by other ports as a software dependency because the system knows where those installed port programs should be. Thirdly the dependencies are all managed for you. If one port relies on some other software that is not installed, in most cases the make file will go about installing that port for you, in some cases, especially when installing an upgraded port you might run into problems you have to solve manually. For instance, when I tried upgrading apache, I ran into this problem:

Found libtool-1.5.26, but you need to upgrade to libtool>=2.2

The make process failed for apache because of this dependency that it couldn’t solve automatically, in this case I had to find out where the libtool port existed (/usr/ports/devel/libtool22) and install that first. You may run into this kind of problem along the way when administering your server but once you get used to installing ports you will find it a walk in the park,the internet is your friend if you run into any problems. The final reason why you should install from the ports collection is a combination of all three, it’s easier!

After apache has finished installing, you need to add a line in /etc/rc.conf so that apache will be started automatically when the computer first starts, as root edit rc.conf and add the following.

apache22_enable="YES"

Installing MySQL Server

Now lets install mysql server, there are a few different versions to choose from, I would recommend going with 5.1, you can try 6.0 if you want. Go to /usr/ports/databases/mysql51-server and type:

make install clean

This is going to take a very long time, longer than apache. When its finished, type rehash, this will refresh you shell path variables so that you will have access to the new binaries installed with mysql server.  After that, you can run the mysql install script which initialises mysql server. Just type mysql_install_db. To make mysql automatically start like we did for apache you need to the following to /etc/rc.conf:

mysql_enable="YES"

You will probably want to change the mysql root password, I think by default it doesn’t require a password and that is probably a bad thing. Just like in unix where the root account can do anything, so to in mysql the root account can do anything to any database on the system. To set a password use:

mysqladmin -u root password 'mypassword'

The quotes are important here. Now if you restart your machine you should have both apache and mysql running, but you don’t have to restart to start using them. In FreeBSD most software that runs as a long term process (i.e. a daemon) is stored in the rc.d directory and are avaible to start and stop. System daemons you will find in /etc/rc.d/, user installed programs such as mysql-server and apache are found in /usr/local/etc/rc.d/. These programs are actually known as rc scripts, many of them can be configured to start when the system starts up. They all usually have a common way to start and stop them, for instance you can do the following for mysql-server:

/usr/local/etc/rc.d/mysql-server start
/usr/local/etc/rc.d/mysql-server stop
/usr/local/etc/rc.d/mysql-server status

These are pretty self explanatory, the status option shows whether or not the daemon is running. These scripts start the processes making sure they run under the correct user (mysql runs under the user mysql, apache runs by default under the www user) and performing the necessary commands to start or stop the process. You can start and stop mysql server this way, but for apache there is a better command called apachectl. If you need to start apache you can run apachectl start, if you want to restart it (because you’ve made some config changes) its best to use apachectl graceful, this will keep any clients connected and do a safe restart.

Installing PHP 5

Now on to PHP and the php extensions, this port is located in /usr/ports/lang/php5. This has the same process, I’ll put all the steps in the one go:

make install clean
cd /usr/ports/lang/php5-extensions
make install clean

For the php extensions you can choose what you need, definitely enable mysql if you are planning to work with mysql and php.

Finally we have a few steps to perform on our apache config file to get php to work with it and to change which files our web server points to. As root edit the apache config file:

edit /usr/local/etc/apache22/httpd.conf

Change the document root to where ever you want, there are two places to change this. This is the default directory on the system that you want apache to serve on the web.

#
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
#
DocumentRoot "/usr/local/www/apache22/data"

#
# This should be changed to whatever you set DocumentRoot to.
#
<Directory "/usr/local/www/apache22/data">

Ok, now we need to make sure php files are recognised by apache, do a search for DirectoryIndex in the file and add index.php before index.html as below. You can change this according to which file you want apache to give preference to, if you put index.php first then apache will look first for an index.php before index.html in a folder to serve.

#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
<IfModule dir_module>
 DirectoryIndex index.php index.php3 index.html index.htm
</IfModule>

Now lets make sure that the php install process has added the php extension in apache. Make sure that this extension is in the exensions list, if not, add it.

LoadModule php5_module  libexec/apache22/libphp5.so

Nearly done, now add the two lines at the end of the file, which tell apache that php and phps files should be handled by php.

AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

That should be it, you now have a FAMP server! Now lets make sure you can get to it from outside.

Setting up Dynamic DNS

In order to get over the problem of your broadband provider assigning you ip addresses that can change at any time you use dynamic dns. This involves installing a program which periodically updates a server with your current IP address. I used dyndns for my home server. They are very good and charge nothing. The way it works is you can sign up for a free account with them, you get to pick a subdomain and one of their many domain names. For instance I chose chris.is-a-geek.net. You can then download their client program which periodically updates their servers with your current ip address, so that anyone that types in for instance, http://chris.is-a-geek.net will end up at my current ip address. Now luckily for me, my wireless router has a section in its admin interface for configuring dynamic dns and DynDNS.org (.org or .com its the same site) is a supported option. I just enabled the Dynamic DNS option on my router and entered my DynDNS account username and password. With this up and running it meant my router was now contactable via the domain chris.is-a-geek.net. Now together with the router port forwards that I mentioned in my previous post I now had a web server that is accessible via the internet, and you can too!

If your broadband router does not have an option for dynamic dns, don’t dispair! There is a port for a dynamic dns client on FreeBSD called ddclient, to get it working follow these steps:

cd /usr/ports/dns/ddclient
make install clean
cd /usr/local/etc
cp ddclient.conf.sample ddclient.conf
edit ddclient.conf

Do a search for a line that starts with use=web, remove the comment # to activate that line, it should say the following:

use=web, web=checkip.dyndns.org/, web-skip='IP Address'

Now uncomment the section for your dynamic dns provider and enter your account login details, domain name and save.
Remember I mentioned rc scripts, well this has one too, you can enable ddclient to start when the system starts by editing rc.conf and adding the following lines:

ddclient_enable="YES"
ddclient_flags="-daemon 600"

This tells ddclient to start on system start up and to update the dynamic dns provider with the current ip address every 600 seconds. You can change this value, don’t set it too low or your dynamic dns provider might get annoyed and block you, don’t set it too long either. As ddclient has an rc script you don’t have to wait to restart for it to work, just run as root:

/usr/local/etc/rc.d/ddclient.sh start

You should now have an accessible web server! You can point existing domains you own to your home server by adding a CNAME (canonical name) record in your domain dns records. For instance I have set up a CNAME dns record for the subdomain server.opencoder.co.uk to point to chris.is-a-geek.net (if you ping both of these you will see they resolve to the same ip address). This way you can point many domains to your home server and be able to run different websites for those domains by setting up apache virtual hosts (I won’t cover this here, maybe in a later post).

That’s it for now, there are many more things you can put on your server to make it even more useful. I may do more posts in the future covering a few of them. That’s enough of this for now, I need to get more techy and start writing about programming, anyway hope you found this info useful. By they way if you are interested in learning more about freebsd I’d highly recommend getting a copy of Absolute FreeBSD 2nd Edition by Michael W. Lucas and for instructions on using FreeBSD as a server, Building a server with FreeBSD 7 by Bryan J. Hong. There are also a few good posts about FreeBSD port management and installing FreeBSD with nice screenshots at my work colleague Luis’ blog http://www.lupomontero.com. We are working closely with Luis on an interesting project called StickyWorld, which involves posting stickynotes on work in realtime in a flash based ‘room’. I will no doubt be writing about that soon, until then, have fun with your server.

2009
08.26

For the first real post here (work, procrastination and thinking about what to write about ate up most of my time) I thought I’d write about what I did to set up a web server at home. I will try and go through all the important steps from the beginning and may split this into multiple posts if it gets a bit too big.

To follow this you will need a pc, connected by ethernet cable to a home broadband router that has DHCP enabled.

Why?

Ok, so why did I want to set up a web server at home in the first place? Well, it so happened that we (Slider Studio) had just aquired a dedicated server at work and in the near future we’d be running quite a lot of stuff from it. We also had set up a development server at work which we could mess about with and make sure everything worked as expected before we put it on our production server. Knowing that I had to work quite a bit with servers in the future, I thought it would be a good idea to get more experience and practice with them. So I looked around for a cheap pc, I wasn’t that really concerned about the spec, mainly that it wouldn’t take up too much space and wasn’t too noisy.

Hardware

At my local computer fair, I managed to get a really good deal on a second-hand compaq evo d510s base unit (only 48 quid!), pics below.

The specs weren’t that bad either:

  • 1.6 GHz processor
  • 256MB SD RAM
  • 20GB hard drive

It was in a pretty small compact case too, designed to be used flat on a desktop with perhaps a monitor on top. It later turned out to be pretty quiet, another bonus. I bought the machine and later upgraded the RAM to 1GB (2 x 512MB SD) and swapped the CD-ROM drive for a DVD drive (I needed a dvd drive to install FreeBSD from an install DVD). Finding the correct SD RAM for an old pc is not easy and certainly not as cheap as just buying any existing DDR memory. Most of what I could find on eBay was specifically for server rack machines, I had very strict requirements on the memory I needed, unbuffered, non-ECC, 266MHz  PC2100 etc. The machine had on-board graphics, which I didn’t really care about, the machine is only going to run a command line interface and I’m not doing any server side graphics intensive stuff.

OS

I decided to use FreeBSD 7.1 as the operating system because this was what our real production server was running and my aim was to replicate the set up at home. You can choose your own operating system, debian, ubuntu, whatever, just don’t bother installing a graphical windowing system, you shouldn’t need it. I would recommend FreeBSD, it’s very easy to install and the huge ports collection makes it super easy to install whatever software you need on the server. Plus, FreeBSD is used in many commercial servers and is very reliable. I will only be talking about setting up a FreeBSD server here.

Okay, on to actually installing now. First thing I did was get rid of the existing Windows XP installation, I did this by using a utilities CD to run the fdisk program and delete all partitions on the hard disk, create one primary partition and proceed to format that new partition. Actually it turns out I didn’t need to do this at all FreeBSD comes with its own fdisk-like program which does the same thing. So after partitioning and formatting the hard disk, I put in the FreeBSD 7.1 dvd (a burnt iso image you can get from here).

The first menu is about language and keyboard layout, just choose the correct one for you, the next screen is the installation type. Here you have a few options: Standard, Express, Custom + other options, I’d recommend just going with the standard install. It will then launch the installer, which is not the most user friendly installer, but don’t be scared! You should get a message talking about setting up the disk partition scheme, press OK for that, if you get a scary message talking about disk geometry don’t worry just press enter. When you get to the partitioning bit, just press A to use all of your disk space for FreeBSD with the default options for the partitions, then press q. Next you’ll get a menu about choosing the boot manager, just leave it on the default standard, we are just running FreeBSD on this system, nothing else. Next you get to choose how to partition the drive for the operating system folders. In FreeBSD the root folders such as /usr, /var and /bin are contained on separate partitions, you can create your own additional partitions if you want for instance if you wanted a partition mounted on /data for doing data backups, but I’d recommend just accepting the default by pressing A and then Q to quit. The default options give the most space to the /usr folder, which is useful because /usr is the location where the ports collection resides and the user accounts. Most of the space you will be using from your day to day server use will be in the /usr folder. The /var folder is commonly used for logs, /etc for system configuration and /bin for system binaries.

The next step is to choose the install source, I chose the install dvd, this later turned out not to work, my dvd drive or the disc may have been bad, blocks of data from the dvd could not be read. When the install failed I retried and this time chose to install from an FTP server. The next screen asks how much of FreeBSD to install, contrary to belief, you don’t need everything on here, just choose the User option, this gives you the basics and everything you need for your server. When it asks you if you want to install the ports collection say yes! You definitely want the ports collection, read on to find out why. After this you are taken back to the previous menu, press Exit, you will get one last chance to change your mind here, after that your drive is partitioned and formatted and the files copied.

When its finished you’ll get a chance to configure the network, say yes to this option (if you chose an ftp install you would have already gone through this). You will be given a list of network interfaces to choose from. Choose the ethernet one, my system is connected by ethernet directly to my broadband router. When it asks about using IPV6 configuration say no. When it asks if you want to try DHCP configuration you can say yes if your machine is connected to a DHCP enabled router. You will have to enter a hostname for your system a domain, IPv4 gateway and name server. Host is something you can choose to identify your server, it can be anything you like but don’t put any funny characters in. Domain should be a domain your server is part of. For me I didn’t have a domain yet, so I made one up, for the gateway and name server I entered the local  ip address of my router. For me this was 192.168.0.1, they are commonly this or 192.168.1.1.

After this you are asked about enabling services, for most of these you can say no, except for SSH which you definitely want to enable, I would recommend only enabling SSH, definitely don’t enable anonymous FTP. You then get asked to choose a time zone, whether to enable Linux mode, say no, set up a PS/2 mouse (if you have one), I ignored this. You are then asked about installing any additional packages, don’t install any at the moment we will do this later.

You will get a chance to create a user account say yes to this, creating a user account separate from the root account is a good idea, you should only use the root account only when you have to and to ssh into your server in the first place will require a user account. In the new user interface, enter the desired username under Login ID, leave the UID as it is, leave the group as it is, by default the group should be the same as the username. Enter your password carefully, you can only do it once here. Enter your full name, under member groups you can put in wheel in order for this user to be able to switch to root or do administrative tasks on the server. The home directory should be fine as it is, for the shell you may want to change the default /bin/sh to /bin/tcsh, there isn’t much difference that I’ve noticed apart from with tcsh you get the tab complete functionality when logged in via ssh, but not with sh. Once you have created the user you can set the root password for the system, you definitely do want to set a root password, enter this twice. Finally you go back to the main menu, select exit and your system will reboot and you should have a fully functioning FreeBSD system. Nearly done here, you just need to make sure the hostname you set for the machine resolves to itself, first lets edit the rc.conf file found in /etc. Log in to you server either at the machine or on another machine in your local network using ssh. Switch to the root user/super user by typing su then:

ee /etc/rc.conf

this file should have some key-value pairs, don’t worry too much about this file now, just make sure there is a key value pair

hostname="myhostname"

obviously replace myhostname with the hostname you set. Next edit the hosts file /etc/hosts and make sure that after 127.0.0.1 you have the localhost and your hostname, e.g.:

::1            localhost
127.0.0.1      localhost myhostname

Now if you run hostname from the command line you should get your hostname echoed back to you.

Router Set Up

In order to get remote access to your newly installed server you will need to perform some router configuration steps. Log into your router configuration, usually this done by opening a browser and going to 192.168.0.1 or 192.168.1.1, you will need the router login details. The first thing to do is set up a static ip address for your new server. For my router (which is a netgear sky broadband router), I did this by going to the Advanced tab -> LAN IP Setup a list of machines connected to the router was shown, I selected the one that looked like my server, entered the static ip address that I wanted (192.168.0.5) and gave the device a name (server). Your router configuration may be different to this and you may have to look at the manual for how to do it.

Next thing to do is set up some port forwards so we can access the server from outside of our home network (the internet). First port forward to set up is for SSH access. For my router this was under Security -> Firewall rules, I was given a list of services to choose from, I chose SSH (TCP/UDP:22), under the action I chose Allow Always,  for the destination IP address I entered the static ip address I had reserved for the server, 192.168.0.5. Under WAN users I selected Any and chose to log this always. If your router does not have ssh listed as a service, you can enter a custom service, just make sure the service is for port 22 using tcp and udp and that the destination address for this is the static IP you set for your server.

Finally you can do the same for http service (port 80) and https service (port 143). We haven’t got a web server yet so the http(s) port forwards won’t be doing anything yet, but it’s better to prepare for it now. You can test whether your port forwards are working by trying to get remote access to your server, first find out the public ip address your router has (this is the address that’s visible to the internet) then try and gain ssh access using your routers public IP address as the server location and the new user account you created on your server. For ssh on windows you can use the free PuTTY ssh client. If you could log in successfully then you now have remote-accessible server, it just can’t do much yet! If you couldn’t log in, try connecting to the server using the local ip address e.g. 192.168.0.5, if that works but the remote address does not, then you have a problem in you router port forwarding. Obviously most people’s public internet ip address will change from time to time, unless you have paid extra for a static one. So how our we supposed to get to our server when we’re away from home? More to the point how are we supposed to run a web site or more from a place  which IP address is changing all the time? The answer to this is Dynamic DNS, which I will leave until the next post, this is already way too long for a blog post, I’ll have to learn to keep things shorter for next time.

So look out for the next post where I’ll cover setting up dynamic dns for your server, installing Apache, MySQL and PHP (making your server a FAMP server)! Peace.

2009
08.05

Blog started

Hey everyone, it is finally here, set your bookmarks and subscribe to the feeds, tell your friends and wake your neighbours. Ok, well only if they happen to be coder geeks and only if they can be bothered with that sort of thing. Quite excited by this, my first blog. See the about page for reasons why I decided on starting one.

I’m still not decided with the theme so might play about with it. Expect some posts soon on technical related issues and things that might be useful for the code enthusiast, or maybe interesting to those that wonder what geeks gets up to (where are these interested people? please point them out to me).

Why is it after doing something like this, you tend to get stuck thinking about what to write about?