mirror of
https://github.com/mattchis/MacRMM-Script.git
synced 2025-10-23 04:52:19 +00:00
Complete rewite
This commit is contained in:
31
README.md
31
README.md
@@ -2,11 +2,13 @@
|
||||
|
||||
This script is designed to assist users in adding Mac agents to Tactical RMM without the need for upfront payment for code-signed agents. If you find this solution beneficial, please consider contributing to the Tactical RMM project!
|
||||
|
||||
> This script had a complete rewrite and now only supports MacOS 14 (Sonoma) and above.
|
||||
|
||||
# rmmagent-script
|
||||
|
||||
Script for one-line installation and updating of the tacticalRMM agent.
|
||||
|
||||
> Currently, both amd64 and arm64 scripts are available; however, only the amd64 version has been tested on macOS 13 (Ventura).
|
||||
> Currently, both amd64 and arm64 scripts are available and has been tested with MacOS 14 (Sonoma) and MacOS 15 (Sequoia); however, only the amd64 version has been tested on macOS 13 (Ventura).
|
||||
|
||||
Scripts for additional platforms will be developed and released as they are adapted. You are welcome to modify the script and contribute your improvements back to the project.
|
||||
|
||||
@@ -21,23 +23,13 @@ Download script with this url: `https://raw.githubusercontent.com/mattchis/MacRM
|
||||
To install agent launch the script with this argument:
|
||||
|
||||
```bash
|
||||
./rmmagent-mac.sh install 'System type' 'Mesh agent' 'API URL' 'Client ID' 'Site ID' 'Auth Key' 'Agent Type'
|
||||
./rmmagent-mac.sh install 'API URL' 'Client ID' 'Site ID' 'Auth Key' 'Agent Type'
|
||||
```
|
||||
The compiling can be quite long, don't panic and wait few minutes... USE THE 'SINGLE QUOTES' IN ALL FIELDS!
|
||||
|
||||
The argument are:
|
||||
|
||||
2. System type
|
||||
|
||||
Type of system. Can be 'amd64' 'arm64'
|
||||
|
||||
3. Mesh agent
|
||||
|
||||
The url given by mesh for installing new agent.
|
||||
Go to mesh.fqdn.com > Add agent > Installation Executable Linux / BSD / macOS > **Select the good system type**
|
||||
Copy **ONLY** the URL with the quote.
|
||||
|
||||
4. API URL
|
||||
2. API URL
|
||||
|
||||
Your api URL for agent communication usually https://api.fqdn.com.
|
||||
|
||||
@@ -62,7 +54,7 @@ The argument are:
|
||||
|
||||
### Example
|
||||
```bash
|
||||
./rmmagent-mac.sh install amd64 "https://mesh.fqdn.com/meshagents?id=XXXXX&installflags=X&meshinstall=X" "https://api.fqdn.com" 3 1 "XXXXX" server
|
||||
./rmmagent-mac.sh install "https://api.fqdn.com" 3 1 "XXXXX" server
|
||||
```
|
||||
|
||||
## Update
|
||||
@@ -71,6 +63,17 @@ Simply launch the script that match your system with *update* as argument.
|
||||
```bash
|
||||
./rmmagent-mac.sh update
|
||||
```
|
||||
## Enable Permissions
|
||||
This sets up all the permissions for screenrecording, file, and disk access for the meshagent.
|
||||
|
||||
```bash
|
||||
./rmmagent-mac.sh enablepermissions
|
||||
```
|
||||
## Seqouia Fix
|
||||
This will fix issues with "Take Control" from the dashboard not displaying the screen. Credit goes to PeetMcK and si458 for the solution (https://github.com/Ylianst/MeshCentral/issues/6402)
|
||||
```bash
|
||||
./rmmagent-mac.sh sequoiafix
|
||||
```
|
||||
|
||||
## Uninstall
|
||||
To uninstall the agent, execute the script with the following argument:
|
||||
|
224
rmmagent-mac.sh
224
rmmagent-mac.sh
@@ -10,100 +10,87 @@ if [[ $1 == "help" ]]; then
|
||||
echo ""
|
||||
echo "List of INSTALL/UPDATE argument (no argument name):"
|
||||
echo "Arg 1: 'install' or 'update'"
|
||||
echo "Arg 2: System type 'amd64' 'arm64'"
|
||||
echo "Arg 3: Mesh agent URL"
|
||||
echo "Arg 4: API URL"
|
||||
echo "Arg 5: Client ID"
|
||||
echo "Arg 6: Site ID"
|
||||
echo "Arg 7: Auth Key"
|
||||
echo "Arg 8: Agent Type 'server' or 'workstation'"
|
||||
echo "Arg 2: API URL"
|
||||
echo "Arg 3: Client ID"
|
||||
echo "Arg 4: Site ID"
|
||||
echo "Arg 5: Auth Key"
|
||||
echo "Arg 6: Agent Type 'server' or 'workstation'"
|
||||
echo ""
|
||||
echo "List of UNINSTALL argument (no argument name):"
|
||||
echo "Arg 1: 'uninstall'"
|
||||
echo "Arg 2: Mesh agent FQDN (i.e. mesh.domain.com)"
|
||||
echo "Arg 3: Mesh agent id (The id needs to have single quotes around it)"
|
||||
echo ""
|
||||
echo "Only argument 1 is needed for update"
|
||||
echo "List of ENABLEPERMISSIONS argument (no argument name):"
|
||||
echo "Arg 1: 'enablepermissions'"
|
||||
echo ""
|
||||
echo "List of SEQUOIAFIX argument (no argument name):"
|
||||
echo "Arg 1: 'SEQUOIAFIX'"
|
||||
echo ""
|
||||
echo "Only argument 1 is needed for update and sequoiafix"
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ $1 != "install" && $1 != "update" && $1 != "uninstall" ]]; then
|
||||
if [[ $1 != "install" && $1 != "update" && $1 != "uninstall" && $1 != "enablepermissions" && $1 != "sequoiafix" ]]; then
|
||||
echo "First argument can only be 'install' or 'update' or 'uninstall' !"
|
||||
echo "Type help for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $1 == "install" && $2 == "" ]]; then
|
||||
echo "Argument 2 (System type) is empty !"
|
||||
echo "Type help for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $1 == "install" && $2 != "amd64" && $2 != "arm64" ]]; then
|
||||
echo "This argument can only be 'amd64' 'arm64' !"
|
||||
echo "Argument 2 (API URL) is empty !"
|
||||
echo "Type help for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $1 == "install" && $3 == "" ]]; then
|
||||
echo "Argument 3 (Mesh agent URL) is empty !"
|
||||
echo "Argument 3 (Client ID) is empty !"
|
||||
echo "Type help for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $1 == "install" && $4 == "" ]]; then
|
||||
echo "Argument 4 (API URL) is empty !"
|
||||
echo "Argument 4 (Site ID) is empty !"
|
||||
echo "Type help for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $1 == "install" && $5 == "" ]]; then
|
||||
echo "Argument 5 (Client ID) is empty !"
|
||||
echo "Argument 5 (Auth Key) is empty !"
|
||||
echo "Type help for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $1 == "install" && $6 == "" ]]; then
|
||||
echo "Argument 6 (Site ID) is empty !"
|
||||
echo "Argument 6 (Agent Type) is empty !"
|
||||
echo "Type help for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $1 == "install" && $7 == "" ]]; then
|
||||
echo "Argument 7 (Auth Key) is empty !"
|
||||
echo "Type help for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $1 == "install" && $8 == "" ]]; then
|
||||
echo "Argument 8 (Agent Type) is empty !"
|
||||
echo "Type help for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $1 == "install" && $8 != "server" && $8 != "workstation" ]]; then
|
||||
if [[ $1 == "install" && $6 != "server" && $6 != "workstation" ]]; then
|
||||
echo "First argument can only be 'server' or 'workstation' !"
|
||||
echo "Type help for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## Setting var for easy scription
|
||||
system=$2
|
||||
mesh_url=$3
|
||||
rmm_url=$4
|
||||
rmm_client_id=$5
|
||||
rmm_site_id=$6
|
||||
rmm_auth=$7
|
||||
rmm_agent_type=$8
|
||||
#system=$2
|
||||
#mesh_url=$2
|
||||
rmm_url=$2
|
||||
rmm_client_id=$3
|
||||
rmm_site_id=$4
|
||||
rmm_auth=$5
|
||||
rmm_agent_type=$6
|
||||
|
||||
go_url_amd64="https://go.dev/dl/go1.20.2.darwin-amd64.pkg"
|
||||
go_url_arm64="https://go.dev/dl/go1.20.2.darwin-arm64.pkg"
|
||||
go_url_amd64="https://go.dev/dl/go1.24.4.darwin-amd64.pkg"
|
||||
go_url_arm64="https://go.dev/dl/go1.24.4.darwin-arm64.pkg"
|
||||
|
||||
function go_install() {
|
||||
## Installing golang
|
||||
case $system in
|
||||
amd64)
|
||||
echo "###########################"
|
||||
echo "# Installing/Upgrading Go #"
|
||||
echo "###########################"
|
||||
case $(uname -m) in
|
||||
x86_64)
|
||||
sudo curl -L -o /tmp/golang.pkg $go_url_amd64
|
||||
;;
|
||||
arm64)
|
||||
@@ -112,7 +99,7 @@ function go_install() {
|
||||
esac
|
||||
|
||||
sudo mkdir /usr/local/go
|
||||
sudo installer -pkg /tmp/golang.pkg -target /usr/local/go
|
||||
sudo installer -pkg /tmp/golang.pkg -target /usr/local/go
|
||||
sudo rm /tmp/golang.pkg
|
||||
|
||||
source /etc/profile
|
||||
@@ -120,44 +107,36 @@ function go_install() {
|
||||
echo "Golang Install Done !"
|
||||
}
|
||||
|
||||
function install_mesh() {
|
||||
## Installing mesh agent
|
||||
sudo curl -L -o /tmp/meshagent $mesh_url
|
||||
sudo chmod +x /tmp/meshagent
|
||||
sudo mkdir /opt/tacticalmesh
|
||||
sudo /tmp/meshagent -install --installPath="/opt/tacticalmesh"
|
||||
sudo rm /tmp/meshagent
|
||||
sudo rm /tmp/meshagent.msh
|
||||
}
|
||||
|
||||
function getCSREQBlob(){
|
||||
# Sign the app
|
||||
sudo codesign --detached /opt/tacticalmesh/meshagent.sig -s - /opt/tacticalmesh/meshagent
|
||||
# Sign the app
|
||||
sudo codesign --detached /opt/tacticalmesh/meshagent.sig -s - /opt/tacticalmesh/meshagent
|
||||
|
||||
# Get the requirement string from codesign
|
||||
req_str=$(sudo codesign -d -r- --detached /opt/tacticalmesh/meshagent.sig /opt/tacticalmesh/meshagent 2>&1 | awk -F ' => ' '/designated/{print $2}')
|
||||
# Get the requirement string from codesign
|
||||
req_str=$(sudo codesign -d -r- --detached /opt/tacticalmesh/meshagent.sig /opt/tacticalmesh/meshagent 2>&1 | awk -F ' => ' '/designated/{print $2}')
|
||||
|
||||
# Convert the requirements string into it's binary representation
|
||||
# csreq requires the output to be a file so we just throw it in /tmp
|
||||
echo "$req_str" | sudo csreq -r- -b /tmp/csreq.bin >/dev/null 2>&1
|
||||
|
||||
# Convert the binary form to hex, and print it nicely for use in sqlite
|
||||
req_hex="X'$(sudo xxd -p /tmp/csreq.bin | tr -d '\n')'"
|
||||
|
||||
echo "$req_hex"
|
||||
|
||||
# Convert the requirements string into it's binary representation
|
||||
# csreq requires the output to be a file so we just throw it in /tmp
|
||||
echo "$req_str" | sudo csreq -r- -b /tmp/csreq.bin
|
||||
|
||||
# Convert the binary form to hex, and print it nicely for use in sqlite
|
||||
req_hex="X'$(sudo xxd -p /tmp/csreq.bin | tr -d '\n')'"
|
||||
|
||||
echo "$req_hex"
|
||||
|
||||
# Remove csqeq.bin
|
||||
sudo rm -f "/tmp/csreq.bin"
|
||||
# Remove csqeq.bin
|
||||
sudo rm -f "/tmp/csreq.bin"
|
||||
}
|
||||
|
||||
function agent_compile() {
|
||||
## Compiling and installing tactical agent from github
|
||||
echo "Agent Compile begin"
|
||||
echo "########################"
|
||||
echo "# Compiling TRMM Agent #"
|
||||
echo "########################"
|
||||
sudo curl -L -o /tmp/rmmagent.zip https://github.com/amidaware/rmmagent/archive/refs/heads/master.zip
|
||||
sudo unzip /tmp/rmmagent.zip -d /tmp/
|
||||
sudo rm /tmp/rmmagent.zip
|
||||
case $system in
|
||||
amd64)
|
||||
case $(uname -m) in
|
||||
x86_64)
|
||||
sudo /bin/sh -c 'cd /tmp/rmmagent-master && env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w" -o /tmp/temp_rmmagent'
|
||||
;;
|
||||
arm64)
|
||||
@@ -170,63 +149,124 @@ function agent_compile() {
|
||||
}
|
||||
|
||||
function install_agent() {
|
||||
echo "#########################"
|
||||
echo "# Installing TRMM Agent #"
|
||||
echo "#########################"
|
||||
sudo cp /tmp/temp_rmmagent /usr/local/bin/rmmagent
|
||||
sudo /tmp/temp_rmmagent -m install -meshdir /opt/tacticalmesh -api $rmm_url -client-id $rmm_client_id -site-id $rmm_site_id -agent-type $rmm_agent_type -auth $rmm_auth
|
||||
sudo rm /tmp/temp_rmmagent
|
||||
sudo xattr -r -d com.apple.quarantine /opt/tacticalmesh/meshagent
|
||||
}
|
||||
|
||||
function update_agent() {
|
||||
sudo launchctl unload /Library/LaunchDaemons/tacticalagent.plist
|
||||
echo "#######################"
|
||||
echo "# Updating TRMM Agent #"
|
||||
echo "#######################"
|
||||
sudo launchctl bootout system /Library/LaunchDaemons/tacticalagent.plist
|
||||
|
||||
sudo cp /tmp/temp_rmmagent /opt/tacticalagent/tacticalagent
|
||||
sudo rm /tmp/temp_rmmagent
|
||||
|
||||
sudo launchctl load -w /Library/LaunchDaemons/tacticalagent.plist
|
||||
sudo xattr -r -d com.apple.quarantine /opt/tacticalmesh/meshagent
|
||||
}
|
||||
|
||||
function config_securityandprivacy () {
|
||||
# Adding permissions to macOS to allow Accessibility, Screen Capture, and All File Access to the meshagent
|
||||
echo "Applying Security and Privacy Exceptions"
|
||||
echo "############################################"
|
||||
echo "# Applying Security and Privacy Exceptions #"
|
||||
echo "############################################"
|
||||
req_hex="$(getCSREQBlob)"
|
||||
sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "REPLACE INTO access VALUES('kTCCServiceAccessibility','/opt/tacticalmesh/meshagent',1,2,4,1,$req_hex,NULL,0,NULL,NULL,0,NULL);"
|
||||
sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "REPLACE INTO access VALUES('kTCCServiceScreenCapture','/opt/tacticalmesh/meshagent',1,2,4,1,$req_hex,NULL,0,NULL,NULL,0,NULL);"
|
||||
sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "REPLACE INTO access VALUES('kTCCServiceSystemPolicyAllFiles','/opt/tacticalmesh/meshagent',1,2,4,1,$req_hex,NULL,0,NULL,NULL,0,NULL);"
|
||||
echo "Hex value = $req_hex"
|
||||
sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "REPLACE INTO access VALUES('kTCCServiceAccessibility','/opt/tacticalmesh/meshagent',1,2,4,1,$req_hex,NULL,0,'UNUSED',NULL,0,NULL,NULL,NULL,NULL,NULL);"
|
||||
sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "REPLACE INTO access VALUES('kTCCServiceScreenCapture','/opt/tacticalmesh/meshagent',1,2,4,1,$req_hex,NULL,0,NULL,NULL,0,NULL,NULL,NULL,NULL,NULL);"
|
||||
sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "REPLACE INTO access VALUES('kTCCServiceSystemPolicyAllFiles','/opt/tacticalmesh/meshagent',1,2,4,1,$req_hex,NULL,0,NULL,NULL,0,NULL,NULL,NULL,NULL,NULL);"
|
||||
}
|
||||
|
||||
function uninstall_agent() {
|
||||
sudo launchctl unload /Library/LaunchDaemons/tacticalagent.plist
|
||||
sudo rm /Library/LaunchDaemons/tacticalagent.plist
|
||||
sudo rm -Rf /opt/tacticalagent/
|
||||
sudo rm /etc/tacticalagent
|
||||
echo "###########################"
|
||||
echo "# Uninstalling TRMM Agent #"
|
||||
echo "###########################"
|
||||
if [ -e "/Library/LaunchDaemons/tacticalagent.plist" ]; then
|
||||
sudo launchctl bootout system /Library/LaunchDaemons/tacticalagent.plist
|
||||
sudo rm /Library/LaunchDaemons/tacticalagent.plist
|
||||
fi
|
||||
if [ -d "/opt/tacticalagent" ]; then
|
||||
sudo rm -Rf /opt/tacticalagent/
|
||||
fi
|
||||
if [ -e "/etc/tacticalagent" ]; then
|
||||
sudo rm /etc/tacticalagent
|
||||
fi
|
||||
sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "delete from access where client='/opt/tacticalagent/tacticalagent';"
|
||||
}
|
||||
|
||||
function uninstall_mesh() {
|
||||
sudo launchctl unload /Library/LaunchDaemons/meshagent.plist
|
||||
sudo /opt/tacticalmesh/meshagent -fulluninstall
|
||||
rm -Rf /opt/tacticalmesh
|
||||
echo "###########################"
|
||||
echo "# Uninstalling Mesh Agent #"
|
||||
echo "###########################"
|
||||
if [ -e "/Library/LaunchDaemons/meshagent.plist" ]; then
|
||||
sudo launchctl bootout system /Library/LaunchDaemons/meshagent.plist
|
||||
fi
|
||||
if [ -e "/Library/LaunchAgents/meshagent-agent.plist" ]; then
|
||||
sudo rm /Library/LaunchAgents/meshagent-agent.plist
|
||||
fi
|
||||
if [ -e "/Library/LaunchAgents/meshagent.plist" ]; then
|
||||
sudo rm /Library/LaunchAgents/meshagent.plist
|
||||
fi
|
||||
if [ -e "/opt/tacticalmesh/meshagent" ]; then
|
||||
sudo /opt/tacticalmesh/meshagent -fulluninstall
|
||||
fi
|
||||
if [ -d "/opt/tacticalmesh" ]; then
|
||||
rm -Rf /opt/tacticalmesh
|
||||
fi
|
||||
sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "delete from access where client='/opt/tacticalmesh/meshagent';"
|
||||
}
|
||||
|
||||
function sequoia_fix() {
|
||||
echo "########################"
|
||||
echo "# Applying Sequoia Fix #"
|
||||
echo "########################"
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
if [ -e "/Library/LaunchAgents/meshagent-agent.plist" ]; then
|
||||
sudo rm /Library/LaunchAgents/meshagent-agent.plist
|
||||
fi
|
||||
if [ -e "/Library/LaunchDaemons/meshagent.plist" ]; then
|
||||
sudo rm /Library/LaunchDaemons/meshagent.plist
|
||||
fi
|
||||
sudo cp "${script_dir}/meshagent.plist" /Library/LaunchAgents/meshagent.plist
|
||||
sudo chown root:wheel /Library/LaunchAgents/meshagent.plist
|
||||
sudo chmod 666 /opt/tacticalmesh/meshagent.msh
|
||||
sudo chmod 666 /opt/tacticalmesh/meshagent.db
|
||||
}
|
||||
|
||||
case $1 in
|
||||
install)
|
||||
go_install
|
||||
install_mesh
|
||||
agent_compile
|
||||
install_agent
|
||||
config_securityandprivacy
|
||||
echo "Tactical Agent Install is done"
|
||||
echo "Please wait about 5 min then run 'rmmagent-mac.sh enablepermissions'"
|
||||
exit 0;;
|
||||
enablepermissions)
|
||||
config_securityandprivacy
|
||||
echo "Security and Privacy configuration is done"
|
||||
echo "If the Mac is running Sequoia then run 'rmmagent-mac.sh sequoiafix'"
|
||||
exit 0;;
|
||||
sequoiafix)
|
||||
sequoia_fix
|
||||
echo "Sequoia Fix has been applied. Please reboot Mac for changes to take effect"
|
||||
exit 0;;
|
||||
update)
|
||||
go_install
|
||||
agent_compile
|
||||
update_agent
|
||||
config_securityandprivacy
|
||||
echo "Tactical Agent Update is done"
|
||||
echo "Please wait about 5 min then run 'rmmagent-mac.sh enablepermissions'"
|
||||
exit 0;;
|
||||
uninstall)
|
||||
uninstall_agent
|
||||
uninstall_mesh
|
||||
echo "Tactical Agent Uninstall is done"
|
||||
echo "TacticalRMM/Mesh Agent Uninstall is complete"
|
||||
echo "You may need to manually remove the agents orphaned connections on TacticalRMM and MeshCentral"
|
||||
exit 0;;
|
||||
esac
|
||||
esac
|
||||
|
Reference in New Issue
Block a user