Just stumbled across this movable type Perl plugin that allows Perl code to be placed and executed in templates during rebuilds. Now THIS is something that could come in handy.
I’ve been experimenting various approaches to keep my remote/local sites in sync. CVS is too much of a pain with blog-driven sites that create static pages. Instead, I’m now using rsync. Since several sites reside behind firewalls, I needed to find a way to tunnel rsync traffic through an ssh hop. Sure enough, the rsync FAQ has some good information on how to do this. I’m using their “Method 2” since I only need to sync against a filesystem target.
rsync through a firewall
If you have a setup where there is no way to directly connect two systems for an rsync transfer, there are several ways to use the firewall system to act as an intermediary in the transfer.
Use your remote shell (e.g. ssh) to access the middle system and have it use a remote shell to hop over to the actual target system.
To effect this extra hop, you’ll need to make sure that the remote-shell connection from the middle system to the target system does not involve any tty-based user interaction (such as prompting for a password) because there is no way for the middle system to access the local user’s tty.
One way that works for both rsh and ssh is to enable host-based authentication, which would allow all connections from the middle system to the target system to succeed (when the username remains the same). However, this may not be a desirable setup.
Another method that works with ssh (and is also very safe) is to setup an ssh key (see the ssh-key manpage) and ensure that ssh-agent forwarding is turned on (e.g. “ForwardAgent yes”). You would put the public version of your key onto the middle and target systems, and the private key on your local system (which I recommend you encrypt). With this setup, a series of ssh connections that starts from the system where your private key is available will auto-authorize (after the pass-phrase prompt on the first system).
You should then test that a series of ssh connections works without multiple prompts by running a command like this (put in the real “middle” and “target” hostnames, of course):
ssh middle ssh target uptime
If you get a password/passphrase prompt to get into the middle system that’s fine, but the extra hop needs to occur without any extra user interaction.
Once that’s done, you can do an rsync copy like this:
rsync -av -e “ssh middle ssh” target:/source/ /dest/
Assuming you’re using ssh as your remote shell, you can configure ssh to forward a local port through your middle system to the ssh port (22) on the target system.
The first thing we need is an ssh configuration that will allow us to connect to the forwarded port as if we were connecting to the target system, and we need ssh to know what we’re doing so that it doesn’t complain about the host keys being wrong. We can do this by adding this section to your ~/.ssh/config file (substitute “target” and “target_user” as appropriate):
Next, we need to enable the port forwarding:
ssh -fN -l middle_user -L 2222:target:22 middle
What this does is cause a connection to port 2222 on the local system to get tunneled to the middle system and then turn into a connection to the target system’s port 22. The -N option tells ssh not to run a command on the remote system, which works with modern ssh versions (you can run a sleep command if -N doesn’t work). The -f option tells ssh to put the command in the background after any password/passphrase prompts.
With this done, you could run a normal-looking rsync command to “target” that would use a connection to port 2222 on localhost automatically:
rsync -av target:/src/ /dest/
Note: starting an ssh tunnel allows anyone on the source system to connect to the localhost port 2222, not just you, but they’d still need to be able to login to the target system using their own credentials.
Install and configure an rsync daemon on the target and use an ssh tunnel to reach the rsync sever. This is similar to method 2, but tunnels the daemon port for those that prefer to use an rsync daemon.
Installing the rsync daemon is beyond the scope of this document, but see the rsyncd.conf manpage for more information. Keep in mind that you don’t need to be root to run an rsync daemon as long as you don’t use a protected port.
Once your rsync daemon is up and running, you build an ssh tunnel through your middle system like this:
ssh -fN -l middle_user -L 8873:target:873 middle
What this does is cause a connection to port 8873 on the local system to turn into a connection from the middle system to the target system on port 873. (Port 873 is the normal port for an rsync daemon.) The -N option tells ssh not to run a command on the remote system, which works with modern ssh versions (you can run a sleep command if -N doesn’t work). The -f option tells ssh to put the command in the background after any password/passphrase prompts.
Now when an rsync command is executed with a daemon-mode command-line syntax to the local system, the conversation is directed to the target system. For example:
rsync -av –port 8873 localhost::module/source dest/
rsync -av rsync://localhost:8873/module/source dest/
Note: starting an ssh tunnel allows anyone on the source system to connect to the localhost port 8873, not just you, so you may want to enable username/password restrictions on you rsync daemon.
Some tips on job control from Peter Van Buren, Stein Lab system admin:
Background: I had asked Peter about how to keep jobs running even when a shell exits. Backgrounding a process is not always sufficient.
It’s probably your shell exiting that is sending signals to your jobs. If you are running bash on your laptop, you can try using the nohup command “nohup myjob &”. That should make the job immune to hangup signals from exiting shells. The nohup command, by default, sends output to a file called nohup.out.
I think you can use redirection with nohup. You can also try running tcsh, which I believe doesn’t send HUP signals to child processes. There is a also a bash builtin command “disown”. If you run “disown -h job#”, signals should no longer be sent to that job if the shell exits.
Subject: Building libgd and GD.pm on Mac OS X.3
Prerequisites: Apple X11 installed
Look, about a billion people have asked me how to build gd and libgd and Mac OS X. It really isn’t that difficult\. Here is how to do it. Please note that there may be a newer version of libgd by this point.
# fetch and build libgd (current for 2.0.15)
% curl -O http://www.boutell.com/gd/http/gd-2.0.15.tar.gz
% gnutar -zxf gd-2.0.15.tar.gz
% cd gd-2.0.15/% ./configure CPPFLAGS=-I/usr/X11R6/include/freetype2 \
% sudo make install
# Fetch and build GD.pm
% curl -O http://stein.cshl.org/WWW/software/GD/GD.pm.tar.gz
% gnutar xzf GD.pm.tar.gz
% cd GD-*/
% perl Makefile.PL
% make test
% sudo make install