Posted on 02-09-2017 12:21 PM
Supporting remote users can be tricky. While it would be great if Casper Remote worked over the public web (I think that's a feature request) currently it does not.
When we first adopted JAMF Pro, I hoped to be able to achieve this with Casper Remote, but when I learned that functionality did not yet exist, I went looking for other options.
Previously, we had used a Zoom meeting and asked the user to share their screen and then we could request control. However, this is not ideal as we would like a solution that only requires a single click from the user, or no action at all.
I found Paul Cowan's (@plite) presentation at JNUC 2016 regarding 10 Ideas for Making Self Service a Killer App (https://www.jamf.com/resources/10-ideas-for-making-self-service-a-killer-app/), and thought his remote support presentation was incredible.
I reached out to Paul asking him how he accomplished it, and the answer was extremely simple, so I thought I would share it with the JAMF Nation, as I am sure others would like to implement it as well. The instructions below are long as I erred on the side of too much detail, but it is actually pretty simple and easy to implement.
Again, many thanks to @plite for his assistance and support, and for sharing his methods.
To achieve the remote support session, you will need a few things.
NOTE: The client's machine that you are attempting to remote control must be accessible over SSH and you must have the credentials of that user. We have a policy that ensures our local admin user's remote login capabilities stay enabled (as some of our users have admin access themselves).
#!/usr/bin/expect -f
set pass [lrange $argv 0 0]
set server [lrange $argv 1 1]
set name [lrange $argv 2 2]
set destport [lrange $argv 3 3]
set ardport [lrange $argv 4 4]
set timeout 10
spawn ssh -f -N -p $ardport -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -R $destport:127.0.0.1:5900 -i /tmp/jamf-remote.pem $name@$server
match_max 100000
#expect "*?assword:*"
#send -- "$pass
"
#send -- "
"
expect eof
In the event you want to use this script with a username and password instead of a PEM to connect (for some other purpose, this implementation requires a PEM), modify this line of the script as follows to remove the -i /tmp/jamf-remote.pem
:
spawn ssh -f -N -p $ardport -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -R $destport:127.0.0.1:5900 $name@$server
Also, you will need to uncomment the three lines at the end so they look like this:
expect "*?assword:*"
send -- "$pass
"
send -- "
"
I am using a single t2.micro in AWS running AWS Linux and as an apache server to act as both the SSH host and the web server. So, I will describe in this guide how to do the same.
When you create your instance, create a new pem, as it is more secure, and the box is going to be open to the public. Please also note that the above script assumes you named the pem "jamf-remote.pem". Amazon creates a generic ubuntu user for you, but I suggest creating two additional users, both with a set of ssh keys: one for your admins, and one for your clients, then deleting the default ubuntu user. If you need assistance achieving this, let me know and I will be happy to assist.
For our implementation, I configured SSH to listen on port 81 (yes, it's security by obscurity, I know). To do this, you need to modify the /etc/ssh/sshd_config
file and add Port 81
beneath Port 22
. Restart the sshd service and test that you can ssh over port 81 before modifying the config and removing the Port 22
line item, of course restarting sshd again.
Our implementation uses the same AWS instance for hosting the script as it does for the SSH tunnel. You can use a different machine if you already have a web server. We did not already have a publicly facing web server, so this was simplest.
Install Apache2 on the machine
sudo apt-get install apache2
You then need to configure apache to host the script
cd /var/www/html
vi kARD.sh
Paste the script above into kARD.sh, and then restart apache2
sudo service apache2 restart
NOTE: Apache uses port 80 by default. So your server will also need to be accessible on port 80, or whichever port you configure Apache to run on.
The JSS policy will allow the user to connect via SSH with VNC forwarding to your AWS instance. You will then do the same thing as an admin and gain access to the user's machine.
The JSS policy first copies the .pem file to the user's machine. I used Packages to package up the .pem and place it in /tmp/ on the end-user's machine.
The same policy then runs a script that we have loaded into our JSS. The script is a single line:
#!/bin/sh
curl -o /tmp/kARD.sh http://<your_web_servers_public_address>/kARD.sh;chmod ugo+rwx /tmp/kARD.sh;/tmp/kARD.sh <password> <your_aws_ssh_servers_public_address> <username> 5901 81 &
NOTE: The original script from @plite had the script going into /usr/bin and being run from the same location. However, due to SIP (System Integrity Protection) I discovered this is not viable and moved it to /tmp. Feel free to put it wherever you like.
You will want to replace the bracketed items with information pertinent to your environment.
This policy pulls the kARD.sh script down from your web server onto the client machine, changes the permissions, and runs it with the set variables.
We make this policy available in Self Service and the user can click "Remote Support" when prompted to do so by IT. Then we initiate our half of the connection (explained below).
Once the user has run the policy, the admin who will be taking control of the remote session needs to run a script or terminal command on their end. I have this packaged as a double-clickable script for the admins running remote support.
Open a terminal and run:
ssh -p 81 -L 5901:127.0.0.1:5901 -i /path/to/jamf-remote.pem <username>@<aws_public_address>
This command is responsible for the port forwarding over SSH. The -p 81 -L 5901:127.0.0.1:5901
can be written as -p W -L X:Y:Z
. This command says "open an ssh connection over port 81
and take port X
on host Y
and forward it to port Z
on the server I am attempting to SSH to". Since 127.0.0.1
is your local Mac, you are forwarding your port 5901
to the AWS instance's 5901
. The user has already forwarded their 5900
(ARD/VNC port) to 5901
on the AWS instance with the expect script (kARD.sh), so you are hopping onto that connection and picking up the VNC traffic.
Once you have initiated the SSH session, go to Finder > Go > Connect to Server (or ïãÿ + K from the Finder) and open a VNC connection to port 5901
on your local mac:
vnc://127.0.0.1:5901
You will then be prompted with a login username and password prompt. This is where you enter the admin credentials of a remote login capable user on the client's machine.
Once you have completed the remote session, go back to your terminal where you initiated the SSH session on the admin side and run sudo killall sshd
. This will kill the sshd process and terminate the connection for you and the end user. Don't worry, Linux takes care of starting it back up again in preparation for the next remote session.
If you want to initiate this connection without the user's interaction, you can modify the JSS policy to run at recurring checkin scoped to a single machine, instead of in self service. Set up an email or Slack alert for when the policy has succeeded, and you will know when to initiate the admin side of the connection.
That's it! You're done!
If you have any questions regarding implementation or need assistance in any way, please let me know.
Thanks again to Paul Cowan @plite for this solution!