Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f1b41227f | ||
|
|
83b9d13ec9 | ||
|
|
cee7896c37 | ||
|
|
0377009d2b | ||
|
|
b472f3644e | ||
|
|
5d8ea837c8 | ||
|
|
82de6bc849 | ||
|
|
cb4bc68c48 | ||
|
|
3ce6b38247 | ||
|
|
716c0fe979 | ||
|
|
c993790b7a | ||
|
|
aa32286531 | ||
|
|
6f94abde00 | ||
|
|
fa19538c9d | ||
|
|
84c858b878 | ||
|
|
865de142d4 | ||
|
|
9118162553 | ||
|
|
f4fc6ee9b4 | ||
|
|
108c38d57b | ||
|
|
a1d73eb830 | ||
|
|
997906a610 | ||
|
|
b6e5d120d3 | ||
|
|
d469d0b435 | ||
|
|
e9f823e000 | ||
|
|
d7fb76ba74 | ||
|
|
b7dde1a0d9 | ||
|
|
15095d8c23 | ||
|
|
dfbebc7606 | ||
|
|
895309d93d | ||
|
|
bcf50e821a | ||
|
|
30195800dd | ||
|
|
6532b0f149 | ||
|
|
5e108e4057 | ||
|
|
c2b2f4d222 | ||
|
|
bc4329ad21 | ||
|
|
aec6d1b2f6 | ||
|
|
2baf119299 | ||
|
|
6fe4c5a2ed | ||
|
|
4abc8e41d8 | ||
|
|
af694f1ce9 | ||
|
|
7c3a5fcb83 | ||
|
|
57f64b18c6 | ||
|
|
4cccc7c2f8 | ||
|
|
903a2d6a6e | ||
|
|
34c674487a | ||
|
|
d15a8c5af3 | ||
|
|
3e0dec9383 | ||
|
|
8b810aad81 | ||
|
|
e676bcb4f4 | ||
|
|
a7aed77764 | ||
|
|
88875c0257 | ||
|
|
f711a0c91a | ||
|
|
d8a076cc6e | ||
|
|
c900831ee9 |
@@ -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 /
|
||||
|
||||
4
.github/workflows/ci-tests.yml
vendored
4
.github/workflows/ci-tests.yml
vendored
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
deb https://nginx.org/packages/debian/ bullseye nginx
|
||||
deb-src https://nginx.org/packages/debian/ bullseye nginx
|
||||
@@ -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}'
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
2
ansible/roles/trmm_dev/templates/nginx.repo.j2
Normal file
2
ansible/roles/trmm_dev/templates/nginx.repo.j2
Normal 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
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -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")},
|
||||
),
|
||||
]
|
||||
@@ -1011,6 +1011,9 @@ class AgentCustomField(models.Model):
|
||||
default=list,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
unique_together = (("agent", "field"),)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.field.name
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 = (
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
45
backup.sh
45
backup.sh
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
14
go.mod
@@ -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
26
go.sum
@@ -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=
|
||||
|
||||
134
install.sh
134
install.sh
@@ -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
|
||||
|
||||
2
main.go
2
main.go
@@ -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
BIN
natsapi/bin/nats-api-arm64
Executable file
Binary file not shown.
200
restore.sh
200
restore.sh
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
83
update.sh
83
update.sh
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user