Node.js & less on Media Temple Grid

Maybe I’m crazy, but I wanted to install Node.js in a (gs) shared hosting environment so that I could compile and save small changes to my LESS-based stylesheets via SSH without having to maintain a local working copy. That’s right. I said it. I change files in a live environment sometimes, and there’s nothing wrong with that! Anyone who opines to the contrary in the comments below will be swiftly dealt with.

This how-to is based on the great work of [Ian Tearle and his commenters](

### Preparation

Get your Media Temple Grid Service site number. If you don’t know your site number, see [this Media Temple support page]( For this tutorial, we’ll use the **123456** as an example.

First, let’s to prepare the shell environment to recognize executables in the new directories we’re going to create. Create or edit *~/.bash_profile* and add the following lines:

export PATH

Save the file and exit, then source *~/.bash_profile* to reflect the changes without logging out and back in:

$ . ~/.bash_profile

### Building Node

Now let’s [grab Node.js from GitHub](

$ git clone
$ cd node
$ mkdir -p /home/123456/data/opt
$ ./configure --prefix=/home/123456/data/opt/
$ make && make install

If all goes well (that make can take a while), you should now have a fully-functioning Node.js installation. Test it out by typing `node -v`. If you see a version number and not an error, you’re in business!

### But wait! There’s less!

Now it’s time to download and install **less**.

$ cd ~/data/
$ npm update
$ npm install less

This will install the **lessc** binary in the *~/data/node_modules/.bin* directory which we added to our $PATH. The installation may fail. If it does, just try running it again a few times until it works.

If all goes as well for you as it did for me, you should now be able to use **lessc** from anywhere within your jailed shell environment!


Getting .bashrc to work on MediaTemple’s Grid Service

I’m spoiled, guys and gals. I can’t work without [my dotfiles]( Watching me work in a vanilla bash shell is excruciating, like watching someone walk with those drunk-driving goggles–fumbling and stumbling through an environment completely devoid of the shortcuts and settings upon which I’ve come to rely so heavily. Even for something as simple as listing and switching directories:

njbair@n16 ~ $ ll
-bash: ll: command not found
njbair@n16 ~ $ ls -l
lrwxrwxrwx 1 njbair njbair 10 Sep 20 05:38 data -> ../../data/
lrwxrwxrwx 1 njbair njbair 13 Sep 20 05:38 domains -> ../../domains/
njbair@n16 ~ $ cd domains
njbair@n16 domains $ ll
-bash: ll: command not found
njbair@n16 domains $ ls -l
drwxr-xr-x 4 njbair www-data 5 Sep 20 05:38
lrwxrwxrwx 1 njbair njbair 6 Sep 20 05:38 ->
njbair@n16 $ ll
-bash: ll: command not found
njbair@n16 $ kill me now

Fortunately, `kill me now` was not installed on that machine.

I’ve been a long-time customer of MediaTemple’s dedicated hosting packages, but only recently set up my first **(gs)** shared hosting account. I’m really happy with the whole service so far. But after enabling SSH for my account, I hit a snag while installing my dotfiles: *.bashrc* wasn’t working. I could manually source the file, but it wasn’t loading upon login. Fortunately, the fix was pretty easy.

### The Fix

So, you’ve set up SSH access on a MediaTemple Grid Service account, but can’t get your *.bashrc* to load? Try this:

echo “if [ -f ~/.bashrc ]; then source ~/.bashrc; fi” >> ~/.bash_profile

Then logout and log back in.

### What just happened?

MediaTemple’s Grid SSH access doesn’t read *.bashrc* by default. This is because of political pressures relating to the high-stakes game of world diplomacy and international intrigue. Or maybe [there’s a reasonable technical explanation](

Hope this helps!


SSH From the Inside

### Problem ###

I need SSH access to a particulr machine (*schoolsvr*) which is behind a NAT. I only need to enable access from a single client (*homesvr*), which has a public IP address of its own. Both machines are running **sshd**. I can access *homesvr* from a shell on *schoolsvr*, but not vise-versa.

If I had admin access on *schoolsvr’s* gateway, I could alter the NAT to forward some unused port (say, 12345) to *schoolsvr:22*, which would allow me to SSH to *schoolsvr* using the gateway’s public IP and port 12345. Unfortunately, I don’t have admin access to the gateway.

How do I enable SSH access to *schoolsvr*?

### Solution ###

The solution is to open an SSH tunnel from *schoolsvr*, which I can access from a shell on *homesvr*. To achieve this, I use the OpenSSH client program’s `-R` option to bind an SSH tunnel to a non-standard port on *homesvr*. Consider the following command:

nick@schoolsvr$ ssh -R 12345:localhost:22 nick@homesvr
nick@homesvr’s password:

This command connects to *homesvr* via the standard SSH port (22) and binds that connection to the specified bind port (12345). This port remains bound until the SSH session is terminated. Now all SSH traffic directed to port 12345 on *homesvr* will be forwarded to port 22. When I get back to *homesvr*, I can open a new SSH session with *schoolsvr* using the following command:

nick@homesvr$ ssh -p 12345 localhost
nick@localhost’s password:

I’m in! I can terminate this session when I am finished, and the original tunnel remains open until I kill it on *schoolsvr*.

This command can be set up in */etc/inittab* (or an Upstart config file, depending on your system configuration) with the `respawn` action, which would ensure that the tunnel is open upon boot and will be automatically reopened upon termination. Note that such a setup requires the appropriate SSH keys to be configured on both machines, as an init process can’t enter a password.

Because each half of the connection is done using SSH, this setup is completely secure. Of course, anyone with physical access to *schoolsvr* would have full control over the open login to *homesvr*. To prevent this, I can modify the original command as follows:

nick@schoolsvr$ ssh -nNT -R 12345:localhost:22 nick@homesvr &

The `-n` option redirects standard input from */dev/null*. The `-N` option is specifically designed for port-forwarding applications such as this, and tells SSH not to bother preparing a command stream for this connection. The `-T` option tells the remote host not to bother allocating a pseudo-tty for this connection. These three options eliminate the possibility of using this open tunnel to execute any other processes on *schoolsvr*. Additionally, I appended an ampersand (`&`) to send the process to the background. Now I can close the shell in which I ran the command without killing the process.

### Conclusion ###

While not as elegant as a true NAT-based port forwarding solution, reverse SSH tunnels are a fast, secure way to connect two remote machines for general use. When used with discretion, they can be a real time-saver.

What do you think of this solution? Did I leave anything out? Let me know in the comments.