Secure Two-Machine Maya commandPort, with SSH Tunneling

A previous posting described some of the security implications of using Maya commandPorts with underlying INET sockets. As Autodesk’s documentation for commandPort prominently warns, “no user identification, or authorization is required to connect to a given socket, and all commands (including “system(…)”) are allowed and executed with the user id and permissions of the Maya user.” This is potential security risk, and it is made more acute if the socket is created on a network interface that other machines can access. However, sometimes it may be desirable to use commandPort between two machines like this. One might want to spread computational responsibilities between a “producer” application on one machine, and Maya as the “consumer” application on another. Or one may simply want to use the screen on one machine to display application windows, while Maya runs on another. This might be a common setup for a developer who is writing code in an external Integrated Development Environment (IDE), for example.

As described in the previous posting, the most direct way to set up a two-machine commandPort connection is to specify an externally-visible IP address in the command’s name parameter. For example, if the IP address of the machine running Maya is 10.0.1.8, then the following commandPort command creates an INET socket on port 5555, which is accessible to users on any other machine which can contact that IP address:

import maya.cmds as cmds
cmds.commandPort(name="10.0.1.8:5555", sourceType="python")

Typically, such machines will be just those on the local network, but wider connections are possible.

Instead of opening a port like this, however, we can set up a more secure two-machine connection by making use of ssh tunneling. To be specific, we will use local port forwarding, so that Maya and the remote application each communicate with a local INET port on localhost, but traffic is transparently routed between these ports over the network via a secure SSH connection.

Let the remote machine be called “remotehost”, and the machine running Maya be “mayahost”. We’ll create a local command port on port 5555 on mayahost, and we’ll want to communicate with that command port from remotehost via port 5556 on its localhost. First, we’ll run Maya on mayahost, and create its command port on localhost:

import maya.cmds as cmds
cmds.commandPort(name=":5555", sourceType="python")

Let’s assume that mayahost is running an SSH server, and that we can log in as the user “mayauser”. Then to set up tunneling from remotehost to mayahost, we’d run this command from a shell on remotehost:

$ ssh -L 5556:localhost:5555 mayauser@mayahost

This logs into mayahost with an SSH connection which, to all appearances, looks like a regular SSH login. But now, from another shell, let’s try connecting to localhost‘s port 5556 on remotehost, using the netcat utility:

$ nc -v localhost 5556
Connection to localhost 5556 port [tcp/freeciv] succeeded!
cmds.about(product=True)
Maya 2014

So connecting to the local port 5556 on remotehost acts like connecting to the local port 5555 on mayahost, which Maya is listening on. This SSH tunnel provides a secure route across the network, and we don’t need to expose external INET sockets on either machine. So it is a much preferable way to set up a two-machine Maya configuration.

It should be noted, however, that with SSH tunneling, we still do face a security risk from local users on both machines. This is just the same security risk of local INET sockets, that we discussed before. Any local user on remotehost can connect to these ports on localhost, without authentication. To close this security hole, we could perhaps integrate SSH, or some other authentication/encryption method, into the prefix command supplied to commandPort, so that all input is verified to come from a trusted user. However, it might well take less work, and be more robust, to just implement our own version of secure command ports in Maya, and not use Autodesk’s commandPort command at all. This could be done with a C/C++ command plug-in, and a library like libssh, or with a Python command plug-in, and the Paramiko pure-Python SSH2 module. I may look at the Paramiko approach in a future post.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s