Compare commits

...

54 Commits

Author SHA1 Message Date
wh1te909
4f1b41227f Release 0.16.2 2023-08-14 20:57:52 +00:00
wh1te909
83b9d13ec9 bump version [skip ci] 2023-08-14 20:57:14 +00:00
wh1te909
cee7896c37 back to dev [skip ci] 2023-08-14 17:06:40 +00:00
wh1te909
0377009d2b Release 0.16.1 2023-08-14 17:05:27 +00:00
wh1te909
b472f3644e bump versions 2023-08-14 16:42:32 +00:00
wh1te909
5d8ea837c8 fix posix restart 2023-08-12 00:28:20 +00:00
wh1te909
82de6bc849 syntax fix [skip ci] 2023-08-11 23:05:14 +00:00
wh1te909
cb4bc68c48 fix syntax [skip ci] 2023-08-11 22:07:59 +00:00
wh1te909
3ce6b38247 bump dev vers [skip ci] 2023-08-11 07:08:48 +00:00
wh1te909
716c0fe979 handle cloud init hosts file 2023-08-11 05:14:43 +00:00
wh1te909
c993790b7a bump web ver [skip ci] 2023-08-06 23:08:35 +00:00
wh1te909
aa32286531 update reqs 2023-08-06 22:31:40 +00:00
wh1te909
6f94abde00 fix alert filtering fixes #1572 2023-07-30 20:05:34 +00:00
wh1te909
fa19538c9d handle custom certs in backup/restore 2023-07-30 07:14:44 +00:00
wh1te909
84c858b878 fix issuer name 2023-07-30 07:12:51 +00:00
wh1te909
865de142d4 update reqs 2023-07-30 07:11:33 +00:00
wh1te909
9118162553 fix duplicate agent customfields 2023-07-18 22:23:34 +00:00
wh1te909
f4fc6ee9b4 update nats 2023-07-18 22:22:19 +00:00
wh1te909
108c38d57b update reqs 2023-07-18 22:20:38 +00:00
wh1te909
a1d73eb830 noexec 2023-07-18 22:10:29 +00:00
wh1te909
997906a610 formatting 2023-07-18 22:06:36 +00:00
wh1te909
b6e5d120d3 mongo check [skip ci] 2023-07-11 01:06:45 +00:00
wh1te909
d469d0b435 format [skip ci] 2023-07-11 01:05:10 +00:00
Dan
e9f823e000 Merge pull request #1560 from dinger1986/develop
change script to work with debian 12
2023-07-10 17:58:02 -07:00
dinger1986
d7fb76ba74 Update troubleshoot_server.sh 2023-07-10 23:35:57 +01:00
dinger1986
b7dde1a0d9 Merge branch 'amidaware:develop' into develop 2023-07-10 23:06:41 +01:00
dinger1986
15095d8c23 Update troubleshoot_server.sh 2023-07-10 10:13:06 +01:00
wh1te909
dfbebc7606 testing psycopg3 2023-07-09 07:04:38 +00:00
wh1te909
895309d93d pg 15 for ci 2023-07-09 07:03:48 +00:00
wh1te909
bcf50e821a update ansible for 0.16.0 2023-07-07 09:07:43 +00:00
wh1te909
30195800dd handle new dir 2023-07-07 03:59:48 +00:00
wh1te909
6532b0f149 back to dev 2023-07-07 03:58:36 +00:00
sadnub
5e108e4057 fix dockerfile 2023-07-05 21:16:43 -04:00
Dan
c2b2f4d222 Merge pull request #1550 from dinger1986/develop
changed find and delete of old backups
2023-07-05 17:49:12 -07:00
dinger1986
bc4329ad21 Update backup.sh 2023-07-05 22:38:50 +01:00
dinger1986
aec6d1b2f6 Update backup.sh 2023-07-05 22:38:30 +01:00
wh1te909
2baf119299 Release 0.16.0 2023-07-05 17:20:19 +00:00
wh1te909
6fe4c5a2ed bump versions 2023-07-05 02:03:34 +00:00
wh1te909
4abc8e41d8 only chown if exists 2023-07-05 02:02:58 +00:00
wh1te909
af694f1ce9 arm64/deb12/ubuntu22 support, remove mongo, postgres 15 and node 18 2023-07-04 08:53:06 +00:00
wh1te909
7c3a5fcb83 update reqs 2023-07-03 23:35:45 +00:00
wh1te909
57f64b18c6 bump web ver [skip ci] 2023-06-30 20:34:12 +00:00
wh1te909
4cccc7c2f8 fix escape error 2023-06-27 23:00:12 +00:00
wh1te909
903a2d6a6e flaky test 2023-06-25 02:16:19 +00:00
wh1te909
34c674487a update reqs 2023-06-24 22:20:59 +00:00
Dan
d15a8c5af3 Merge pull request #1543 from dinger1986/develop
Update troubleshoot_server.sh
2023-06-23 20:23:51 -07:00
dinger1986
3e0dec9383 Update troubleshoot_server.sh 2023-06-24 00:02:41 +01:00
wh1te909
8b810aad81 add arm64 bin [skip ci] 2023-06-19 06:31:50 +00:00
wh1te909
e676bcb4f4 update reqs 2023-06-19 05:44:00 +00:00
wh1te909
a7aed77764 python 3.11.4 2023-06-19 05:29:10 +00:00
wh1te909
88875c0257 update reqs 2023-06-19 05:25:52 +00:00
wh1te909
f711a0c91a update reqs 2023-06-05 05:40:36 +00:00
wh1te909
d8a076cc6e update demo 2023-06-04 01:59:46 +00:00
wh1te909
c900831ee9 back to dev 2023-06-04 01:59:25 +00:00
36 changed files with 694 additions and 475 deletions

View File

@@ -1,11 +1,11 @@
# pulls community scripts from git repo
FROM python:3.11.3-slim AS GET_SCRIPTS_STAGE
FROM python:3.11.4-slim AS GET_SCRIPTS_STAGE
RUN apt-get update && \
apt-get install -y --no-install-recommends git && \
RUN apt-get update &&
apt-get install -y --no-install-recommends git &&
git clone https://github.com/amidaware/community-scripts.git /community-scripts
FROM python:3.11.3-slim
FROM python:3.11.4-slim
ENV TACTICAL_DIR /opt/tactical
ENV TACTICAL_READY_FILE ${TACTICAL_DIR}/tmp/tactical.ready
@@ -17,17 +17,17 @@ ENV PYTHONUNBUFFERED=1
EXPOSE 8000 8383 8005
RUN apt-get update && \
RUN apt-get update &&
apt-get install -y build-essential
RUN groupadd -g 1000 tactical && \
RUN groupadd -g 1000 tactical &&
useradd -u 1000 -g 1000 tactical
# copy community scripts
COPY --from=GET_SCRIPTS_STAGE /community-scripts /community-scripts
# Copy dev python reqs
COPY .devcontainer/requirements.txt /
COPY .devcontainer/requirements.txt /
# Copy docker entrypoint.sh
COPY .devcontainer/entrypoint.sh /

View File

@@ -14,14 +14,14 @@ jobs:
name: Tests
strategy:
matrix:
python-version: ["3.11.3"]
python-version: ["3.11.4"]
steps:
- uses: actions/checkout@v3
- uses: harmon758/postgresql-action@v1
with:
postgresql version: "14"
postgresql version: "15"
postgresql db: "pipeline"
postgresql user: "pipeline"
postgresql password: "pipeline123456"

View File

@@ -1,6 +1,6 @@
---
user: "tactical"
python_ver: "3.11.3"
python_ver: "3.11.4"
go_ver: "1.20.4"
backend_repo: "https://github.com/amidaware/tacticalrmm.git"
frontend_repo: "https://github.com/amidaware/tacticalrmm-web.git"

View File

@@ -1,2 +0,0 @@
deb https://nginx.org/packages/debian/ bullseye nginx
deb-src https://nginx.org/packages/debian/ bullseye nginx

View File

@@ -41,11 +41,15 @@
with_items:
- "{{ base_pkgs }}"
- name: set arch fact
ansible.builtin.set_fact:
goarch: "{{ 'amd64' if ansible_architecture == 'x86_64' else 'arm64' }}"
- name: download and install golang
tags: golang
become: yes
ansible.builtin.unarchive:
src: "https://go.dev/dl/go{{ go_ver }}.linux-amd64.tar.gz"
src: "https://go.dev/dl/go{{ go_ver }}.linux-{{ goarch }}.tar.gz"
dest: /usr/local
remote_src: yes
@@ -111,7 +115,7 @@
tags: postgres
become: yes
ansible.builtin.copy:
content: "deb http://apt.postgresql.org/pub/repos/apt bullseye-pgdg main"
content: "deb http://apt.postgresql.org/pub/repos/apt {{ ansible_distribution_release }}-pgdg main"
dest: /etc/apt/sources.list.d/pgdg.list
owner: root
group: root
@@ -128,7 +132,7 @@
tags: postgres
become: yes
ansible.builtin.apt:
pkg: postgresql-14
pkg: postgresql-15
state: present
update_cache: yes
@@ -140,7 +144,7 @@
enabled: yes
state: started
- name: setup database
- name: setup trmm database
tags: postgres
become: yes
become_user: postgres
@@ -153,6 +157,23 @@
psql -c "ALTER ROLE {{ db_user }} SET timezone TO 'UTC'"
psql -c "ALTER ROLE {{ db_user }} CREATEDB"
psql -c "GRANT ALL PRIVILEGES ON DATABASE tacticalrmm TO {{ db_user }}"
psql -c "ALTER DATABASE tacticalrmm OWNER TO {{ db_user }}"
psql -c "GRANT USAGE, CREATE ON SCHEMA PUBLIC TO {{ db_user }}"
- name: setup mesh database
tags: postgres
become: yes
become_user: postgres
ansible.builtin.shell:
cmd: |
psql -c "CREATE DATABASE meshcentral"
psql -c "CREATE USER {{ mesh_db_user }} WITH PASSWORD '{{ mesh_db_passwd }}'"
psql -c "ALTER ROLE {{ mesh_db_user }} SET client_encoding TO 'utf8'"
psql -c "ALTER ROLE {{ mesh_db_user }} SET default_transaction_isolation TO 'read committed'"
psql -c "ALTER ROLE {{ mesh_db_user }} SET timezone TO 'UTC'"
psql -c "GRANT ALL PRIVILEGES ON DATABASE meshcentral TO {{ mesh_db_user }}"
psql -c "ALTER DATABASE meshcentral OWNER TO {{ mesh_db_user }}"
psql -c "GRANT USAGE, CREATE ON SCHEMA PUBLIC TO {{ mesh_db_user }}"
- name: create repo dirs
become: yes
@@ -202,7 +223,7 @@
- name: download and extract nats
tags: nats
ansible.builtin.unarchive:
src: "https://github.com/nats-io/nats-server/releases/download/v{{ nats_server_ver.stdout }}/nats-server-v{{ nats_server_ver.stdout }}-linux-amd64.tar.gz"
src: "https://github.com/nats-io/nats-server/releases/download/v{{ nats_server_ver.stdout }}/nats-server-v{{ nats_server_ver.stdout }}-linux-{{ goarch }}.tar.gz"
dest: "{{ nats_tmp.path }}"
remote_src: yes
@@ -211,7 +232,7 @@
become: yes
ansible.builtin.copy:
remote_src: yes
src: "{{ nats_tmp.path }}/nats-server-v{{ nats_server_ver.stdout }}-linux-amd64/nats-server"
src: "{{ nats_tmp.path }}/nats-server-v{{ nats_server_ver.stdout }}-linux-{{ goarch }}/nats-server"
dest: /usr/local/bin/nats-server
owner: "{{ user }}"
group: "{{ user }}"
@@ -227,7 +248,7 @@
- name: download nodejs setup
tags: nodejs
ansible.builtin.get_url:
url: https://deb.nodesource.com/setup_16.x
url: https://deb.nodesource.com/setup_18.x
dest: "{{ nodejs_tmp.path }}/setup_node.sh"
mode: "0755"
@@ -314,8 +335,8 @@
- name: add nginx repo
tags: nginx
become: yes
ansible.builtin.copy:
src: nginx.repo
ansible.builtin.template:
src: nginx.repo.j2
dest: /etc/apt/sources.list.d/nginx.list
owner: "root"
group: "root"
@@ -391,12 +412,16 @@
enabled: yes
state: restarted
- name: set natsapi fact
ansible.builtin.set_fact:
natsapi: "{{ 'nats-api' if ansible_architecture == 'x86_64' else 'nats-api-arm64' }}"
- name: copy nats-api bin
tags: nats-api
become: yes
ansible.builtin.copy:
remote_src: yes
src: "{{ backend_dir }}/natsapi/bin/nats-api"
src: "{{ backend_dir }}/natsapi/bin/{{ natsapi }}"
dest: /usr/local/bin/nats-api
owner: "{{ user }}"
group: "{{ user }}"
@@ -482,39 +507,6 @@
- { src: nats-server.systemd.j2, dest: /etc/systemd/system/nats.service }
- { src: mesh.systemd.j2, dest: /etc/systemd/system/meshcentral.service }
- name: import mongodb repo signing key
tags: mongo
become: yes
ansible.builtin.apt_key:
url: https://www.mongodb.org/static/pgp/server-4.4.asc
state: present
- name: setup mongodb repo
tags: mongo
become: yes
ansible.builtin.copy:
content: "deb https://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main"
dest: /etc/apt/sources.list.d/mongodb-org-4.4.list
owner: root
group: root
mode: "0644"
- name: install mongodb
tags: mongo
become: yes
ansible.builtin.apt:
pkg: mongodb-org
state: present
update_cache: yes
- name: ensure mongodb enabled and started
tags: mongo
become: yes
ansible.builtin.service:
name: mongod
enabled: yes
state: started
- name: get mesh_ver
tags: mesh
ansible.builtin.shell: grep "^MESH_VER" {{ settings_file }} | awk -F'[= "]' '{print $5}'

