mirror of
https://github.com/bashclub/zamba-lxc-toolbox.git
synced 2024-11-07 19:31:58 +01:00
Add tactical rmm container
This commit is contained in:
parent
f52d8adfa8
commit
e01a6f67bc
47
src/tactical-rmm/constants-service.conf
Normal file
47
src/tactical-rmm/constants-service.conf
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Authors:
|
||||||
|
# (C) 2021 Idea an concept by Christian Zengel <christian@sysops.de>
|
||||||
|
# (C) 2021 Script design and prototype by Markus Helmke <m.helmke@nettwarker.de>
|
||||||
|
# (C) 2021 Script rework and documentation by Thorsten Spille <thorsten@spille-edv.de>
|
||||||
|
|
||||||
|
# This file contains the project constants on service level
|
||||||
|
|
||||||
|
# Debian Version, which will be installed
|
||||||
|
LXC_TEMPLATE_VERSION="debian-11-standard"
|
||||||
|
|
||||||
|
# Create sharefs mountpoint
|
||||||
|
LXC_MP="1"
|
||||||
|
|
||||||
|
# Create unprivileged container
|
||||||
|
LXC_UNPRIVILEGED="0"
|
||||||
|
|
||||||
|
# enable nesting feature
|
||||||
|
LXC_NESTING="1"
|
||||||
|
|
||||||
|
# Defines the IP from the SQL server
|
||||||
|
RMM_DB_IP="127.0.0.1"
|
||||||
|
|
||||||
|
# Defines the PORT from the SQL server
|
||||||
|
RMM_DB_PORT="5432"
|
||||||
|
|
||||||
|
# Defines the name from the SQL database
|
||||||
|
RMM_DB_NAME="rmm"
|
||||||
|
|
||||||
|
# Defines the name from the SQL user
|
||||||
|
pgusername="rmm"
|
||||||
|
|
||||||
|
# Build a strong password for the SQL user - could be overwritten with something fixed
|
||||||
|
RMMUSER=tactical
|
||||||
|
pgpw="$(random_password)"
|
||||||
|
DJANGO_SEKRET="$(random_password)"
|
||||||
|
ADMINURL="$(random_password)"
|
||||||
|
MESHPASSWD="$(random_password)"
|
||||||
|
meshusername="$(random_password)"
|
||||||
|
|
||||||
|
# vars from tactical-rmm install script
|
||||||
|
SCRIPTS_DIR="/opt/trmm-community-scripts"
|
||||||
|
PYTHON_VER="3.10.4"
|
||||||
|
TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX")
|
||||||
|
osname=debian
|
||||||
|
djangousername=admin
|
712
src/tactical-rmm/install-service.sh
Normal file
712
src/tactical-rmm/install-service.sh
Normal file
@ -0,0 +1,712 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Authors:
|
||||||
|
# (C) 2021 Idea an concept by Christian Zengel <christian@sysops.de>
|
||||||
|
# (C) 2021 Script design and prototype by Markus Helmke <m.helmke@nettwarker.de>
|
||||||
|
# (C) 2021 Script rework and documentation by Thorsten Spille <thorsten@spille-edv.de>
|
||||||
|
|
||||||
|
source /root/functions.sh
|
||||||
|
source /root/zamba.conf
|
||||||
|
source /root/constants-service.conf
|
||||||
|
|
||||||
|
codename=$(lsb_release -cs)
|
||||||
|
|
||||||
|
useradd -m -G sudo -s /bin/bash ${RMMUSER}
|
||||||
|
|
||||||
|
echo "deb https://repo.mongodb.org/apt/$osname buster/mongodb-org/4.4 main" > /etc/apt/sources.list.d/mongodb.list
|
||||||
|
echo "deb https://apt.postgresql.org/pub/repos/apt/ $codename-pgdg main" > /etc/apt/sources.list.d/postgres.list
|
||||||
|
echo "deb https://deb.nodesource.com/node_16.x $codename main" > /etc/apt/sources.list.d/nodejs.list
|
||||||
|
echo "deb https://dl.yarnpkg.com/debian stable main" > tee /etc/apt/sources.list.d/yarn.list
|
||||||
|
|
||||||
|
apt-key adv --fetch https://pgp.mongodb.com/server-4.4.pub
|
||||||
|
apt-key adv --fetch https://deb.nodesource.com/gpgkey/nodesource.gpg.key
|
||||||
|
apt-key adv --fetch https://dl.yarnpkg.com/debian/yarnkey.gpg
|
||||||
|
apt-key adv --fetch https://www.postgresql.org/media/keys/ACCC4CF8.asc
|
||||||
|
|
||||||
|
|
||||||
|
apt update
|
||||||
|
DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical apt install -y -qq sudo ssl-cert nginx mongodb-org gcc g++ make build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev ca-certificates redis git postgresql-14 rpl
|
||||||
|
DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical apt install -y -qq nodejs
|
||||||
|
|
||||||
|
echo "${RMMUSER} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${RMMUSER}
|
||||||
|
|
||||||
|
npm install --no-fund --location=global npm
|
||||||
|
|
||||||
|
openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout /etc/ssl/private/${frontenddomain}.key -out /etc/ssl/certs/${frontenddomain}.pem -subj "/CN=$frontenddomain" -addext "subjectAltName=DNS:*.${frontenddomain}"
|
||||||
|
chown root:ssl-cert /etc/ssl/private/${frontenddomain}.key
|
||||||
|
chmod 640 /etc/ssl/private/${frontenddomain}.key
|
||||||
|
usermod -aG ssl-cert ${RMMUSER}
|
||||||
|
|
||||||
|
update-ca-certificates
|
||||||
|
|
||||||
|
systemctl enable mongod.service postgresql.service
|
||||||
|
|
||||||
|
# configure hosts file
|
||||||
|
echo "127.0.1.1 ${rmmdomain} ${frontenddomain} ${meshdomain}" | tee --append /etc/hosts > /dev/null
|
||||||
|
|
||||||
|
# set global nginx vars
|
||||||
|
sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf
|
||||||
|
sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf
|
||||||
|
|
||||||
|
# compile python3
|
||||||
|
su - ${RMMUSER} << EOF
|
||||||
|
cd ~
|
||||||
|
wget https://www.python.org/ftp/python/${PYTHON_VER}/Python-${PYTHON_VER}.tgz
|
||||||
|
tar -xf Python-${PYTHON_VER}.tgz
|
||||||
|
cd Python-${PYTHON_VER}
|
||||||
|
./configure --enable-optimizations
|
||||||
|
make -j $(nproc)
|
||||||
|
sudo make altinstall
|
||||||
|
cd ~
|
||||||
|
sudo rm -rf Python-${PYTHON_VER} Python-${PYTHON_VER}.tgz
|
||||||
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
systemctl restart mongod postgresql
|
||||||
|
systemctl stop nginx
|
||||||
|
|
||||||
|
# configure postgresql
|
||||||
|
cd /var/lib/postgresql
|
||||||
|
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};"
|
||||||
|
|
||||||
|
# clone tacticalrmm
|
||||||
|
mkdir /rmm
|
||||||
|
chown ${RMMUSER}:${RMMUSER} /rmm
|
||||||
|
mkdir -p /var/log/celery
|
||||||
|
chown ${RMMUSER}:${RMMUSER} /var/log/celery
|
||||||
|
mkdir -p ${SCRIPTS_DIR}
|
||||||
|
chown ${RMMUSER}:${RMMUSER} ${SCRIPTS_DIR}
|
||||||
|
su - ${RMMUSER} << EOF
|
||||||
|
cd /rmm
|
||||||
|
git clone -b master https://github.com/amidaware/tacticalrmm.git /rmm
|
||||||
|
git config user.email "admin@example.com"
|
||||||
|
git config user.name "Bob"
|
||||||
|
cd ${SCRIPTS_DIR}
|
||||||
|
git clone -b main https://github.com/amidaware/community-scripts.git ${SCRIPTS_DIR}/
|
||||||
|
git config user.email "admin@example.com"
|
||||||
|
git config user.name "Bob"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# configure NATS server
|
||||||
|
NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" /rmm/api/tacticalrmm/tacticalrmm/settings.py | awk -F'[= "]' '{print $5}')
|
||||||
|
nats_tmp=$(mktemp -d -t nats-server-XXXXXXXXXXXXX)
|
||||||
|
wget https://github.com/nats-io/nats-server/releases/download/v${NATS_SERVER_VER}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz -O ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz
|
||||||
|
tar -xzf ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz -C ${nats_tmp}
|
||||||
|
mv ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64/nats-server /usr/local/bin/
|
||||||
|
chmod +x /usr/local/bin/nats-server
|
||||||
|
chown ${RMMUSER}:${RMMUSER} /usr/local/bin/nats-server
|
||||||
|
rm -rf ${nats_tmp}
|
||||||
|
|
||||||
|
# fix cert in nats-rmm.conf
|
||||||
|
rpl "/etc/letsencrypt/live/${frontenddomain}/fullchain.pem" "/etc/ssl/certs/${frontenddomain}.pem" /rmm/api/tacticalrmm/nats-rmm.conf
|
||||||
|
rpl "/etc/letsencrypt/live/${frontenddomain}/privkey.pem" "/etc/ssl/private/${frontenddomain}.key" /rmm/api/tacticalrmm/nats-rmm.conf
|
||||||
|
|
||||||
|
# install meshcentral
|
||||||
|
MESH_VER=$(grep "^MESH_VER" /rmm/api/tacticalrmm/tacticalrmm/settings.py | awk -F'[= "]' '{print $5}')
|
||||||
|
|
||||||
|
mkdir -p /meshcentral/meshcentral-data
|
||||||
|
chown ${RMMUSER}:${RMMUSER} -R /meshcentral
|
||||||
|
|
||||||
|
su - ${RMMUSER} << EOF
|
||||||
|
cd /meshcentral
|
||||||
|
npm install meshcentral@${MESH_VER}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chown ${RMMUSER}:${RMMUSER} -R /meshcentral
|
||||||
|
|
||||||
|
meshcfg="$(cat << EOF
|
||||||
|
{
|
||||||
|
"settings": {
|
||||||
|
"Cert": "${meshdomain}",
|
||||||
|
"MongoDb": "mongodb://127.0.0.1:27017",
|
||||||
|
"MongoDbName": "meshcentral",
|
||||||
|
"WANonly": true,
|
||||||
|
"Minify": 1,
|
||||||
|
"Port": 4430,
|
||||||
|
"AliasPort": 443,
|
||||||
|
"RedirPort": 800,
|
||||||
|
"AllowLoginToken": true,
|
||||||
|
"AllowFraming": true,
|
||||||
|
"_AgentPing": 60,
|
||||||
|
"AgentPong": 300,
|
||||||
|
"AllowHighQualityDesktop": true,
|
||||||
|
"TlsOffload": "127.0.0.1",
|
||||||
|
"agentCoreDump": false,
|
||||||
|
"Compression": true,
|
||||||
|
"WsCompression": true,
|
||||||
|
"AgentWsCompression": true,
|
||||||
|
"MaxInvalidLogin": { "time": 5, "count": 5, "coolofftime": 30 }
|
||||||
|
},
|
||||||
|
"domains": {
|
||||||
|
"": {
|
||||||
|
"Title": "Tactical RMM",
|
||||||
|
"Title2": "Tactical RMM",
|
||||||
|
"NewAccounts": false,
|
||||||
|
"CertUrl": "https://${meshdomain}:443/",
|
||||||
|
"GeoLocation": true,
|
||||||
|
"CookieIpCheck": false,
|
||||||
|
"mstsc": true,
|
||||||
|
"force2factor": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
sudo -u ${RMMUSER} echo "${meshcfg}" > /meshcentral/meshcentral-data/config.json
|
||||||
|
|
||||||
|
localvars="$(cat << EOF
|
||||||
|
SECRET_KEY = "${DJANGO_SEKRET}"
|
||||||
|
|
||||||
|
DEBUG = False
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = ['${rmmdomain}']
|
||||||
|
|
||||||
|
ADMIN_URL = "${ADMINURL}/"
|
||||||
|
|
||||||
|
CORS_ORIGIN_WHITELIST = [
|
||||||
|
"https://${frontenddomain}"
|
||||||
|
]
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.postgresql',
|
||||||
|
'NAME': 'tacticalrmm',
|
||||||
|
'USER': '${pgusername}',
|
||||||
|
'PASSWORD': '${pgpw}',
|
||||||
|
'HOST': 'localhost',
|
||||||
|
'PORT': '5432',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MESH_USERNAME = "${meshusername}"
|
||||||
|
MESH_SITE = "https://${meshdomain}"
|
||||||
|
REDIS_HOST = "localhost"
|
||||||
|
ADMIN_ENABLED = True
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
sudo -u ${RMMUSER} echo "${localvars}" > /rmm/api/tacticalrmm/tacticalrmm/local_settings.py
|
||||||
|
|
||||||
|
cp /rmm/natsapi/bin/nats-api /usr/local/bin
|
||||||
|
chown ${RMMUSER}:${RMMUSER} /usr/local/bin/nats-api
|
||||||
|
chmod +x /usr/local/bin/nats-api
|
||||||
|
|
||||||
|
SETUPTOOLS_VER=$(grep "^SETUPTOOLS_VER" /rmm/api/tacticalrmm/tacticalrmm/settings.py | awk -F'[= "]' '{print $5}')
|
||||||
|
WHEEL_VER=$(grep "^WHEEL_VER" /rmm/api/tacticalrmm/tacticalrmm/settings.py | awk -F'[= "]' '{print $5}')
|
||||||
|
|
||||||
|
su - ${RMMUSER} << EOF
|
||||||
|
cd /rmm/api/
|
||||||
|
/usr/local/bin/python3.10 -m venv env
|
||||||
|
source /rmm/api/env/bin/activate
|
||||||
|
cd /rmm/api/tacticalrmm
|
||||||
|
pip install --no-cache-dir --upgrade pip
|
||||||
|
pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER}
|
||||||
|
pip install --no-cache-dir -r /rmm/api/tacticalrmm/requirements.txt
|
||||||
|
python manage.py migrate
|
||||||
|
python manage.py collectstatic --no-input
|
||||||
|
python manage.py create_natsapi_conf
|
||||||
|
python manage.py load_chocos
|
||||||
|
python manage.py load_community_scripts
|
||||||
|
python manage.py create_installer_user
|
||||||
|
deactivate
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# install backend
|
||||||
|
echo 'Optimizing for number of processors'
|
||||||
|
uwsgiprocs=4
|
||||||
|
if [[ "$(nproc)" == "1" ]]; then
|
||||||
|
uwsgiprocs=2
|
||||||
|
else
|
||||||
|
uwsgiprocs=$(nproc)
|
||||||
|
fi
|
||||||
|
|
||||||
|
uwsgini="$(cat << EOF
|
||||||
|
[uwsgi]
|
||||||
|
chdir = /rmm/api/tacticalrmm
|
||||||
|
module = tacticalrmm.wsgi
|
||||||
|
home = /rmm/api/env
|
||||||
|
master = true
|
||||||
|
processes = ${uwsgiprocs}
|
||||||
|
threads = ${uwsgiprocs}
|
||||||
|
enable-threads = true
|
||||||
|
socket = /rmm/api/tacticalrmm/tacticalrmm.sock
|
||||||
|
harakiri = 300
|
||||||
|
chmod-socket = 660
|
||||||
|
buffer-size = 65535
|
||||||
|
vacuum = true
|
||||||
|
die-on-term = true
|
||||||
|
max-requests = 500
|
||||||
|
disable-logging = true
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
sudo -u ${RMMUSER} echo "${uwsgini}" > /rmm/api/tacticalrmm/app.ini
|
||||||
|
|
||||||
|
# create systemd services
|
||||||
|
|
||||||
|
rmmservice="$(cat << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=tacticalrmm uwsgi daemon
|
||||||
|
After=network.target postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=${RMMUSER}
|
||||||
|
Group=www-data
|
||||||
|
WorkingDirectory=/rmm/api/tacticalrmm
|
||||||
|
Environment="PATH=/rmm/api/env/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
ExecStart=/rmm/api/env/bin/uwsgi --ini app.ini
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
echo "${rmmservice}" | sudo tee /etc/systemd/system/rmm.service > /dev/null
|
||||||
|
|
||||||
|
daphneservice="$(cat << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=django channels daemon
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=${RMMUSER}
|
||||||
|
Group=www-data
|
||||||
|
WorkingDirectory=/rmm/api/tacticalrmm
|
||||||
|
Environment="PATH=/rmm/api/env/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
ExecStart=/rmm/api/env/bin/daphne -u /rmm/daphne.sock tacticalrmm.asgi:application
|
||||||
|
Restart=always
|
||||||
|
RestartSec=3s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
echo "${daphneservice}" | sudo tee /etc/systemd/system/daphne.service > /dev/null
|
||||||
|
|
||||||
|
natsservice="$(cat << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=NATS Server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
PrivateTmp=true
|
||||||
|
Type=simple
|
||||||
|
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=${RMMUSER}
|
||||||
|
Group=www-data
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5s
|
||||||
|
LimitNOFILE=1000000
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
echo "${natsservice}" | sudo tee /etc/systemd/system/nats.service > /dev/null
|
||||||
|
|
||||||
|
natsapi="$(cat << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=TacticalRMM Nats Api v1
|
||||||
|
After=nats.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/local/bin/nats-api
|
||||||
|
User=${RMMUSER}
|
||||||
|
Group=${RMMUSER}
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
echo "${natsapi}" | sudo tee /etc/systemd/system/nats-api.service > /dev/null
|
||||||
|
|
||||||
|
celeryservice="$(cat << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=Celery Service V2
|
||||||
|
After=network.target redis-server.service postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=forking
|
||||||
|
User=${RMMUSER}
|
||||||
|
Group=${RMMUSER}
|
||||||
|
EnvironmentFile=/etc/conf.d/celery.conf
|
||||||
|
WorkingDirectory=/rmm/api/tacticalrmm
|
||||||
|
ExecStart=/bin/sh -c '\${CELERY_BIN} -A \$CELERY_APP multi start \$CELERYD_NODES --pidfile=\${CELERYD_PID_FILE} --logfile=\${CELERYD_LOG_FILE} --loglevel="\${CELERYD_LOG_LEVEL}" \$CELERYD_OPTS'
|
||||||
|
ExecStop=/bin/sh -c '\${CELERY_BIN} multi stopwait \$CELERYD_NODES --pidfile=\${CELERYD_PID_FILE} --loglevel="\${CELERYD_LOG_LEVEL}"'
|
||||||
|
ExecReload=/bin/sh -c '\${CELERY_BIN} -A \$CELERY_APP multi restart \$CELERYD_NODES --pidfile=\${CELERYD_PID_FILE} --logfile=\${CELERYD_LOG_FILE} --loglevel="\${CELERYD_LOG_LEVEL}" \$CELERYD_OPTS'
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
echo "${celeryservice}" | sudo tee /etc/systemd/system/celery.service > /dev/null
|
||||||
|
|
||||||
|
celerybeatservice="$(cat << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=Celery Beat Service V2
|
||||||
|
After=network.target redis-server.service postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=${RMMUSER}
|
||||||
|
Group=${RMMUSER}
|
||||||
|
EnvironmentFile=/etc/conf.d/celery.conf
|
||||||
|
WorkingDirectory=/rmm/api/tacticalrmm
|
||||||
|
ExecStart=/bin/sh -c '\${CELERY_BIN} -A \${CELERY_APP} beat --pidfile=\${CELERYBEAT_PID_FILE} --logfile=\${CELERYBEAT_LOG_FILE} --loglevel=\${CELERYD_LOG_LEVEL}'
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
echo "${celerybeatservice}" | sudo tee /etc/systemd/system/celerybeat.service > /dev/null
|
||||||
|
|
||||||
|
meshservice="$(cat << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=MeshCentral Server
|
||||||
|
After=network.target mongod.service nginx.service
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
LimitNOFILE=1000000
|
||||||
|
ExecStart=/usr/bin/node node_modules/meshcentral
|
||||||
|
Environment=NODE_ENV=production
|
||||||
|
WorkingDirectory=/meshcentral
|
||||||
|
User=${RMMUSER}
|
||||||
|
Group=${RMMUSER}
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
echo "${meshservice}" | sudo tee /etc/systemd/system/meshcentral.service > /dev/null
|
||||||
|
|
||||||
|
|
||||||
|
# create nginx config
|
||||||
|
|
||||||
|
nginxrmm="$(cat << EOF
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
upstream tacticalrmm {
|
||||||
|
server unix:////rmm/api/tacticalrmm/tacticalrmm.sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
map \$http_user_agent \$ignore_ua {
|
||||||
|
"~python-requests.*" 0;
|
||||||
|
"~go-resty.*" 0;
|
||||||
|
default 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name ${rmmdomain};
|
||||||
|
return 301 https://\$server_name\$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
server_name ${rmmdomain};
|
||||||
|
client_max_body_size 300M;
|
||||||
|
access_log /rmm/api/tacticalrmm/tacticalrmm/private/log/access.log combined if=\$ignore_ua;
|
||||||
|
error_log /rmm/api/tacticalrmm/tacticalrmm/private/log/error.log;
|
||||||
|
ssl_certificate /etc/ssl/certs/${frontenddomain}.pem;
|
||||||
|
ssl_certificate_key /etc/ssl/private/${frontenddomain}.key;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
|
||||||
|
ssl_ecdh_curve secp384r1;
|
||||||
|
ssl_stapling on;
|
||||||
|
ssl_stapling_verify on;
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
|
||||||
|
location /static/ {
|
||||||
|
root /rmm/api/tacticalrmm;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /private/ {
|
||||||
|
internal;
|
||||||
|
add_header "Access-Control-Allow-Origin" "https://${frontenddomain}";
|
||||||
|
alias /rmm/api/tacticalrmm/tacticalrmm/private/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^/(natsapi) {
|
||||||
|
allow 127.0.0.1;
|
||||||
|
deny all;
|
||||||
|
uwsgi_pass tacticalrmm;
|
||||||
|
include /etc/nginx/uwsgi_params;
|
||||||
|
uwsgi_read_timeout 500s;
|
||||||
|
uwsgi_ignore_client_abort on;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^/ws/ {
|
||||||
|
proxy_pass http://unix:/rmm/daphne.sock;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade \$http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host \$host;
|
||||||
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host \$server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
uwsgi_pass tacticalrmm;
|
||||||
|
include /etc/nginx/uwsgi_params;
|
||||||
|
uwsgi_read_timeout 9999s;
|
||||||
|
uwsgi_ignore_client_abort on;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
echo "${nginxrmm}" | sudo tee /etc/nginx/sites-available/rmm.conf > /dev/null
|
||||||
|
|
||||||
|
|
||||||
|
nginxmesh="$(cat << EOF
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name ${meshdomain};
|
||||||
|
return 301 https://\$server_name\$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
proxy_send_timeout 330s;
|
||||||
|
proxy_read_timeout 330s;
|
||||||
|
server_name ${meshdomain};
|
||||||
|
ssl_certificate /etc/ssl/certs/${frontenddomain}.pem;
|
||||||
|
ssl_certificate_key /etc/ssl/private/${frontenddomain}.key;
|
||||||
|
|
||||||
|
ssl_session_cache shared:WEBSSL:10m;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
|
||||||
|
ssl_ecdh_curve secp384r1;
|
||||||
|
ssl_stapling on;
|
||||||
|
ssl_stapling_verify on;
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:4430/;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
proxy_set_header Host \$host;
|
||||||
|
proxy_set_header Upgrade \$http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header X-Forwarded-Host \$host:\$server_port;
|
||||||
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
echo "${nginxmesh}" | sudo tee /etc/nginx/sites-available/meshcentral.conf > /dev/null
|
||||||
|
|
||||||
|
ln -s /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-enabled/rmm.conf
|
||||||
|
ln -s /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-enabled/meshcentral.conf
|
||||||
|
|
||||||
|
# configure celery
|
||||||
|
mkdir /etc/conf.d
|
||||||
|
|
||||||
|
celeryconf="$(cat << EOF
|
||||||
|
CELERYD_NODES="w1"
|
||||||
|
|
||||||
|
CELERY_BIN="/rmm/api/env/bin/celery"
|
||||||
|
|
||||||
|
CELERY_APP="tacticalrmm"
|
||||||
|
|
||||||
|
CELERYD_MULTI="multi"
|
||||||
|
|
||||||
|
CELERYD_OPTS="--time-limit=86400 --autoscale=20,2"
|
||||||
|
|
||||||
|
CELERYD_PID_FILE="/rmm/api/tacticalrmm/%n.pid"
|
||||||
|
CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
|
||||||
|
CELERYD_LOG_LEVEL="ERROR"
|
||||||
|
|
||||||
|
CELERYBEAT_PID_FILE="/rmm/api/tacticalrmm/beat.pid"
|
||||||
|
CELERYBEAT_LOG_FILE="/var/log/celery/beat.log"
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
echo "${celeryconf}" | sudo tee /etc/conf.d/celery.conf > /dev/null
|
||||||
|
|
||||||
|
chown ${RMMUSER}:${RMMUSER} -R /etc/conf.d/
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
# install frontend
|
||||||
|
|
||||||
|
su - ${RMMUSER} << EOF
|
||||||
|
|
||||||
|
if [ -d ~/.npm ]; then
|
||||||
|
chown -R $RMMUSER:$RMMUSER ~/.npm
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d ~/.config ]; then
|
||||||
|
chown -R $RMMUSER:$RMMUSER ~/.config
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "PROD_URL = \"https://${rmmdomain}\"\nDEV_URL = \"https://${rmmdomain}\"" > /rmm/web/.env
|
||||||
|
|
||||||
|
cd /rmm/web
|
||||||
|
npm install
|
||||||
|
npm audit fix
|
||||||
|
npm run build
|
||||||
|
EOF
|
||||||
|
|
||||||
|
mkdir -p /var/www/rmm
|
||||||
|
cp -pvr /rmm/web/dist /var/www/rmm/
|
||||||
|
chown www-data:www-data -R /var/www/rmm/dist
|
||||||
|
|
||||||
|
nginxfrontend="$(cat << EOF
|
||||||
|
server {
|
||||||
|
server_name ${frontenddomain};
|
||||||
|
charset utf-8;
|
||||||
|
location / {
|
||||||
|
root /var/www/rmm/dist;
|
||||||
|
try_files \$uri \$uri/ /index.html;
|
||||||
|
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
||||||
|
add_header Pragma "no-cache";
|
||||||
|
}
|
||||||
|
error_log /var/log/nginx/frontend-error.log;
|
||||||
|
access_log /var/log/nginx/frontend-access.log;
|
||||||
|
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
ssl_certificate /etc/ssl/certs/${frontenddomain}.pem;
|
||||||
|
ssl_certificate_key /etc/ssl/private/${frontenddomain}.key;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
|
||||||
|
ssl_ecdh_curve secp384r1;
|
||||||
|
ssl_stapling on;
|
||||||
|
ssl_stapling_verify on;
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
if (\$host = ${frontenddomain}) {
|
||||||
|
return 301 https://\$host\$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name ${frontenddomain};
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
echo "${nginxfrontend}" | tee /etc/nginx/sites-available/frontend.conf > /dev/null
|
||||||
|
|
||||||
|
ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf
|
||||||
|
|
||||||
|
|
||||||
|
for i in rmm.service daphne.service celery.service celerybeat.service nginx
|
||||||
|
do
|
||||||
|
systemctl enable ${i}
|
||||||
|
systemctl stop ${i}
|
||||||
|
systemctl start ${i}
|
||||||
|
done
|
||||||
|
sleep 5
|
||||||
|
systemctl enable meshcentral
|
||||||
|
|
||||||
|
systemctl restart meshcentral
|
||||||
|
|
||||||
|
CHECK_MESH_READY=1
|
||||||
|
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 "Mesh Central not ready yet...\n"
|
||||||
|
sleep 3
|
||||||
|
done
|
||||||
|
|
||||||
|
node /meshcentral/node_modules/meshcentral --logintokenkey
|
||||||
|
|
||||||
|
MESHTOKENKEY=$(node /meshcentral/node_modules/meshcentral --logintokenkey)
|
||||||
|
sudo -u ${USER} echo "MESH_TOKEN_KEY = \"$MESHTOKENKEY\"" >> /rmm/api/tacticalrmm/tacticalrmm/local_settings.py
|
||||||
|
|
||||||
|
systemctl stop meshcentral
|
||||||
|
sleep 1
|
||||||
|
cd /meshcentral
|
||||||
|
|
||||||
|
sudo -u ${RMMUSER} node node_modules/meshcentral --createaccount ${meshusername} --pass ${MESHPASSWD} --email ${adminemail}
|
||||||
|
sleep 1
|
||||||
|
sudo -u ${RMMUSER} node node_modules/meshcentral --adminaccount ${meshusername}
|
||||||
|
|
||||||
|
systemctl start meshcentral
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
|
||||||
|
sudo -u ${RMMUSER} node node_modules/meshcentral/meshctrl.js --url wss://${meshdomain}:443 --loginuser ${meshusername} --loginpass ${MESHPASSWD} AddDeviceGroup --name TacticalRMM
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
systemctl enable nats.service
|
||||||
|
su - ${RMMUSER} <<EOF
|
||||||
|
cd /rmm/api/tacticalrmm
|
||||||
|
source /rmm/api/env/bin/activate
|
||||||
|
python manage.py initial_db_setup
|
||||||
|
python manage.py reload_nats
|
||||||
|
deactivate
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl start nats.service
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
systemctl enable nats-api.service
|
||||||
|
systemctl start nats-api.service
|
||||||
|
|
||||||
|
## disable django admin
|
||||||
|
sudo -u ${RMMUSER} sed -i 's/ADMIN_ENABLED = True/ADMIN_ENABLED = False/g' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py
|
||||||
|
|
||||||
|
echo 'Restarting services'
|
||||||
|
for i in rmm.service daphne.service celery.service celerybeat.service
|
||||||
|
do
|
||||||
|
systemctl stop ${i}
|
||||||
|
systemctl start ${i}
|
||||||
|
done
|
||||||
|
|
||||||
|
cat << EOF > /usr/local/bin/register-rmm-admin
|
||||||
|
cd /rmm/api
|
||||||
|
source /rmm/api/env/bin/activate
|
||||||
|
cd /rmm/api/tacticalrmm
|
||||||
|
printf >&2 "Please create your login for the RMM website and django admin\n"
|
||||||
|
printf >&2 "\n"
|
||||||
|
echo -ne "Username: "
|
||||||
|
read djangousername
|
||||||
|
python manage.py createsuperuser --username \${djangousername} --email ${adminemail}
|
||||||
|
RANDBASE=\$(python manage.py generate_totp)
|
||||||
|
python manage.py generate_barcode \${RANDBASE} \${djangousername} ${frontenddomain}
|
||||||
|
deactivate
|
||||||
|
EOF
|
||||||
|
chmod +x /usr/local/bin/register-rmm-admin
|
||||||
|
|
||||||
|
printf >&2 "Installation complete!\n\n"
|
||||||
|
printf >&2 "Access your rmm at: https://${frontenddomain}\n\n"
|
||||||
|
printf >&2 "Django admin url (disabled by default): https://${rmmdomain}/${ADMINURL}/\n\n"
|
||||||
|
printf >&2 "MeshCentral username: ${meshusername}\n"
|
||||||
|
printf >&2 "MeshCentral password: ${MESHPASSWD}\n\n"
|
||||||
|
|
||||||
|
printf >&2 "Please run 'register-rmm-admin' to create an administrative rmm user.\n\n"
|
Loading…
Reference in New Issue
Block a user