Port Forwarding

This HOWTO describes the steps required to setup your RedHat (well any Linux distro) firewall to forward the port used by gtk-gnutella to a machine on your internal network. This is useful because it allows your gtk-gnutella client to behave in a non firewalled mode and thus more of the gnutella network is available to you. In particular, other machines that are behind firewalls that can handle push requests will become available to you.

What is Port Forwarding?

Port forwarding is a feature of the IPTables system. It allows one computer to forward connections made to it so that another computer can actually process the request. If you want a very simple metaphor you can think of it as mail forwarding. Each computer has a number of addresses called ports, and IPTables allows (among other things) connections to these ports to be sent to another computer. The most common use of port forwarding that I am aware of is allowing servers to run on machines that would normally be hidden behind a firewall.

Firewall script

I am going to assume that you are using the default firewall script that comes with RedHat or whatever distribution you are running. My system is currently running RedHat 8.0 (heh, not anymore). And I am using a firewall script called rc.firewall-2.4. You should be able to find it in your /etc/rc.d directory. If you don't find it it may be that I had to install it and just don't remember. :) You can search for rc.firewall-2.4 on Google and find many copies.


My goal was to make gtk-gnutella work in a non-firewalled mode from within my firewalled LAN. To do this people suggested a line of the form:

$IPTABLES -t nat -I PREROUTING -p tcp -i $EXTIF --dport 6346 -j DNAT --to

Where $IPTABLES is the iptables executable, $EXTIF is the external ethernet interface (I use two ethernet cards in my firewall), port 6346 is the gtk-gnutella port and is the machine on my internal network on which I wished to run gtk-gnutella.

With the rc.firewall-2.4 script this doesn't quite work. The reason is that by default any connection that would open a new session from the outside world is dropped. This is done with the line:


The solution is to add a rule into the FORWARD chain that causes connections from the outside world to port 6346 to not be dropped, but instead to be accepted. Then the PREROUTING rule above will be encountered and the connection will be forwarded to the internal machine as desired. The line to accomplish this is:

$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p tcp --dport 6346 -j ACCEPT

I placed this right before the line:


I did this because this line will will add a rule that causes all rules added after it to not be checked.


Virtual Hosting and SSL

All right, now that we have some blogs up. We will want to enable SSL/TLS security, also known as https. The reason you want this may be obvious to some. But to spell it out for you, if you don't use https to connect to your administrative pages in Movable Type while you're sipping on your latte, then everyone else that's on that wireless network can see you type your password in, plain as day. And by "can", I mean there is nothing preventing them from watching your traffic. Most likely, no one is, but you never know.

There are a couple of complications that we will need to work through though. Firstly, SSL and name based virtual hosting are mostly incompatible. And secondly, unless you get a Certificate Authority, such as Verisign, to sign your SSL key you and your security conscious visitors will be presented with an ugly message from the browser saying that your site is trying to identify itself with an invalid security certificate.

So, why are SSL and name based virtual hosting mostly incompatible? Well, it turns out that the way name based virtual hosting works is for the browser to send to your web server the name of the server it's trying to connect to. And then your web server uses that information to look through the list of virtually hosted domains until it finds a match. Then the page the browser wants is sent from the server to the browser. But if you have connected to the web server using an https connection then the communication channel needs to be encrypted. So the server needs to send the browser the public key of the domain the browser is trying to connect to. But the server doesn't yet know what domain the browser is trying to connect to, because that information is part of what will eventually be encrypted and sent by the browser. Apache will just serve the first certificate it finds in this case. So all but the first domain in your list of virtually hosted domains will cause the browser to issue an additional warning, that the certificate is for the wrong domain. This isn't a big problem for large hosting companies or business, they can just assign a separate IP address to each domain. And then use that extra information to configure the web server, allowing it to pass the correct domain specific key back to the browser. For us little guys, that's not really a suitable approach. You can do something similar by having your web server listen on a bunch of different ports, one for each domains SSL connection. But then your URLs will have to have the port number in them as well. Not a really classy solution. There is a solution to this problem in the works. It's called "Server Name Indication" or SNI, and it's part of the TLS protocol. Unfortunately it's still not readily available (see this page). So, what's the solution? It's pretty simple actually, just use one certificate for all of your domains. There is an extension that allows for multiple domain names to be associated with a single certificate. When a browser receives such a certificate, it looks at all of the domain names and if any of them match it is satisfied. There seem to be some security issues with this feature (see this page). But since we are mainly interested in using it to authenticate ourselves with our own server, it's not a big deal, I think. And that brings us to our second issue. We can pay Verisign to generate a certificate for us, or we can sign it ourself. If you pay Verisign (or other Certificate Authority) then anyone that browses your web site with a secure https connection will feel right at home, secure even. If you sign the certificate yourself, then viewers will be presented with a nastygram from their browser. Since I am mainly interested in being able to securely access my servers from insecure networks, I'm happy to sign the certificates myself.

First you need to enable SSL in your Apache configuration. In the Apache2 configuration for Ubuntu these files are located in /etc/apache2. You'll need to make sure that your ports.conf file contains something like the following:

Listen 80

<IfModule mod_ssl.c>
    Listen 443

This causes Apache to listen on port 443 for connections as well as port 80. Port 443 is the https port. And your conf.d/namevirtualhosts file should look something like:

NameVirtualHost *:80
NameVirtualHost *:443

This tells Apache to look up virtual hosts by name for traffic coming in on either port. Next you need to make sure that your conf.d/ssl_certificate file looks something like:

SSLCertificateFile    /etc/apache2/ssl/serverwide.crt
SSLCertificateKeyFile /etc/apache2/ssl/serverwide.key

