How do I run an OS X command script on remote Xserves from a desktop OS X script? The answer to an earlier question, Access and control home office network, iMacs, and Xserves, left me with a new problem. To review, I have a computing environment comprised of:


27" iMac with dual cores running Mac OS X 10.6.8
2 Xserves each with 2 quad cores running Mac OS X Server 10.6.8
All networked over Ethernet to a Time Capsule.


As this question has more general application than the earlier one, I thought it merited its own post.



I need to launch and shut down a service (in my case Wolfram Lightweight Grid Manager but this really applies to any service, program, or application) which needs to run on a server (or more generally, any other machine) attached to my network (or again more generally, any network to which one has authorized access).

I need to have that script:    


Access and log on to 2 Xserves on my local network and there
Launch a script on the Xserves that will in turn launch Wolfram Lightweight Grid Manager


Note: I have this script. It currently runs from launchd when I turn on the Xserves. I just need to control its running and ensure it is not running more frequently than needed so the Xserves can sleep (the grid manager appears to keep the Xserves from sleeping).

At some later point, I'll need to do the same thing as above, but turn off the service on the remote servers.


  Q U E S T I O N S:
  
  
  How do I go about this?
  How do I get to a remote machine, especially as it does not likely have a fixed IP address?
  


I do have machine names and logon credentials.

I've very rarely done this sort of thing.

References or examples welcome.

My OS X server scripting never amounted to much, so any guidance welcome.
So there are a few components to this, which I'll tackle in chunks. The most important is how to execute a remote command/script. As IconDaemon points out, SSH is the best use for this. There's even a pretty good and secure means of doing this without requiring a password, for automated scripting purposes.

For clairity's sake, I'm going to refer to the Xserves as the server and your iMac or other machine accessing them as the client.

Execute a Shell Command on a Remote Server


On the server, open the Sharing panel in System Preferences, and check the Remote Login box

This enables the SSH server, allowing us get a remote command-line login. 

On the client, open Terminal.app and type the following, then press enter: ssh-keygen -f examplekey

This creates two files in your home directory. examplekey (the private key) and examplekey.pub (the public key). These are cryptographic signatures that will allow anyone with examplekey to connect to your server, without any password. For this reason, we're going to restrict what commands can be executed, but you should also be careful to keep the private key file stored safely, only on devices that will need to execute your remote script.

On the server, open /Users/YOURUSERNAME/.ssh/authorized_keys in a text editor.

Make sure you're doing this with whichever user has permissions to run the script.

On a new line, enter command="/path/to/yourscript", followed by a space, then paste the contents of examplekey.pub

The command in the quotes should be whatever you want executed (presumably the script to activate/deactivate the Grid Manager).
If you have two scripts, one to turn it on, one to turn it off, you'll need to either combine them into a script that toggles it on/off, or repeat steps 2-4 to create a second key, so that you have one to turn it off, one to turn it on.
This command is the only thing that can or will be run; unlike a standard ssh session, the command= parameter doesn't give you an interactive prompt, it just executes the command and closes. We want this for security purposes.

Now with all the pieces in place, we can run the command. In Terminal on the client, type ssh -i /path/to/examplekey user@serveraddress and run it. If everything's been set up properly, it should run your script, then close the connection.

You can omit the user@ portion, if the usernames are the same between the client and server.
The server address can be an IP or hostname. The second part of my answer will address how to connect over the internet, when you don't have a static IP.
If you need to use a non-standard port (i.e. not 22), change the command to read ssh -i /path/to/examplekey -p PORT user@serveraddress. You may need this for the next section.



Now that you have SSH working, we need a way to run this from a remote computer.

Accessing a Computer Remotely without a Static IP

There are a few different ways to do this - you can access your iMac over the internet through VNC/Remote Desktop, then access your servers across the local network as above. Or you can directly access the servers over the internet.

Either way, you'll need two things:
- A way to access your local network remotely, without keeping track of your IP.
- Port forwarding to enable access for whatever protocol you want to use (SSH, VNC or Apple Remote Desktop).

Dynamic DNS

This is basically a simple way to give yourself remote access without having to worry about your ISP changing your IP. You sign up for a free service, which gives you domain name that points to your home network. To keep track of your IP changing, you run a client program that updates the service's records whenever you get a new public IP.

I use DynDNS, but it seems they've discontinued new signups for their service. No-IP seems to be the best alternative.


Make an account for their "No-IP Free" service.
Once you're signed up, follow the steps to add a new hostname. Make a note of the hostname you choose, it will be something like myhostexample.no-ip.info.
Download the Mac updater program here and install it on a computer that's going to be running often. It doesn't matter which one, since anything on your home network uses the same public IP, you just want it to be running often enough that it doesn't miss any updates to your public IP.


Now you've got an address to connect to your home network, we need to configure your router to allow remote access to the services you need. This depends on how you want to connect remotely (SSH, VNC or a combination). I'll give a general example.

Static DHCP and Port Forwarding

To access a computer inside your network from the internet, we need to allow certain traffic through your router's firewall, and have an address to send it to.

Most routers use DHCP to assign your local IP addresses (if you've manually configured your IP, you know this and can skip this part). However, they can be set to configure each machine with the same IP every time (called static DHCP).

There's a good guide on how to do this with an Airport Extreme here, but it should be nearly identical for your Time Capsule. Take note that the final portion of the guide is redundant, and possibly undesirable (the last three paragraphs and last screenshot). You'll want to do that for each computer you need remote access too (potentially both Xserves and your iMac).

Now that you've got static DHCP set up, we need to do some port forwarding. Which ports you forward depends on how you want to do your remote access, but I would suggest forwarding SSH to both Xserves. That way you can use the SSH setup in the first section from wherever you happen to be. This guide covers how to enable it on your Time Capsule.
- The basic concept is that you can forward any port accessed on your external address (the myhostexample.no-ip.info that we setup before) to any port on any of your external machines. So if you go to myhostexample.no-ip.info:1234, it can be redirected internally to 192.168.1.9:567.
- For SSH, you'll want to redirect some arbitrary public port to port 22 on each of your Xserves. So you can set up (for example) public port 9022 to go to port 22 on one Xserve, and use public port 9122 to go to port 22 on the other Xserve. The public ports don't matter (you just have to change the ssh command to match), but using port 22 internally eliminates extra configuration.

You can use the same principles to allow other access to your iMac or Xserves (like VNC or Apple Remote Desktop), you just need to make note of which ports you need to forward. http://www.portforward.com is a good resource for this. Also note that if you're using VNC, it's not encrypted, so you'll be sending your password in the clear. If you have to use VNC, google "VNC SSH tunnelling", which should give you some good guides on how to secure it.

Wrap-up

Once you have all this in place, you should be able to ssh from anywhere to your Xserves and activate your scripts. Assuming you set up myhostexample.no-ip.info as your dynamic DNS and 9022 as your port forward, you just need to run ssh -i /path/to/examplekey -p 9022 user@myhostexample.no-ip.info.

Hope that works for you, sorry it's a bit long, but I think I covered most of the bases. Please ask if something's not clear!