View File

@@ -1,8 +1,6 @@
{
"settings": {
"Cert": "{{ mesh }}",
"MongoDb": "mongodb://127.0.0.1:27017",
"MongoDbName": "meshcentral",
"WANonly": true,
"Minify": 1,
"Port": 4430,
@@ -10,19 +8,25 @@
"RedirPort": 800,
"AllowLoginToken": true,
"AllowFraming": true,
"AgentPong": 300,
"AgentPing": 35,
"AllowHighQualityDesktop": true,
"TlsOffload": "127.0.0.1",
"agentCoreDump": false,
"Compression": true,
"WsCompression": true,
"AgentWsCompression": true,
"MaxInvalidLogin": { "time": 5, "count": 5, "coolofftime": 30 }
"MaxInvalidLogin": { "time": 5, "count": 5, "coolofftime": 30 },
"postgres": {
"user": "{{ mesh_db_user }}",
"password": "{{ mesh_db_passwd }}",
"port": "5432",
"host": "localhost"
}
},
"domains": {
"": {
"Title": "Tactical RMM",
"Title2": "Tactical RMM",
"Title": "Tactical RMM Dev",
"Title2": "Tactical RMM Dev",
"NewAccounts": false,
"CertUrl": "https://{{ mesh }}:443/",
"GeoLocation": true,

View File

@@ -1,6 +1,6 @@
[Unit]
Description=MeshCentral Server
After=network.target mongod.service nginx.service
After=network.target postgresql.service nginx.service
[Service]
Type=simple

View File

@@ -0,0 +1,2 @@
deb https://nginx.org/packages/debian/ {{ ansible_distribution_release }} nginx
deb-src https://nginx.org/packages/debian/ {{ ansible_distribution_release }} nginx

View File

@@ -13,6 +13,8 @@
mesh_password: "changeme"
db_user: "changeme"
db_passwd: "changeme"
mesh_db_user: "changeme"
mesh_db_passwd: "changeme"
django_secret: "changeme"
django_user: "changeme"
django_password: "changeme"

View File

@@ -5,6 +5,8 @@ from rest_framework.serializers import (
SerializerMethodField,
)
from tacticalrmm.helpers import get_webdomain
from .models import APIKey, Role, User
@@ -61,7 +63,7 @@ class TOTPSetupSerializer(ModelSerializer):
def get_qr_url(self, obj):
return pyotp.totp.TOTP(obj.totp_key).provisioning_uri(
obj.username, issuer_name="Tactical RMM"
obj.username, issuer_name=get_webdomain()
)

View File

@@ -0,0 +1,24 @@
from django.core.management.base import BaseCommand
from agents.models import Agent
from tacticalrmm.constants import AGENT_DEFER
class Command(BaseCommand):
def find_duplicates(self, lst):
return list(set([item for item in lst if lst.count(item) > 1]))
def handle(self, *args, **kwargs):
for agent in Agent.objects.defer(*AGENT_DEFER).prefetch_related(
"custom_fields__field"
):
if dupes := self.find_duplicates(
[i.field.name for i in agent.custom_fields.all()]
):
for dupe in dupes:
cf = list(
agent.custom_fields.filter(field__name=dupe).order_by("id")
)
to_delete = cf[:-1]
for i in to_delete:
i.delete()

View File

@@ -0,0 +1,17 @@
# Generated by Django 4.2.3 on 2023-07-18 01:15
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("core", "0037_coresettings_open_ai_model_and_more"),
("agents", "0056_alter_agent_time_zone"),
]
operations = [
migrations.AlterUniqueTogether(
name="agentcustomfield",
unique_together={("agent", "field")},
),
]

View File

@@ -1011,6 +1011,9 @@ class AgentCustomField(models.Model):
default=list,
)
class Meta:
unique_together = (("agent", "field"),)
def __str__(self) -> str:
return self.field.name

View File

@@ -639,6 +639,8 @@ class Alert(models.Model):
try:
temp_args.append(re.sub("\\{\\{.*\\}\\}", value, arg))
except re.error:
temp_args.append(re.sub("\\{\\{.*\\}\\}", re.escape(value), arg))
except Exception as e:
DebugLog.error(log_type=DebugLogType.SCRIPTING, message=str(e))
continue

View File

@@ -25,12 +25,16 @@ class GetAddAlerts(APIView):
def patch(self, request):
# top 10 alerts for dashboard icon
if "top" in request.data.keys():
alerts = Alert.objects.filter(
resolved=False, snoozed=False, hidden=False
).order_by("alert_time")[: int(request.data["top"])]
count = Alert.objects.filter(
resolved=False, snoozed=False, hidden=False
).count()
alerts = (
Alert.objects.filter_by_role(request.user)
.filter(resolved=False, snoozed=False, hidden=False)
.order_by("alert_time")[: int(request.data["top"])]
)
count = (
Alert.objects.filter_by_role(request.user)
.filter(resolved=False, snoozed=False, hidden=False)
.count()
)
return Response(
{
"alerts_count": count,

View File

@@ -1,8 +1,8 @@
#!/usr/bin/env bash
if [ $EUID -ne 0 ]; then
echo "ERROR: Must be run as root"
exit 1
echo "ERROR: Must be run as root"
exit 1
fi
HAS_SYSTEMD=$(ps --no-headers -o comm 1)
@@ -37,15 +37,15 @@ deb=(ubuntu debian raspbian kali linuxmint)
rhe=(fedora rocky centos rhel amzn arch opensuse)
set_locale_deb() {
locale-gen "en_US.UTF-8"
localectl set-locale LANG=en_US.UTF-8
. /etc/default/locale
locale-gen "en_US.UTF-8"
localectl set-locale LANG=en_US.UTF-8
. /etc/default/locale
}
set_locale_rhel() {
localedef -c -i en_US -f UTF-8 en_US.UTF-8 > /dev/null 2>&1
localectl set-locale LANG=en_US.UTF-8
. /etc/locale.conf
localedef -c -i en_US -f UTF-8 en_US.UTF-8 >/dev/null 2>&1
localectl set-locale LANG=en_US.UTF-8
. /etc/locale.conf
}
RemoveOldAgent() {
@@ -67,8 +67,14 @@ RemoveOldAgent() {
InstallMesh() {
if [ -f /etc/os-release ]; then
distroID=$(. /etc/os-release; echo $ID)
distroIDLIKE=$(. /etc/os-release; echo $ID_LIKE)
distroID=$(
. /etc/os-release
echo $ID
)
distroIDLIKE=$(
. /etc/os-release
echo $ID_LIKE
)
if [[ " ${deb[*]} " =~ " ${distroID} " ]]; then
set_locale_deb
elif [[ " ${deb[*]} " =~ " ${distroIDLIKE} " ]]; then
@@ -80,11 +86,9 @@ InstallMesh() {
fi
fi
meshTmpDir=$(mktemp -d -t "mesh-XXXXXXXXX")
if [ $? -ne 0 ]; then
meshTmpDir='/root/meshtemp'
mkdir -p ${meshTmpDir}
fi
meshTmpDir='/root/meshtemp'
mkdir -p $meshTmpDir
meshTmpBin="${meshTmpDir}/meshagent"
wget --no-check-certificate -q -O ${meshTmpBin} ${meshDL}
chmod +x ${meshTmpBin}
@@ -101,8 +105,8 @@ RemoveMesh() {
fi
if [ -f "${meshSysD}" ]; then
systemctl stop ${meshSvcName} > /dev/null 2>&1
systemctl disable ${meshSvcName} > /dev/null 2>&1
systemctl stop ${meshSvcName} >/dev/null 2>&1
systemctl disable ${meshSvcName} >/dev/null 2>&1
rm -f ${meshSysD}
fi
@@ -166,7 +170,8 @@ fi
eval ${INSTALL_CMD}
tacticalsvc="$(cat << EOF
tacticalsvc="$(
cat <<EOF
[Unit]
Description=Tactical RMM Linux Agent
@@ -184,7 +189,7 @@ KillMode=process
WantedBy=multi-user.target
EOF
)"
echo "${tacticalsvc}" | tee ${agentSysD} > /dev/null
echo "${tacticalsvc}" | tee ${agentSysD} >/dev/null
systemctl daemon-reload
systemctl enable ${agentSvcName}

View File

@@ -1,3 +1,4 @@
from django.core.management import call_command
from django.core.management.base import BaseCommand
from core.utils import clear_entire_cache
@@ -10,3 +11,4 @@ class Command(BaseCommand):
self.stdout.write(self.style.WARNING("Cleaning the cache"))
clear_entire_cache()
self.stdout.write(self.style.SUCCESS("Cache was cleared!"))
call_command("fix_dupe_agent_customfields")

View File

@@ -3,28 +3,30 @@ from unittest.mock import patch
import requests
from channels.db import database_sync_to_async
from channels.testing import WebsocketCommunicator
from django.conf import settings
# from django.conf import settings
from django.core.management import call_command
from django.test import override_settings
from model_bakery import baker
from rest_framework.authtoken.models import Token
from agents.models import Agent
# from agents.models import Agent
from core.utils import get_core_settings, get_meshagent_url
from logs.models import PendingAction
# from logs.models import PendingAction
from tacticalrmm.constants import (
CONFIG_MGMT_CMDS,
CustomFieldModel,
MeshAgentIdent,
PAAction,
PAStatus,
# PAAction,
# PAStatus,
)
from tacticalrmm.test import TacticalTestCase
from .consumers import DashInfo
from .models import CustomField, GlobalKVStore, URLAction
from .serializers import CustomFieldSerializer, KeyStoreSerializer, URLActionSerializer
from .tasks import core_maintenance_tasks, resolve_pending_actions
from .tasks import core_maintenance_tasks # , resolve_pending_actions
class TestCodeSign(TacticalTestCase):
@@ -410,28 +412,28 @@ class TestCoreTasks(TacticalTestCase):
self.check_not_authenticated("get", url)
def test_resolved_pending_agentupdate_task(self):
online = baker.make_recipe("agents.online_agent", version="2.0.0", _quantity=20)
offline = baker.make_recipe(
"agents.offline_agent", version="2.0.0", _quantity=20
)
agents = online + offline
for agent in agents:
baker.make_recipe("logs.pending_agentupdate_action", agent=agent)
# def test_resolved_pending_agentupdate_task(self):
# online = baker.make_recipe("agents.online_agent", version="2.0.0", _quantity=20)
# offline = baker.make_recipe(
# "agents.offline_agent", version="2.0.0", _quantity=20
# )
# agents = online + offline
# for agent in agents:
# baker.make_recipe("logs.pending_agentupdate_action", agent=agent)
Agent.objects.update(version=settings.LATEST_AGENT_VER)
# Agent.objects.update(version=settings.LATEST_AGENT_VER)
resolve_pending_actions()
# resolve_pending_actions()
complete = PendingAction.objects.filter(
action_type=PAAction.AGENT_UPDATE, status=PAStatus.COMPLETED
).count()
old = PendingAction.objects.filter(
action_type=PAAction.AGENT_UPDATE, status=PAStatus.PENDING
).count()
# complete = PendingAction.objects.filter(
# action_type=PAAction.AGENT_UPDATE, status=PAStatus.COMPLETED
# ).count()
# old = PendingAction.objects.filter(
# action_type=PAAction.AGENT_UPDATE, status=PAStatus.PENDING
# ).count()
self.assertEqual(complete, 20)
self.assertEqual(old, 20)
# self.assertEqual(complete, 20)
# self.assertEqual(old, 20)
class TestCoreMgmtCommands(TacticalTestCase):

View File

@@ -1,40 +1,39 @@
adrf==0.1.1
asgiref==3.7.2
celery==5.2.7
certifi==2023.5.7
celery==5.3.1
certifi==2023.7.22
cffi==1.15.1
channels==4.0.0
channels_redis==4.1.0
chardet==4.0.0
cryptography==40.0.2
cryptography==41.0.3
daphne==4.0.0
Django==4.1.9
django-cors-headers==4.0.0
Django==4.2.4
django-cors-headers==4.2.0
django-ipware==5.0.0
django-rest-knox==4.2.0
djangorestframework==3.14.0
drf-spectacular==0.26.2
drf-spectacular==0.26.4
hiredis==2.2.3
meshctrl==0.1.15
msgpack==1.0.5
nats-py==2.2.0
nats-py==2.3.1
packaging==23.1
psutil==5.9.5
psycopg2-binary==2.9.6
psycopg[binary]==3.1.10
pycparser==2.21
pycryptodome==3.17
pyotp==2.8.0
pyparsing==3.0.9
pycryptodome==3.18.0
pyotp==2.9.0
pyparsing==3.1.1
pytz==2023.3
qrcode==7.4.2
redis==4.5.5
requests==2.31.0
six==1.16.0
sqlparse==0.4.4
twilio==7.17.0
urllib3==1.26.16
uWSGI==2.0.21
twilio==8.5.0
urllib3==2.0.4
uWSGI==2.0.22
validators==0.20.0
vine==5.0.0
websockets==11.0.3
zipp==3.15.0
zipp==3.16.2

View File

@@ -216,7 +216,12 @@ class Script(BaseAuditModel):
)
if value:
temp_args.append(re.sub("\\{\\{.*\\}\\}", value, arg))
try:
temp_args.append(re.sub("\\{\\{.*\\}\\}", value, arg))
except re.error:
temp_args.append(
re.sub("\\{\\{.*\\}\\}", re.escape(value), arg)
)
else:
# pass parameter unaltered
temp_args.append(arg)

View File

@@ -65,6 +65,8 @@ class GetEditActionService(APIView):
# win service action
def post(self, request, agent_id, svcname):
agent = get_object_or_404(Agent, agent_id=agent_id)
if agent.is_posix:
return notify_error("Please use 'Recover Connection' instead.")
action = request.data["sv_action"]
data = {
"func": "winsvcaction",

View File

@@ -427,6 +427,7 @@ DEMO_NOT_ALLOWED = [
{"name": "Reset2FA", "methods": ["PUT"]},
{"name": "bulk_run_checks", "methods": ["GET"]},
{"name": "OpenAICodeCompletion", "methods": ["POST"]},
{"name": "wol", "methods": ["POST"]},
]
CONFIG_MGMT_CMDS = (

View File

@@ -20,27 +20,27 @@ MAC_UNINSTALL = BASE_DIR / "core" / "mac_uninstall.sh"
AUTH_USER_MODEL = "accounts.User"
# latest release
TRMM_VERSION = "0.15.12"
TRMM_VERSION = "0.16.2"
# https://github.com/amidaware/tacticalrmm-web
WEB_VERSION = "0.101.22"
WEB_VERSION = "0.101.28"
# bump this version everytime vue code is changed
# to alert user they need to manually refresh their browser
APP_VER = "0.0.181"
APP_VER = "0.0.183"
# https://github.com/amidaware/rmmagent
LATEST_AGENT_VER = "2.4.9"
LATEST_AGENT_VER = "2.4.11"
MESH_VER = "1.1.4"
MESH_VER = "1.1.9"
NATS_SERVER_VER = "2.9.17"
NATS_SERVER_VER = "2.9.21"
# for the update script, bump when need to recreate venv
PIP_VER = "36"
PIP_VER = "38"
SETUPTOOLS_VER = "67.6.1"
WHEEL_VER = "0.40.0"
SETUPTOOLS_VER = "68.0.0"
WHEEL_VER = "0.41.1"
AGENT_BASE_URL = "https://agents.tacticalrmm.com"

View File

@@ -1,4 +1,4 @@
from itertools import cycle
# from itertools import cycle
from unittest.mock import patch
from model_bakery import baker
@@ -161,34 +161,34 @@ class WinupdateTasks(TacticalTestCase):
)
self.offline_agent = baker.make_recipe("agents.agent", site=site)
@patch("agents.models.Agent.nats_cmd")
@patch("time.sleep")
def test_auto_approve_task(self, mock_sleep, nats_cmd):
from .tasks import auto_approve_updates_task
# @patch("agents.models.Agent.nats_cmd")
# @patch("time.sleep")
# def test_auto_approve_task(self, mock_sleep, nats_cmd):
# from .tasks import auto_approve_updates_task
# Setup data
baker.make_recipe(
"winupdate.winupdate",
agent=cycle(
[self.online_agents[0], self.online_agents[1], self.offline_agent]
),
_quantity=20,
)
baker.make_recipe(
"winupdate.winupdate_approve",
agent=cycle(
[self.online_agents[0], self.online_agents[1], self.offline_agent]
),
_quantity=3,
)
# # Setup data
# baker.make_recipe(
# "winupdate.winupdate",
# agent=cycle(
# [self.online_agents[0], self.online_agents[1], self.offline_agent]
# ),
# _quantity=20,
# )
# baker.make_recipe(
# "winupdate.winupdate_approve",
# agent=cycle(
# [self.online_agents[0], self.online_agents[1], self.offline_agent]
# ),
# _quantity=3,
# )
# run task synchronously
auto_approve_updates_task()
# # run task synchronously
# auto_approve_updates_task()
# make sure the check_for_updates_task was run once for each online agent
self.assertEqual(nats_cmd.call_count, 2)
# # make sure the check_for_updates_task was run once for each online agent
# self.assertEqual(nats_cmd.call_count, 2)
# check if all of the created updates were approved
winupdates = WinUpdate.objects.all()
for update in winupdates:
self.assertEqual(update.action, "approve")
# # check if all of the created updates were approved
# winupdates = WinUpdate.objects.all()
# for update in winupdates:
# self.assertEqual(update.action, "approve")

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
SCRIPT_VERSION="24"
SCRIPT_VERSION="28"
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
@@ -16,13 +16,13 @@ fi
if [[ $* == *--schedule* ]]; then
(
crontab -l 2>/dev/null
echo "0 0 * * * /rmm/backup.sh --auto"
echo "0 0 * * * /rmm/backup.sh --auto > /dev/null 2>&1"
) | crontab -
if [ ! -d /rmmbackups ]; then
if [ ! -d /rmmbackups ]; then
sudo mkdir /rmmbackups
fi
if [ ! -d /rmmbackups/daily ]; then
sudo mkdir /rmmbackups/daily
fi
@@ -35,7 +35,7 @@ if [[ $* == *--schedule* ]]; then
sudo mkdir /rmmbackups/monthly
fi
sudo chown ${USER}:${USER} -R /rmmbackups
printf >&2 "${GREEN}Backups setup to run at midnight and rotate.${NC}\n"
exit 0
fi
@@ -49,6 +49,10 @@ if [ -d /meshcentral/meshcentral-backup ]; then
rm -rf /meshcentral/meshcentral-backup/*
fi
if [ -d /meshcentral/meshcentral-backups ]; then
rm -rf /meshcentral/meshcentral-backups/*
fi
if [ -d /meshcentral/meshcentral-coredumps ]; then
rm -f /meshcentral/meshcentral-coredumps/*
fi
@@ -70,11 +74,11 @@ POSTGRES_PW=$(/rmm/api/env/bin/python /rmm/api/tacticalrmm/manage.py get_config
pg_dump --dbname=postgresql://"${POSTGRES_USER}":"${POSTGRES_PW}"@127.0.0.1:5432/tacticalrmm | gzip -9 >${tmp_dir}/postgres/db-${dt_now}.psql.gz
tar -czvf ${tmp_dir}/meshcentral/mesh.tar.gz --exclude=/meshcentral/node_modules /meshcentral
node /meshcentral/node_modules/meshcentral --dbexport # for import to postgres
if grep -q postgres "/meshcentral/meshcentral-data/config.json"; then
if ! which jq >/dev/null; then
sudo apt-get install -y jq >null
sudo apt-get install -y jq >/dev/null
fi
MESH_POSTGRES_USER=$(jq '.settings.postgres.user' /meshcentral/meshcentral-data/config.json -r)
MESH_POSTGRES_PW=$(jq '.settings.postgres.password' /meshcentral/meshcentral-data/config.json -r)
@@ -83,7 +87,21 @@ else
mongodump --gzip --out=${tmp_dir}/meshcentral/mongo
fi
sudo tar -czvf ${tmp_dir}/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt .
tar -czvf ${tmp_dir}/meshcentral/mesh.tar.gz --exclude=/meshcentral/node_modules /meshcentral
if [ -d /etc/letsencrypt ]; then
sudo tar -czvf ${tmp_dir}/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt .
fi
local_settings='/rmm/api/tacticalrmm/tacticalrmm/local_settings.py'
if grep -q CERT_FILE "$local_settings"; then
mkdir -p ${tmp_dir}/certs/custom
CERT_FILE=$(grep "^CERT_FILE" "$local_settings" | awk -F'[= "]' '{print $5}')
KEY_FILE=$(grep "^KEY_FILE" "$local_settings" | awk -F'[= "]' '{print $5}')
cp -p $CERT_FILE ${tmp_dir}/certs/custom/cert
cp -p $KEY_FILE ${tmp_dir}/certs/custom/key
fi
for i in rmm frontend meshcentral; do
sudo cp /etc/nginx/sites-available/${i}.conf ${tmp_dir}/nginx/
@@ -93,8 +111,7 @@ sudo tar -czvf ${tmp_dir}/confd/etc-confd.tar.gz -C /etc/conf.d .
sudo cp ${sysd}/rmm.service ${sysd}/celery.service ${sysd}/celerybeat.service ${sysd}/meshcentral.service ${sysd}/nats.service ${sysd}/daphne.service ${sysd}/nats-api.service ${tmp_dir}/systemd/
cat /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | gzip -9 >${tmp_dir}/rmm/debug.log.gz
cp /rmm/api/tacticalrmm/tacticalrmm/local_settings.py ${tmp_dir}/rmm/
cp $local_settings ${tmp_dir}/rmm/
if [[ $* == *--auto* ]]; then
@@ -113,9 +130,9 @@ if [[ $* == *--auto* ]]; then
rm -rf ${tmp_dir}
find /rmmbackups/daily/ -maxdepth 1 -mtime +14 -type d -exec rm -rv {} \;
find /rmmbackups/weekly/ -maxdepth 1 -mtime +60 -type d -exec rm -rv {} \;
find /rmmbackups/monthly/ -maxdepth 1 -mtime +380 -type d -exec rm -rv {} \;
find /rmmbackups/daily/ -type f -mtime +14 -name '*.tar' -execdir rm -- '{}' \;
find /rmmbackups/weekly/ -type f -mtime +60 -name '*.tar' -execdir rm -- '{}' \;
find /rmmbackups/monthly/ -type f -mtime +380 -name '*.tar' -execdir rm -- '{}' \;
echo -ne "${GREEN}Backup Completed${NC}\n"
exit

View File

@@ -1,4 +1,4 @@
FROM nats:2.9.17-alpine
FROM nats:2.9.20-alpine
ENV TACTICAL_DIR /opt/tactical
ENV TACTICAL_READY_FILE ${TACTICAL_DIR}/tmp/tactical.ready

View File

@@ -1,5 +1,5 @@
# creates python virtual env
FROM python:3.11.3-slim AS CREATE_VENV_STAGE
FROM python:3.11.4-slim AS CREATE_VENV_STAGE
ARG DEBIAN_FRONTEND=noninteractive
@@ -21,14 +21,14 @@ RUN apt-get update && \
pip install --no-cache-dir -r ${TACTICAL_TMP_DIR}/api/requirements.txt
# pulls community scripts from git repo
FROM python:3.11.3-slim AS GET_SCRIPTS_STAGE
FROM python:3.11.4-slim AS GET_SCRIPTS_STAGE
RUN apt-get update && \
apt-get install -y --no-install-recommends git && \
git clone https://github.com/amidaware/community-scripts.git /community-scripts
# runtime image
FROM python:3.11.3-slim
FROM python:3.11.4-slim
# set env variables
ENV VIRTUAL_ENV /opt/venv

14
go.mod
View File

@@ -6,21 +6,21 @@ require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/jmoiron/sqlx v1.3.5
github.com/lib/pq v1.10.9
github.com/nats-io/nats-server/v2 v2.9.17 // indirect
github.com/nats-io/nats.go v1.26.0
github.com/nats-io/nats-server/v2 v2.9.21 // indirect
github.com/nats-io/nats.go v1.28.0
github.com/ugorji/go/codec v1.2.11
github.com/wh1te909/trmm-shared v0.0.0-20220227075846-f9f757361139
google.golang.org/protobuf v1.28.0 // indirect
)
require github.com/sirupsen/logrus v1.9.0
require github.com/sirupsen/logrus v1.9.3
require (
github.com/klauspost/compress v1.16.5 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/nats-io/nkeys v0.4.4 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/stretchr/testify v1.7.1 // indirect
golang.org/x/crypto v0.8.0 // indirect
golang.org/x/sys v0.7.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/sys v0.10.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

26
go.sum
View File

@@ -9,8 +9,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
@@ -18,10 +18,10 @@ github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRU
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
github.com/nats-io/jwt/v2 v2.4.1 h1:Y35W1dgbbz2SQUYDPCaclXcuqleVmpbRa7646Jf2EX4=
github.com/nats-io/nats-server/v2 v2.9.17 h1:gFpUQ3hqIDJrnqog+Bl5vaXg+RhhYEZIElasEuRn2tw=
github.com/nats-io/nats-server/v2 v2.9.17/go.mod h1:eQysm3xDZmIjfkjr7DuD9DjRFpnxQc2vKVxtEg0Dp6s=
github.com/nats-io/nats.go v1.26.0 h1:fWJTYPnZ8DzxIaqIHOAMfColuznchnd5Ab5dbJpgPIE=
github.com/nats-io/nats.go v1.26.0/go.mod h1:XpbWUlOElGwTYbMR7imivs7jJj9GtK7ypv321Wp6pjc=
github.com/nats-io/nats-server/v2 v2.9.21 h1:2TBTh0UDE74eNXQmV4HofsmRSCiVN0TH2Wgrp6BD6fk=
github.com/nats-io/nats-server/v2 v2.9.21/go.mod h1:ozqMZc2vTHcNcblOiXMWIXkf8+0lDGAi5wQcG+O1mHU=
github.com/nats-io/nats.go v1.28.0 h1:Th4G6zdsz2d0OqXdfzKLClo6bOfoI/b1kInhRtFIy5c=
github.com/nats-io/nats.go v1.28.0/go.mod h1:XpbWUlOElGwTYbMR7imivs7jJj9GtK7ypv321Wp6pjc=
github.com/nats-io/nkeys v0.4.4 h1:xvBJ8d69TznjcQl9t6//Q5xXuVhyYiSos6RPtvQNTwA=
github.com/nats-io/nkeys v0.4.4/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
@@ -30,6 +30,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
@@ -38,11 +40,11 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/wh1te909/trmm-shared v0.0.0-20220227075846-f9f757361139 h1:PfOl03o+Y+svWrfXAAu1QWUDePu1yqTq0pf4rpnN8eA=
github.com/wh1te909/trmm-shared v0.0.0-20220227075846-f9f757361139/go.mod h1:ILUz1utl5KgwrxmNHv0RpgMtKeh8gPAABvK2MiXBqv8=
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
@@ -51,5 +53,5 @@ google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscL
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
SCRIPT_VERSION="73"
SCRIPT_VERSION="75"
SCRIPT_URL='https://raw.githubusercontent.com/amidaware/tacticalrmm/master/install.sh'
sudo apt install -y curl wget dirmngr gnupg lsb-release
@@ -12,7 +12,7 @@ RED='\033[0;31m'
NC='\033[0m'
SCRIPTS_DIR='/opt/trmm-community-scripts'
PYTHON_VER='3.11.3'
PYTHON_VER='3.11.4'
SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py'
TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX")
@@ -30,8 +30,8 @@ fi
rm -f $TMP_FILE
arch=$(uname -m)
if [ "$arch" != "x86_64" ]; then
echo -ne "${RED}ERROR: Only x86_64 arch is supported, not ${arch}${NC}\n"
if [[ "$arch" != "x86_64" ]] && [[ "$arch" != "aarch64" ]]; then
echo -ne "${RED}ERROR: Only x86_64 and aarch64 is supported, not ${arch}${NC}\n"
exit 1
fi
@@ -49,19 +49,22 @@ codename=$(lsb_release -sc)
relno=$(lsb_release -sr | cut -d. -f1)
fullrelno=$(lsb_release -sr)
# Fallback if lsb_release -si returns anything else than Ubuntu, Debian or Raspbian
if [ ! "$osname" = "ubuntu" ] && [ ! "$osname" = "debian" ]; then
osname=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"')
osname=${osname^}
fi
not_supported() {
echo -ne "${RED}ERROR: Only Debian 11, Debian 12 and Ubuntu 22.04 are supported.${NC}\n"
}
# determine system
if ([ "$osname" = "ubuntu" ] && [ "$fullrelno" = "20.04" ]) || ([ "$osname" = "debian" ] && [ $relno -ge 10 ]); then
echo $fullrel
if [[ "$osname" == "debian" ]]; then
if [[ "$relno" -ne 11 && "$relno" -ne 12 ]]; then
not_supported
exit 1
fi
elif [[ "$osname" == "ubuntu" ]]; then
if [[ "$fullrelno" != "22.04" ]]; then
not_supported
exit 1
fi
else
echo $fullrel
echo -ne "${RED}Supported versions: Ubuntu 20.04, Debian 10 and 11\n"
echo -ne "Your system does not appear to be supported${NC}\n"
not_supported
exit 1
fi
@@ -78,16 +81,12 @@ if [[ "$LANG" != *".UTF-8" ]]; then
exit 1
fi
if ([ "$osname" = "ubuntu" ]); then
mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse"
# there is no bullseye repo yet for mongo so just use buster on debian 11
elif ([ "$osname" = "debian" ] && [ $relno -eq 11 ]); then
mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname buster/mongodb-org/4.4 main"
if [ "$arch" = "x86_64" ]; then
pgarch='amd64'
else
mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 main"
pgarch='arm64'
fi
postgresql_repo="deb [arch=amd64] https://apt.postgresql.org/pub/repos/apt/ $codename-pgdg main"
postgresql_repo="deb [arch=${pgarch}] https://apt.postgresql.org/pub/repos/apt/ $codename-pgdg main"
# prevents logging issues with some VPS providers like Vultr if this is a freshly provisioned instance that hasn't been rebooted yet
sudo systemctl restart systemd-journald.service
@@ -98,6 +97,8 @@ MESHPASSWD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 25 | head -n 1)
pgusername=$(cat /dev/urandom | tr -dc 'a-z' | fold -w 8 | head -n 1)
pgpw=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)
meshusername=$(cat /dev/urandom | tr -dc 'a-z' | fold -w 8 | head -n 1)
MESHPGUSER=$(cat /dev/urandom | tr -dc 'a-z' | fold -w 8 | head -n 1)
MESHPGPWD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)
cls() {
printf "\033c"
@@ -136,11 +137,12 @@ while [[ $letsemail != *[@]*[.]* ]]; do
read letsemail
done
# if server is behind NAT we need to add the 3 subdomains to the host file
# so that nginx can properly route between the frontend, backend and meshcentral
# EDIT 8-29-2020
# running this even if server is __not__ behind NAT just to make DNS resolving faster
# this also allows the install script to properly finish even if DNS has not fully propagated
if grep -q manage_etc_hosts /etc/hosts; then
sudo sed -i '/manage_etc_hosts: true/d' /etc/cloud/cloud.cfg >/dev/null
echo -e "\nmanage_etc_hosts: false" | sudo tee --append /etc/cloud/cloud.cfg >/dev/null
sudo systemctl restart cloud-init >/dev/null
fi
CHECK_HOSTS=$(grep 127.0.1.1 /etc/hosts | grep "$rmmdomain" | grep "$meshdomain" | grep "$frontenddomain")
HAS_11=$(grep 127.0.1.1 /etc/hosts)
@@ -230,21 +232,12 @@ done
print_green 'Installing NodeJS'
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt update
sudo apt install -y gcc g++ make
sudo apt install -y nodejs
sudo npm install -g npm
print_green 'Installing MongoDB'
wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
echo "$mongodb_repo" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
sudo apt update
sudo apt install -y mongodb-org
sudo systemctl enable mongod
sudo systemctl restart mongod
print_green "Installing Python ${PYTHON_VER}"
sudo apt install -y build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev
@@ -268,7 +261,7 @@ echo "$postgresql_repo" | sudo tee /etc/apt/sources.list.d/pgdg.list
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt update
sudo apt install -y postgresql-14
sudo apt install -y postgresql-15
sleep 2
sudo systemctl enable --now postgresql
@@ -277,7 +270,7 @@ until pg_isready >/dev/null; do
sleep 3
done
print_green 'Creating database for the rmm'
print_green 'Creating database for trmm'
sudo -u postgres psql -c "CREATE DATABASE tacticalrmm"
sudo -u postgres psql -c "CREATE USER ${pgusername} WITH PASSWORD '${pgpw}'"
@@ -285,6 +278,19 @@ sudo -u postgres psql -c "ALTER ROLE ${pgusername} SET client_encoding TO 'utf8'
sudo -u postgres psql -c "ALTER ROLE ${pgusername} SET default_transaction_isolation TO 'read committed'"
sudo -u postgres psql -c "ALTER ROLE ${pgusername} SET timezone TO 'UTC'"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE tacticalrmm TO ${pgusername}"
sudo -u postgres psql -c "ALTER DATABASE tacticalrmm OWNER TO ${pgusername}"
sudo -u postgres psql -c "GRANT USAGE, CREATE ON SCHEMA PUBLIC TO ${pgusername}"
print_green 'Creating database for meshcentral'
sudo -u postgres psql -c "CREATE DATABASE meshcentral"
sudo -u postgres psql -c "CREATE USER ${MESHPGUSER} WITH PASSWORD '${MESHPGPWD}'"
sudo -u postgres psql -c "ALTER ROLE ${MESHPGUSER} SET client_encoding TO 'utf8'"
sudo -u postgres psql -c "ALTER ROLE ${MESHPGUSER} SET default_transaction_isolation TO 'read committed'"
sudo -u postgres psql -c "ALTER ROLE ${MESHPGUSER} SET timezone TO 'UTC'"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE meshcentral TO ${MESHPGUSER}"
sudo -u postgres psql -c "ALTER DATABASE meshcentral OWNER TO ${MESHPGUSER}"
sudo -u postgres psql -c "GRANT USAGE, CREATE ON SCHEMA PUBLIC TO ${MESHPGUSER}"
print_green 'Cloning repos'
@@ -308,11 +314,17 @@ git checkout main
print_green 'Downloading NATS'
if [ "$arch" = "x86_64" ]; then
natsarch='amd64'
else
natsarch='arm64'
fi
NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}')
nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX)
wget https://github.com/nats-io/nats-server/releases/download/v${NATS_SERVER_VER}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz -P ${nats_tmp}
tar -xzf ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz -C ${nats_tmp}
sudo mv ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64/nats-server /usr/local/bin/
wget https://github.com/nats-io/nats-server/releases/download/v${NATS_SERVER_VER}/nats-server-v${NATS_SERVER_VER}-linux-${natsarch}.tar.gz -P ${nats_tmp}
tar -xzf ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-${natsarch}.tar.gz -C ${nats_tmp}
sudo mv ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-${natsarch}/nats-server /usr/local/bin/
sudo chmod +x /usr/local/bin/nats-server
sudo chown ${USER}:${USER} /usr/local/bin/nats-server
rm -rf ${nats_tmp}
@@ -332,8 +344,6 @@ meshcfg="$(
{
"settings": {
"cert": "${meshdomain}",
"mongoDb": "mongodb://127.0.0.1:27017",
"mongoDbName": "meshcentral",
"WANonly": true,
"minify": 1,
"port": 4430,
@@ -341,15 +351,20 @@ meshcfg="$(
"redirPort": 800,
"allowLoginToken": true,
"allowFraming": true,
"_agentPing": 60,
"agentPong": 300,
"agentPing": 35,
"allowHighQualityDesktop": true,
"tlsOffload": "127.0.0.1",
"agentCoreDump": false,
"compression": true,
"wsCompression": true,
"agentWsCompression": true,
"maxInvalidLogin": { "time": 5, "count": 5, "coolofftime": 30 }
"maxInvalidLogin": { "time": 5, "count": 5, "coolofftime": 30 },
"postgres": {
"user": "${MESHPGUSER}",
"password": "${MESHPGPWD}",
"port": "5432",
"host": "localhost"
}
},
"domains": {
"": {
@@ -400,7 +415,13 @@ EOF
)"
echo "${localvars}" >/rmm/api/tacticalrmm/tacticalrmm/local_settings.py
sudo cp /rmm/natsapi/bin/nats-api /usr/local/bin
if [ "$arch" = "x86_64" ]; then
natsapi='nats-api'
else
natsapi='nats-api-arm64'
fi
sudo cp /rmm/natsapi/bin/${natsapi} /usr/local/bin/nats-api
sudo chown ${USER}:${USER} /usr/local/bin/nats-api
sudo chmod +x /usr/local/bin/nats-api
@@ -495,7 +516,7 @@ ExecStart=/usr/local/bin/nats-server -c /rmm/api/tacticalrmm/nats-rmm.conf
ExecReload=/usr/bin/kill -s HUP \$MAINPID
ExecStop=/usr/bin/kill -s SIGINT \$MAINPID
User=${USER}
Group=www-data
Group=${USER}
Restart=always
RestartSec=5s
LimitNOFILE=1000000
@@ -567,6 +588,7 @@ server {
location /static/ {
root /rmm/api/tacticalrmm;
add_header "Access-Control-Allow-Origin" "https://${frontenddomain}";
}
location /private/ {
@@ -575,6 +597,12 @@ server {
alias /rmm/api/tacticalrmm/tacticalrmm/private/;
}
location /assets/ {
internal;
add_header "Access-Control-Allow-Origin" "https://${frontenddomain}";
alias /opt/tactical/reporting/assets/;
}
location ~ ^/ws/ {
proxy_pass http://unix:/rmm/daphne.sock;
@@ -736,7 +764,7 @@ meshservice="$(
cat <<EOF
[Unit]
Description=MeshCentral Server
After=network.target mongod.service nginx.service
After=network.target postgresql.service nginx.service
[Service]
Type=simple
LimitNOFILE=1000000
@@ -840,7 +868,7 @@ sleep 3
while ! [[ $CHECK_MESH_READY ]]; do
CHECK_MESH_READY=$(sudo journalctl -u meshcentral.service -b --no-pager | grep "MeshCentral HTTP server running on port")
echo -ne "${GREEN}Mesh Central not ready yet...${NC}\n"
sleep 3
sleep 5
done
print_green 'Generating meshcentral login token key'
@@ -870,7 +898,7 @@ sleep 5
while ! [[ $CHECK_MESH_READY2 ]]; do
CHECK_MESH_READY2=$(sudo journalctl -u meshcentral.service -b --no-pager | grep "MeshCentral HTTP server running on port")
echo -ne "${GREEN}Mesh Central not ready yet...${NC}\n"
sleep 3
sleep 5
done
node node_modules/meshcentral/meshctrl.js --url wss://${meshdomain}:443 --loginuser ${meshusername} --loginpass ${MESHPASSWD} AddDeviceGroup --name TacticalRMM

View File

@@ -12,7 +12,7 @@ import (
)
var (
version = "3.4.6"
version = "3.4.8"
log = logrus.New()
)

Binary file not shown.

BIN
natsapi/bin/nats-api-arm64 Executable file

Binary file not shown.

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
SCRIPT_VERSION="48"
SCRIPT_VERSION="50"
SCRIPT_URL='https://raw.githubusercontent.com/amidaware/tacticalrmm/master/restore.sh'
sudo apt update
@@ -13,7 +13,7 @@ RED='\033[0;31m'
NC='\033[0m'
SCRIPTS_DIR='/opt/trmm-community-scripts'
PYTHON_VER='3.11.3'
PYTHON_VER='3.11.4'
SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py'
TMP_FILE=$(mktemp -p "" "rmmrestore_XXXXXXXXXX")
@@ -30,8 +30,8 @@ fi
rm -f $TMP_FILE
arch=$(uname -m)
if [ "$arch" != "x86_64" ]; then
echo -ne "${RED}ERROR: Only x86_64 arch is supported, not ${arch}${NC}\n"
if [[ "$arch" != "x86_64" ]] && [[ "$arch" != "aarch64" ]]; then
echo -ne "${RED}ERROR: Only x86_64 and aarch64 is supported, not ${arch}${NC}\n"
exit 1
fi
@@ -49,33 +49,25 @@ codename=$(lsb_release -sc)
relno=$(lsb_release -sr | cut -d. -f1)
fullrelno=$(lsb_release -sr)
# Fallback if lsb_release -si returns anything else than Ubuntu, Debian or Raspbian
if [ ! "$osname" = "ubuntu" ] && [ ! "$osname" = "debian" ]; then
osname=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"')
osname=${osname^}
fi
not_supported() {
echo -ne "${RED}ERROR: Only Debian 11, Debian 12 and Ubuntu 22.04 are supported.${NC}\n"
}
# determine system
if ([ "$osname" = "ubuntu" ] && [ "$fullrelno" = "20.04" ]) || ([ "$osname" = "debian" ] && [ $relno -ge 10 ]); then
echo $fullrel
if [[ "$osname" == "debian" ]]; then
if [[ "$relno" -ne 11 && "$relno" -ne 12 ]]; then
not_supported
exit 1
fi
elif [[ "$osname" == "ubuntu" ]]; then
if [[ "$fullrelno" != "22.04" ]]; then
not_supported
exit 1
fi
else
echo $fullrel
echo -ne "${RED}Supported versions: Ubuntu 20.04, Debian 10 and 11\n"
echo -ne "Your system does not appear to be supported${NC}\n"
not_supported
exit 1
fi
if ([ "$osname" = "ubuntu" ]); then
mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse"
# there is no bullseye repo yet for mongo so just use buster on debian 11
elif ([ "$osname" = "debian" ] && [ $relno -eq 11 ]); then
mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname buster/mongodb-org/4.4 main"
else
mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 main"
fi
postgresql_repo="deb [arch=amd64] https://apt.postgresql.org/pub/repos/apt/ $codename-pgdg main"
if [ $EUID -eq 0 ]; then
echo -ne "\033[0;31mDo NOT run this script as root. Exiting.\e[0m\n"
exit 1
@@ -89,6 +81,13 @@ if [[ "$LANG" != *".UTF-8" ]]; then
exit 1
fi
if [ "$arch" = "x86_64" ]; then
pgarch='amd64'
else
pgarch='arm64'
fi
postgresql_repo="deb [arch=${pgarch}] https://apt.postgresql.org/pub/repos/apt/ $codename-pgdg main"
if [ ! -f "${1}" ]; then
echo -ne "\n${RED}usage: ./restore.sh rmm-backup-xxxx.tar${NC}\n"
exit 1
@@ -123,7 +122,7 @@ sudo apt update
print_green 'Installing NodeJS'
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt update
sudo apt install -y gcc g++ make
sudo apt install -y nodejs
@@ -194,10 +193,24 @@ sudo apt install -y certbot openssl
print_green 'Restoring certs'
sudo rm -rf /etc/letsencrypt
sudo mkdir /etc/letsencrypt
sudo tar -xzf $tmp_dir/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt
sudo chown ${USER}:${USER} -R /etc/letsencrypt
if [ -f "$tmp_dir/certs/etc-letsencrypt.tar.gz" ]; then
sudo rm -rf /etc/letsencrypt
sudo mkdir /etc/letsencrypt
sudo tar -xzf $tmp_dir/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt
sudo chown ${USER}:${USER} -R /etc/letsencrypt
fi
if [ -d "${tmp_dir}/certs/custom" ]; then
CERT_FILE=$(grep "^CERT_FILE" "$tmp_dir/rmm/local_settings.py" | awk -F'[= "]' '{print $5}')
KEY_FILE=$(grep "^KEY_FILE" "$tmp_dir/rmm/local_settings.py" | awk -F'[= "]' '{print $5}')
sudo mkdir -p $(dirname $CERT_FILE) $(dirname $KEY_FILE)
sudo chown ${USER}:${USER} $(dirname $CERT_FILE) $(dirname $KEY_FILE)
cp -p ${tmp_dir}/certs/custom/cert $CERT_FILE
cp -p ${tmp_dir}/certs/custom/key $KEY_FILE
fi
print_green 'Restoring celery configs'
@@ -232,7 +245,7 @@ print_green 'Installing postgresql'
echo "$postgresql_repo" | sudo tee /etc/apt/sources.list.d/pgdg.list
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt update
sudo apt install -y postgresql-14
sudo apt install -y postgresql-15
sleep 2
sudo systemctl enable --now postgresql
@@ -261,73 +274,114 @@ git checkout main
print_green 'Restoring NATS'
if [ "$arch" = "x86_64" ]; then
natsarch='amd64'
else
natsarch='arm64'
fi
NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}')
nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX)
wget https://github.com/nats-io/nats-server/releases/download/v${NATS_SERVER_VER}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz -P ${nats_tmp}
tar -xzf ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz -C ${nats_tmp}
sudo mv ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64/nats-server /usr/local/bin/
wget https://github.com/nats-io/nats-server/releases/download/v${NATS_SERVER_VER}/nats-server-v${NATS_SERVER_VER}-linux-${natsarch}.tar.gz -P ${nats_tmp}
tar -xzf ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-${natsarch}.tar.gz -C ${nats_tmp}
sudo mv ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-${natsarch}/nats-server /usr/local/bin/
sudo chmod +x /usr/local/bin/nats-server
sudo chown ${USER}:${USER} /usr/local/bin/nats-server
rm -rf ${nats_tmp}
print_green 'Restoring MeshCentral'
sudo apt install -y jq
MESH_VER=$(grep "^MESH_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}')
sudo tar -xzf $tmp_dir/meshcentral/mesh.tar.gz -C /
sudo chown ${USER}:${USER} -R /meshcentral
rm -f /meshcentral/package.json /meshcentral/package-lock.json
FROM_MONGO=false
if grep -q postgres "/meshcentral/meshcentral-data/config.json"; then
MESH_POSTGRES_USER=$(jq '.settings.postgres.user' /meshcentral/meshcentral-data/config.json -r)
MESH_POSTGRES_PW=$(jq '.settings.postgres.password' /meshcentral/meshcentral-data/config.json -r)
else
FROM_MONGO=true
MESH_POSTGRES_USER=$(cat /dev/urandom | tr -dc 'a-z' | fold -w 8 | head -n 1)
MESH_POSTGRES_PW=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)
fi
print_green 'Creating MeshCentral DB'
sudo -u postgres psql -c "CREATE DATABASE meshcentral"
sudo -u postgres psql -c "CREATE USER ${MESH_POSTGRES_USER} WITH PASSWORD '${MESH_POSTGRES_PW}'"
sudo -u postgres psql -c "ALTER ROLE ${MESH_POSTGRES_USER} SET client_encoding TO 'utf8'"
sudo -u postgres psql -c "ALTER ROLE ${MESH_POSTGRES_USER} SET default_transaction_isolation TO 'read committed'"
sudo -u postgres psql -c "ALTER ROLE ${MESH_POSTGRES_USER} SET timezone TO 'UTC'"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE meshcentral TO ${MESH_POSTGRES_USER}"
sudo -u postgres psql -c "ALTER DATABASE meshcentral OWNER TO ${MESH_POSTGRES_USER}"
sudo -u postgres psql -c "GRANT USAGE, CREATE ON SCHEMA PUBLIC TO ${MESH_POSTGRES_USER}"
if [ "$FROM_MONGO" = true ]; then
print_green 'Converting mesh mongo to postgres'
# https://github.com/amidaware/trmm-awesome/blob/main/scripts/migrate-mesh-to-postgres.sh
mesh_data='/meshcentral/meshcentral-data'
if [[ ! -f "${mesh_data}/meshcentral.db.json" ]]; then
echo -ne "${RED}ERROR: meshcentral.db.json was not found${NC}\n"
echo -ne "${RED}Unable to convert mongo to postgres${NC}\n"
echo -ne "${RED}You probably didn't download the lastest backup.sh file before doing a backup and were using an outdated version${NC}\n"
echo -ne "${RED}You will need to download the latest backup script, run a fresh backup on your old server, wipe this server and attempt a fresh restore.${NC}\n"
exit 1
fi
MESH_PG_PORT='5432'
MESH_PG_HOST='localhost'
cp ${mesh_data}/config.json ${mesh_data}/config-mongodb-$(date "+%Y%m%dT%H%M%S").bak
cat ${mesh_data}/config.json |
jq '.settings |= with_entries(select((.key | ascii_downcase) as $key | $key != "mongodb" and $key != "mongodbname"))' |
jq " .settings.postgres.user |= \"${MESH_POSTGRES_USER}\" " |
jq " .settings.postgres.password |= \"${MESH_POSTGRES_PW}\" " |
jq " .settings.postgres.port |= \"${MESH_PG_PORT}\" " |
jq " .settings.postgres.host |= \"${MESH_PG_HOST}\" " >${mesh_data}/config-postgres.json
mv ${mesh_data}/config-postgres.json ${mesh_data}/config.json
else
gzip -d $tmp_dir/postgres/mesh-db*.psql.gz
PGPASSWORD=${MESH_POSTGRES_PW} psql -h localhost -U ${MESH_POSTGRES_USER} -d meshcentral -f $tmp_dir/postgres/mesh-db*.psql
fi
cd /meshcentral
npm install meshcentral@${MESH_VER}
print_green 'Restoring MeshCentral DB'
if grep -q postgres "/meshcentral/meshcentral-data/config.json"; then
if ! which jq >/dev/null; then
sudo apt-get install -y jq >null
fi
MESH_POSTGRES_USER=$(jq '.settings.postgres.user' /meshcentral/meshcentral-data/config.json -r)
MESH_POSTGRES_PW=$(jq '.settings.postgres.password' /meshcentral/meshcentral-data/config.json -r)
sudo -u postgres psql -c "DROP DATABASE IF EXISTS meshcentral"
sudo -u postgres psql -c "CREATE DATABASE meshcentral"
sudo -u postgres psql -c "CREATE USER ${MESH_POSTGRES_USER} WITH PASSWORD '${MESH_POSTGRES_PW}'"
sudo -u postgres psql -c "ALTER ROLE ${MESH_POSTGRES_USER} SET client_encoding TO 'utf8'"
sudo -u postgres psql -c "ALTER ROLE ${MESH_POSTGRES_USER} SET default_transaction_isolation TO 'read committed'"
sudo -u postgres psql -c "ALTER ROLE ${MESH_POSTGRES_USER} SET timezone TO 'UTC'"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE meshcentral TO ${MESH_POSTGRES_USER}"
gzip -d $tmp_dir/postgres/mesh-db*.psql.gz
PGPASSWORD=${MESH_POSTGRES_PW} psql -h localhost -U ${MESH_POSTGRES_USER} -d meshcentral -f $tmp_dir/postgres/mesh-db*.psql
else
print_green 'Installing MongoDB'
wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
echo "$mongodb_repo" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
sudo apt update
sudo apt install -y mongodb-org
sudo systemctl enable --now mongod
sleep 5
mongorestore --gzip $tmp_dir/meshcentral/mongo
if [ "$FROM_MONGO" = true ]; then
node node_modules/meshcentral --dbimport >/dev/null
fi
print_green 'Restoring the backend'
cp $tmp_dir/rmm/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/
gzip -d $tmp_dir/rmm/debug.log.gz
cp $tmp_dir/rmm/django_debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/
sudo cp /rmm/natsapi/bin/nats-api /usr/local/bin
if [ "$arch" = "x86_64" ]; then
natsapi='nats-api'
else
natsapi='nats-api-arm64'
fi
sudo cp /rmm/natsapi/bin/${natsapi} /usr/local/bin/nats-api
sudo chown ${USER}:${USER} /usr/local/bin/nats-api
sudo chmod +x /usr/local/bin/nats-api
print_green 'Restoring the database'
print_green 'Restoring the trmm database'
pgusername=$(grep -w USER /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//')
pgpw=$(grep -w PASSWORD /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//')
sudo -u postgres psql -c "DROP DATABASE IF EXISTS tacticalrmm"
sudo -u postgres psql -c "CREATE DATABASE tacticalrmm"
sudo -u postgres psql -c "CREATE USER ${pgusername} WITH PASSWORD '${pgpw}'"
sudo -u postgres psql -c "ALTER ROLE ${pgusername} SET client_encoding TO 'utf8'"
sudo -u postgres psql -c "ALTER ROLE ${pgusername} SET default_transaction_isolation TO 'read committed'"
sudo -u postgres psql -c "ALTER ROLE ${pgusername} SET timezone TO 'UTC'"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE tacticalrmm TO ${pgusername}"
sudo -u postgres psql -c "ALTER DATABASE tacticalrmm OWNER TO ${pgusername}"
sudo -u postgres psql -c "GRANT USAGE, CREATE ON SCHEMA PUBLIC TO ${pgusername}"
gzip -d $tmp_dir/postgres/db*.psql.gz
PGPASSWORD=${pgpw} psql -h localhost -U ${pgusername} -d tacticalrmm -f $tmp_dir/postgres/db*.psql
@@ -356,6 +410,12 @@ deactivate
print_green 'Restoring hosts file'
if grep -q manage_etc_hosts /etc/hosts; then
sudo sed -i '/manage_etc_hosts: true/d' /etc/cloud/cloud.cfg >/dev/null
echo -e "\nmanage_etc_hosts: false" | sudo tee --append /etc/cloud/cloud.cfg >/dev/null
sudo systemctl restart cloud-init >/dev/null
fi
HAS_11=$(grep 127.0.1.1 /etc/hosts)
if [[ $HAS_11 ]]; then
sudo sed -i "/127.0.1.1/s/$/ ${API} ${webdomain} ${meshdomain}/" /etc/hosts
@@ -384,7 +444,13 @@ sudo chown -R $USER:$GROUP /home/${USER}/.npm
sudo chown -R $USER:$GROUP /home/${USER}/.config
sudo chown -R $USER:$GROUP /home/${USER}/.cache
print_green 'Enabling Services'
print_green 'Enabling and starting services'
HAS_OLD_MONGO_DEP=$(grep mongod /etc/systemd/system/meshcentral.service)
if [[ $HAS_OLD_MONGO_DEP ]]; then
sudo sed -i 's/mongod.service/postgresql.service/g' /etc/systemd/system/meshcentral.service
fi
sudo systemctl daemon-reload
for i in celery.service celerybeat.service rmm.service daphne.service nats-api.service nginx; do

View File

@@ -3,8 +3,9 @@
# Tactical RMM install troubleshooting script
# Contributed by https://github.com/dinger1986
# v1.1 1/21/2022 update to include all services
# v 1.2 6/24/2023 changed to add date, easier readability and ipv4 addresses only for checks
# This script asks for the 3 subdomains, checks they exist, checks they resolve locally and remotely (using google dns for remote),
# This script asks for the 3 subdomains, checks they exist, checks they resolve locally and remotely (using google dns for remote),
# checks services are running, checks ports are opened. The only part that will make the script stop is if the sub domains dont exist, theres literally no point in going further if thats the case
GREEN='\033[0;32m'
@@ -12,120 +13,136 @@ YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
# Set date at the top of the troubleshooting script
now=$(date)
echo -e -------------- $now -------------- | tee -a checklog.log
osname=$(lsb_release -si)
osname=${osname^}
osname=$(echo "$osname" | tr '[A-Z]' '[a-z]')
relno=$(lsb_release -sr | cut -d. -f1)
# Resolve Locally used DNS server
locdns=$(resolvectl | grep 'Current DNS Server:' | cut -d: -f2 | awk '{ print $1}')
resolvestatus=$(systemctl is-active systemd-resolved.service)
if [[ "$osname" == "debian" && "$relno" == 12 ]]; then
locdns=$(resolvconf -l | tail -n +1 | grep -m 1 -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
while [[ $rmmdomain != *[.]*[.]* ]]
do
echo -ne "${YELLOW}Enter the subdomain for the backend (e.g. api.example.com)${NC}: "
read rmmdomain
done
if ping -c 1 $rmmdomain &> /dev/null
then
echo -ne ${GREEN} Verified $rmmdomain | tee -a checklog.log
printf >&2 "\n\n"
elif [ $resolvestatus = active ]; then
locdns=$(resolvectl | tail -n +1 | grep -m 1 -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
else
echo -ne ${RED} $rmmdomain doesnt exist please create it or check for a typo | tee -a checklog.log
printf >&2 "\n\n"
printf >&2 "You will have a log file called checklog.log in the directory you ran this script from\n\n"
printf >&2 "\n\n"
exit
while ! [[ $resolveconf ]]; do
resolveconf=$(sudo systemctl status systemd-resolved.service | grep "Active: active (running)")
sudo systemctl start systemd-resolved.service
echo -ne "DNS Resolver not ready yet...${NC}\n"
sleep 3
done
locdns=$(resolvectl | tail -n +1 | grep -m 1 -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
sudo systemctl stop systemd-resolved.service
fi
while [[ $frontenddomain != *[.]*[.]* ]]
do
echo -ne "${YELLOW}Enter the subdomain for the frontend (e.g. rmm.example.com)${NC}: "
read frontenddomain
while [[ $rmmdomain != *[.]*[.]* ]]; do
echo -e "${YELLOW}Enter the subdomain for the backend (e.g. api.example.com)${NC}: "
read rmmdomain
done
if ping -c 1 $frontenddomain &> /dev/null
then
echo -ne ${GREEN} Verified $frontenddomain | tee -a checklog.log
if ping -c 1 $rmmdomain &>/dev/null; then
echo -e ${GREEN} Verified $rmmdomain | tee -a checklog.log
printf >&2 "\n\n"
else
echo -ne ${RED} $frontenddomain doesnt exist please create it or check for a typo | tee -a checklog.log
printf >&2 "\n\n"
printf >&2 "You will have a log file called checklog.log in the directory you ran this script from\n\n"
printf >&2 "\n\n"
exit
echo -e ${RED} $rmmdomain doesnt exist please create it or check for a typo | tee -a checklog.log
printf >&2 "\n\n"
printf >&2 "You will have a log file called checklog.log in the directory you ran this script from\n\n"
printf >&2 "\n\n"
exit
fi
while [[ $meshdomain != *[.]*[.]* ]]
do
echo -ne "${YELLOW}Enter the subdomain for meshcentral (e.g. mesh.example.com)${NC}: "
read meshdomain
while [[ $frontenddomain != *[.]*[.]* ]]; do
echo -e "${YELLOW}Enter the subdomain for the frontend (e.g. rmm.example.com)${NC}: "
read frontenddomain
done
if ping -c 1 $meshdomain &> /dev/null
then
echo -ne ${GREEN} Verified $meshdomain | tee -a checklog.log
if ping -c 1 $frontenddomain &>/dev/null; then
echo -e ${GREEN} Verified $frontenddomain | tee -a checklog.log
printf >&2 "\n\n"
else
echo -ne ${RED} $meshdomain doesnt exist please create it or check for a typo | tee -a checklog.log
printf >&2 "\n\n" | tee -a checklog.log
printf >&2 "You will have a log file called checklog.log in the directory you ran this script from\n\n"
printf >&2 "\n\n"
exit
echo -e ${RED} $frontenddomain doesnt exist please create it or check for a typo | tee -a checklog.log
printf >&2 "\n\n"
printf >&2 "You will have a log file called checklog.log in the directory you ran this script from\n\n"
printf >&2 "\n\n"
exit
fi
while [[ $domain != *[.]* ]]
do
echo -ne "${YELLOW}Enter yourdomain used for letsencrypt (e.g. example.com)${NC}: "
read domain
while [[ $meshdomain != *[.]*[.]* ]]; do
echo -e "${YELLOW}Enter the subdomain for meshcentral (e.g. mesh.example.com)${NC}: "
read meshdomain
done
echo -ne ${YELLOW} Checking IPs | tee -a checklog.log
if ping -c 1 $meshdomain &>/dev/null; then
echo -e ${GREEN} Verified $meshdomain | tee -a checklog.log
printf >&2 "\n\n"
else
echo -e ${RED} $meshdomain doesnt exist please create it or check for a typo | tee -a checklog.log
printf >&2 "\n\n" | tee -a checklog.log
printf >&2 "You will have a log file called checklog.log in the directory you ran this script from\n\n"
printf >&2 "\n\n"
exit
fi
while [[ $domain != *[.]* ]]; do
echo -e "${YELLOW}Enter yourdomain used for letsencrypt (e.g. example.com)${NC}: "
read domain
done
echo -e ${YELLOW} Checking IPs | tee -a checklog.log
printf >&2 "\n\n"
# Check rmmdomain IPs
locapiip=`dig @"$locdns" +short $rmmdomain`
remapiip=`dig @8.8.8.8 +short $rmmdomain`
locapiip=$(dig @"$locdns" +short $rmmdomain | grep -m 1 -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
remapiip=$(dig @8.8.8.8 +short $rmmdomain | grep -m 1 -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
if [ "$locapiip" = "$remapiip" ]; then
echo -ne ${GREEN} Success $rmmdomain is Locally Resolved: "$locapiip" Remotely Resolved: "$remapiip" | tee -a checklog.log
echo -e ${GREEN} Success $rmmdomain is Locally Resolved: "$locapiip" Remotely Resolved: "$remapiip" | tee -a checklog.log
printf >&2 "\n\n"
else
echo -ne ${RED} Locally Resolved: "$locapiip" Remotely Resolved: "$remapiip" | tee -a checklog.log
echo -e ${RED} Locally Resolved: "$locapiip" Remotely Resolved: "$remapiip" | tee -a checklog.log
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} Your Local and Remote IP for $rmmdomain all agents will require non-public DNS to find TRMM server | tee -a checklog.log
echo -e ${RED} Your Local and Remote IP for $rmmdomain all agents will require non-public DNS to find TRMM server | tee -a checklog.log
printf >&2 "\n\n"
fi
# Check Frontenddomain IPs
locrmmip=`dig @"$locdns" +short $frontenddomain`
remrmmip=`dig @8.8.8.8 +short $frontenddomain`
locrmmip=$(dig @"$locdns" +short $frontenddomain | grep -m 1 -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
remrmmip=$(dig @8.8.8.8 +short $frontenddomain | grep -m 1 -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
if [ "$locrmmip" = "$remrmmip" ]; then
echo -ne ${GREEN} Success $frontenddomain is Locally Resolved: "$locrmmip" Remotely Resolved: "$remrmmip"| tee -a checklog.log
echo -e ${GREEN} Success $frontenddomain is Locally Resolved: "$locrmmip" Remotely Resolved: "$remrmmip" | tee -a checklog.log
printf >&2 "\n\n"
else
echo -ne ${RED} Locally Resolved: "$locrmmip" Remotely Resolved: "$remrmmip" | tee -a checklog.log
echo -e ${RED} Locally Resolved: "$locrmmip" Remotely Resolved: "$remrmmip" | tee -a checklog.log
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} echo Your Local and Remote IP for $frontenddomain all agents will require non-public DNS to find TRMM server | tee -a checklog.log
echo -e ${RED} echo Your Local and Remote IP for $frontenddomain all agents will require non-public DNS to find TRMM server | tee -a checklog.log
printf >&2 "\n\n"
fi
# Check meshdomain IPs
locmeship=`dig @"$locdns" +short $meshdomain`
remmeship=`dig @8.8.8.8 +short $meshdomain`
locmeship=$(dig @"$locdns" +short $meshdomain | grep -m 1 -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
remmeship=$(dig @8.8.8.8 +short $meshdomain | grep -m 1 -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
if [ "$locmeship" = "$remmeship" ]; then
echo -ne ${GREEN} Success $meshdomain is Locally Resolved: "$locmeship" Remotely Resolved: "$remmeship" | tee -a checklog.log
echo -e ${GREEN} Success $meshdomain is Locally Resolved: "$locmeship" Remotely Resolved: "$remmeship" | tee -a checklog.log
printf >&2 "\n\n" | tee -a checklog.log
else
echo -ne ${RED} Locally Resolved: "$locmeship" Remotely Resolved: "$remmeship" | tee -a checklog.log
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} Your Local and Remote IP for $meshdomain all agents will require non-public DNS to find TRMM server | tee -a checklog.log
echo -e ${RED} Locally Resolved: "$locmeship" Remotely Resolved: "$remmeship" | tee -a checklog.log
printf >&2 "\n\n" | tee -a checklog.log
echo -e ${RED} Your Local and Remote IP for $meshdomain all agents will require non-public DNS to find TRMM server | tee -a checklog.log
printf >&2 "\n\n" | tee -a checklog.log
fi
echo -ne ${YELLOW} Checking Services | tee -a checklog.log
printf >&2 "\n\n"
echo -e ${YELLOW} Checking Services | tee -a checklog.log
printf >&2 "\n\n"
# Check if services are running
rmmstatus=$(systemctl is-active rmm)
@@ -142,195 +159,201 @@ redisserverstatus=$(systemctl is-active redis-server)
# RMM Service
if [ $rmmstatus = active ]; then
echo -ne ${GREEN} Success RMM Service is Running | tee -a checklog.log
echo -e ${GREEN} Success RMM Service is Running | tee -a checklog.log
printf >&2 "\n\n"
else
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} 'RMM Service isnt running (Tactical wont work without this)' | tee -a checklog.log
echo -e ${RED} 'RMM Service isnt running (Tactical wont work without this)' | tee -a checklog.log
printf >&2 "\n\n"
fi
# daphne Service
if [ $daphnestatus = active ]; then
echo -ne ${GREEN} Success daphne Service is Running | tee -a checklog.log
echo -e ${GREEN} Success daphne Service is Running | tee -a checklog.log
printf >&2 "\n\n"
else
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} 'daphne Service isnt running (Tactical wont work without this)' | tee -a checklog.log
echo -e ${RED} 'daphne Service isnt running (Tactical wont work without this)' | tee -a checklog.log
printf >&2 "\n\n"
fi
# celery Service
if [ $celerystatus = active ]; then
echo -ne ${GREEN} Success celery Service is Running | tee -a checklog.log
echo -e ${GREEN} Success celery Service is Running | tee -a checklog.log
printf >&2 "\n\n"
else
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} 'celery Service isnt running (Tactical wont work without this)' | tee -a checklog.log
echo -e ${RED} 'celery Service isnt running (Tactical wont work without this)' | tee -a checklog.log
printf >&2 "\n\n"
fi
# celerybeat Service
if [ $celerybeatstatus = active ]; then
echo -ne ${GREEN} Success celerybeat Service is Running | tee -a checklog.log
echo -e ${GREEN} Success celerybeat Service is Running | tee -a checklog.log
printf >&2 "\n\n"
else
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} 'celerybeat Service isnt running (Tactical wont work without this)' | tee -a checklog.log
echo -e ${RED} 'celerybeat Service isnt running (Tactical wont work without this)' | tee -a checklog.log
printf >&2 "\n\n"
fi
# nginx Service
if [ $nginxstatus = active ]; then
echo -ne ${GREEN} Success nginx Service is Running | tee -a checklog.log
echo -e ${GREEN} Success nginx Service is Running | tee -a checklog.log
printf >&2 "\n\n"
else
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} 'nginx Service isnt running (Tactical wont work without this)' | tee -a checklog.log
echo -e ${RED} 'nginx Service isnt running (Tactical wont work without this)' | tee -a checklog.log
printf >&2 "\n\n"
fi
# nats Service
if [ $natsstatus = active ]; then
echo -ne ${GREEN} Success nats Service is running | tee -a checklog.log
echo -e ${GREEN} Success nats Service is running | tee -a checklog.log
printf >&2 "\n\n"
else
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} 'nats Service isnt running (Tactical wont work without this)' | tee -a checklog.log
echo -e ${RED} 'nats Service isnt running (Tactical wont work without this)' | tee -a checklog.log
printf >&2 "\n\n"
fi
# nats-api Service
if [ $natsapistatus = active ]; then
echo -ne ${GREEN} Success nats-api Service is running | tee -a checklog.log
echo -e ${GREEN} Success nats-api Service is running | tee -a checklog.log
printf >&2 "\n\n"
else
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} 'nats-api Service isnt running (Tactical wont work without this)' | tee -a checklog.log
echo -e ${RED} 'nats-api Service isnt running (Tactical wont work without this)' | tee -a checklog.log
printf >&2 "\n\n"
fi
# meshcentral Service
if [ $meshcentralstatus = active ]; then
echo -ne ${GREEN} Success meshcentral Service is running | tee -a checklog.log
echo -e ${GREEN} Success meshcentral Service is running | tee -a checklog.log
printf >&2 "\n\n"
else
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} 'meshcentral Service isnt running (Tactical wont work without this)' | tee -a checklog.log
echo -e ${RED} 'meshcentral Service isnt running (Tactical wont work without this)' | tee -a checklog.log
printf >&2 "\n\n"
fi
# mongod Service
if [ $mongodstatus = active ]; then
echo -ne ${GREEN} Success mongod Service is running | tee -a checklog.log
printf >&2 "\n\n"
else
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} 'mongod Service isnt running (Tactical wont work without this)' | tee -a checklog.log
printf >&2 "\n\n"
if grep -q mongo "/meshcentral/meshcentral-data/config.json"; then
if [ $mongodstatus = active ]; then
echo -e ${GREEN} Success mongod Service is running | tee -a checklog.log
printf >&2 "\n\n"
else
printf >&2 "\n\n" | tee -a checklog.log
echo -e ${RED} 'mongod Service isnt running (Tactical wont work without this)' | tee -a checklog.log
printf >&2 "\n\n"
fi
fi
# postgresql Service
if [ $postgresqlstatus = active ]; then
echo -ne ${GREEN} Success postgresql Service is running | tee -a checklog.log
echo -e ${GREEN} Success postgresql Service is running | tee -a checklog.log
printf >&2 "\n\n"
else
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} 'postgresql Service isnt running (Tactical wont work without this)' | tee -a checklog.log
echo -e ${RED} 'postgresql Service isnt running (Tactical wont work without this)' | tee -a checklog.log
printf >&2 "\n\n"
fi
# redis-server Service
if [ $redisserverstatus = active ]; then
echo -ne ${GREEN} Success redis-server Service is running | tee -a checklog.log
echo -e ${GREEN} Success redis-server Service is running | tee -a checklog.log
printf >&2 "\n\n"
else
printf >&2 "\n\n" | tee -a checklog.log
echo -ne ${RED} 'redis-server Service isnt running (Tactical wont work without this)' | tee -a checklog.log
echo -e ${RED} 'redis-server Service isnt running (Tactical wont work without this)' | tee -a checklog.log
printf >&2 "\n\n"
fi
echo -ne ${YELLOW} Checking Open Ports | tee -a checklog.log
printf >&2 "\n\n"
echo -e ${YELLOW} Checking Open Ports | tee -a checklog.log
printf >&2 "\n\n"
#Get WAN IP
wanip=$(dig @resolver4.opendns.com myip.opendns.com +short)
echo -ne ${GREEN} WAN IP is $wanip | tee -a checklog.log
echo -e ${GREEN} WAN IP is $wanip | tee -a checklog.log
printf >&2 "\n\n"
if ! which nc >/dev/null; then
echo "netcat is not installed, installing now"
sudo apt-get install netcat -y
fi
#Check if HTTPs Port is open
if ( nc -zv $wanip 443 2>&1 >/dev/null ); then
echo -ne ${GREEN} 'HTTPs Port is open' | tee -a checklog.log
if (nc -zv $wanip 443 2>&1 >/dev/null); then
echo -e ${GREEN} 'HTTPs Port is open' | tee -a checklog.log
printf >&2 "\n\n"
else
echo -ne ${RED} 'HTTPs port is closed (you may want this if running locally only)' | tee -a checklog.log
echo -e ${RED} 'HTTPs port is closed (you may want this if running locally only)' | tee -a checklog.log
printf >&2 "\n\n"
fi
echo -ne ${YELLOW} Checking For Proxy | tee -a checklog.log
printf >&2 "\n\n"
echo -ne ${YELLOW} ......this might take a while!!
printf >&2 "\n\n"
echo -e ${YELLOW} Checking For Proxy | tee -a checklog.log
printf >&2 "\n\n"
echo -e ${YELLOW} ......this might take a while!!
printf >&2 "\n\n"
# Detect Proxy via cert
proxyext=$(openssl s_client -showcerts -servername $remapiip -connect $remapiip:443 2>/dev/null | openssl x509 -inform pem -noout -text)
proxyint=$(openssl s_client -showcerts -servername 127.0.0.1 -connect 127.0.0.1:443 2>/dev/null | openssl x509 -inform pem -noout -text)
if [[ $proxyext == $proxyint ]]; then
echo -ne ${GREEN} No Proxy detected using Certificate | tee -a checklog.log
echo -e ${GREEN} No Proxy detected using Certificate | tee -a checklog.log
printf >&2 "\n\n"
else
echo -ne ${RED} Proxy detected using Certificate | tee -a checklog.log
echo -e ${RED} Proxy detected using Certificate | tee -a checklog.log
printf >&2 "\n\n"
fi
# Detect Proxy via IP
if [ $wanip != $remrmmip ]; then
echo -ne ${RED} Proxy detected using IP | tee -a checklog.log
echo -e ${RED} Proxy detected using IP | tee -a checklog.log
printf >&2 "\n\n"
else
echo -ne ${GREEN} No Proxy detected using IP | tee -a checklog.log
echo -e ${GREEN} No Proxy detected using IP | tee -a checklog.log
printf >&2 "\n\n"
fi
echo -ne ${YELLOW} Checking SSL Certificate is up to date | tee -a checklog.log
printf >&2 "\n\n"
echo -e ${YELLOW} Checking SSL Certificate is up to date | tee -a checklog.log
printf >&2 "\n\n"
#SSL Certificate check
cert=$(sudo certbot certificates)
if [[ "$cert" != *"INVALID"* ]]; then
echo -ne ${GREEN} SSL Certificate for $domain is fine | tee -a checklog.log
echo -e ${GREEN} SSL Certificate for $domain is fine | tee -a checklog.log
printf >&2 "\n\n"
else
echo -ne ${RED} SSL Certificate has expired or doesnt exist for $domain | tee -a checklog.log
echo -e ${RED} SSL Certificate has expired or doesnt exist for $domain | tee -a checklog.log
printf >&2 "\n\n"
fi
# Get List of Certbot Certificates
sudo certbot certificates | tee -a checklog.log
echo -ne ${YELLOW} Getting summary output of logs | tee -a checklog.log
echo -e ${YELLOW} Getting summary output of logs | tee -a checklog.log
tail /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | tee -a checklog.log
printf >&2 "\n\n"
tail /rmm/api/tacticalrmm/tacticalrmm/private/log/error.log | tee -a checklog.log
printf >&2 "\n\n"
tail /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | tee -a checklog.log
printf >&2 "\n\n"
tail /rmm/api/tacticalrmm/tacticalrmm/private/log/error.log | tee -a checklog.log
printf >&2 "\n\n"
printf >&2 "\n\n"
echo -ne ${YELLOW}
echo -e ${YELLOW}
printf >&2 "You will have a log file called checklog.log in the directory you ran this script from\n\n"
echo -ne ${NC}
echo -e ${NC}

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
SCRIPT_VERSION="144"
SCRIPT_VERSION="146"
SCRIPT_URL='https://raw.githubusercontent.com/amidaware/tacticalrmm/master/update.sh'
LATEST_SETTINGS_URL='https://raw.githubusercontent.com/amidaware/tacticalrmm/master/api/tacticalrmm/tacticalrmm/settings.py'
YELLOW='\033[1;33m'
@@ -10,7 +10,7 @@ NC='\033[0m'
THIS_SCRIPT=$(readlink -f "$0")
SCRIPTS_DIR='/opt/trmm-community-scripts'
PYTHON_VER='3.11.3'
PYTHON_VER='3.11.4'
SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py'
TMP_FILE=$(mktemp -p "" "rmmupdate_XXXXXXXXXX")
@@ -225,16 +225,24 @@ if ! [[ $HAS_PY311 ]]; then
sudo rm -rf Python-${PYTHON_VER} Python-${PYTHON_VER}.tgz
fi
arch=$(uname -m)
nats_server='/usr/local/bin/nats-server'
HAS_LATEST_NATS=$(/usr/local/bin/nats-server -version | grep "${NATS_SERVER_VER}")
if ! [[ $HAS_LATEST_NATS ]]; then
printf >&2 "${GREEN}Updating nats to v${NATS_SERVER_VER}${NC}\n"
nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX)
wget https://github.com/nats-io/nats-server/releases/download/v${NATS_SERVER_VER}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz -P ${nats_tmp}
tar -xzf ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz -C ${nats_tmp}
sudo rm -f /usr/local/bin/nats-server
sudo mv ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64/nats-server /usr/local/bin/
sudo chmod +x /usr/local/bin/nats-server
sudo chown ${USER}:${USER} /usr/local/bin/nats-server
if [ "$arch" = "x86_64" ]; then
natsarch='amd64'
else
natsarch='arm64'
fi
wget https://github.com/nats-io/nats-server/releases/download/v${NATS_SERVER_VER}/nats-server-v${NATS_SERVER_VER}-linux-${natsarch}.tar.gz -P ${nats_tmp}
tar -xzf ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-${natsarch}.tar.gz -C ${nats_tmp}
sudo rm -f $nats_server
sudo mv ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-${natsarch}/nats-server /usr/local/bin/
sudo chmod +x $nats_server
sudo chown ${USER}:${USER} $nats_server
rm -rf ${nats_tmp}
fi
@@ -250,24 +258,6 @@ if [ -d ~/.config ]; then
sudo chown -R $USER:$GROUP ~/.config
fi
HAS_NODE16=$(node --version | grep v16)
if ! [[ $HAS_NODE16 ]]; then
printf >&2 "${GREEN}Updating NodeJS to v16${NC}\n"
rm -rf /rmm/web/node_modules
sudo systemctl stop meshcentral
sudo apt remove -y nodejs
sudo rm -rf /usr/lib/node_modules
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt update
sudo apt install -y nodejs
sudo npm install -g npm
sudo chown ${USER}:${USER} -R /meshcentral
cd /meshcentral
rm -rf node_modules/
npm install meshcentral@${LATEST_MESH_VER}
sudo systemctl start meshcentral
fi
sudo npm install -g npm
# update from main repo
@@ -307,8 +297,10 @@ sudo chown ${USER}:${USER} -R ${SCRIPTS_DIR}
sudo chown ${USER}:${USER} /var/log/celery
sudo chown ${USER}:${USER} -R /etc/conf.d/
sudo chown ${USER}:${USER} -R /etc/letsencrypt
sudo chown ${USER}:${USER} -R /rmmbackups
if [ -d /rmmbackups ]; then
sudo chown ${USER}:${USER} -R /rmmbackups
fi
CHECK_CELERY_CONFIG=$(grep "autoscale=20,2" /etc/conf.d/celery.conf)
if ! [[ $CHECK_CELERY_CONFIG ]]; then
@@ -325,9 +317,16 @@ EOF
echo "${adminenabled}" | tee --append /rmm/api/tacticalrmm/tacticalrmm/local_settings.py >/dev/null
fi
sudo cp /rmm/natsapi/bin/nats-api /usr/local/bin
sudo chown ${USER}:${USER} /usr/local/bin/nats-api
sudo chmod +x /usr/local/bin/nats-api
if [ "$arch" = "x86_64" ]; then
natsapi='nats-api'
else
natsapi='nats-api-arm64'
fi
nats_api='/usr/local/bin/nats-api'
sudo cp /rmm/natsapi/bin/${natsapi} $nats_api
sudo chown ${USER}:${USER} $nats_api
sudo chmod +x $nats_api
if [[ "${CURRENT_PIP_VER}" != "${LATEST_PIP_VER}" ]] || [[ "$force" = true ]]; then
rm -rf /rmm/api/env
@@ -358,8 +357,29 @@ python manage.py clear_redis_celery_locks
python manage.py post_update_tasks
API=$(python manage.py get_config api)
WEB_VERSION=$(python manage.py get_config webversion)
FRONTEND=$(python manage.py get_config webdomain)
MESHDOMAIN=$(python manage.py get_config meshdomain)
deactivate
if grep -q manage_etc_hosts /etc/hosts; then
sudo sed -i '/manage_etc_hosts: true/d' /etc/cloud/cloud.cfg >/dev/null
if ! grep -q "manage_etc_hosts: false" /etc/cloud/cloud.cfg; then
echo -e "\nmanage_etc_hosts: false" | sudo tee --append /etc/cloud/cloud.cfg >/dev/null
sudo systemctl restart cloud-init >/dev/null
fi
fi
CHECK_HOSTS=$(grep 127.0.1.1 /etc/hosts | grep "$API" | grep "$FRONTEND" | grep "$MESHDOMAIN")
HAS_11=$(grep 127.0.1.1 /etc/hosts)
if ! [[ $CHECK_HOSTS ]]; then
if [[ $HAS_11 ]]; then
sudo sed -i "/127.0.1.1/s/$/ ${API} ${FRONTEND} ${MESHDOMAIN}/" /etc/hosts
else
echo "127.0.1.1 ${API} ${FRONTEND} ${MESHDOMAIN}" | sudo tee --append /etc/hosts >/dev/null
fi
fi
if [ -d /rmm/web ]; then
rm -rf /rmm/web
fi
@@ -381,9 +401,6 @@ for i in nats nats-api rmm daphne celery celerybeat nginx; do
sudo systemctl start ${i}
done
sleep 1
/rmm/api/env/bin/python /rmm/api/tacticalrmm/manage.py update_agents
CURRENT_MESH_VER=$(cd /meshcentral/node_modules/meshcentral && node -p -e "require('./package.json').version")
if [[ "${CURRENT_MESH_VER}" != "${LATEST_MESH_VER}" ]] || [[ "$force" = true ]]; then
printf >&2 "${GREEN}Updating meshcentral from ${CURRENT_MESH_VER} to ${LATEST_MESH_VER}${NC}\n"