Mule in a Shell: The SSH Connector
Join the DZone community and get the full member experience.
Join For FreeWhy do I want this?
This connector is mainly aimed to situations in which systems integration requires executing shell commands into a remote system. Examples are:
- Config changes (passwords, permissions, accounts, etc)
- Resource provisioning
- File System operations on non FTP-mapped drives or folders
You can also use this connector as a security gateway. Suppose you’re a system admin and you’re taking a vacation at an all inclusive hotel in Fiji. You receive an urgency call from your boss saying that there’s been a problem and you need to jump into it right now. You’re probably thinking that if you have your notebook or smartphone with you, you could just SSH your way into the server. But what happens if that SSH endpoint is only accessible from within a corporate VPN that’s unreachable from Fiji?. Using this connector plus the power of Mule, you can easily build a secure gateway that exposes the SSH to the outside world as a web client, a chat bot or whatever protocol you need… Cloud is the limit!
What Can I do with it?
The connector’s main features are:
- Full Duplex communication: Fundamentally, SSH is a bidirectional full duplex protocol, which means that it’s not synchronous like HTTP where you need to send a message for a response to happen. With SSH the remote host might want to tell you something even if you have remained silent. This connector uses a callback flow approach to decouple the “sending” operation from the “receiving” operation.
- Shell Mode: The connector provides an optional Shell Mode capability. If turned on, the connector will maintain your remote session so that you can execute several commands and still maintain context, similar to a traditional terminal based client such as PuTTY. Using shell mode truly shows the power of the full duplex support. If you just want to execute a single command, then you can turn this off and save resources.
- Connection multiplexing: Another particular feature of SSH is that you can have several users logged into the same server. The base connection is represented by the concept of a session and each user operates over a Channel. This connector completely hides this complexity for you while providing a similar model in which you can have multiple users operating over the same client.
I’m sold! How do I use it?
First, you need to visit the Mule Forge site and follow the installation guide following this link.
Now that we’re all set, let’s start by adding the namespace:
<mule xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ssh="http://www.mulesoft.org/schema/mule/sshmultiplexedconnector" xsi:schemaLocation=" http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd http://www.mulesoft.org/schema/mule/ssh http://www.mulesoft.org/schema/mule/sshmultiplexedconnector/1.0/mule-sshmultiplexedconnector.xsd">
Now, we config the connector:
<ssh:config host="ssh.mycompany.com" port="22" timeout="6000" callbackFlowName="callback" shellMode="true" />
As you can see the configuration is pretty descriptive and straight forward. It’s pretty much about:
- Host
- TCP port
- Timeout (in milliseconds)
- Callback flow name (to support full duplex, carry on reading for a full example)
- Shell Mode: Boolean property to enable (or not) shell mode. We’ll use it in this example.
Now, let’s send a couple of commands!
<flow name="exampleFlow"> <ssh:send username="${ssh.user}" password="${ssh.pass}" content="cd test" breakLine="true" /> <ssh:send username="${ssh.user}" password="${ssh.pass}" content="cat helloWorld.txt" breakLine="true"/> </flow>
So what this code doing is navigating to a folder named test and output the contents of the helloWorld.txt file. Since we’re using shell mode, the second command is still aware of the navigation performed in the first command and therefore can output the file. If shell mode were disabled, then the second command would fail because the user’s location would be set to $HOME again.
Now that we’re clear on what this flow does, let’s take a closer look at the parameters:
- Username and password: Besides the obvious, the
nice thing about this parameters is that the connector will use the
username to multiplex and reuse the underlying channel associated to
this username.
- Content: The payload you want to get across
- breakLine: This parameter is optional and defaults
to false. If true, it will add a ‘\n’ character to the end of the
content. This is because if you want to execute a command, the remote
shell needs you to hit enter to end the line. So, if you’re payload is
fixed like in the example, adding a break to end the line automatically
comes handy. If you’re getting the content from a web client, chat
channel or whatever source that will include the line break, or if you
simply don’t need it, then don’t set this value.
And how do I read the response? Defining the callback flow that was specified in the connector’s config:
<flow name="callback"> <logger message="sent to #[header:INBOUND:SSH_CALLBACK_USER], message says: #[payload]" /> </flow>
There’re two things to notice about this flow:
- The name matches the config’s callbackFlowName property
- The message payload contains the server response and the SSH_CALLBACK_USER inbound property has the username to whom the message was sent (remember that connections are full duplex and multiplexed, so concurrency makes it impossible to assure the order in which responses will arrive)
So, we’re pretty much done here, the last thing is to release the connection once we’re done using it:
<flow name="release"> <ssh:release username="${ssh.user}"/> </flow>
Notice that the release operation has the username as a mandatory parameter. This is because the connector is a multiplexed, and while user A may be ready to free some resources, users B and C might still be operating.
That’s all folks! Please visit the MuleForge for further info and don’t hesitate to share questions or thoughts about this connector. We look forward to your feedback.
Published at DZone with permission of Mariano Gonzalez, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments