A simple node.js web application environment

I'm a big fan of using node.js to build small web applications, I feel that javascript is the future for the web and develpers can do some cool stuff with it. So far I've built a few applications that utalize node.js and a few node modules that make building applications a lot easier. I like to build most of my apps with express for the application, jade for templates, an less for generating css.

To work with node.js you need to install it and install it's package manager npm. I used the homebrew version of node.

zach@brains ~/projects » brew install node

And the version of npm from their website:

zach@brains ~/projects » curl http://npmjs.org/install.sh | sh

Now create a folder for your app

zach@brains ~/projects » mkdir things.zach.seifts.us

And download a few express, jade, and less

zach@brains projects/things.zach.seifts.us » npm install express jade less
less@1.1.6 ./node_modules/less 
jade@0.20.0 ./node_modules/jade 
├── mkdirp@0.2.1└── commander@0.2.1
express@2.5.2 ./node_modules/express 
├── mime@1.2.4
├── qs@0.4.0
├── mkdirp@0.0.7
└── connect@1.8.5

Now you can go ahead and create your express application

zach@brains projects/things.zach.seifts.us » ./node_modules/express/bin/express -s -t jade -c less appname

   create : appname
   create : appname/package.json
   create : appname/app.js
   create : appname/public
   create : appname/routes
   create : appname/routes/index.js
   create : appname/views
   create : appname/views/layout.jade
   create : appname/views/index.jade
   create : appname/public/javascripts
   create : appname/public/images
   create : appname/public/stylesheets
   create : appname/public/stylesheets/style.css

   dont forget to install dependencies:
   $ cd appname && npm install

And boom, you have an express web application ready to go, you can go ahead and start the application in development mode and go to localhost:3000 to see it in action

zach@brains projects/things.zach.seifts.us » node ./appname/app.js 
Express server listening on port 3000 in development mode

Now go ahead and build your app.

Building an Aegir based Drupal hosting environment (Part 6)

There's only I've got to setup before we can call this pretty much done. I want to be able to clone git repos hosted in my gitolite instance. First we need to generate a ssh public key pair and I know it's going to sound weird but we need to generate a key without a pass phrase. I'm okay with it because it will only have read-only access to the repo and the repo can only talk to specific boxes.

root@aegir:~# su aegir
aegir@aegir:/root$ cd
aegir@aegir:~$ ssh-keygen -t rsa

I added the key it generated to my gitolite-admin for the install profile the site should be built form and my builds repo and pushed it the changes up

Next I cloned the builds director

aegir@aegir:~$ cd ~/
aegir@aegir:~$ git clone git@git.EXAMPLE.us:builds.git
Cloning into builds...
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.

After that all I have to do is build a platform, a site, and we're ready to start building Drupal sites.

Read more

Building an Aegir based Drupal hosting environment (Part 5)

Okay, so now we've got our instances backing up regularly and our server updated and secure I want to start running aegir under ssl. I'm not a big fan of passing passwords in plain text across the internet.

First you need to make sure you have openssl installed

root@aegir:~# aptitude show openssl
Package: openssl                         
State: installed
Automatically installed: no
Version: 1.0.0e-2ubuntu4
Priority: standard
Section: utils
Maintainer: Ubuntu Developers 
Uncompressed Size: 1,040 k
Depends: libc6 (>= 2.7), libssl1.0.0 (>= 1.0.0)
Suggests: ca-certificates
Description: Secure Socket Layer (SSL) binary and related cryptographic tools
This package contains the openssl binary and related tools. 

It is part of the OpenSSL implementation of SSL. 

You need it to perform certain cryptographic actions like: 
* Creation of RSA, DH and DSA key parameters;
* Creation of X.509 certificates, CSRs and CRLs;
* Calculation of message digests;
* Encryption and decryption with ciphers;
* SSL/TLS client and server tests;
* Handling of S/MIME signed or encrypted mail.

Apparently Ubuntu installs it by default on 11.10, you might not have it and need to intsall it from aptitude.

There, you now have certs and you've made the certs read only by everyone, now we have to change the iptables rules to allow us to talk over port 443. In Part 3 of this blog post series thing I opened a few ports (80 and 22) that the machines can talk through. Well, we need to open port 443 now.

root@aegir:~# iptables -I INPUT 3 -p tcp --dport 443 -j ACCEPT
root@aegir:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            ctstate RELATED,ESTABLISHED 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:https 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www 
DROP       all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

There we go, port 443 is now open in the firewall, if we want our rules to stay after a reboot we need to generate the /etc/iptables.rules.

root@aegir:~# iptables-save > /etc/iptables.rules

Let's check and see if the apache ssl mod is enabled.

root@aegir:~# apache2ctl -t -D DUMP_MODULES | grep ssl
[Thu Dec 22 16:17:58 2011] [warn] NameVirtualHost *:80 has no VirtualHosts
Syntax OK
ssl_module (shared)

Right, so it is. If it wasn't installed you would do this:

root@aegir:~# a2enmod ssl

Now we have to configure Aegir to work over ssl, use this guide: http://groups.drupal.org/node/98399. It's how you do it. After that you should have Aegir running under ssl. I select the "require" when saving Aegir instance.

Read more

Building an Aegir based Drupal hosting environment (Part 4)