You can see that I've called my certificate and key files serverwide to make it obvious that they are used by all domains served by this server. It is very important that these files have their permissions set so that only root can read them. You'll also need to make symlinks from the ssl.conf and ssl.load files in your mods-available directory to your mods-enabled directory.

Now we're ready to generate and sign our key and certificate. Once you have generated the certificate you can inspect it's contents with this command.

openssl x509 -in serverwide.crt -noout -text

To generate a key use the following command. You will be asked for a pass phrase. It is important that you remember this pass phrase or your key will be lost to you forever. Or at least until computers are powerful enough to brute force crack your key.

openssl genrsa -des3 -rand /dev/urandom -out serverwide.key 1024

Once you have a key you can create and sign a certificate with the following command. You will be asked for the pass phrase you entered above. This is because the key is protected by that pass phrase and can't be used without it. This certificate will be valid for one year.

openssl req -config server.config -new -key serverwide.key -out serverwide.crt -x509 -days 365

Most of the options we need to pass to OpenSSL to create and sign the certificate can be passed in a configuration file. The command line above assumes the configuration file is called server.config. Below is an example server.config file, the main lines of interest are in the alt_names section. The alt_names section is where you can put all of the virtually hosted domains on your server. The browser will look for a match with any of those domains when the server passes it the certificate we have just generated. I also found that subjectAltName had to be in both the v3_req and v3_ca sections.

[ req ]
default_bits       = 1024
default_md         = sha1
distinguished_name = req_distinguished_name
prompt             = no
string_mask        = nombstr
req_extensions     = v3_req
x509_extensions    = v3_ca

[ req_distinguished_name ]
countryName            = &lt;country code&gt;
stateOrProvinceName    = &lt;state&gt;
localityName           = &lt;city&gt;
organizationName       = &lt;whatever, could be your name&gt;
organizationalUnitName = &lt;again, whatever&gt;
commonName             = www.domain1.com
emailAddress           = webmaster@domain1.com

[ v3_req ]
basicConstraints       = CA:FALSE
keyUsage               = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName         = @alt_names

[ v3_ca ]
subjectAltName         = @alt_names

[ alt_names ]
DNS.1 = www.domain1.com
DNS.2 = www.domain2.com
DNS.3 = www.domain3.com

The key that we have generated will have a pass phrase associated with it (the one you entered when you generated the key). This pass phrase will need to be entered every time you restart your apache server. There are ways of removing this extra security, but if you want to do that I'll let you look that one up elsewhere. For me with a server running on a UPS, I reboot or restart apache a couple of times a year at most. The added security is well woth it. If your server get's compromised, and it will eventually, then your security key will be coppied. And that is as they say, a bad thing.

And finally, in your site configuration file, probably in /etc/apache2/sites-available, you will need to add the following:

<VirtualHost *:443>
    ServerName   www.domain1.com
    ServerAlias  domain1.com *.domain1.com
    DocumentRoot /var/www/domain1

    SSLEngine    On

This is the Virtual host configuration file for your secured site. You'll want to add any additional configurations to it from your normal *:80 configuration section.


Virtual Hosting and Movable Type

It was a lot harder than I anticipated to get Movable Type to run from a single global install on all of my virtually hosted domains. So in the spirit of sharing, here's how I did it.

First, install movable type into a directory at the root of your web servers directory structure. I put mine in /var/www/shared/. The resulting directory structure contained:

This directory contains pretty much everything in the Movable Type tarball.
This directory is the mt-static directory from the Movable Type tarball. I moved it out to the top level of the shared directory because I have Apache configured to not serve documents from the cgi-bin directory.
This directory will contain the configuration files for all of the sites you will be virtually hosting.

Next configure apache for each of your virtually hosted domains. I assume you already have virtual hosting up and running. The configuration file for socialhacker.com looks like this:

<VirtualHost *:80>
    ServerName   www.socialhacker.com
    ServerAlias  socialhacker.com *.socialhacker.com

    DocumentRoot /var/www/socialhacker

    AddHandler   cgi-script .cgi
    SetEnv       MT_HOME     /var/www/shared/cgi-bin/mt
    SetEnv       MT_CONFIG   /var/www/shared/conf/socialhacker.cgi
    ScriptAlias  /cgi-bin/   /var/www/shared/cgi-bin/
    Alias        /mt-static/ /var/www/shared/mt-static/

The important bits here are how you set up the alias' and the environment variables. And all of this is covered in this article.

Finally, you need to create a configuration file in the shared/conf directry for your site. I did this by hand, which you'll need to do as well since Movable Type won't set most of these options in the configuration file it generates.

CGIPath             /cgi-bin/mt/
StaticWebPath       /mt-static/
StaticFilePath      /var/www/shared/mt-static/
PluginPath          /var/www/shared/cgi-bin/mt/plugins/
TemplatePath        /var/www/shared/cgi-bin/mt/tmpl/
WeblogTemplatesPath /var/www/shared/cgi-bin/mt/default_templates/

ObjectDriver        DBI::mysql
Database            <your database name>
DBUser              <your database user>
DBPassword          <your database password>
DBHost              localhost

MailTransfer        smtp
SMTPServer          smtp.<your provider>.com _(probably)_

And there's the real magic. You have to specify paths to the Static content as well as both Template directories, and the Plugin directory. If you forget the first template directory you won't get very far as the administrative pages won't load. But if you forget the second template path you'll get all the way to making a post and find that all of the files in your blog directory are zero length. If you forget the Plugin path you'll be missing all of your plugins.

Hopefully you've found this useful in setting up your own Movable Type blogs.