Right, so in the interest of time I'm going to go through how I setup my Aegir instances and some best practices I follow when working with Aegir.

First, let's extend aegir a bit, there's a great page of contributed modules for Aegir and there's a few that I really like. Here's what I typically download and use:

This is pretty much the only functionality I see missing in Aegir core, this could easily be done with a cronjob or Jenkins job, but I choose to let Aegir manage it's own backups. It's built into it anyways. Switch to the aegir user and download the files:

root@aegir:~# su aegir 
aegir@aegir:~$ drush @hostmaster dl hosting_backup_gc, hosting_backup_queue --destination=profiles/hostmaster/modules
Project hosting_backup_gc (6.x-1.2) downloaded to profiles/hostmaster/modules/hosting_backup_gc.         [success]
Project hosting_backup_queue (6.x-1.0-beta4) downloaded to                                               [success]
profiles/hostmaster/modules/hosting_backup_queue.

Now go to your Aegir instance and go to the Features admin page, then click on the Experimental fieldset and enable the backup features we downloaded earlier.

Now configure the Backup garbage collection module. I enabled it and set it to save 2 weeks worth of backups and save 1 week out of the two when it gets rid of the old backups.

And then configure the Backup queue to schedule backups

Then when you go to create a site you have the option to overide the default backup settings.

Well, there you go. A secure and working Aegir instance ready to host Drupal instances in 4 parts.  We'll move the database to a different machine in the next few days, get a cert on the box, and get Jenkins working too.

Read more

Building an Aegir based Drupal hosting environment (Part 3)

Okay, now that we have our Aegir instance up and the system updated we need to get to work on securing the ports on the linode. I'm a big fan of using iptables to do this mainly because it's the first firewall I learned how to setup and it's installed by default in Ubuntu. You have to setup some type of firewall to block people from trying to connect to open ports and comprimising your server.

root@aegir:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

By default Ubuntu doesn't have any firewall rules enabled, so your box is pretty much open. So I add these rules:

root@aegir:~# iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
root@aegir:~# iptables -A INPUT -p tcp --dport ssh -j ACCEPT
root@aegir:~# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
root@aegir:~# iptables -A INPUT -j DROP
  • First we're allowing incoming connections
  • Then we're allowing ssh connections
  • After that we're allowing traffic on port 80
  • Finally we're dropping all other traffic

This is the output of iptables -L:

root@aegir:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            ctstate RELATED,ESTABLISHED 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www 
DROP       all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

After you run those commands try accessing the aegir instance and logging out and logging back into your server to make sure your firewall rules aren't broken. If you do have trouble, Linode has a nifty shell they have you can use to login to the instance and fix whatever you broke.

Now we need to save the rules so when the server reboots the rules are still there. I use to generate it like so:

root@aegir:~# iptables-save > /etc/iptables.rules

That gives us this:

root@aegir:~# more /etc/iptables.rules 
# Generated by iptables-save v1.4.10 on Thu Dec 22 14:17:35 2011
*security
:INPUT ACCEPT [52640:65134441]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [20821:1765839]
COMMIT
# Completed on Thu Dec 22 14:17:35 2011
# Generated by iptables-save v1.4.10 on Thu Dec 22 14:17:35 2011
*raw
:PREROUTING ACCEPT [52717:65141157]
:OUTPUT ACCEPT [20821:1765839]
COMMIT
# Completed on Thu Dec 22 14:17:35 2011
# Generated by iptables-save v1.4.10 on Thu Dec 22 14:17:35 2011
*nat
:PREROUTING ACCEPT [202:14197]
:INPUT ACCEPT [125:7481]
:OUTPUT ACCEPT [2427:169661]
:POSTROUTING ACCEPT [2427:169661]
COMMIT
# Completed on Thu Dec 22 14:17:35 2011
# Generated by iptables-save v1.4.10 on Thu Dec 22 14:17:35 2011
*mangle
:PREROUTING ACCEPT [52717:65141157]
:INPUT ACCEPT [52709:65138421]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [20821:1765839]
:POSTROUTING ACCEPT [20821:1765839]
COMMIT
# Completed on Thu Dec 22 14:17:35 2011
# Generated by iptables-save v1.4.10 on Thu Dec 22 14:17:35 2011
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [238:22071]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT 
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT 
-A INPUT -j DROP 
COMMIT
# Completed on Thu Dec 22 14:17:35 2011

Right, so now we have our iptables config setup we need to edit the /etc/network/interfaces file to tell it about our new rules.

root@aegir:~# vim /etc/network/interfaces

And make it look like this:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp
  pre-up iptables-restore < /etc/iptables.rules
  post-down iptables-restore < /etc/iptables.downrules

Now if we reboot the machine we should have the iptable rules working properly

zach@brains ~ » ssh aegir.EXAMPLE.com
Last login: Thu Dec 22 13:58:47 2011 from where.who.whatever.com
root@aegir:~# uptime
 14:27:29 up 0 min,  1 user,  load average: 0.15, 0.03, 0.01
root@aegir:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            ctstate RELATED,ESTABLISHED 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www 
DROP       all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Sweet, the server is now blocking all traffic except ssh and port 80 traffic.

You can read more about iptables here:

Read more