From 72fb7425790f2e1997967a0fda01cb8286ec81de Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 12:31:29 -0500 Subject: [PATCH 001/203] Create config.json --- default-configs/mesh/config.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 default-configs/mesh/config.json diff --git a/default-configs/mesh/config.json b/default-configs/mesh/config.json new file mode 100644 index 0000000000..48cdce8528 --- /dev/null +++ b/default-configs/mesh/config.json @@ -0,0 +1 @@ +placeholder From a7f79a2b8bea8f737d71319ee9d12f30ee1f22ef Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 12:33:43 -0500 Subject: [PATCH 002/203] Change URLs to defaults for editing during install --- default-configs/mesh/config.json | 35 +++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/default-configs/mesh/config.json b/default-configs/mesh/config.json index 48cdce8528..52ae3097f2 100644 --- a/default-configs/mesh/config.json +++ b/default-configs/mesh/config.json @@ -1 +1,34 @@ -placeholder +{ + "settings": { + "Cert": "mesh.example.com", + "MongoDb": "mongodb://127.0.0.1:27017", + "MongoDbName": "meshcentral", + "WANonly": true, + "Minify": 1, + "Port": 4443, + "AgentAliasPort": 443, + "AliasPort": 443, + "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://mesh.example.com/", + "GeoLocation": true, + "CookieIpCheck": false, + "mstsc": true + } + } +} From ab02d877dda22fa6fd1aac715fa4c8ff19cf93f6 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 12:39:23 -0500 Subject: [PATCH 003/203] Update config.json --- default-configs/mesh/config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/default-configs/mesh/config.json b/default-configs/mesh/config.json index 52ae3097f2..15eaf705f8 100644 --- a/default-configs/mesh/config.json +++ b/default-configs/mesh/config.json @@ -1,6 +1,6 @@ { "settings": { - "Cert": "mesh.example.com", + "Cert": "meshdomain", "MongoDb": "mongodb://127.0.0.1:27017", "MongoDbName": "meshcentral", "WANonly": true, @@ -25,7 +25,7 @@ "Title": "Tactical RMM", "Title2": "Tactical RMM", "NewAccounts": false, - "CertUrl": "https://mesh.example.com/", + "CertUrl": "https://meshdomain/", "GeoLocation": true, "CookieIpCheck": false, "mstsc": true From 26462672a98e9c6c1a8c38aefeaabe4b666fc479 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 12:42:05 -0500 Subject: [PATCH 004/203] Create local_settings.py --- default-configs/python/local_settings.py | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 default-configs/python/local_settings.py diff --git a/default-configs/python/local_settings.py b/default-configs/python/local_settings.py new file mode 100644 index 0000000000..908a9faccb --- /dev/null +++ b/default-configs/python/local_settings.py @@ -0,0 +1,27 @@ +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 From 8799af46e9d9c37d25a83123bf5a71790b1c83dd Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 12:44:41 -0500 Subject: [PATCH 005/203] Create app.ini --- default-configs/uwsgi/app.ini | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 default-configs/uwsgi/app.ini diff --git a/default-configs/uwsgi/app.ini b/default-configs/uwsgi/app.ini new file mode 100644 index 0000000000..839ad00745 --- /dev/null +++ b/default-configs/uwsgi/app.ini @@ -0,0 +1,16 @@ +[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 From 84a39dd72f97c8c20b8cebabc801c0f941e70c53 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 12:50:33 -0500 Subject: [PATCH 006/203] Create rmm.service --- service-definitions/rmm.service | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 service-definitions/rmm.service diff --git a/service-definitions/rmm.service b/service-definitions/rmm.service new file mode 100644 index 0000000000..8967bc243a --- /dev/null +++ b/service-definitions/rmm.service @@ -0,0 +1,15 @@ +[Unit] +Description=tacticalrmm uwsgi daemon +After=network.target postgresql.service + +[Service] +User=REPLACEME +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 From f026940362390ac5bb7bedcabab77d10943f3300 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 12:51:42 -0500 Subject: [PATCH 007/203] Create daphne.service --- service-definitions/daphne.service | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 service-definitions/daphne.service diff --git a/service-definitions/daphne.service b/service-definitions/daphne.service new file mode 100644 index 0000000000..a1576ad889 --- /dev/null +++ b/service-definitions/daphne.service @@ -0,0 +1,15 @@ +[Unit] +Description=django channels daemon +After=network.target + +[Service] +User=REPLACEME +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 From 6b9b081350352dfbc176424b18768e5c62e05bed Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 12:53:04 -0500 Subject: [PATCH 008/203] Create nats.service --- service-definitions/nats.service | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 service-definitions/nats.service diff --git a/service-definitions/nats.service b/service-definitions/nats.service new file mode 100644 index 0000000000..bb85259f44 --- /dev/null +++ b/service-definitions/nats.service @@ -0,0 +1,18 @@ +[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=REPLACEME +Group=www-data +Restart=always +RestartSec=5s +LimitNOFILE=1000000 + +[Install] +WantedBy=multi-user.target From d0f932cc79014c4997f670bbbac940ec1d4a44e3 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 12:54:17 -0500 Subject: [PATCH 009/203] Create nats-api.service --- service-definitions/nats-api.service | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 service-definitions/nats-api.service diff --git a/service-definitions/nats-api.service b/service-definitions/nats-api.service new file mode 100644 index 0000000000..90e26f8ec2 --- /dev/null +++ b/service-definitions/nats-api.service @@ -0,0 +1,14 @@ +[Unit] +Description=TacticalRMM Nats Api v1 +After=nats.service + +[Service] +Type=simple +ExecStart=/usr/local/bin/nats-api +User=REPLACEME +Group=REPLACEME +Restart=always +RestartSec=5s + +[Install] +WantedBy=multi-user.target From 52867db790fb47eafa90fb9b7386c879d2bb75ed Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 13:02:53 -0500 Subject: [PATCH 010/203] Create celery.service --- service-definitions/celery.service | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 service-definitions/celery.service diff --git a/service-definitions/celery.service b/service-definitions/celery.service new file mode 100644 index 0000000000..6bd94eacf2 --- /dev/null +++ b/service-definitions/celery.service @@ -0,0 +1,18 @@ +[Unit] +Description=Celery Service V2 +After=network.target redis-server.service postgresql.service + +[Service] +Type=forking +User=REPLACEME +Group=REPLACEME +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 From 4183be2588387616d3bd091a6f8533f99da2d0c8 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 13:04:04 -0500 Subject: [PATCH 011/203] Create celery.conf --- default-configs/celery/celery.conf | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 default-configs/celery/celery.conf diff --git a/default-configs/celery/celery.conf b/default-configs/celery/celery.conf new file mode 100644 index 0000000000..92cb5e1486 --- /dev/null +++ b/default-configs/celery/celery.conf @@ -0,0 +1,16 @@ +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" From d5646579eafe60f63b75a0ddcecf79270db2e8f3 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 13:05:23 -0500 Subject: [PATCH 012/203] Create meshcentral.conf --- default-configs/nginx/meshcentral.conf | 39 ++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 default-configs/nginx/meshcentral.conf diff --git a/default-configs/nginx/meshcentral.conf b/default-configs/nginx/meshcentral.conf new file mode 100644 index 0000000000..1cadf5b94f --- /dev/null +++ b/default-configs/nginx/meshcentral.conf @@ -0,0 +1,39 @@ +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 ${CERT_PUB_KEY}; + ssl_certificate_key ${CERT_PRIV_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:4443/; + 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; + } +} From 3c15fe87dd4026b57fdb3f7ceef6e24fe8646b0d Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 13:06:35 -0500 Subject: [PATCH 013/203] Create rmm.conf --- default-configs/nginx/rmm.conf | 68 ++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 default-configs/nginx/rmm.conf diff --git a/default-configs/nginx/rmm.conf b/default-configs/nginx/rmm.conf new file mode 100644 index 0000000000..7b036a2b70 --- /dev/null +++ b/default-configs/nginx/rmm.conf @@ -0,0 +1,68 @@ +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 ${CERT_PUB_KEY}; + ssl_certificate_key ${CERT_PRIV_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 ~ ^/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 300s; + uwsgi_ignore_client_abort on; + } +} From 678d089e15de5f43f39de40ac731921acb335e85 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 13:09:18 -0500 Subject: [PATCH 014/203] Create celerybeat.service --- service-definitions/celerybeat.service | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 service-definitions/celerybeat.service diff --git a/service-definitions/celerybeat.service b/service-definitions/celerybeat.service new file mode 100644 index 0000000000..d6cefee030 --- /dev/null +++ b/service-definitions/celerybeat.service @@ -0,0 +1,16 @@ +[Unit] +Description=Celery Beat Service V2 +After=network.target redis-server.service postgresql.service + +[Service] +Type=simple +User=REPLACEME +Group=REPLACEME +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 From 0ba355d755a57ee9b63bda401d6c1f26f1d9825d Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 13:10:17 -0500 Subject: [PATCH 015/203] Create meshcentral.service --- service-definitions/meshcentral.service | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 service-definitions/meshcentral.service diff --git a/service-definitions/meshcentral.service b/service-definitions/meshcentral.service new file mode 100644 index 0000000000..bd5a528624 --- /dev/null +++ b/service-definitions/meshcentral.service @@ -0,0 +1,16 @@ +[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=REPLACEME +Group=REPLACEME +Restart=always +RestartSec=10s + +[Install] +WantedBy=multi-user.target From 0798a5a51246ed22f1f37ce4e669a3a6dc453a55 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 13:11:30 -0500 Subject: [PATCH 016/203] Create frontend.conf --- default-configs/nginx/frontend.conf | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 default-configs/nginx/frontend.conf diff --git a/default-configs/nginx/frontend.conf b/default-configs/nginx/frontend.conf new file mode 100644 index 0000000000..7b4bec28b4 --- /dev/null +++ b/default-configs/nginx/frontend.conf @@ -0,0 +1,36 @@ +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 ${CERT_PUB_KEY}; + ssl_certificate_key ${CERT_PRIV_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; +} From 5d27f6372e162ba581abd64aaaecd1d187b2c37f Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 14:20:34 -0500 Subject: [PATCH 017/203] Update frontend.conf --- default-configs/nginx/frontend.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/default-configs/nginx/frontend.conf b/default-configs/nginx/frontend.conf index 7b4bec28b4..0c0caa828b 100644 --- a/default-configs/nginx/frontend.conf +++ b/default-configs/nginx/frontend.conf @@ -1,5 +1,5 @@ server { - server_name ${frontenddomain}; + server_name rmm.example.com; charset utf-8; location / { root /var/www/rmm/dist; @@ -25,12 +25,12 @@ server { } server { - if (\$host = ${frontenddomain}) { + if (\$host = rmm.example.com) { return 301 https://\$host\$request_uri; } listen 80; listen [::]:80; - server_name ${frontenddomain}; + server_name rmm.example.com; return 404; } From be851c9b2e3ca1753cc809cfd72a8890fbc8869c Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 14:21:48 -0500 Subject: [PATCH 018/203] Update meshcentral.conf --- default-configs/nginx/meshcentral.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/default-configs/nginx/meshcentral.conf b/default-configs/nginx/meshcentral.conf index 1cadf5b94f..894108a2e7 100644 --- a/default-configs/nginx/meshcentral.conf +++ b/default-configs/nginx/meshcentral.conf @@ -1,7 +1,7 @@ server { listen 80; listen [::]:80; - server_name ${meshdomain}; + server_name mesh.example.com; return 301 https://\$server_name\$request_uri; } @@ -11,7 +11,7 @@ server { listen [::]:443 ssl; proxy_send_timeout 330s; proxy_read_timeout 330s; - server_name ${meshdomain}; + server_name mesh.example.com; ssl_certificate ${CERT_PUB_KEY}; ssl_certificate_key ${CERT_PRIV_KEY}; From edab4f791b0ccc6d371be35e11d3e105812da332 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 14:29:49 -0500 Subject: [PATCH 019/203] Update rmm.conf --- default-configs/nginx/rmm.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/default-configs/nginx/rmm.conf b/default-configs/nginx/rmm.conf index 7b036a2b70..9e90a41e56 100644 --- a/default-configs/nginx/rmm.conf +++ b/default-configs/nginx/rmm.conf @@ -13,14 +13,14 @@ map \$http_user_agent \$ignore_ua { server { listen 80; listen [::]:80; - server_name ${rmmdomain}; + server_name api.example.com; return 301 https://\$server_name\$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; - server_name ${rmmdomain}; + server_name api.example.com; 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; @@ -41,7 +41,7 @@ server { location /private/ { internal; - add_header "Access-Control-Allow-Origin" "https://${frontenddomain}"; + add_header "Access-Control-Allow-Origin" "https://rmm.example.com"; alias /rmm/api/tacticalrmm/tacticalrmm/private/; } From 621273c1c2a5e16907706db199943f0ea625e181 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 14:31:21 -0500 Subject: [PATCH 020/203] Update frontend.conf --- default-configs/nginx/frontend.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/default-configs/nginx/frontend.conf b/default-configs/nginx/frontend.conf index 0c0caa828b..c8a4fea73b 100644 --- a/default-configs/nginx/frontend.conf +++ b/default-configs/nginx/frontend.conf @@ -12,8 +12,8 @@ server { listen 443 ssl; listen [::]:443 ssl; - ssl_certificate ${CERT_PUB_KEY}; - ssl_certificate_key ${CERT_PRIV_KEY}; + ssl_certificate /etc/ssl/certs/fullchain.pem; + ssl_certificate_key /etc/ssl/private/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; From 3ff42423c54fd0cf21d322492ad79ea204dbba8c Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 14:31:44 -0500 Subject: [PATCH 021/203] Update meshcentral.conf --- default-configs/nginx/meshcentral.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/default-configs/nginx/meshcentral.conf b/default-configs/nginx/meshcentral.conf index 894108a2e7..242497dd36 100644 --- a/default-configs/nginx/meshcentral.conf +++ b/default-configs/nginx/meshcentral.conf @@ -12,8 +12,8 @@ server { proxy_send_timeout 330s; proxy_read_timeout 330s; server_name mesh.example.com; - ssl_certificate ${CERT_PUB_KEY}; - ssl_certificate_key ${CERT_PRIV_KEY}; + ssl_certificate /etc/ssl/certs/fullchain.pem; + ssl_certificate_key /etc/ssl/private/privkey.pem; ssl_session_cache shared:WEBSSL:10m; From fbd01646209061b2e4f734ca5b0ba01f36473f00 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 14:32:28 -0500 Subject: [PATCH 022/203] Update rmm.conf --- default-configs/nginx/rmm.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/default-configs/nginx/rmm.conf b/default-configs/nginx/rmm.conf index 9e90a41e56..5bead63cb0 100644 --- a/default-configs/nginx/rmm.conf +++ b/default-configs/nginx/rmm.conf @@ -24,8 +24,8 @@ server { 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 ${CERT_PUB_KEY}; - ssl_certificate_key ${CERT_PRIV_KEY}; + ssl_certificate /etc/ssl/certs/fullchain.pem; + ssl_certificate_key /etc/ssl/private/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; From 1f30e57db25b9a618329b035f4a4fd3bdd508e8b Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 14:33:46 -0500 Subject: [PATCH 023/203] Update config.json --- default-configs/mesh/config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/default-configs/mesh/config.json b/default-configs/mesh/config.json index 15eaf705f8..52ae3097f2 100644 --- a/default-configs/mesh/config.json +++ b/default-configs/mesh/config.json @@ -1,6 +1,6 @@ { "settings": { - "Cert": "meshdomain", + "Cert": "mesh.example.com", "MongoDb": "mongodb://127.0.0.1:27017", "MongoDbName": "meshcentral", "WANonly": true, @@ -25,7 +25,7 @@ "Title": "Tactical RMM", "Title2": "Tactical RMM", "NewAccounts": false, - "CertUrl": "https://meshdomain/", + "CertUrl": "https://mesh.example.com/", "GeoLocation": true, "CookieIpCheck": false, "mstsc": true From 84e941b72ae9ebe069a23b811b0d1c07b7b5c3f5 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 1 Jun 2022 14:36:12 -0500 Subject: [PATCH 024/203] Update local_settings.py --- default-configs/python/local_settings.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/default-configs/python/local_settings.py b/default-configs/python/local_settings.py index 908a9faccb..954b54a650 100644 --- a/default-configs/python/local_settings.py +++ b/default-configs/python/local_settings.py @@ -2,12 +2,12 @@ DEBUG = False -ALLOWED_HOSTS = ['rmmdomain'] +ALLOWED_HOSTS = ['api.example.com'] ADMIN_URL = "ADMINURL/" CORS_ORIGIN_WHITELIST = [ - "https://frontenddomain" + "https://rmm.example.com" ] DATABASES = { @@ -22,6 +22,6 @@ } MESH_USERNAME = "meshusername" -MESH_SITE = "https://meshdomain" +MESH_SITE = "https://mesh.example.com" REDIS_HOST = "localhost" ADMIN_ENABLED = True From 9a9789de2c4f269e6500f7b9f188fed561dd2cce Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 9 Jun 2022 20:27:29 -0500 Subject: [PATCH 025/203] Update app.ini --- default-configs/uwsgi/app.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/default-configs/uwsgi/app.ini b/default-configs/uwsgi/app.ini index 839ad00745..5875198cb7 100644 --- a/default-configs/uwsgi/app.ini +++ b/default-configs/uwsgi/app.ini @@ -3,8 +3,8 @@ chdir = /rmm/api/tacticalrmm module = tacticalrmm.wsgi home = /rmm/api/env master = true -processes = uwsgiprocs -threads = uwsgiprocs +processes = uwsgiprocs1 +threads = uwsgiprocs2 enable-threads = true socket = /rmm/api/tacticalrmm/tacticalrmm.sock harakiri = 300 From 9b99d9b56abe7f6f5b37662710a37a06909da6b8 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 17 Jun 2022 16:14:31 -0500 Subject: [PATCH 026/203] Update frontend.conf --- default-configs/nginx/frontend.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/default-configs/nginx/frontend.conf b/default-configs/nginx/frontend.conf index c8a4fea73b..e78019c660 100644 --- a/default-configs/nginx/frontend.conf +++ b/default-configs/nginx/frontend.conf @@ -17,10 +17,12 @@ server { ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; + ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_ciphers EECDH+AESGCM:EDH+AESGCM; ssl_ecdh_curve secp384r1; ssl_stapling on; ssl_stapling_verify on; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; add_header X-Content-Type-Options nosniff; } From d0a8a9f8a64b2a71ebc5f5938284d1b88a91439c Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 17 Jun 2022 16:15:23 -0500 Subject: [PATCH 027/203] Update meshcentral.conf --- default-configs/nginx/meshcentral.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/default-configs/nginx/meshcentral.conf b/default-configs/nginx/meshcentral.conf index 242497dd36..ecab990a40 100644 --- a/default-configs/nginx/meshcentral.conf +++ b/default-configs/nginx/meshcentral.conf @@ -19,10 +19,12 @@ server { ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; + ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_ciphers EECDH+AESGCM:EDH+AESGCM; ssl_ecdh_curve secp384r1; ssl_stapling on; ssl_stapling_verify on; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; add_header X-Content-Type-Options nosniff; location / { From d1fcd9bfb21fdb77286fd5c7e558a5e2fa01cf81 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 17 Jun 2022 16:16:21 -0500 Subject: [PATCH 028/203] Update rmm.conf --- default-configs/nginx/rmm.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/default-configs/nginx/rmm.conf b/default-configs/nginx/rmm.conf index 5bead63cb0..4ed94f8f1b 100644 --- a/default-configs/nginx/rmm.conf +++ b/default-configs/nginx/rmm.conf @@ -29,10 +29,12 @@ server { ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; + ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_ciphers EECDH+AESGCM:EDH+AESGCM; ssl_ecdh_curve secp384r1; ssl_stapling on; ssl_stapling_verify on; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; add_header X-Content-Type-Options nosniff; location /static/ { From 229fb5d5b7f204070370966c27a82583077da70b Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 17 Jun 2022 16:17:32 -0500 Subject: [PATCH 029/203] Update app.ini --- default-configs/uwsgi/app.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/default-configs/uwsgi/app.ini b/default-configs/uwsgi/app.ini index 5875198cb7..dd57eb10c8 100644 --- a/default-configs/uwsgi/app.ini +++ b/default-configs/uwsgi/app.ini @@ -3,8 +3,8 @@ chdir = /rmm/api/tacticalrmm module = tacticalrmm.wsgi home = /rmm/api/env master = true -processes = uwsgiprocs1 -threads = uwsgiprocs2 +processes = uwsgiprocs +threads = uwsgithreads enable-threads = true socket = /rmm/api/tacticalrmm/tacticalrmm.sock harakiri = 300 From 0327542250141e8eb6bde179f8afc0dd5a97679d Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 17 Jun 2022 16:22:53 -0500 Subject: [PATCH 030/203] Create bashfunctions.cfg --- bashfunctions.cfg | 2088 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2088 insertions(+) create mode 100644 bashfunctions.cfg diff --git a/bashfunctions.cfg b/bashfunctions.cfg new file mode 100644 index 0000000000..110aa8079e --- /dev/null +++ b/bashfunctions.cfg @@ -0,0 +1,2088 @@ +################### +# CFG file info # +################### + +CFG_VERSION="5" + + +######################## +# Input verification # +######################## + +errortrack=0 + +# Translate user input to all lower case to prevent ID10T errors +translateToLowerCase() +{ + local lowercase="" + lowercase="$(echo $1 | tr '[:upper:]' '[:lower:]')" + echo "$lowercase" +} + +# Function to track ID10T errors +derpDerp() +{ + if [ "$errortrack" -lt 12 ]; then + errortrack=$((errortrack+1)) + fi + + derptext="" + + case $errortrack in + 1 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "Need some coffee?" 10 30;; + 2 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You should get some coffee." 10 35;; + 3 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You are paying attention, right?" 10 40;; + 4 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "All your typos are belong to us." 10 40;; + 5 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "We're sorry, your fingers are too fat.\n\nIf you would like to obtain a typing wand,\nplease mash your hand on the keyboard now." 15 75;; + 6 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You have got to be kidding me...\n\nThis really isn't that difficult." 15 50;; + 7 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You're doing this intentionally, aren't you?\n\nThis really isn't that difficult." 15 75;; + 8 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "Please step away from the keyboard, and back away slowly.\n\nThe instructions are literally right there." 15 75;; + 9 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You're making me angry.\nYou wouldn't like me when I'm angry.\n\nThe instructions are literally right there." 15 75;; + 10 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "How did you even get to this point?!\n\nThe instructions are literally right there." 15 75;; + 11 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "Seriously, just give it up.\n\nI just can't with you right now..." 15 60;; + * ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "\*sigh\* Why are you still here?\n\nI just can't with you right now..." 15 60;; + esac + + return +} + +###################################################################################### +# Misc Functions, must be before any functions except input verification functions # +###################################################################################### + +# Set bash text colors +setColors() +{ + GREEN='\033[0;32m' + YELLOW='\033[1;33m' + BLUE='\033[0;34m' + RED='\033[0;31m' + NC='\033[0m' +} + +# Clear screen +cls() +{ + printf "\033c" +} + +# Purdy install text +print_green() +{ + printf >&2 "${GREEN}%0.s-${NC}" {1..80} + printf >&2 "\n" + printf >&2 "${GREEN}${1}${NC}\n" + printf >&2 "${GREEN}%0.s-${NC}" {1..80} + printf >&2 "\n" +} + +# Check for new script version +checkScriptVer() +{ + TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") + curl -s -L "$2" > ${TMP_FILE} + NEW_VER=$(grep "^SCRIPT_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') + + if [ "$1" -ne "${NEW_VER}" ]; then + wget -q "$2" -O "$3" + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 + rm -f $TMP_FILE + clear -x + exit 1 + fi + + rm -f $TMP_FILE +} + +# Check for functions updates +checkCfgVer() +{ + TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") + curl -s -L "$1" > "$TMP_FILE" + NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') + + if [ "$CFG_VERSION" -ne "$NEW_VER" ]; then + wget -q "$1" -O bashfunctions.cfg + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old bash function file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$2" 10 40 + rm -f $TMP_FILE + clear -x + exit 1 + fi + + rm -f $TMP_FILE +} + +# Check for root as user +checkRoot() +{ + if [ $EUID -eq 0 ]; then + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Do NOT run this script as root. Exiting." 0 0 + clear -x + exit 1 + fi +} + +# Clone primary repo +clonePrimaryRepo() +{ + if [ "$1" == "install" ]; then + sudo mkdir /rmm + sudo chown "${USER}:${USER}" /rmm + sudo mkdir -p /var/log/celery + sudo chown "${USER}:${USER}" /var/log/celery + git clone "$2" /rmm/ + fi + cd /rmm + git config user.email "admin@example.com" + git config user.name "Bob" + if [ "$1" == "install" ]; then + git checkout "$3" + elif [ "$1" == "update" ]; then + git fetch + git checkout "$3" + git reset --hard FETCH_HEAD + git clean -df + git pull + fi +} + +# Clone scripts repo +cloneScriptsRepo() +{ + if [ ! -d "${SCRIPTS_DIR}" ]; then + sudo mkdir -p "${SCRIPTS_DIR}" + sudo chown "${USER}:${USER}" "${SCRIPTS_DIR}" + git clone "$2" "${SCRIPTS_DIR}"/ + fi + cd "${SCRIPTS_DIR}" + git config user.email "admin@example.com" + git config user.name "Bob" + if [ "$1" == "install" ]; then + git checkout main + elif [ "$1" == "update" ]; then + git fetch + git checkout main + git reset --hard FETCH_HEAD + git clean -df + git pull + fi +} + +# Set primary repos to use +decideMainRepos() +{ + userconfirm="n" + local own="" + local bran="" + + until [ "$userconfirm" == "y" ]; do + own=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository" --inputbox "Enter the dev repo owner name.\nThis is right after github.com in the URL:" 10 90 3>&1 1>&2 2>&3) + own="$(translateToLowerCase $own)" + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository" --yesno "Is this correct?\n$own" 0 0 + case $? in + 0 ) userconfirm="y" + clear -x;; + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + REPO_OWNER="$own" + + until [ "$userconfirm" == "y" ]; do + bran=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository Branch" --inputbox "Enter the dev repo branch name.\nThis is right after tacticalrmm in the URL:" 10 90 3>&1 1>&2 2>&3) + bran="$(translateToLowerCase $bran)" + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository Branch" --yesno "Is this correct?\n$bran" 0 0 + case $? in + 0 ) userconfirm="y" + clear -x;; + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + BRANCH="$bran" + + ### Check for new functions version, only include script name as variable + checkCfgVer "$CFG_URL" "$THIS_SCRIPT"; + ### Check for new script version, pass script version, url, and script name variables in that order + checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; +} + + +########################### +# System info functions # +########################### + +# Gather OS info +getOSInfo() +{ + osname=$(lsb_release -si); osname=${osname^} + osname=$(echo "$osname" | tr '[A-Z]' '[a-z]') + fullrel=$(lsb_release -sd) + codename=$(lsb_release -sc) + relno=$(lsb_release -sr | cut -d. -f1) + fullrelno=$(lsb_release -sr) +} + +# Check OS if not recognised +wutOSThis() +{ + if [ ! "$osname" = "ubuntu" ] && [ ! "$osname" = "debian" ]; then + osname=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"') + osname=${osname^} + fi +} + +# Verify Debian or Ubuntu and version +verifySupportedOS() +{ + if ([ "$osname" = "ubuntu" ] && ([ "$fullrelno" = "20.04" ] || [ "$fullrelno" = "22.04" ])) || ([ "$osname" = "debian" ] && [ $relno -ge 10 ]); then + echo "$fullrel" + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 + clear -x + exit 1 + fi +} + +# Check language/locale +checkLocale() +{ + if [[ "$LANG" != *".UTF-8" ]]; then + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "System locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting." 0 0 + clear -x + exit 1 + fi +} + + +################ +# User Input # +################ + +# Create usernames and passwords +generateUsersAndPass() +{ + DJANGO_SEKRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1) + ADMINURL=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 70 | head -n 1) + + dialog --cr-wrap --clear --yes-label "Automatic" --no-label "Manual" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "User and Password Generation" --yesno "Would you like to have usernames and passwords automatically randomly generated, or enter your own manually?" 0 0 + case $? in + 0 ) 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) + clear -x;; + + 1 ) userconfirm="n" + + ### Get MeshCentral admin username + until [ "$userconfirm" == "y" ]; do + meshusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --inputbox "Enter the MeshCentral Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --yesno "Is this correct?\n$meshusername" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + + ### Get MeshCentral admin password + MESHPASSWD="dont" + passinput="match" + until [ "$passinput" == "$MESHPASSWD" ]; do + MESHPASSWD=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Re-enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + if [ "$passinput" != "$MESHPASSWD" ]; then + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 + derpDerp; + else + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 + fi + done + + ### Get Postgresql admin username + until [ "$userconfirm" == "y" ]; do + pgusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --inputbox "Enter the Postgresql Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --yesno "Is this correct?\n$pgusername" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + + ### Get Postgresql admin password + pgpw="dont" + passinput="match" + until [ "$passinput" == "$pgpw" ]; do + pgpw=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Re-enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + if [ "$passinput" != "$pgpw" ]; then + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 + derpDerp; + else + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 + fi + done + clear -x;; + esac +} + +# Get host and domain info +getHostAndDomainInfo() +{ + hostsconfirm="n" + + until [ $hostsconfirm == "y" ]; do + rootdomain="none" + letsemail="none" + + ### Get root domain + while [[ $rootdomain != *[.]* ]]; do + rootdomain=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Root Domain" --inputbox "Enter the root domain (eg example.com or example.co.uk):" 10 90 3>&1 1>&2 2>&3) + rootdomain="$(translateToLowerCase $rootdomain)" + if [[ $rootdomain != *[.]* ]]; then + derpDerp; + fi + done + + ### Get backend hostname + rmmhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Backend Hostname" --inputbox "Enter the hostname for the backend (e.g. api):" 10 90 3>&1 1>&2 2>&3) + rmmhost="$(translateToLowerCase $rmmhost)" + + ### Get frontend hostname + frontendhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Frontend Hostname" --inputbox "Enter the hostname for the frontend (e.g. rmm):" 10 90 3>&1 1>&2 2>&3) + frontendhost="$(translateToLowerCase $frontendhost)" + + ### Get MeshCentral hostname + meshhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter MeshCentral Hostname" --inputbox "Enter the hostname for MeshCentral (e.g. mesh):" 10 90 3>&1 1>&2 2>&3) + meshhost="$(translateToLowerCase $meshhost)" + + ### Get Admin email + while [[ $letsemail != *[@]*[.]* ]]; do + letsemail=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Admin E-Mail Address" --inputbox "Enter a valid e-mail address for Django, MeshCentral, and LetsEncrypt:" 10 90 3>&1 1>&2 2>&3) + letsemail="$(translateToLowerCase $letsemail)" + if [[ $letsemail != *[@]*[.]* ]]; then + derpDerp; + fi + done + + ### Verify input + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Confirm Input" --yesno "Is this correct?\n\nroot domain: $rootdomain\nbackend: $rmmhost.$rootdomain\nfrontend: $frontendhost.$rootdomain\nmeshcentral: $meshhost.$rootdomain\ne-mail address: $letsemail" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + clear -x + + ### Combine host/domain entries for later use while keeping seperate entries as well + rmmdomain="$rmmhost.$rootdomain" + meshdomain="$meshhost.$rootdomain" + frontenddomain="$frontendhost.$rootdomain" +} + + +####################### +# Network Functions # +####################### + +# Function to set site hostnames +setSiteHostname() +{ + local textcomp="0" + local runtimes=0 + local line1="" + local line2="" + until [ "$textcomp" == "" ]; do + runtimes=$(($runtimes+1)) + + # determine line number of localhost entry (this should always be the first entry) + line1=$(sed -n "/127.0.0.1/=" /etc/hosts) + + # determine next cumulative line number + line2=$(($line1+$runtimes)) + + # read total lines after localhost + textcomp=$(sed -n "$line2"p /etc/hosts) + + if [ "$textcomp" == "" ]; then + sudo sed -i "${runtimes} a\127.0.1.1\t$1.$2 $1" /etc/hosts + fi + done + + return +} + +# Check hosts file, add hosts +configHosts() +{ + # 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 + CHECK_LOCALHOST=$(grep "127.0.0.1 localhost" /etc/hosts) + if ! [ $CHECK_LOCALHOST ]; then + print_green 'Adding localhost to hosts file' + sudo sed -i '1i 127.0.0.1 localhost' /etc/hosts + fi + + CHECK_HOSTS=$(grep "127.0.1.1 $rmmdomain $frontenddomain $meshdomain" /etc/hosts) + if [[ $CHECK_HOSTS ]]; then + print_green 'Correcting subdomains entries' + sudo sed -i "/127.0.1.1 $rmmdomain $frontenddomain $meshdomain/d" /etc/hosts + setSiteHostname "$rmmhost" "$rootdomain"; + setSiteHostname "$frontendhost" "$rootdomain"; + setSiteHostname "$meshhost" "$rootdomain"; + else + setSiteHostname "$rmmhost" "$rootdomain"; + setSiteHostname "$frontendhost" "$rootdomain"; + setSiteHostname "$meshhost" "$rootdomain"; + fi + + BEHIND_NAT=false + IPV4=$(ip -4 addr | sed -ne 's|^.* inet \([^/]*\)/.* scope global.*$|\1|p' | head -1) + if echo "$IPV4" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then + BEHIND_NAT=true + fi +} + + +####################### +# Install Functions # +####################### + +# Install script prereqs +installPreReqs() +{ + sudo apt update && sudo apt install -y curl wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev +} + +# Install remaining prereqs +installAdditionalPreReqs() +{ + sudo apt install -y software-properties-common openssl ca-certificates apt-transport-https gcc g++ make build-essential zlib1g-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev git +} + +# Configure repos for stuff +setInstallRepos() +{ + # There is no Jammy repo yet so use Focal for Ubuntu 22.04 + if ([ "$osname" = "ubuntu" ] && [ "$fullrelno" = "20.04" ]); then + mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" + elif ([ "$osname" = "ubuntu" ] && [ "$fullrelno" = "22.04" ]); then + codename="focal" + 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 10 ]); then + mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 main" + else + codename="buster" + 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" +} + +# Install MongoDB +installMongo() +{ + wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/mongo.gpg > /dev/null + 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 + sleep 5 +} + +# Install NodeJS +installNodeJS() +{ + if [ "$1" == "update" ]; then + 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 + fi + fi + 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 + if [ "$1" == "update" ]; then + sudo chown "${USER}:${USER}" -R /meshcentral + cd /meshcentral + rm -rf node_modules/ + npm install meshcentral@${LATEST_MESH_VER} + sudo systemctl start meshcentral + fi +} + +# Install Redis +installRedis() +{ + sudo apt install -y redis +} + +# Install Python +installPython() +{ + if [ "$1" == "update" ]; then + HAS_PY310=$(python3.10 --version | grep ${PYTHON_VER}) + if ! [ $HAS_PY310 ]; then + printf >&2 "${GREEN}Updating to ${PYTHON_VER}${NC}\n" + fi + fi + + if [ "$INSTALL_TYPE" == "devinstall" ]; then + echo -e "${GREEN}Python already installed${NC}" + else + numprocs=$(nproc) + 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 $numprocs + sudo make altinstall + cd ~ + sudo rm -rf Python-${PYTHON_VER} Python-${PYTHON_VER}.tgz + if [ "$INSTALL_TYPE" == "devprep" ]; then + print_green 'All Prereqs installed' + exit + fi + fi +} + +# Install Postgresql +installPostgresql() +{ + echo "$postgresql_repo" | sudo tee /etc/apt/sources.list.d/pgdg.list + wget -qO - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/postgresql.gpg > /dev/null + sudo apt update && sudo apt install -y postgresql-14 + sleep 2 + sudo systemctl enable postgresql + sudo systemctl restart postgresql + sleep 5 +} + +# Install NATS +installNats() +{ + if [ "$1" == "update" ]; then + 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" + fi + fi + if [ "$1" == "install" ]; then + NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') + fi + nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) + wget -q 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} + if [ "$1" == "update" ]; then + sudo rm -f /usr/local/bin/nats-server + fi + 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 + rm -rf ${nats_tmp} +} + +# Install frontend +installFrontEnd() +{ + if [ "$1" == "update" ]; then + if [ -d /rmm/web ]; then + rm -rf /rmm/web + fi + + if [ ! -d /var/www/rmm ]; then + sudo mkdir -p /var/www/rmm + fi + fi + + webtar="trmm-web-v${WEB_VERSION}.tar.gz" + wget -q "$2" -O /tmp/${webtar} + + if [ "$1" == "update" ]; then + sudo rm -rf /var/www/rmm/dist + else + sudo mkdir -p /var/www/rmm + fi + sudo tar -xzf /tmp/${webtar} -C /var/www/rmm + echo "window._env_ = {PROD_URL: \"https://${rmmdomain}\"}" | sudo tee /var/www/rmm/dist/env-config.js > /dev/null + sudo chown www-data:www-data -R /var/www/rmm/dist + rm -f /tmp/${webtar} +} + +# Install Nginx +installNginx() +{ + if [ "$1" == "install" ]; then + sudo apt install -y nginx + sudo systemctl stop nginx + sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf + sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf + elif [ "$1" == "updatepart1" ]; then + ### Check Nginx config + if ! sudo nginx -t > /dev/null 2>&1; then + sudo nginx -t + echo -ne "\n" + echo -ne "${RED}You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script.${NC}\n" + echo -ne "${RED}Aborting...${NC}\n" + exit 1 + fi + elif [ "$1" == "updatepart2" ]; then + CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" /etc/nginx/nginx.conf) + if ! [ $CHECK_NGINX_WORKER_CONN ]; then + printf >&2 "${GREEN}Changing nginx worker connections to 2048${NC}\n" + sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf + fi + sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf + else + return + fi +} + +# Install NATS Api +installNatsApi() +{ + 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 +} + +# Install MeshCentral +installMeshCentral() +{ + MESH_VER=$(grep "^MESH_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') + + if [ "$1" == "install" ]; then + sudo mkdir -p /meshcentral/meshcentral-data + elif [ "$1" == "restore" ]; then + sudo tar -xzf $tmp_dir/meshcentral/mesh.tar.gz -C / + fi + sudo chown "${USER}:${USER}" -R /meshcentral + cd /meshcentral + npm install meshcentral@${MESH_VER} + sudo chown "${USER}:${USER}" -R /meshcentral +} + +# Install fail2ban +installFail2ban() +{ + sudo apt install -y fail2ban + + ### Copy default jail config to create override config + sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local + sudo truncate -s 0 /etc/fail2ban/jail.local + + ### Write default jail config override + sudo chmod 777 /etc/fail2ban/jail.local + sudo printf '[DEFAULT]' >> /etc/fail2ban/jail.local + sudo printf "\nignoreip = 127.0.0.1/8" >> /etc/fail2ban/jail.local + sudo printf "\n\n" >> /etc/fail2ban/jail.local + sudo printf '[sshd]' >> /etc/fail2ban/jail.local + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local + sudo printf "\nport = ssh" >> /etc/fail2ban/jail.local + sudo printf "\n\n" >> /etc/fail2ban/jail.local + sudo printf '[nginx-http-auth]' >> /etc/fail2ban/jail.local + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local + sudo printf "\n\n" >> /etc/fail2ban/jail.local + sudo printf '[nginx-botsearch]' >> /etc/fail2ban/jail.local + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local + sudo printf "\n\n" >> /etc/fail2ban/jail.local + sudo printf '[tacticalrmm]' >> /etc/fail2ban/jail.local + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local + sudo printf "\nport = http,https" >> /etc/fail2ban/jail.local + sudo printf "\nfilter = tacticalrmm" >> /etc/fail2ban/jail.local + sudo printf "\n" >> /etc/fail2ban/jail.local + sudo printf 'action = iptables-allports[name=tactical]' >> /etc/fail2ban/jail.local + sudo printf "\n" >> /etc/fail2ban/jail.local + sudo printf 'logpath = /rmm/api/tacticalrmm/tacticalrmm/private/log/access.log' >> /etc/fail2ban/jail.local + sudo printf "\nmaxretry = 5" >> /etc/fail2ban/jail.local + sudo printf "\nbantime = 3600" >> /etc/fail2ban/jail.local + sudo printf "\nfindtime = 3600" >> /etc/fail2ban/jail.local + sudo printf "\n\n" >> /etc/fail2ban/jail.local + sudo printf '[recidive]' >> /etc/fail2ban/jail.local + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local + sudo printf "\nbantime = 31536000 ; 1 year" >> /etc/fail2ban/jail.local + sudo chmod 644 /etc/fail2ban/jail.local + + ### Copy default app config to create override config + sudo cp /etc/fail2ban/fail2ban.conf /etc/fail2ban/fail2ban.local + sudo truncate -s 0 /etc/fail2ban/fail2ban.local + + ### Write default app config override + sudo chmod 777 /etc/fail2ban/fail2ban.local + sudo printf '[Definition]' >> /etc/fail2ban/fail2ban.local + sudo printf "\ndbpurgeage = 31579200" >> /etc/fail2ban/fail2ban.local + sudo printf "\nloglevel = INFO" >> /etc/fail2ban/fail2ban.local + sudo chmod 644 /etc/fail2ban/fail2ban.local + + ### Add T-RMM definition + sudo echo '[Definition]' | sudo tee /etc/fail2ban/filter.d/tacticalrmm.conf + sudo chmod 777 /etc/fail2ban/filter.d/tacticalrmm.conf + sudo printf "\n" >> /etc/fail2ban/filter.d/tacticalrmm.conf + sudo printf 'failregex = ^.*400.17.*$' >> /etc/fail2ban/filter.d/tacticalrmm.conf + sudo printf "\n" >> /etc/fail2ban/filter.d/tacticalrmm.conf + sudo printf 'ignoreregex = ^.*200.*$' >> /etc/fail2ban/filter.d/tacticalrmm.conf + sudo chmod 644 /etc/fail2ban/filter.d/tacticalrmm.conf + + ### Restart Fail2ban + sudo systemctl restart fail2ban +} + + +######################## +# Database Functions # +######################## + +# Postgres DB creation +createPGDB() +{ + 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}" +} + + +########################### +# Certificate Functions # +########################### + +# Renew Certs +renewCerts() +{ + rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + local temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" + local tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" + rootdomain="$temprootdomain.$tempdotsomething" + generateCerts; + sudo systemctl restart nginx.service rmm.service celery celerybeat.service nats-api.service nats.service meshcentral.service +} + +# Import certs +importCerts() +{ + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate and your private key, in that order.\n\nTo paste the contents, type i , then right click in the window.\n\nAfter pasting the contents, type esc , then shift-: , then x , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 + sudo vim /etc/ssl/certs/fullchain.pem + sudo vim /etc/ssl/private/privkey.pem +} + +# Generate certs +generateCerts() +{ + print_green 'Getting wildcard cert' + + ### Get initial DNS text entry + sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email + + ### Keep going until successful cert issue after adding DNS txt entry + while [[ $? -ne 0 ]]; do + sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email + done +} + +# Install Certbot and get initial certs +installCertbot() +{ + ### Install Certbot + sudo apt install -y certbot + if [ "$1" == "restore" ]; then + return + fi + + if [ "$INSTALL_TYPE" == "devinstall" ]; then + echo -e "${GREEN}Certificates should be in place${NC}" + else + dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have wildcard certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 + case $? in + ### Get wildcard cert via LetsEncrypt + 0 ) generateCerts;; + + 1 ) importCerts;; + esac + fi + + ### Set symlinks to avoid security concerns and simplify Nginx config + sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem + sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem + + ### Generate DH + if [ ! -f /etc/ssl/certs/dhparam.pem ]; then + sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096 + else + return + fi +} + + +####################################### +# Config file and service functions # +####################################### + +# Generate mesh configuration +createMeshConfig() +{ + sudo cp /rmm/default-configs/mesh/config.json /meshcentral/meshcentral-data/config.json + + sudo sed -i "s/mesh.example.com/$meshdomain/" /meshcentral/meshcentral-data/config.json +} + +# Generate local settings file +createLocalSettings() +{ + sudo cp /rmm/default-configs/python/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + + sudo sed -i "s/DJANGO_SEKRET/$DJANGO_SEKRET/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/api.example.com/$rmmdomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/ADMINURL/$ADMINURL/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/rmm.example.com/$frontenddomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/pgusername/$pgusername/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/pgpw/$pgpw/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/meshusername/$meshusername/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/mesh.example.com/$meshdomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py +} + +# Backend configuration +configureBackend() +{ + SETUPTOOLS_VER=$(grep "^SETUPTOOLS_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') + WHEEL_VER=$(grep "^WHEEL_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') + userconfirm="n" + + if [ "$1" == "update" ]; then + CHECK_ADMIN_ENABLED=$(grep ADMIN_ENABLED /rmm/api/tacticalrmm/tacticalrmm/local_settings.py) + if ! [ $CHECK_ADMIN_ENABLED ]; then + sudo sed -i '$ a ADMIN_ENABLED = False' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + 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 [ "${CURRENT_PIP_VER}" != "${LATEST_PIP_VER}" ] || [ "$UPDATE_TYPE" == "forced" ]; then + rm -rf /rmm/api/env + fi + fi + + if [ "${CURRENT_PIP_VER}" == "${LATEST_PIP_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then + source /rmm/api/env/bin/activate + cd /rmm/api/tacticalrmm + pip install -r /rmm/api/tacticalrmm/requirements.txt + else + cd /rmm/api + 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 + fi + + if [ "$1" == "update" ]; then + python manage.py pre_update_tasks + celery -A tacticalrmm purge -f + python manage.py migrate + python manage.py delete_tokens + python manage.py collectstatic --no-input + python manage.py reload_nats + python manage.py load_chocos + python manage.py create_installer_user + python manage.py create_natsapi_conf + python manage.py post_update_tasks + rmmdomain=$(python manage.py get_config api) + WEB_VERSION=$(python manage.py get_config webversion) + deactivate + elif [ "$1" == "restore" ]; then + python manage.py migrate + python manage.py collectstatic --no-input + python manage.py create_natsapi_conf + python manage.py reload_nats + python manage.py post_update_tasks + rmmdomain=$(python manage.py get_config api) + WEB_VERSION=$(python manage.py get_config webversion) + deactivate + else + 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 + WEB_VERSION=$(python manage.py get_config webversion) + until [ "$userconfirm" == "y" ]; do + djangousername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Create Site/Django Admin Login" --inputbox "Please enter the RMM website and django admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Create Site/Django Admin Login" --yesno "Is this correct?\n$djangousername" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + clear -x + python manage.py createsuperuser --username ${djangousername} --email ${letsemail} + python manage.py create_installer_user + RANDBASE=$(python manage.py generate_totp) + cls; + python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} + deactivate + read -n 1 -s -r -p "Press any key to continue..." + fi +} + +# Set uwsgi procs +setUwsgiProcs() +{ + uwsgiprocs=4 + uwsgithreads=4 + if [[ "$numprocs" == "1" ]]; then + uwsgiprocs=2 + uwsgithreads=2 + else + uwsgiprocs=$numprocs + uwsgithreads=$numprocs + fi +} + +# Create UWSGI config +createUwsgiConf() +{ + sudo cp /rmm/default-configs/uwsgi/app.ini /rmm/api/tacticalrmm/app.ini + + sudo sed -i "s/uwsgiprocs/$uwsgiprocs/" /rmm/api/tacticalrmm/app.ini + sudo sed -i "s/uwsgithreads/$uwsgithreads/" /rmm/api/tacticalrmm/app.ini +} + +# Create UWSGI service +createUwsgiService() +{ + sudo cp /rmm/service-definitions/rmm.service /etc/systemd/system/rmm.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/rmm.service +} + +# Create Daphne service +createDaphneService() +{ + sudo cp /rmm/service-definitions/daphne.service /etc/systemd/system/daphne.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/daphne.service +} + +# Create NATS service +createNatsService() +{ + sudo cp /rmm/service-definitions/nats.service /etc/systemd/system/nats.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats.service +} + +# Create NATS service +createNatsApiService() +{ + sudo cp /rmm/service-definitions/nats-api.service /etc/systemd/system/nats-api.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats-api.service +} + +# Create backend nginx conf +createBackendNginxConf() +{ + sudo cp /rmm/default-configs/nginx/rmm.conf /etc/nginx/sites-available/rmm.conf + + sudo sed -i "s/api.example.com/$rmmdomain/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/rmm.conf +} + +# Create Mesh nginx conf +createMeshNginxConf() +{ + sudo cp /rmm/default-configs/nginx/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf + + sudo sed -i "s/mesh.example.com/$meshdomain/" /etc/nginx/sites-available/meshcentral.conf +} + +# Create Celery service +createCeleryService() +{ + sudo cp /rmm/service-definitions/celery.service /etc/systemd/system/celery.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/celery.service +} + +# Create Celery config +createCeleryConf() +{ + sudo cp /rmm/default-configs/celery/celery.conf /etc/conf.d/celery.conf +} + +# Create CeleryBeat service +createCeleryBeatService() +{ + sudo cp /rmm/service-definitions/celerybeat.service /etc/systemd/system/celerybeat.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/celerybeat.service +} + +# Create MeshCentral service +createMeshCentralService() +{ + sudo cp /rmm/service-definitions/meshcentral.service /etc/systemd/system/meshcentral.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/meshcentral.service +} + +# Create Frontend Nginx config +createFrontendNginxConf() +{ + sudo cp /rmm/default-configs/nginx/frontend.conf /etc/nginx/sites-available/frontend.conf + + sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/frontend.conf +} + +# Enable MeshCentral service +enableMeshService() +{ + if [ "$1" != "update" ]; then + sudo systemctl enable meshcentral + fi + sudo systemctl restart meshcentral + sleep 3 + + # The first time we start meshcentral, it will need some time to generate certs and install plugins. + # This will take anywhere from a few seconds to a few minutes depending on the server's hardware + # We will know it's ready once the last line of the systemd service stdout is 'MeshCentral HTTP server running on port.....' + 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 + done +} + +# Generate Mesh Token +generateMeshToken() +{ + MESHTOKENKEY="$(node /meshcentral/node_modules/meshcentral --logintokenkey)" + + sudo sed -i '$ a MESH_TOKEN_KEY = "MESHTOKENKEY"' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/MESHTOKENKEY/$MESHTOKENKEY/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py +} + +# Configure Mesh user and group, restart service +configMeshUserGroup() +{ + sudo systemctl stop meshcentral + sleep 1 + cd /meshcentral + + node node_modules/meshcentral --createaccount ${meshusername} --pass ${MESHPASSWD} --email ${letsemail} + sleep 1 + node node_modules/meshcentral --adminaccount ${meshusername} + + sudo systemctl start meshcentral + 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 + done + + node node_modules/meshcentral/meshctrl.js --url wss://${meshdomain} --loginuser ${meshusername} --loginpass ${MESHPASSWD} AddDeviceGroup --name TacticalRMM + sleep 1 +} + +# Configure and enable NATS service +enableNatsService() +{ + sudo systemctl enable nats.service + cd /rmm/api/tacticalrmm + source /rmm/api/env/bin/activate + python manage.py initial_db_setup + python manage.py reload_nats + deactivate + sudo systemctl start nats.service + + sleep 1 + sudo systemctl enable nats-api.service + sudo systemctl start nats-api.service +} + +# Change UWSGI settings +changeUWSGIProcs() +{ + local countconfirm="n" + + ### Get UWSGI Processes value + until [ $countconfirm == "y" ]; do + uwsgiprocs=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Process Count" --inputbox "Enter the desired UWSGI Process Count, usually the same as CPU core count:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Process Count" --yesno "Is this correct?\n$uwsgiprocs" 0 0 + case $? in + 0 ) countconfirm="y";; + + 1 ) countconfirm="n" + derpDerp;; + esac + done + countconfirm="n" + + ### Get UWSGI Threads value + until [ $countconfirm == "y" ]; do + uwsgithreads=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Thread Count" --inputbox "Enter the desired UWSGI Process Count, usually the same as CPU core count:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Thread Count" --yesno "Is this correct?\n$uwsgithreads" 0 0 + case $? in + 0 ) countconfirm="y";; + + 1 ) countconfirm="n" + derpDerp;; + esac + done + countconfirm="n" + + ### Stop rmm service, copy default file, edit processes/threads, start service + sudo systemctl stop rmm + createUwsgiConf; + sudo systemctl start rmm +} + +########################################### +# Update and Restore specific functions # +########################################### + +# Check that user is same as during install +checkSameUser() +{ + strip="User=" + if [ "$1" == "update" ]; then + ORIGUSER=$(grep ${strip} /etc/systemd/system/rmm.service | sed -e "s/^${strip}//") + elif [ "$1" == "restore" ]; then + ORIGUSER=$(grep ${strip} $tmp_dir/systemd/rmm.service | sed -e "s/^${strip}//") + fi + if [ "$ORIGUSER" != "$USER" ]; then + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "You must run this update script from the same user account used during install: ${ORIGUSER}\n\nExiting." 0 0 + if [ "$1" == "restore" ]; then + rm -rf $tmp_dir + fi + clear -x + exit 1 + fi +} + +# Check if T-RMM update is necessary +checkIfUpdate() +{ + TMP_SETTINGS=$(mktemp -p "" "rmmsettings_XXXXXXXXXX") + curl -s -L "${LATEST_SETTINGS_URL}" > ${TMP_SETTINGS} + + LATEST_TRMM_VER=$(grep "^TRMM_VERSION" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') + CURRENT_TRMM_VER=$(grep "^TRMM_VERSION" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') + + if [ "${CURRENT_TRMM_VER}" == "${LATEST_TRMM_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then + printf >&2 "${GREEN}Already on latest version. Current version: ${CURRENT_TRMM_VER} Latest version: ${LATEST_TRMM_VER}${NC}\n" + rm -f $TMP_SETTINGS + exit 0 + fi +} + +# Get current versions of necessary included apps +checkAdditionalAppsVers() +{ + LATEST_MESH_VER=$(grep "^MESH_VER" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') + LATEST_PIP_VER=$(grep "^PIP_VER" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') + NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') + CURRENT_PIP_VER=$(grep "^PIP_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') +} + +# Check CHECK_NATS_LIMITNOFILE, whatever that means +checkNatsLimitNoFile() +{ + CHECK_NATS_LIMITNOFILE=$(grep LimitNOFILE /etc/systemd/system/nats.service) + if ! [ $CHECK_NATS_LIMITNOFILE ]; then + + sudo rm -f /etc/systemd/system/nats.service + createNatsService; + sudo systemctl daemon-reload + fi +} + +# Disable Redis append only +turnOffRedisAppendOnly() +{ + printf >&2 "${GREEN}Turning off redis aof${NC}\n" + sudo redis-cli config set appendonly no + sudo redis-cli config rewrite + sudo rm -f /var/lib/redis/appendonly.aof +} + +# Update MeshCentral +updateMeshCentral() +{ + 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" + sudo systemctl stop meshcentral + sudo chown "${USER}:${USER}" -R /meshcentral + cd /meshcentral + rm -rf node_modules/ + npm install meshcentral@${LATEST_MESH_VER} + sudo chown "${USER}:${USER}" -R /meshcentral + fi +} + +# Get backup location +getBackupFileLocation() +{ + backuppath="" + userconfirm="n" + + until [ "$userconfirm" == "y" ]; do + backuppath=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Path to Backup File" --inputbox "Enter the full path to the backup file, including filename:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Backup File Path" --yesno "Is this correct?\n$backuppath" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + if [ ! -f "$backuppath" ]; then + userconfirm="n" + derpDerp; + else + userconfirm="y" + fi + done + userconfirm="n" +} + +# Extract backup +extractBackup() +{ + print_green 'Unpacking backup' + tmp_dir=$(mktemp -d -t tacticalrmm-XXXXXXXXXXXXXXXXXXXXX) + + tar -xf ${1} -C $tmp_dir +} + + +############################### +# Troubleshooting functions # +############################### + +# Ping to test if domain is live +pingDomain() +{ + if ping -c 1 $1 &> /dev/null + then + echo -ne "${GREEN} Verified $1${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$1 doesnt exist please create it or check for a typo.\n\nYou will have a log file called checklog.log in the directory you ran this script from.\n\nExiting." 0 0 + clear -x + exit + fi +} + +# Check IPs +checkIPisLive() +{ + locinputip=`dig @"$locdns" +short $1` + reminputip=`dig @8.8.8.8 +short $1` + + if [ "$locinputip" = "$reminputip" ]; then + echo -ne "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + echo -ne "${RED} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log + printf >&2 "\n\n" | tee -a checklog.log + echo -ne "${RED} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + fi +} + +# Check services status +readServicesStatus() +{ + rmmstatus=$(systemctl is-active rmm) + daphnestatus=$(systemctl is-active daphne) + celerystatus=$(systemctl is-active celery) + celerybeatstatus=$(systemctl is-active celerybeat) + nginxstatus=$(systemctl is-active nginx) + natsstatus=$(systemctl is-active nats) + natsapistatus=$(systemctl is-active nats-api) + meshcentralstatus=$(systemctl is-active meshcentral) + mongodstatus=$(systemctl is-active mongod) + postgresqlstatus=$(systemctl is-active postgresql) + redisserverstatus=$(systemctl is-active redis-server) +} + +# Verify services active +checkIfServiceActive() +{ + if [ $1 = active ]; then + echo -ne "${GREEN} Success $2 is Running.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + printf >&2 "\n\n" | tee -a checklog.log + echo -ne "${RED} $2 is not running. \(Tactical will not work without this\)${NC}" | tee -a checklog.log + printf >&2 "\n\n" + fi +} + +# Check for open ports +isPortOpen() +{ + if ( nc -zv $wanip $1 2>&1 >/dev/null ); then + echo -ne "${GREEN} $2 Port is open.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + echo -ne "${RED} $2 port is closed. \(you may want this if running locally only\)${NC}" | tee -a checklog.log + printf >&2 "\n\n" + fi +} + +# Check proxy +checkProxy() +{ + echo -ne "${YELLOW} Checking For Proxy.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + echo -ne "${YELLOW} ......this might take a while!!${NC}" + 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.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + echo -ne "${YELLOW} Proxy detected using Certificate.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + fi + + # Detect Proxy via IP + if [ $wanip != $remrmmip ]; then + echo -ne "${YELLOW} Proxy detected using IP.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + echo -ne "${GREEN} No Proxy detected using IP.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + fi +} + +# Check for valid cert +checkIfCertIsValid() +{ + echo -ne "${YELLOW} Checking if SSL Certificate is up to date.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + + # SSL Certificate check + cert=$(openssl verify -CAfile /etc/letsencrypt/live/$rootdomain/chain.pem /etc/letsencrypt/live/$rootdomain/cert.pem) + + if [ "$cert" == *"OK"* ]; then + echo -ne "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + echo -ne "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + fi +} + + +###################### +# Parent Functions # +###################### + +# Main install function +mainInstall() +{ + ### Repo info for Postegres and Mongo + setInstallRepos; + + ### Create usernames and passwords + generateUsersAndPass; + + ### This does... something + cls; + + ### Get host/domain info + getHostAndDomainInfo; + + ### Configure hosts file + print_green 'Configuring Hosts file' + configHosts; + + ### Certificate generation + print_green 'Installing Certbot' + installCertbot; + + ### Install Nginx + print_green 'Installing Nginx' + installNginx; + + ### Install NodeJS + print_green 'Installing NodeJS' + installNodeJS; + + ### Install and enable MongoDB + print_green 'Installing MongoDB' + installMongo; + + ### Install Python + print_green "Installing Python ${PYTHON_VER}" + installPython; + + ### Installing Redis + print_green 'Installing redis' + installRedis; + + ### Install and enable Postgresql + print_green 'Installing postgresql' + installPostgresql; + + ### Postgres DB creation + print_green 'Creating database for the rmm' + createPGDB; + + ### Clone main repo + print_green 'Cloning primary repo' + clonePrimaryRepo "install" "$REPO_URL" "$BRANCH"; + + ### Clone scripts repo + print_green 'Cloning community scripts repo' + cloneScriptsRepo "install" "$SCRIPTS_REPO_URL"; + + ### Installing NATS + print_green 'Installing NATS' + installNats "$INSTALL_TYPE"; + + ### Install MeshCentral + print_green 'Installing MeshCentral' + installMeshCentral "install"; + + ### Create MeshCentral config + print_green 'Generating MeshCentral Config' + createMeshConfig; + + ### Create local settings file + print_green 'Generating Local Settings' + createLocalSettings; + + ### Install NATS-API and correct permissions + print_green 'Installing NATS API' + installNatsApi; + + ### Install backend, configure primary admin user, setup admin 2fa + print_green 'Installing the backend' + configureBackend "install"; + + ### Determine Proc setting for UWSGI + print_green 'Optimizing UWSGI for number of processors' + setUwsgiProcs; + + ### Create UWSGI config + print_green 'Creating UWSGI configuration' + createUwsgiConf; + + ### Create RMM UWSGI systemd service + print_green 'Creating UWSGI service' + createUwsgiService; + + ### Create Daphne systemd service + print_green 'Creating Daphne service' + createDaphneService; + + ### Create NATS systemd service + print_green 'Creating NATS service' + createNatsService; + + ### Create NATS-api systemd service + print_green 'Creating NATS-API service' + createNatsApiService; + + ### Create Backend Nginx site config + print_green 'Creating Backend Nginx config' + createBackendNginxConf; + + ### Create MeshCentral Nginx configuration + print_green 'Creating MeshCentral Nginx config' + createMeshNginxConf; + + ### Enable Mesh and RMM sites + sudo ln -s /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-enabled/rmm.conf + sudo ln -s /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-enabled/meshcentral.conf + + ### Create conf directory + sudo mkdir /etc/conf.d + + ### Create Celery systemd service + print_green 'Creating Celery service' + createCeleryService; + + ### Configure Celery service + print_green 'Creating Celery config' + createCeleryConf; + + ### Create CeleryBeat systemd service + print_green 'Creating CeleryBeat service' + createCeleryBeatService; + + ### Correct conf dir ownership + sudo chown "${USER}:${USER}" -R /etc/conf.d/ + + ### Create MeshCentral systemd service + print_green 'Creating MeshCentral service' + createMeshCentralService; + + ### Update services info + sudo systemctl daemon-reload + + ### Verify and correct permissions + if [ -d ~/.npm ]; then + sudo chown -R "${USER}:${GROUP}" ~/.npm + fi + + if [ -d ~/.config ]; then + sudo chown -R "${USER}:${GROUP}" ~/.config + fi + + ### Install frontend + print_green 'Installing the frontend' + installFrontEnd "install" "$FRONTEND_URL"; + + ### Set front end Nginx config and enable + print_green 'Creating Frontend Nginx config' + createFrontendNginxConf; + + ### Enable Frontend site + sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf + + ### Enable RMM, Daphne, Celery, and Nginx services + print_green 'Enabling Services' + + for i in rmm.service daphne.service celery.service celerybeat.service nginx + do + sudo systemctl enable ${i} + sudo systemctl stop ${i} + sudo systemctl start ${i} + done + sleep 5 + + ### Enable MeshCentral service + print_green 'Starting meshcentral and waiting for it to install plugins' + enableMeshService; + + ### Generating MeshCentral key + print_green 'Generating meshcentral login token key' + generateMeshToken; + + ### Configuring MeshCentral admin user and device group, restart service + print_green 'Creating meshcentral account and group' + configMeshUserGroup; + + ### Enable and configure NATS service + print_green 'Starting NATS service' + enableNatsService; + + ### Disable django admin + sed -i 's/ADMIN_ENABLED = True/ADMIN_ENABLED = False/g' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + + ### Restart core services + print_green 'Restarting services' + + for i in rmm.service daphne.service celery.service celerybeat.service + do + sudo systemctl stop ${i} + sudo systemctl start ${i} + done + + ### Yay, we're done! + printf >&2 "${YELLOW}%0.s*${NC}" {1..80} + printf >&2 "\n\n" + printf >&2 "${YELLOW}Installation complete!${NC}\n\n" + printf >&2 "${YELLOW}Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n\n" + printf >&2 "${YELLOW}Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n\n" + printf >&2 "${YELLOW}MeshCentral username: ${GREEN}${meshusername}${NC}\n" + printf >&2 "${YELLOW}MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n\n" + + if [ "$BEHIND_NAT" = true ]; then + echo -ne "${YELLOW}Read below if your router does NOT support Hairpin NAT${NC}\n\n" + echo -ne "${GREEN}If you will be accessing the web interface of the RMM from the same LAN as this server,${NC}\n" + echo -ne "${GREEN}you'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" + echo -ne "${GREEN}This also applies to any agents that will be on the same local network as the rmm.${NC}\n" + echo -ne "${GREEN}You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp.${NC}\n\n" + fi + + printf >&2 "${YELLOW}Please refer to the github README for next steps${NC}\n\n" + printf >&2 "${YELLOW}%0.s*${NC}" {1..80} + printf >&2 "\n" + + return +} + +# Update function +updateTRMM() +{ + ### Check if user is same as during installation + checkSameUser "update"; + + ### Get current release version and check if update is necessary + checkIfUpdate; + + ### Get current versions of necessary included apps + checkAdditionalAppsVers; + + ### Clear screen + cls; + + ### Check CHECK_NATS_LIMITNOFILE, whatever that means + checkNatsLimitNoFile; + + ### Check Nginx config + installNginx "updatepart1"; + + ### Stop services + for i in nginx nats-api nats rmm daphne celery celerybeat + do + printf >&2 "${GREEN}Stopping ${i} service...${NC}\n" + sudo systemctl stop ${i} + done + + ### Rebuild uwsgi config + rm -f /rmm/api/tacticalrmm/app.ini + setUwsgiProcs; + createUwsgiConf; + + ### Check if Python is up to date, if not, update + installPython "update"; + + ### Check if NATS is up to date, if not, update + installNats "update"; + + ### This does stuff + if [ -d ~/.npm ]; then + sudo rm -rf ~/.npm + fi + + if [ -d ~/.cache ]; then + sudo rm -rf ~/.cache + fi + + if [ -d ~/.config ]; then + sudo chown -R "${USER}:${GROUP}" ~/.config + fi + + ### Check NodeJS version, update if needed and update MeshCentral + print_green 'Updating NodeJS' + installNodeJS "update"; + + ### Pull domain info from existing Nginx confs + rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + + ### Set symlinks to avoid security concerns and simplify Nginx config + sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem + sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem + + ### Update from main repo + print_green 'Cloning primary repo' + clonePrimaryRepo "update" "$REPO_URL" "$BRANCH"; + + ### Update from community-scripts repo + print_green 'Cloning community scripts repo' + cloneScriptsRepo "update" "$SCRIPTS_REPO_URL"; + + ### Apply updated Ownership and perms + sudo chown "${USER}:${USER}" -R /rmm + sudo chown "${USER}:${USER}" -R ${SCRIPTS_DIR} + sudo chown "${USER}:${USER}" /var/log/celery + sudo chown "${USER}:${USER}" -R /etc/conf.d/ + + ### Check additional Nginx settings and update + installNginx "updatepart2"; + + ### Update Nginx conf files + createMeshNginxConf; + createFrontendNginxConf; + createBackendNginxConf; + + ### Reconfigure backend + createCeleryConf; + configureBackend "update"; + + ### Disable Redis append only + turnOffRedisAppendOnly; + + ### Update Frontend + installFrontEnd "update" "$FRONTEND_URL"; + + ### Start services + for i in nats nats-api rmm daphne celery celerybeat nginx + do + printf >&2 "${GREEN}Starting ${i} service${NC}\n" + sudo systemctl start ${i} + done + sleep 1 + + ### Push agent updates + /rmm/api/env/bin/python /rmm/api/tacticalrmm/manage.py update_agents + + ### Update MeshCentral if necessary + updateMeshCentral; + createMeshConfig; + enableMeshService "update"; + + ### Cleanup + rm -f $TMP_SETTINGS + + ### Bye-bye + printf >&2 "${GREEN}Update finished!${NC}\n" + + return +} + +# Backup Function +backupTRMM() +{ + ### Pull Postgres info + POSTGRES_USER=$(grep -w USER /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//') + POSTGRES_PW=$(grep -w PASSWORD /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//') + + ### Check if rmmbackup folder exists, if not create it + if [ ! -d /rmmbackups ]; then + sudo mkdir /rmmbackups + sudo chown "${USER}:${USER}" /rmmbackups + fi + + ### Remove old MeshCentral backups + if [ -d /meshcentral/meshcentral-backup ]; then + rm -rf /meshcentral/meshcentral-backup/* + fi + + ### Remove old MeshCentral DB backups + if [ -d /meshcentral/meshcentral-coredumps ]; then + rm -f /meshcentral/meshcentral-coredumps/* + fi + + ### Set info for backup and folders + dt_now=$(date '+%Y_%m_%d__%H_%M_%S') + tmp_dir=$(mktemp -d -t tacticalrmm-XXXXXXXXXXXXXXXXXXXXX) + sysd="/etc/systemd/system" + + ### Create temp backup subdirectories + mkdir -p ${tmp_dir}/meshcentral/mongo + mkdir ${tmp_dir}/postgres + mkdir ${tmp_dir}/certs + mkdir ${tmp_dir}/nginx + mkdir ${tmp_dir}/systemd + mkdir ${tmp_dir}/rmm + mkdir ${tmp_dir}/confd + + ### Dump Postgres database + pg_dump --dbname=postgresql://"${POSTGRES_USER}":"${POSTGRES_PW}"@127.0.0.1:5432/tacticalrmm | gzip -9 > ${tmp_dir}/postgres/db-${dt_now}.psql.gz + + ### Backup Mesh stuff + tar -czvf ${tmp_dir}/meshcentral/mesh.tar.gz --exclude=/meshcentral/node_modules /meshcentral + mongodump --gzip --out=${tmp_dir}/meshcentral/mongo + + ### Backup certs + sudo tar -czvf ${tmp_dir}/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt . + + ### Backup Nginx configs + sudo tar -czvf ${tmp_dir}/nginx/etc-nginx.tar.gz -C /etc/nginx . + + ### Backup other config files + sudo tar -czvf ${tmp_dir}/confd/etc-confd.tar.gz -C /etc/conf.d . + + ### Copy service files + sudo cp ${sysd}/rmm.service ${sysd}/celery.service ${sysd}/celerybeat.service ${sysd}/meshcentral.service ${sysd}/nats.service ${sysd}/daphne.service ${tmp_dir}/systemd/ + if [ -f "${sysd}/nats-api.service" ]; then + sudo cp ${sysd}/nats-api.service ${tmp_dir}/systemd/ + fi + + 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/ + + tar -cf /rmmbackups/rmm-backup-${dt_now}.tar -C ${tmp_dir} . + + ### Remove temp files/folders + rm -rf ${tmp_dir} + + echo -ne "${GREEN}Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar${NC}\n" + + return +} + +# Restore T-RMM +restoreTRMM() +{ + ### Repo info for Postegres and Mongo + setInstallRepos; + + ### Get backup file location + getBackupFileLocation; + + ### Extract backup + extractBackup "$backuppath"; + + ### Check if original user + checkSameUser "restore"; + + ### Install NodeJS + print_green 'Installing NodeJS' + installNodeJS "install"; + + ### Install Nginx + print_green 'Installing Nginx' + installNginx "install"; + + ### Restore Nginx configuration + print_green 'Restoring Nginx configuration' + + sudo rm -rf /etc/nginx + sudo mkdir /etc/nginx + sudo tar -xzf $tmp_dir/nginx/etc-nginx.tar.gz -C /etc/nginx + sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf + rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + local temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" + local tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" + rootdomain="$temprootdomain.$tempdotsomething" + + ### Restore hosts config + configHosts; + + ### Restore Certbot + print_green 'Installing Certbot' + installCertbot "restore"; + + ### Restoring existing certs + 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 + + ### Set symlinks to avoid security concerns and simplify Nginx config + sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem + sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem + + ### Recreate Nginx conf files + createMeshNginxConf; + createFrontendNginxConf; + createBackendNginxConf; + + ### Restore Celery configs + print_green 'Restoring celery configs' + + sudo mkdir /etc/conf.d + sudo tar -xzf $tmp_dir/confd/etc-confd.tar.gz -C /etc/conf.d + sudo chown "${USER}:${USER}" -R /etc/conf.d + + ### Restoring services + print_green 'Restoring systemd services' + + sudo cp $tmp_dir/systemd/* /etc/systemd/system/ + sudo systemctl daemon-reload + + ### Install Python + print_green "Installing Python ${PYTHON_VER}" + installPython; + + ### Installing Redis + print_green 'Installing redis' + installRedis; + + ### Install and enable Postgresql + print_green 'Installing postgresql' + installPostgresql; + + ### Install and enable MongoDB + print_green 'Installing MongoDB' + installMongo; + + ### Restore Mongo database + print_green 'Restoring MongoDB' + mongorestore --gzip $tmp_dir/meshcentral/mongo + + ### Clone main repo + print_green 'Cloning primary repo' + clonePrimaryRepo "install" "$REPO_URL" "$BRANCH"; + + ### Clone scripts repo + print_green 'Cloning community scripts repo' + cloneScriptsRepo "install" "$SCRIPTS_REPO_URL"; + + ### Installing NATS + print_green 'Installing NATS' + installNats "install"; + + ### Restore MeshCentral + print_green 'Restoring MeshCentral' + installMeshCentral "restore"; + + ### Restore UWSGI + print_green 'Optimizing UWSGI for number of processors' + setUwsgiProcs; + print_green 'Creating UWSGI configuration' + createUwsgiConf; + + ### Restoring other misc stuff + cp $tmp_dir/rmm/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/ + cp $tmp_dir/rmm/env /rmm/web/.env + gzip -d $tmp_dir/rmm/debug.log.gz + cp $tmp_dir/rmm/django_debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/ + + ### Install NATS-API + print_green 'Installing NATS API' + installNatsApi; + + ### Restore Postgres database + print_green 'Restoring the Postgres 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" + createPGDB; + + gzip -d $tmp_dir/postgres/*.psql.gz + PGPASSWORD="${pgpw} psql -h localhost -U ${pgusername} -d tacticalrmm -f $tmp_dir/postgres/db*.psql" + + ### Restore Backend + print_green 'Restoring the backend' + configureBackend "restore"; + + ### Start NATS + print_green 'Start NATS' + sudo systemctl enable nats.service + sudo systemctl start nats.service + + ### Install frontend + print_green 'Installing the frontend' + installFrontEnd; + + # reset perms + sudo chown "${USER}:${USER}" -R /rmm + sudo chown "${USER}:${USER}" /var/log/celery + sudo chown "${USER}:${USER}" -R /etc/conf.d/ + sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.npm + sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.config + sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.cache + + ### Update services info + sudo systemctl daemon-reload + + ### Enable RMM, Daphne, Celery, Nats-api, and Nginx services + print_green 'Enabling Services' + + for i in celery.service celerybeat.service rmm.service daphne.service nats-api.service nginx + do + sudo systemctl enable ${i} + sudo systemctl stop ${i} + sudo systemctl start ${i} + done + sleep 5 + + ### Start MeshCentral + print_green 'Starting meshcentral' + sudo systemctl enable meshcentral + sudo systemctl start meshcentral + + ### Done!!!! + printf >&2 "${YELLOW}%0.s*${NC}" {1..80} + printf >&2 "\n\n" + printf >&2 "${YELLOW}Restore complete!${NC}\n\n" + printf >&2 "${YELLOW}%0.s*${NC}" {1..80} + printf >&2 "\n" + + return +} + +# Troubleshooting utility +troubleShoot() +{ + ### Resolve Locally used DNS server + locdns=$(resolvectl | grep 'Current DNS Server:' | cut -d: -f2 | awk '{ print $1}') + + ### Prompt for host, domain, and email info + getHostAndDomainInfo; + + ### Verify domains are live + pingDomain "$rmmdomain"; + pingDomain "$frontenddomain"; + pingDomain "$meshdomain"; + + ### Verify IPs + echo -ne "${YELLOW} Checking IPs${NC}" | tee -a checklog.log + printf >&2 "\n\n" + checkIPisLive "$rmmdomain"; + remapiip="${reminputip}" + checkIPisLive "$frontenddomain"; + checkIPisLive "$meshdomain"; + + ### Get services status + readServicesStatus; + + ### Verify services active + checkIfServiceActive "$rmmstatus" "RMM Service"; + checkIfServiceActive "$daphnestatus" "Daphne Service"; + checkIfServiceActive "$celerystatus" "Celery Service"; + checkIfServiceActive "$celerybeatstatus" "CeleryBeat Service"; + checkIfServiceActive "$nginxstatus" "Nginx Service"; + checkIfServiceActive "$natsstatus" "NATS Service"; + checkIfServiceActive "$natsapistatus" "NATS-API Service"; + checkIfServiceActive "$meshcentralstatus" "MeshCentral Service"; + checkIfServiceActive "$mongodstatus" "MongoD Service"; + checkIfServiceActive "$postgresqlstatus" "Postgresql Service"; + checkIfServiceActive "$redisserverstatus" "Redis-Server Service"; + + ### Get WAN IP + wanip=$(dig @resolver4.opendns.com myip.opendns.com +short) + echo -ne "${GREEN} WAN IP is $wanip.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + + ### Check if ports are open + isPortOpen "4222" "NATS"; + isPortOpen "80" "HTTP"; + isPortOpen "443" "HTTPS"; + + ### Checking Proxy + checkProxy; + + ### Check for valid cert + checkIfCertIsValid; + + ### Generate log summary + echo -ne "${YELLOW} Getting summary output of logs.${NC}" | 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" + + printf >&2 "\n\n" + echo -ne "${YELLOW} You will have a log file called checklog.log in the directory you ran this script from.${NC}" + printf >&2 "\n\n" + + return +} From 24f74c35cef6f9716b79d6247de58e632326ee90 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 17 Jun 2022 16:27:22 -0500 Subject: [PATCH 031/203] Create installer-util.sh --- installer-util.sh | 202 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 installer-util.sh diff --git a/installer-util.sh b/installer-util.sh new file mode 100644 index 0000000000..241ef2f8c9 --- /dev/null +++ b/installer-util.sh @@ -0,0 +1,202 @@ +#!/usr/bin/env bash + +### Menu option variables +INPUT=/tmp/menu.sh.$$ +menuselection="" +#declare -a menuoptions=('Test Install' 'Exit') +declare -a mainmenuoptions=('Installation' 'Update' 'Utilities' 'Exit') +declare -a installmenuoptions=('Standard Install' 'Dev Test Prereqs' 'Dev Test Install' 'Return' 'Exit') +declare -a updatemenuoptions=('Standard Update' 'Backup and Update' 'Force Update' 'Return' 'Exit') +declare -a utilitymenuoptions=('Backup' 'Restore' 'Renew Certs' 'Import Certs' 'Edit UWSGI config' 'Add Fail2ban - Use at your own risk' 'Run Server Troubleshooter' 'Return' 'Exit') + +### Script Info variables +REPO_OWNER="ninjamonkey198206" +BRANCH="develop-bash-updates" +CFG_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/bashfunctions.cfg" +SCRIPT_VERSION="66" +SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/install.sh" +REPO_URL="https://github.com/${REPO_OWNER}/tacticalrmm.git" +SCRIPTS_REPO_URL="https://github.com/amidaware/community-scripts.git" +FRONTEND_URL="https://github.com/amidaware/tacticalrmm-web/releases/download/v${WEB_VERSION}/${webtar}" +THIS_SCRIPT=$(readlink -f "$0") + +### Misc info variables +INSTALL_TYPE="install" +UPDATE_TYPE="standard" +SCRIPTS_DIR='/opt/trmm-community-scripts' +PYTHON_VER='3.10.4' +SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py' +LATEST_SETTINGS_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/api/tacticalrmm/tacticalrmm/settings.py" + +### Get cfg file +if [ ! -f "$PWD/bashfunctions.cfg" ]; then + wget -q "${CFG_URL}" -O bashfunctions.cfg +fi + +### Import functions +. $PWD/bashfunctions.cfg + +### Set colors +setColors; + +### Gather OS info +getOSInfo; + +### Install script pre-reqs +installPreReqs; + +### Check for new functions version, only include script name as variable +checkCfgVer "$CFG_URL" "$THIS_SCRIPT"; + +### Check for new script version, pass script version, url, and script name variables in that order +checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; + +### Install additional prereqs +installAdditionalPreReqs; + +### Fallback if lsb_release -si returns anything else than Ubuntu, Debian or Raspbian +wutOSThis; + +### Verify compatible OS and version +verifySupportedOS; + +### Check if root +checkRoot; + +### Check language/locale +checkLocale; + +### 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 + +#################### +# Menu Functions # +#################### + +# Installation menu +installMenu() +{ + until [ "$menuselection" = "0" ]; do + dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Installation Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections.\n\nSelect Return to return to the previous menu." 0 0 0 \ + 1 "${installmenuoptions[0]}" \ + 2 "${installmenuoptions[1]}" \ + 3 "${installmenuoptions[2]}" \ + 4 "${installmenuoptions[3]}" \ + 5 "${installmenuoptions[4]}" 2>"${INPUT}" + + menuselection=$(<"${INPUT}") + + case $menuselection in + 1 ) INSTALL_TYPE="install" + mainInstall;; + 2 ) INSTALL_TYPE="devprep" + mainInstall;; + 3 ) INSTALL_TYPE="devinstall" + decideMainRepos + mainInstall;; + 4 ) return;; + 5 ) [ -f $INPUT ] && rm $INPUT + clear -x + exit;; + * ) derpDerp;; + esac + done + + return +} + +# Utilities menu +utilityMenu() +{ + until [ "$menuselection" = "0" ]; do + dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Utility Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections.\n\nSelect Return to return to the previous menu." 0 0 0 \ + 1 "${utilitymenuoptions[0]}" \ + 2 "${utilitymenuoptions[1]}" \ + 3 "${utilitymenuoptions[2]}" \ + 4 "${utilitymenuoptions[3]}" \ + 5 "${utilitymenuoptions[4]}" \ + 6 "${utilitymenuoptions[5]}" \ + 7 "${utilitymenuoptions[6]}" \ + 8 "${utilitymenuoptions[7]}" \ + 9 "${utilitymenuoptions[8]}" 2>"${INPUT}" + + menuselection=$(<"${INPUT}") + + case $menuselection in + 1 ) backupTRMM;; + 2 ) restoreTRMM;; + 3 ) renewCerts;; + 4 ) importCerts;; + 5 ) changeUWSGIProcs;; + 6 ) installFail2ban;; + 7 ) troubleShoot;; + 8 ) return;; + 9 ) [ -f $INPUT ] && rm $INPUT + clear -x + exit;; + * ) derpDerp;; + esac + done + + return +} + +# Update menu +updateMenu() +{ + until [ "$menuselection" = "0" ]; do + dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Update Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections.\n\nSelect Return to return to the previous menu." 0 0 0 \ + 1 "${updatemenuoptions[0]}" \ + 2 "${updatemenuoptions[1]}" \ + 3 "${updatemenuoptions[2]}" \ + 4 "${updatemenuoptions[3]}" \ + 5 "${updatemenuoptions[4]}" 2>"${INPUT}" + + menuselection=$(<"${INPUT}") + + case $menuselection in + 1 ) UPDATE_TYPE="standard" + updateTRMM;; + 2 ) UPDATE_TYPE="standard" + backupTRMM + updateTRMM;; + 3 ) UPDATE_TYPE="forced" + updateTRMM;; + 4 ) return;; + 5 ) [ -f $INPUT ] && rm $INPUT + clear -x + exit;; + * ) derpDerp;; + esac + done + + return +} + +# Main menu +mainMenu() +{ + until [ "$menuselection" = "0" ]; do + dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Main Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections." 0 0 0 \ + 1 "${mainmenuoptions[0]}" \ + 2 "${mainmenuoptions[1]}" \ + 3 "${mainmenuoptions[2]}" \ + 4 "${mainmenuoptions[3]}" 2>"${INPUT}" + + menuselection=$(<"${INPUT}") + + case $menuselection in + 1 ) installMenu;; + 2 ) updateMenu;; + 3 ) utilityMenu;; + 4 ) [ -f $INPUT ] && rm $INPUT + clear -x + exit;; + * ) derpDerp;; + esac + done + + return +} + +mainMenu; From c36e0b9abc04e6ea59d4960c6164f31dd6879c73 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 17 Jun 2022 16:47:40 -0500 Subject: [PATCH 032/203] Correcting tabs from import --- bashfunctions.cfg | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bashfunctions.cfg b/bashfunctions.cfg index 110aa8079e..f5e87f639e 100644 --- a/bashfunctions.cfg +++ b/bashfunctions.cfg @@ -63,17 +63,17 @@ setColors() # Clear screen cls() { - printf "\033c" + printf "\033c" } # Purdy install text print_green() { - printf >&2 "${GREEN}%0.s-${NC}" {1..80} - printf >&2 "\n" - printf >&2 "${GREEN}${1}${NC}\n" - printf >&2 "${GREEN}%0.s-${NC}" {1..80} - printf >&2 "\n" + printf >&2 "${GREEN}%0.s-${NC}" {1..80} + printf >&2 "\n" + printf >&2 "${GREEN}${1}${NC}\n" + printf >&2 "${GREEN}%0.s-${NC}" {1..80} + printf >&2 "\n" } # Check for new script version From 1303c496cf1dea997901d58efb3167f8dee431e5 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 17 Jun 2022 22:48:58 -0500 Subject: [PATCH 033/203] Adding Section/CFG file descriptions --- bash/MiscFunctions.cfg | 169 +++++++++++++++++++++++++++++++++++ bash/SystemInfoFunctions.cfg | 45 ++++++++++ installer-util.sh | 12 +-- 3 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 bash/MiscFunctions.cfg create mode 100644 bash/SystemInfoFunctions.cfg diff --git a/bash/MiscFunctions.cfg b/bash/MiscFunctions.cfg new file mode 100644 index 0000000000..be1f24f008 --- /dev/null +++ b/bash/MiscFunctions.cfg @@ -0,0 +1,169 @@ +################### +# CFG file info # +################### + +MISCFUNC_VERSION="5" + + +###################################################################################### +# Misc Functions, must be before any functions except input verification functions # +###################################################################################### + +# Set bash text colors +setColors() +{ + GREEN='\033[0;32m' + YELLOW='\033[1;33m' + BLUE='\033[0;34m' + RED='\033[0;31m' + NC='\033[0m' +} + +# Clear screen +cls() +{ + printf "\033c" +} + +# Purdy install text +print_green() +{ + printf >&2 "${GREEN}%0.s-${NC}" {1..80} + printf >&2 "\n" + printf >&2 "${GREEN}${1}${NC}\n" + printf >&2 "${GREEN}%0.s-${NC}" {1..80} + printf >&2 "\n" +} + +# Check for new script version +checkScriptVer() +{ + TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") + curl -s -L "$2" > ${TMP_FILE} + NEW_VER=$(grep "^SCRIPT_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') + + if [ "$1" -ne "${NEW_VER}" ]; then + wget -q "$2" -O "$3" + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 + rm -f $TMP_FILE + clear -x + exit 1 + fi + + rm -f $TMP_FILE +} + +# Check for functions updates +checkMiscFuncVer() +{ + TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") + curl -s -L "$1" > "$TMP_FILE" + NEW_VER=$(grep "^MISCFUNC_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') + + if [ "$MISCFUNC_VERSION" -ne "$NEW_VER" ]; then + wget -q "$1" -O bashfunctions.cfg + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old bash function file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$2" 10 40 + rm -f $TMP_FILE + clear -x + exit 1 + fi + + rm -f $TMP_FILE +} + +# Check for root as user +checkRoot() +{ + if [ $EUID -eq 0 ]; then + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Do NOT run this script as root. Exiting." 0 0 + clear -x + exit 1 + fi +} + +# Clone primary repo +clonePrimaryRepo() +{ + if [ "$1" == "install" ]; then + sudo mkdir /rmm + sudo chown "${USER}:${USER}" /rmm + sudo mkdir -p /var/log/celery + sudo chown "${USER}:${USER}" /var/log/celery + git clone "$2" /rmm/ + fi + cd /rmm + git config user.email "admin@example.com" + git config user.name "Bob" + if [ "$1" == "install" ]; then + git checkout "$3" + elif [ "$1" == "update" ]; then + git fetch + git checkout "$3" + git reset --hard FETCH_HEAD + git clean -df + git pull + fi +} + +# Clone scripts repo +cloneScriptsRepo() +{ + if [ ! -d "${SCRIPTS_DIR}" ]; then + sudo mkdir -p "${SCRIPTS_DIR}" + sudo chown "${USER}:${USER}" "${SCRIPTS_DIR}" + git clone "$2" "${SCRIPTS_DIR}"/ + fi + cd "${SCRIPTS_DIR}" + git config user.email "admin@example.com" + git config user.name "Bob" + if [ "$1" == "install" ]; then + git checkout main + elif [ "$1" == "update" ]; then + git fetch + git checkout main + git reset --hard FETCH_HEAD + git clean -df + git pull + fi +} + +# Set primary repos to use +decideMainRepos() +{ + userconfirm="n" + local own="" + local bran="" + + until [ "$userconfirm" == "y" ]; do + own=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository" --inputbox "Enter the dev repo owner name.\nThis is right after github.com in the URL:" 10 90 3>&1 1>&2 2>&3) + own="$(translateToLowerCase $own)" + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository" --yesno "Is this correct?\n$own" 0 0 + case $? in + 0 ) userconfirm="y" + clear -x;; + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + REPO_OWNER="$own" + + until [ "$userconfirm" == "y" ]; do + bran=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository Branch" --inputbox "Enter the dev repo branch name.\nThis is right after tacticalrmm in the URL:" 10 90 3>&1 1>&2 2>&3) + bran="$(translateToLowerCase $bran)" + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository Branch" --yesno "Is this correct?\n$bran" 0 0 + case $? in + 0 ) userconfirm="y" + clear -x;; + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + BRANCH="$bran" + + ### Check for new functions version, only include script name as variable + checkCfgVer "$CFG_URL" "$THIS_SCRIPT"; + ### Check for new script version, pass script version, url, and script name variables in that order + checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; +} \ No newline at end of file diff --git a/bash/SystemInfoFunctions.cfg b/bash/SystemInfoFunctions.cfg new file mode 100644 index 0000000000..28902fdd6f --- /dev/null +++ b/bash/SystemInfoFunctions.cfg @@ -0,0 +1,45 @@ +########################### +# System info functions # +########################### + +# Gather OS info +getOSInfo() +{ + osname=$(lsb_release -si); osname=${osname^} + osname=$(echo "$osname" | tr '[A-Z]' '[a-z]') + fullrel=$(lsb_release -sd) + codename=$(lsb_release -sc) + relno=$(lsb_release -sr | cut -d. -f1) + fullrelno=$(lsb_release -sr) +} + +# Check OS if not recognised +wutOSThis() +{ + if [ ! "$osname" = "ubuntu" ] && [ ! "$osname" = "debian" ]; then + osname=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"') + osname=${osname^} + fi +} + +# Verify Debian or Ubuntu and version +verifySupportedOS() +{ + if ([ "$osname" = "ubuntu" ] && ([ "$fullrelno" = "20.04" ] || [ "$fullrelno" = "22.04" ])) || ([ "$osname" = "debian" ] && [ $relno -ge 10 ]); then + echo "$fullrel" + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 + clear -x + exit 1 + fi +} + +# Check language/locale +checkLocale() +{ + if [[ "$LANG" != *".UTF-8" ]]; then + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "System locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting." 0 0 + clear -x + exit 1 + fi +} \ No newline at end of file diff --git a/installer-util.sh b/installer-util.sh index 241ef2f8c9..0a481fa9fc 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -40,7 +40,7 @@ fi setColors; ### Gather OS info -getOSInfo; +getOSInfo; # SystemInfoFunctions ### Install script pre-reqs installPreReqs; @@ -54,17 +54,17 @@ checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; ### Install additional prereqs installAdditionalPreReqs; -### Fallback if lsb_release -si returns anything else than Ubuntu, Debian or Raspbian -wutOSThis; +### Fallback if lsb_release -si returns anything else than Ubuntu, Debian, or Raspbian +wutOSThis; # SystemInfoFunctions ### Verify compatible OS and version -verifySupportedOS; +verifySupportedOS; # SystemInfoFunctions ### Check if root -checkRoot; +checkRoot; # MiscFunctions ### Check language/locale -checkLocale; +checkLocale; # SystemInfoFunctions ### 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 From 3e8906ec71569b25631985fb7aaa5295148195f7 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 18 Jun 2022 09:27:05 -0500 Subject: [PATCH 034/203] Testing cfg function to pull multiple files --- bash/MiscFunctions.cfg | 10 +++++----- installer-util.sh | 18 ++++++++++++------ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/bash/MiscFunctions.cfg b/bash/MiscFunctions.cfg index be1f24f008..5bb7150875 100644 --- a/bash/MiscFunctions.cfg +++ b/bash/MiscFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -MISCFUNC_VERSION="5" +CFG_VERSION="5" ###################################################################################### @@ -58,11 +58,11 @@ checkMiscFuncVer() { TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") curl -s -L "$1" > "$TMP_FILE" - NEW_VER=$(grep "^MISCFUNC_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') + NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') - if [ "$MISCFUNC_VERSION" -ne "$NEW_VER" ]; then - wget -q "$1" -O bashfunctions.cfg - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old bash function file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$2" 10 40 + if [ "$CFG_VERSION" -ne "$NEW_VER" ]; then + wget -q "$1" -O MiscFunctions.cfg + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old MiscFunctions file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$2" 10 40 rm -f $TMP_FILE clear -x exit 1 diff --git a/installer-util.sh b/installer-util.sh index 0a481fa9fc..183540c8c5 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -12,7 +12,7 @@ declare -a utilitymenuoptions=('Backup' 'Restore' 'Renew Certs' 'Import Certs' ' ### Script Info variables REPO_OWNER="ninjamonkey198206" BRANCH="develop-bash-updates" -CFG_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/bashfunctions.cfg" +CFG_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" SCRIPT_VERSION="66" SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/install.sh" REPO_URL="https://github.com/${REPO_OWNER}/tacticalrmm.git" @@ -28,16 +28,22 @@ PYTHON_VER='3.10.4' SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py' LATEST_SETTINGS_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/api/tacticalrmm/tacticalrmm/settings.py" -### Get cfg file -if [ ! -f "$PWD/bashfunctions.cfg" ]; then - wget -q "${CFG_URL}" -O bashfunctions.cfg -fi +### Get cfg files function +getCfgFiles() +{ + if [ ! -f "$PWD/$2" ]; then + wget -q "$1/$2" -O "$2" + fi +} + +### Get bashfunctions file +getCfgFiles "$CFG_URL" "bashfunctions.cfg"; ### Import functions . $PWD/bashfunctions.cfg ### Set colors -setColors; +setColors; # MiscFunctions ### Gather OS info getOSInfo; # SystemInfoFunctions From 2de1f53f66b3dd1edda7d1abae9c318fd4e73c35 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 18 Jun 2022 09:28:46 -0500 Subject: [PATCH 035/203] updated repo url --- installer-util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer-util.sh b/installer-util.sh index 183540c8c5..a163ed6a23 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -11,7 +11,7 @@ declare -a utilitymenuoptions=('Backup' 'Restore' 'Renew Certs' 'Import Certs' ' ### Script Info variables REPO_OWNER="ninjamonkey198206" -BRANCH="develop-bash-updates" +BRANCH="develop-installer-update" CFG_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" SCRIPT_VERSION="66" SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/install.sh" From bd72b24e411ae5b5479021d7a82747492df91a2c Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 18 Jun 2022 10:42:32 -0500 Subject: [PATCH 036/203] Added cfg files for breakout --- bash/CertificateFunctions.cfg | 76 ++++ bash/ConfigAndServiceFunctions.cfg | 334 ++++++++++++++ bash/DatabaseFunctions.cfg | 21 + bash/InputAndError.cfg | 47 ++ bash/InstallFunctions.cfg | 295 +++++++++++++ bash/NetworkFunctions.cfg | 71 +++ bash/ParentFunctions.cfg | 687 +++++++++++++++++++++++++++++ bash/SystemInfoFunctions.cfg | 7 + bash/TroubleshootingFunctions.cfg | 130 ++++++ bash/UpdateRestoreFunctions.cfg | 124 ++++++ bash/UserInput.cfg | 139 ++++++ bashfunctions.cfg | 14 +- installer-util.sh | 16 +- 13 files changed, 1947 insertions(+), 14 deletions(-) create mode 100644 bash/CertificateFunctions.cfg create mode 100644 bash/ConfigAndServiceFunctions.cfg create mode 100644 bash/DatabaseFunctions.cfg create mode 100644 bash/InputAndError.cfg create mode 100644 bash/InstallFunctions.cfg create mode 100644 bash/NetworkFunctions.cfg create mode 100644 bash/ParentFunctions.cfg create mode 100644 bash/TroubleshootingFunctions.cfg create mode 100644 bash/UpdateRestoreFunctions.cfg create mode 100644 bash/UserInput.cfg diff --git a/bash/CertificateFunctions.cfg b/bash/CertificateFunctions.cfg new file mode 100644 index 0000000000..94b18c98ce --- /dev/null +++ b/bash/CertificateFunctions.cfg @@ -0,0 +1,76 @@ +################### +# CFG file info # +################### + +CFG_VERSION="5" + + +########################### +# Certificate Functions # +########################### + +# Renew Certs +renewCerts() +{ + rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + local temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" + local tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" + rootdomain="$temprootdomain.$tempdotsomething" + generateCerts; + sudo systemctl restart nginx.service rmm.service celery celerybeat.service nats-api.service nats.service meshcentral.service +} + +# Import certs +importCerts() +{ + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate and your private key, in that order.\n\nTo paste the contents, type i , then right click in the window.\n\nAfter pasting the contents, type esc , then shift-: , then x , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 + sudo vim /etc/ssl/certs/fullchain.pem + sudo vim /etc/ssl/private/privkey.pem +} + +# Generate certs +generateCerts() +{ + print_green 'Getting wildcard cert' + + ### Get initial DNS text entry + sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email + + ### Keep going until successful cert issue after adding DNS txt entry + while [[ $? -ne 0 ]]; do + sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email + done +} + +# Install Certbot and get initial certs +installCertbot() +{ + ### Install Certbot + sudo apt install -y certbot + if [ "$1" == "restore" ]; then + return + fi + + if [ "$INSTALL_TYPE" == "devinstall" ]; then + echo -e "${GREEN}Certificates should be in place${NC}" + else + dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have wildcard certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 + case $? in + ### Get wildcard cert via LetsEncrypt + 0 ) generateCerts;; + + 1 ) importCerts;; + esac + fi + + ### Set symlinks to avoid security concerns and simplify Nginx config + sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem + sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem + + ### Generate DH + if [ ! -f /etc/ssl/certs/dhparam.pem ]; then + sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096 + else + return + fi +} \ No newline at end of file diff --git a/bash/ConfigAndServiceFunctions.cfg b/bash/ConfigAndServiceFunctions.cfg new file mode 100644 index 0000000000..4ffd1a65bc --- /dev/null +++ b/bash/ConfigAndServiceFunctions.cfg @@ -0,0 +1,334 @@ +################### +# CFG file info # +################### + +CFG_VERSION="5" + + +####################################### +# Config file and service functions # +####################################### + +# Generate mesh configuration +createMeshConfig() +{ + sudo cp /rmm/default-configs/mesh/config.json /meshcentral/meshcentral-data/config.json + + sudo sed -i "s/mesh.example.com/$meshdomain/" /meshcentral/meshcentral-data/config.json +} + +# Generate local settings file +createLocalSettings() +{ + sudo cp /rmm/default-configs/python/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + + sudo sed -i "s/DJANGO_SEKRET/$DJANGO_SEKRET/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/api.example.com/$rmmdomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/ADMINURL/$ADMINURL/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/rmm.example.com/$frontenddomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/pgusername/$pgusername/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/pgpw/$pgpw/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/meshusername/$meshusername/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/mesh.example.com/$meshdomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py +} + +# Backend configuration +configureBackend() +{ + SETUPTOOLS_VER=$(grep "^SETUPTOOLS_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') + WHEEL_VER=$(grep "^WHEEL_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') + userconfirm="n" + + if [ "$1" == "update" ]; then + CHECK_ADMIN_ENABLED=$(grep ADMIN_ENABLED /rmm/api/tacticalrmm/tacticalrmm/local_settings.py) + if ! [ $CHECK_ADMIN_ENABLED ]; then + sudo sed -i '$ a ADMIN_ENABLED = False' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + 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 [ "${CURRENT_PIP_VER}" != "${LATEST_PIP_VER}" ] || [ "$UPDATE_TYPE" == "forced" ]; then + rm -rf /rmm/api/env + fi + fi + + if [ "${CURRENT_PIP_VER}" == "${LATEST_PIP_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then + source /rmm/api/env/bin/activate + cd /rmm/api/tacticalrmm + pip install -r /rmm/api/tacticalrmm/requirements.txt + else + cd /rmm/api + 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 + fi + + if [ "$1" == "update" ]; then + python manage.py pre_update_tasks + celery -A tacticalrmm purge -f + python manage.py migrate + python manage.py delete_tokens + python manage.py collectstatic --no-input + python manage.py reload_nats + python manage.py load_chocos + python manage.py create_installer_user + python manage.py create_natsapi_conf + python manage.py post_update_tasks + rmmdomain=$(python manage.py get_config api) + WEB_VERSION=$(python manage.py get_config webversion) + deactivate + elif [ "$1" == "restore" ]; then + python manage.py migrate + python manage.py collectstatic --no-input + python manage.py create_natsapi_conf + python manage.py reload_nats + python manage.py post_update_tasks + rmmdomain=$(python manage.py get_config api) + WEB_VERSION=$(python manage.py get_config webversion) + deactivate + else + 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 + WEB_VERSION=$(python manage.py get_config webversion) + until [ "$userconfirm" == "y" ]; do + djangousername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Create Site/Django Admin Login" --inputbox "Please enter the RMM website and django admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Create Site/Django Admin Login" --yesno "Is this correct?\n$djangousername" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + clear -x + python manage.py createsuperuser --username ${djangousername} --email ${letsemail} + python manage.py create_installer_user + RANDBASE=$(python manage.py generate_totp) + cls; + python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} + deactivate + read -n 1 -s -r -p "Press any key to continue..." + fi +} + +# Set uwsgi procs +setUwsgiProcs() +{ + uwsgiprocs=4 + uwsgithreads=4 + if [[ "$numprocs" == "1" ]]; then + uwsgiprocs=2 + uwsgithreads=2 + else + uwsgiprocs=$numprocs + uwsgithreads=$numprocs + fi +} + +# Create UWSGI config +createUwsgiConf() +{ + sudo cp /rmm/default-configs/uwsgi/app.ini /rmm/api/tacticalrmm/app.ini + + sudo sed -i "s/uwsgiprocs/$uwsgiprocs/" /rmm/api/tacticalrmm/app.ini + sudo sed -i "s/uwsgithreads/$uwsgithreads/" /rmm/api/tacticalrmm/app.ini +} + +# Create UWSGI service +createUwsgiService() +{ + sudo cp /rmm/service-definitions/rmm.service /etc/systemd/system/rmm.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/rmm.service +} + +# Create Daphne service +createDaphneService() +{ + sudo cp /rmm/service-definitions/daphne.service /etc/systemd/system/daphne.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/daphne.service +} + +# Create NATS service +createNatsService() +{ + sudo cp /rmm/service-definitions/nats.service /etc/systemd/system/nats.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats.service +} + +# Create NATS service +createNatsApiService() +{ + sudo cp /rmm/service-definitions/nats-api.service /etc/systemd/system/nats-api.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats-api.service +} + +# Create backend nginx conf +createBackendNginxConf() +{ + sudo cp /rmm/default-configs/nginx/rmm.conf /etc/nginx/sites-available/rmm.conf + + sudo sed -i "s/api.example.com/$rmmdomain/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/rmm.conf +} + +# Create Mesh nginx conf +createMeshNginxConf() +{ + sudo cp /rmm/default-configs/nginx/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf + + sudo sed -i "s/mesh.example.com/$meshdomain/" /etc/nginx/sites-available/meshcentral.conf +} + +# Create Celery service +createCeleryService() +{ + sudo cp /rmm/service-definitions/celery.service /etc/systemd/system/celery.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/celery.service +} + +# Create Celery config +createCeleryConf() +{ + sudo cp /rmm/default-configs/celery/celery.conf /etc/conf.d/celery.conf +} + +# Create CeleryBeat service +createCeleryBeatService() +{ + sudo cp /rmm/service-definitions/celerybeat.service /etc/systemd/system/celerybeat.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/celerybeat.service +} + +# Create MeshCentral service +createMeshCentralService() +{ + sudo cp /rmm/service-definitions/meshcentral.service /etc/systemd/system/meshcentral.service + + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/meshcentral.service +} + +# Create Frontend Nginx config +createFrontendNginxConf() +{ + sudo cp /rmm/default-configs/nginx/frontend.conf /etc/nginx/sites-available/frontend.conf + + sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/frontend.conf +} + +# Enable MeshCentral service +enableMeshService() +{ + if [ "$1" != "update" ]; then + sudo systemctl enable meshcentral + fi + sudo systemctl restart meshcentral + sleep 3 + + # The first time we start meshcentral, it will need some time to generate certs and install plugins. + # This will take anywhere from a few seconds to a few minutes depending on the server's hardware + # We will know it's ready once the last line of the systemd service stdout is 'MeshCentral HTTP server running on port.....' + 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 + done +} + +# Generate Mesh Token +generateMeshToken() +{ + MESHTOKENKEY="$(node /meshcentral/node_modules/meshcentral --logintokenkey)" + + sudo sed -i '$ a MESH_TOKEN_KEY = "MESHTOKENKEY"' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i "s/MESHTOKENKEY/$MESHTOKENKEY/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py +} + +# Configure Mesh user and group, restart service +configMeshUserGroup() +{ + sudo systemctl stop meshcentral + sleep 1 + cd /meshcentral + + node node_modules/meshcentral --createaccount ${meshusername} --pass ${MESHPASSWD} --email ${letsemail} + sleep 1 + node node_modules/meshcentral --adminaccount ${meshusername} + + sudo systemctl start meshcentral + 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 + done + + node node_modules/meshcentral/meshctrl.js --url wss://${meshdomain} --loginuser ${meshusername} --loginpass ${MESHPASSWD} AddDeviceGroup --name TacticalRMM + sleep 1 +} + +# Configure and enable NATS service +enableNatsService() +{ + sudo systemctl enable nats.service + cd /rmm/api/tacticalrmm + source /rmm/api/env/bin/activate + python manage.py initial_db_setup + python manage.py reload_nats + deactivate + sudo systemctl start nats.service + + sleep 1 + sudo systemctl enable nats-api.service + sudo systemctl start nats-api.service +} + +# Change UWSGI settings +changeUWSGIProcs() +{ + local countconfirm="n" + + ### Get UWSGI Processes value + until [ $countconfirm == "y" ]; do + uwsgiprocs=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Process Count" --inputbox "Enter the desired UWSGI Process Count, usually the same as CPU core count:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Process Count" --yesno "Is this correct?\n$uwsgiprocs" 0 0 + case $? in + 0 ) countconfirm="y";; + + 1 ) countconfirm="n" + derpDerp;; + esac + done + countconfirm="n" + + ### Get UWSGI Threads value + until [ $countconfirm == "y" ]; do + uwsgithreads=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Thread Count" --inputbox "Enter the desired UWSGI Process Count, usually the same as CPU core count:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Thread Count" --yesno "Is this correct?\n$uwsgithreads" 0 0 + case $? in + 0 ) countconfirm="y";; + + 1 ) countconfirm="n" + derpDerp;; + esac + done + countconfirm="n" + + ### Stop rmm service, copy default file, edit processes/threads, start service + sudo systemctl stop rmm + createUwsgiConf; + sudo systemctl start rmm +} \ No newline at end of file diff --git a/bash/DatabaseFunctions.cfg b/bash/DatabaseFunctions.cfg new file mode 100644 index 0000000000..a3ada48f05 --- /dev/null +++ b/bash/DatabaseFunctions.cfg @@ -0,0 +1,21 @@ +################### +# CFG file info # +################### + +CFG_VERSION="5" + + +######################## +# Database Functions # +######################## + +# Postgres DB creation +createPGDB() +{ + 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}" +} \ No newline at end of file diff --git a/bash/InputAndError.cfg b/bash/InputAndError.cfg new file mode 100644 index 0000000000..833e2ba009 --- /dev/null +++ b/bash/InputAndError.cfg @@ -0,0 +1,47 @@ +################### +# CFG file info # +################### + +CFG_VERSION="5" + + +############################# +# Input cleanup and error # +############################# + +errortrack=0 + +# Translate user input to all lower case to prevent ID10T errors +translateToLowerCase() +{ + local lowercase="" + lowercase="$(echo $1 | tr '[:upper:]' '[:lower:]')" + echo "$lowercase" +} + +# Function to track ID10T errors +derpDerp() +{ + if [ "$errortrack" -lt 12 ]; then + errortrack=$((errortrack+1)) + fi + + derptext="" + + case $errortrack in + 1 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "Need some coffee?" 10 30;; + 2 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You should get some coffee." 10 35;; + 3 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You are paying attention, right?" 10 40;; + 4 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "All your typos are belong to us." 10 40;; + 5 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "We're sorry, your fingers are too fat.\n\nIf you would like to obtain a typing wand,\nplease mash your hand on the keyboard now." 15 75;; + 6 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You have got to be kidding me...\n\nThis really isn't that difficult." 15 50;; + 7 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You're doing this intentionally, aren't you?\n\nThis really isn't that difficult." 15 75;; + 8 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "Please step away from the keyboard, and back away slowly.\n\nThe instructions are literally right there." 15 75;; + 9 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You're making me angry.\nYou wouldn't like me when I'm angry.\n\nThe instructions are literally right there." 15 75;; + 10 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "How did you even get to this point?!\n\nThe instructions are literally right there." 15 75;; + 11 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "Seriously, just give it up.\n\nI just can't with you right now..." 15 60;; + * ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "\*sigh\* Why are you still here?\n\nI just can't with you right now..." 15 60;; + esac + + return +} \ No newline at end of file diff --git a/bash/InstallFunctions.cfg b/bash/InstallFunctions.cfg new file mode 100644 index 0000000000..8fbdb43cce --- /dev/null +++ b/bash/InstallFunctions.cfg @@ -0,0 +1,295 @@ +################### +# CFG file info # +################### + +CFG_VERSION="5" + + +####################### +# Install Functions # +####################### + +# Install script prereqs +installPreReqs() +{ + sudo apt update && sudo apt install -y curl wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev +} + +# Install remaining prereqs +installAdditionalPreReqs() +{ + sudo apt install -y software-properties-common openssl ca-certificates apt-transport-https gcc g++ make build-essential zlib1g-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev git +} + +# Configure repos for stuff +setInstallRepos() +{ + # There is no Jammy repo yet so use Focal for Ubuntu 22.04 + if ([ "$osname" = "ubuntu" ] && [ "$fullrelno" = "20.04" ]); then + mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" + elif ([ "$osname" = "ubuntu" ] && [ "$fullrelno" = "22.04" ]); then + codename="focal" + 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 10 ]); then + mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 main" + else + codename="buster" + 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" +} + +# Install MongoDB +installMongo() +{ + wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/mongo.gpg > /dev/null + 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 + sleep 5 +} + +# Install NodeJS +installNodeJS() +{ + if [ "$1" == "update" ]; then + 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 + fi + fi + 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 + if [ "$1" == "update" ]; then + sudo chown "${USER}:${USER}" -R /meshcentral + cd /meshcentral + rm -rf node_modules/ + npm install meshcentral@${LATEST_MESH_VER} + sudo systemctl start meshcentral + fi +} + +# Install Redis +installRedis() +{ + sudo apt install -y redis +} + +# Install Python +installPython() +{ + if [ "$1" == "update" ]; then + HAS_PY310=$(python3.10 --version | grep ${PYTHON_VER}) + if ! [ $HAS_PY310 ]; then + printf >&2 "${GREEN}Updating to ${PYTHON_VER}${NC}\n" + fi + fi + + if [ "$INSTALL_TYPE" == "devinstall" ]; then + echo -e "${GREEN}Python already installed${NC}" + else + numprocs=$(nproc) + 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 $numprocs + sudo make altinstall + cd ~ + sudo rm -rf Python-${PYTHON_VER} Python-${PYTHON_VER}.tgz + if [ "$INSTALL_TYPE" == "devprep" ]; then + print_green 'All Prereqs installed' + exit + fi + fi +} + +# Install Postgresql +installPostgresql() +{ + echo "$postgresql_repo" | sudo tee /etc/apt/sources.list.d/pgdg.list + wget -qO - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/postgresql.gpg > /dev/null + sudo apt update && sudo apt install -y postgresql-14 + sleep 2 + sudo systemctl enable postgresql + sudo systemctl restart postgresql + sleep 5 +} + +# Install NATS +installNats() +{ + if [ "$1" == "update" ]; then + 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" + fi + fi + if [ "$1" == "install" ]; then + NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') + fi + nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) + wget -q 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} + if [ "$1" == "update" ]; then + sudo rm -f /usr/local/bin/nats-server + fi + 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 + rm -rf ${nats_tmp} +} + +# Install frontend +installFrontEnd() +{ + if [ "$1" == "update" ]; then + if [ -d /rmm/web ]; then + rm -rf /rmm/web + fi + + if [ ! -d /var/www/rmm ]; then + sudo mkdir -p /var/www/rmm + fi + fi + + webtar="trmm-web-v${WEB_VERSION}.tar.gz" + wget -q "$2" -O /tmp/${webtar} + + if [ "$1" == "update" ]; then + sudo rm -rf /var/www/rmm/dist + else + sudo mkdir -p /var/www/rmm + fi + sudo tar -xzf /tmp/${webtar} -C /var/www/rmm + echo "window._env_ = {PROD_URL: \"https://${rmmdomain}\"}" | sudo tee /var/www/rmm/dist/env-config.js > /dev/null + sudo chown www-data:www-data -R /var/www/rmm/dist + rm -f /tmp/${webtar} +} + +# Install Nginx +installNginx() +{ + if [ "$1" == "install" ]; then + sudo apt install -y nginx + sudo systemctl stop nginx + sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf + sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf + elif [ "$1" == "updatepart1" ]; then + ### Check Nginx config + if ! sudo nginx -t > /dev/null 2>&1; then + sudo nginx -t + echo -ne "\n" + echo -ne "${RED}You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script.${NC}\n" + echo -ne "${RED}Aborting...${NC}\n" + exit 1 + fi + elif [ "$1" == "updatepart2" ]; then + CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" /etc/nginx/nginx.conf) + if ! [ $CHECK_NGINX_WORKER_CONN ]; then + printf >&2 "${GREEN}Changing nginx worker connections to 2048${NC}\n" + sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf + fi + sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf + else + return + fi +} + +# Install NATS Api +installNatsApi() +{ + 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 +} + +# Install MeshCentral +installMeshCentral() +{ + MESH_VER=$(grep "^MESH_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') + + if [ "$1" == "install" ]; then + sudo mkdir -p /meshcentral/meshcentral-data + elif [ "$1" == "restore" ]; then + sudo tar -xzf $tmp_dir/meshcentral/mesh.tar.gz -C / + fi + sudo chown "${USER}:${USER}" -R /meshcentral + cd /meshcentral + npm install meshcentral@${MESH_VER} + sudo chown "${USER}:${USER}" -R /meshcentral +} + +# Install fail2ban +installFail2ban() +{ + sudo apt install -y fail2ban + + ### Copy default jail config to create override config + sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local + sudo truncate -s 0 /etc/fail2ban/jail.local + + ### Write default jail config override + sudo chmod 777 /etc/fail2ban/jail.local + sudo printf '[DEFAULT]' >> /etc/fail2ban/jail.local + sudo printf "\nignoreip = 127.0.0.1/8" >> /etc/fail2ban/jail.local + sudo printf "\n\n" >> /etc/fail2ban/jail.local + sudo printf '[sshd]' >> /etc/fail2ban/jail.local + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local + sudo printf "\nport = ssh" >> /etc/fail2ban/jail.local + sudo printf "\n\n" >> /etc/fail2ban/jail.local + sudo printf '[nginx-http-auth]' >> /etc/fail2ban/jail.local + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local + sudo printf "\n\n" >> /etc/fail2ban/jail.local + sudo printf '[nginx-botsearch]' >> /etc/fail2ban/jail.local + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local + sudo printf "\n\n" >> /etc/fail2ban/jail.local + sudo printf '[tacticalrmm]' >> /etc/fail2ban/jail.local + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local + sudo printf "\nport = http,https" >> /etc/fail2ban/jail.local + sudo printf "\nfilter = tacticalrmm" >> /etc/fail2ban/jail.local + sudo printf "\n" >> /etc/fail2ban/jail.local + sudo printf 'action = iptables-allports[name=tactical]' >> /etc/fail2ban/jail.local + sudo printf "\n" >> /etc/fail2ban/jail.local + sudo printf 'logpath = /rmm/api/tacticalrmm/tacticalrmm/private/log/access.log' >> /etc/fail2ban/jail.local + sudo printf "\nmaxretry = 5" >> /etc/fail2ban/jail.local + sudo printf "\nbantime = 3600" >> /etc/fail2ban/jail.local + sudo printf "\nfindtime = 3600" >> /etc/fail2ban/jail.local + sudo printf "\n\n" >> /etc/fail2ban/jail.local + sudo printf '[recidive]' >> /etc/fail2ban/jail.local + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local + sudo printf "\nbantime = 31536000 ; 1 year" >> /etc/fail2ban/jail.local + sudo chmod 644 /etc/fail2ban/jail.local + + ### Copy default app config to create override config + sudo cp /etc/fail2ban/fail2ban.conf /etc/fail2ban/fail2ban.local + sudo truncate -s 0 /etc/fail2ban/fail2ban.local + + ### Write default app config override + sudo chmod 777 /etc/fail2ban/fail2ban.local + sudo printf '[Definition]' >> /etc/fail2ban/fail2ban.local + sudo printf "\ndbpurgeage = 31579200" >> /etc/fail2ban/fail2ban.local + sudo printf "\nloglevel = INFO" >> /etc/fail2ban/fail2ban.local + sudo chmod 644 /etc/fail2ban/fail2ban.local + + ### Add T-RMM definition + sudo echo '[Definition]' | sudo tee /etc/fail2ban/filter.d/tacticalrmm.conf + sudo chmod 777 /etc/fail2ban/filter.d/tacticalrmm.conf + sudo printf "\n" >> /etc/fail2ban/filter.d/tacticalrmm.conf + sudo printf 'failregex = ^.*400.17.*$' >> /etc/fail2ban/filter.d/tacticalrmm.conf + sudo printf "\n" >> /etc/fail2ban/filter.d/tacticalrmm.conf + sudo printf 'ignoreregex = ^.*200.*$' >> /etc/fail2ban/filter.d/tacticalrmm.conf + sudo chmod 644 /etc/fail2ban/filter.d/tacticalrmm.conf + + ### Restart Fail2ban + sudo systemctl restart fail2ban +} \ No newline at end of file diff --git a/bash/NetworkFunctions.cfg b/bash/NetworkFunctions.cfg new file mode 100644 index 0000000000..4cf85c841c --- /dev/null +++ b/bash/NetworkFunctions.cfg @@ -0,0 +1,71 @@ +################### +# CFG file info # +################### + +CFG_VERSION="5" + + +####################### +# Network Functions # +####################### + +# Function to set site hostnames +setSiteHostname() +{ + local textcomp="0" + local runtimes=0 + local line1="" + local line2="" + until [ "$textcomp" == "" ]; do + runtimes=$(($runtimes+1)) + + # determine line number of localhost entry (this should always be the first entry) + line1=$(sed -n "/127.0.0.1/=" /etc/hosts) + + # determine next cumulative line number + line2=$(($line1+$runtimes)) + + # read total lines after localhost + textcomp=$(sed -n "$line2"p /etc/hosts) + + if [ "$textcomp" == "" ]; then + sudo sed -i "${runtimes} a\127.0.1.1\t$1.$2 $1" /etc/hosts + fi + done + + return +} + +# Check hosts file, add hosts +configHosts() +{ + # 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 + CHECK_LOCALHOST=$(grep "127.0.0.1 localhost" /etc/hosts) + if ! [ $CHECK_LOCALHOST ]; then + print_green 'Adding localhost to hosts file' + sudo sed -i '1i 127.0.0.1 localhost' /etc/hosts + fi + + CHECK_HOSTS=$(grep "127.0.1.1 $rmmdomain $frontenddomain $meshdomain" /etc/hosts) + if [[ $CHECK_HOSTS ]]; then + print_green 'Correcting subdomains entries' + sudo sed -i "/127.0.1.1 $rmmdomain $frontenddomain $meshdomain/d" /etc/hosts + setSiteHostname "$rmmhost" "$rootdomain"; + setSiteHostname "$frontendhost" "$rootdomain"; + setSiteHostname "$meshhost" "$rootdomain"; + else + setSiteHostname "$rmmhost" "$rootdomain"; + setSiteHostname "$frontendhost" "$rootdomain"; + setSiteHostname "$meshhost" "$rootdomain"; + fi + + BEHIND_NAT=false + IPV4=$(ip -4 addr | sed -ne 's|^.* inet \([^/]*\)/.* scope global.*$|\1|p' | head -1) + if echo "$IPV4" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then + BEHIND_NAT=true + fi +} \ No newline at end of file diff --git a/bash/ParentFunctions.cfg b/bash/ParentFunctions.cfg new file mode 100644 index 0000000000..065b72fb0b --- /dev/null +++ b/bash/ParentFunctions.cfg @@ -0,0 +1,687 @@ +################### +# CFG file info # +################### + +CFG_VERSION="5" + + +###################### +# Parent Functions # +###################### + +# Main install function +mainInstall() +{ + ### Repo info for Postegres and Mongo + setInstallRepos; + + ### Create usernames and passwords + generateUsersAndPass; + + ### This does... something + cls; + + ### Get host/domain info + getHostAndDomainInfo; + + ### Configure hosts file + print_green 'Configuring Hosts file' + configHosts; + + ### Certificate generation + print_green 'Installing Certbot' + installCertbot; + + ### Install Nginx + print_green 'Installing Nginx' + installNginx; + + ### Install NodeJS + print_green 'Installing NodeJS' + installNodeJS; + + ### Install and enable MongoDB + print_green 'Installing MongoDB' + installMongo; + + ### Install Python + print_green "Installing Python ${PYTHON_VER}" + installPython; + + ### Installing Redis + print_green 'Installing redis' + installRedis; + + ### Install and enable Postgresql + print_green 'Installing postgresql' + installPostgresql; + + ### Postgres DB creation + print_green 'Creating database for the rmm' + createPGDB; + + ### Clone main repo + print_green 'Cloning primary repo' + clonePrimaryRepo "install" "$REPO_URL" "$BRANCH"; + + ### Clone scripts repo + print_green 'Cloning community scripts repo' + cloneScriptsRepo "install" "$SCRIPTS_REPO_URL"; + + ### Installing NATS + print_green 'Installing NATS' + installNats "$INSTALL_TYPE"; + + ### Install MeshCentral + print_green 'Installing MeshCentral' + installMeshCentral "install"; + + ### Create MeshCentral config + print_green 'Generating MeshCentral Config' + createMeshConfig; + + ### Create local settings file + print_green 'Generating Local Settings' + createLocalSettings; + + ### Install NATS-API and correct permissions + print_green 'Installing NATS API' + installNatsApi; + + ### Install backend, configure primary admin user, setup admin 2fa + print_green 'Installing the backend' + configureBackend "install"; + + ### Determine Proc setting for UWSGI + print_green 'Optimizing UWSGI for number of processors' + setUwsgiProcs; + + ### Create UWSGI config + print_green 'Creating UWSGI configuration' + createUwsgiConf; + + ### Create RMM UWSGI systemd service + print_green 'Creating UWSGI service' + createUwsgiService; + + ### Create Daphne systemd service + print_green 'Creating Daphne service' + createDaphneService; + + ### Create NATS systemd service + print_green 'Creating NATS service' + createNatsService; + + ### Create NATS-api systemd service + print_green 'Creating NATS-API service' + createNatsApiService; + + ### Create Backend Nginx site config + print_green 'Creating Backend Nginx config' + createBackendNginxConf; + + ### Create MeshCentral Nginx configuration + print_green 'Creating MeshCentral Nginx config' + createMeshNginxConf; + + ### Enable Mesh and RMM sites + sudo ln -s /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-enabled/rmm.conf + sudo ln -s /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-enabled/meshcentral.conf + + ### Create conf directory + sudo mkdir /etc/conf.d + + ### Create Celery systemd service + print_green 'Creating Celery service' + createCeleryService; + + ### Configure Celery service + print_green 'Creating Celery config' + createCeleryConf; + + ### Create CeleryBeat systemd service + print_green 'Creating CeleryBeat service' + createCeleryBeatService; + + ### Correct conf dir ownership + sudo chown "${USER}:${USER}" -R /etc/conf.d/ + + ### Create MeshCentral systemd service + print_green 'Creating MeshCentral service' + createMeshCentralService; + + ### Update services info + sudo systemctl daemon-reload + + ### Verify and correct permissions + if [ -d ~/.npm ]; then + sudo chown -R "${USER}:${GROUP}" ~/.npm + fi + + if [ -d ~/.config ]; then + sudo chown -R "${USER}:${GROUP}" ~/.config + fi + + ### Install frontend + print_green 'Installing the frontend' + installFrontEnd "install" "$FRONTEND_URL"; + + ### Set front end Nginx config and enable + print_green 'Creating Frontend Nginx config' + createFrontendNginxConf; + + ### Enable Frontend site + sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf + + ### Enable RMM, Daphne, Celery, and Nginx services + print_green 'Enabling Services' + + for i in rmm.service daphne.service celery.service celerybeat.service nginx + do + sudo systemctl enable ${i} + sudo systemctl stop ${i} + sudo systemctl start ${i} + done + sleep 5 + + ### Enable MeshCentral service + print_green 'Starting meshcentral and waiting for it to install plugins' + enableMeshService; + + ### Generating MeshCentral key + print_green 'Generating meshcentral login token key' + generateMeshToken; + + ### Configuring MeshCentral admin user and device group, restart service + print_green 'Creating meshcentral account and group' + configMeshUserGroup; + + ### Enable and configure NATS service + print_green 'Starting NATS service' + enableNatsService; + + ### Disable django admin + sed -i 's/ADMIN_ENABLED = True/ADMIN_ENABLED = False/g' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + + ### Restart core services + print_green 'Restarting services' + + for i in rmm.service daphne.service celery.service celerybeat.service + do + sudo systemctl stop ${i} + sudo systemctl start ${i} + done + + ### Yay, we're done! + printf >&2 "${YELLOW}%0.s*${NC}" {1..80} + printf >&2 "\n\n" + printf >&2 "${YELLOW}Installation complete!${NC}\n\n" + printf >&2 "${YELLOW}Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n\n" + printf >&2 "${YELLOW}Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n\n" + printf >&2 "${YELLOW}MeshCentral username: ${GREEN}${meshusername}${NC}\n" + printf >&2 "${YELLOW}MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n\n" + + if [ "$BEHIND_NAT" = true ]; then + echo -ne "${YELLOW}Read below if your router does NOT support Hairpin NAT${NC}\n\n" + echo -ne "${GREEN}If you will be accessing the web interface of the RMM from the same LAN as this server,${NC}\n" + echo -ne "${GREEN}you'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" + echo -ne "${GREEN}This also applies to any agents that will be on the same local network as the rmm.${NC}\n" + echo -ne "${GREEN}You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp.${NC}\n\n" + fi + + printf >&2 "${YELLOW}Please refer to the github README for next steps${NC}\n\n" + printf >&2 "${YELLOW}%0.s*${NC}" {1..80} + printf >&2 "\n" + + return +} + +# Update function +updateTRMM() +{ + ### Check if user is same as during installation + checkSameUser "update"; + + ### Get current release version and check if update is necessary + checkIfUpdate; + + ### Get current versions of necessary included apps + checkAdditionalAppsVers; + + ### Clear screen + cls; + + ### Check CHECK_NATS_LIMITNOFILE, whatever that means + checkNatsLimitNoFile; + + ### Check Nginx config + installNginx "updatepart1"; + + ### Stop services + for i in nginx nats-api nats rmm daphne celery celerybeat + do + printf >&2 "${GREEN}Stopping ${i} service...${NC}\n" + sudo systemctl stop ${i} + done + + ### Rebuild uwsgi config + rm -f /rmm/api/tacticalrmm/app.ini + setUwsgiProcs; + createUwsgiConf; + + ### Check if Python is up to date, if not, update + installPython "update"; + + ### Check if NATS is up to date, if not, update + installNats "update"; + + ### This does stuff + if [ -d ~/.npm ]; then + sudo rm -rf ~/.npm + fi + + if [ -d ~/.cache ]; then + sudo rm -rf ~/.cache + fi + + if [ -d ~/.config ]; then + sudo chown -R "${USER}:${GROUP}" ~/.config + fi + + ### Check NodeJS version, update if needed and update MeshCentral + print_green 'Updating NodeJS' + installNodeJS "update"; + + ### Pull domain info from existing Nginx confs + rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + + ### Set symlinks to avoid security concerns and simplify Nginx config + sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem + sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem + + ### Update from main repo + print_green 'Cloning primary repo' + clonePrimaryRepo "update" "$REPO_URL" "$BRANCH"; + + ### Update from community-scripts repo + print_green 'Cloning community scripts repo' + cloneScriptsRepo "update" "$SCRIPTS_REPO_URL"; + + ### Apply updated Ownership and perms + sudo chown "${USER}:${USER}" -R /rmm + sudo chown "${USER}:${USER}" -R ${SCRIPTS_DIR} + sudo chown "${USER}:${USER}" /var/log/celery + sudo chown "${USER}:${USER}" -R /etc/conf.d/ + + ### Check additional Nginx settings and update + installNginx "updatepart2"; + + ### Update Nginx conf files + createMeshNginxConf; + createFrontendNginxConf; + createBackendNginxConf; + + ### Reconfigure backend + createCeleryConf; + configureBackend "update"; + + ### Disable Redis append only + turnOffRedisAppendOnly; + + ### Update Frontend + installFrontEnd "update" "$FRONTEND_URL"; + + ### Start services + for i in nats nats-api rmm daphne celery celerybeat nginx + do + printf >&2 "${GREEN}Starting ${i} service${NC}\n" + sudo systemctl start ${i} + done + sleep 1 + + ### Push agent updates + /rmm/api/env/bin/python /rmm/api/tacticalrmm/manage.py update_agents + + ### Update MeshCentral if necessary + updateMeshCentral; + createMeshConfig; + enableMeshService "update"; + + ### Cleanup + rm -f $TMP_SETTINGS + + ### Bye-bye + printf >&2 "${GREEN}Update finished!${NC}\n" + + return +} + +# Backup Function +backupTRMM() +{ + ### Pull Postgres info + POSTGRES_USER=$(grep -w USER /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//') + POSTGRES_PW=$(grep -w PASSWORD /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//') + + ### Check if rmmbackup folder exists, if not create it + if [ ! -d /rmmbackups ]; then + sudo mkdir /rmmbackups + sudo chown "${USER}:${USER}" /rmmbackups + fi + + ### Remove old MeshCentral backups + if [ -d /meshcentral/meshcentral-backup ]; then + rm -rf /meshcentral/meshcentral-backup/* + fi + + ### Remove old MeshCentral DB backups + if [ -d /meshcentral/meshcentral-coredumps ]; then + rm -f /meshcentral/meshcentral-coredumps/* + fi + + ### Set info for backup and folders + dt_now=$(date '+%Y_%m_%d__%H_%M_%S') + tmp_dir=$(mktemp -d -t tacticalrmm-XXXXXXXXXXXXXXXXXXXXX) + sysd="/etc/systemd/system" + + ### Create temp backup subdirectories + mkdir -p ${tmp_dir}/meshcentral/mongo + mkdir ${tmp_dir}/postgres + mkdir ${tmp_dir}/certs + mkdir ${tmp_dir}/nginx + mkdir ${tmp_dir}/systemd + mkdir ${tmp_dir}/rmm + mkdir ${tmp_dir}/confd + + ### Dump Postgres database + pg_dump --dbname=postgresql://"${POSTGRES_USER}":"${POSTGRES_PW}"@127.0.0.1:5432/tacticalrmm | gzip -9 > ${tmp_dir}/postgres/db-${dt_now}.psql.gz + + ### Backup Mesh stuff + tar -czvf ${tmp_dir}/meshcentral/mesh.tar.gz --exclude=/meshcentral/node_modules /meshcentral + mongodump --gzip --out=${tmp_dir}/meshcentral/mongo + + ### Backup certs + sudo tar -czvf ${tmp_dir}/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt . + + ### Backup Nginx configs + sudo tar -czvf ${tmp_dir}/nginx/etc-nginx.tar.gz -C /etc/nginx . + + ### Backup other config files + sudo tar -czvf ${tmp_dir}/confd/etc-confd.tar.gz -C /etc/conf.d . + + ### Copy service files + sudo cp ${sysd}/rmm.service ${sysd}/celery.service ${sysd}/celerybeat.service ${sysd}/meshcentral.service ${sysd}/nats.service ${sysd}/daphne.service ${tmp_dir}/systemd/ + if [ -f "${sysd}/nats-api.service" ]; then + sudo cp ${sysd}/nats-api.service ${tmp_dir}/systemd/ + fi + + 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/ + + tar -cf /rmmbackups/rmm-backup-${dt_now}.tar -C ${tmp_dir} . + + ### Remove temp files/folders + rm -rf ${tmp_dir} + + echo -ne "${GREEN}Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar${NC}\n" + + return +} + +# Restore T-RMM +restoreTRMM() +{ + ### Repo info for Postegres and Mongo + setInstallRepos; + + ### Get backup file location + getBackupFileLocation; + + ### Extract backup + extractBackup "$backuppath"; + + ### Check if original user + checkSameUser "restore"; + + ### Install NodeJS + print_green 'Installing NodeJS' + installNodeJS "install"; + + ### Install Nginx + print_green 'Installing Nginx' + installNginx "install"; + + ### Restore Nginx configuration + print_green 'Restoring Nginx configuration' + + sudo rm -rf /etc/nginx + sudo mkdir /etc/nginx + sudo tar -xzf $tmp_dir/nginx/etc-nginx.tar.gz -C /etc/nginx + sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf + rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + local temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" + local tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" + rootdomain="$temprootdomain.$tempdotsomething" + + ### Restore hosts config + configHosts; + + ### Restore Certbot + print_green 'Installing Certbot' + installCertbot "restore"; + + ### Restoring existing certs + 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 + + ### Set symlinks to avoid security concerns and simplify Nginx config + sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem + sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem + + ### Recreate Nginx conf files + createMeshNginxConf; + createFrontendNginxConf; + createBackendNginxConf; + + ### Restore Celery configs + print_green 'Restoring celery configs' + + sudo mkdir /etc/conf.d + sudo tar -xzf $tmp_dir/confd/etc-confd.tar.gz -C /etc/conf.d + sudo chown "${USER}:${USER}" -R /etc/conf.d + + ### Restoring services + print_green 'Restoring systemd services' + + sudo cp $tmp_dir/systemd/* /etc/systemd/system/ + sudo systemctl daemon-reload + + ### Install Python + print_green "Installing Python ${PYTHON_VER}" + installPython; + + ### Installing Redis + print_green 'Installing redis' + installRedis; + + ### Install and enable Postgresql + print_green 'Installing postgresql' + installPostgresql; + + ### Install and enable MongoDB + print_green 'Installing MongoDB' + installMongo; + + ### Restore Mongo database + print_green 'Restoring MongoDB' + mongorestore --gzip $tmp_dir/meshcentral/mongo + + ### Clone main repo + print_green 'Cloning primary repo' + clonePrimaryRepo "install" "$REPO_URL" "$BRANCH"; + + ### Clone scripts repo + print_green 'Cloning community scripts repo' + cloneScriptsRepo "install" "$SCRIPTS_REPO_URL"; + + ### Installing NATS + print_green 'Installing NATS' + installNats "install"; + + ### Restore MeshCentral + print_green 'Restoring MeshCentral' + installMeshCentral "restore"; + + ### Restore UWSGI + print_green 'Optimizing UWSGI for number of processors' + setUwsgiProcs; + print_green 'Creating UWSGI configuration' + createUwsgiConf; + + ### Restoring other misc stuff + cp $tmp_dir/rmm/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/ + cp $tmp_dir/rmm/env /rmm/web/.env + gzip -d $tmp_dir/rmm/debug.log.gz + cp $tmp_dir/rmm/django_debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/ + + ### Install NATS-API + print_green 'Installing NATS API' + installNatsApi; + + ### Restore Postgres database + print_green 'Restoring the Postgres 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" + createPGDB; + + gzip -d $tmp_dir/postgres/*.psql.gz + PGPASSWORD="${pgpw} psql -h localhost -U ${pgusername} -d tacticalrmm -f $tmp_dir/postgres/db*.psql" + + ### Restore Backend + print_green 'Restoring the backend' + configureBackend "restore"; + + ### Start NATS + print_green 'Start NATS' + sudo systemctl enable nats.service + sudo systemctl start nats.service + + ### Install frontend + print_green 'Installing the frontend' + installFrontEnd; + + # reset perms + sudo chown "${USER}:${USER}" -R /rmm + sudo chown "${USER}:${USER}" /var/log/celery + sudo chown "${USER}:${USER}" -R /etc/conf.d/ + sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.npm + sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.config + sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.cache + + ### Update services info + sudo systemctl daemon-reload + + ### Enable RMM, Daphne, Celery, Nats-api, and Nginx services + print_green 'Enabling Services' + + for i in celery.service celerybeat.service rmm.service daphne.service nats-api.service nginx + do + sudo systemctl enable ${i} + sudo systemctl stop ${i} + sudo systemctl start ${i} + done + sleep 5 + + ### Start MeshCentral + print_green 'Starting meshcentral' + sudo systemctl enable meshcentral + sudo systemctl start meshcentral + + ### Done!!!! + printf >&2 "${YELLOW}%0.s*${NC}" {1..80} + printf >&2 "\n\n" + printf >&2 "${YELLOW}Restore complete!${NC}\n\n" + printf >&2 "${YELLOW}%0.s*${NC}" {1..80} + printf >&2 "\n" + + return +} + +# Troubleshooting utility +troubleShoot() +{ + ### Resolve Locally used DNS server + locdns=$(resolvectl | grep 'Current DNS Server:' | cut -d: -f2 | awk '{ print $1}') + + ### Prompt for host, domain, and email info + getHostAndDomainInfo; + + ### Verify domains are live + pingDomain "$rmmdomain"; + pingDomain "$frontenddomain"; + pingDomain "$meshdomain"; + + ### Verify IPs + echo -ne "${YELLOW} Checking IPs${NC}" | tee -a checklog.log + printf >&2 "\n\n" + checkIPisLive "$rmmdomain"; + remapiip="${reminputip}" + checkIPisLive "$frontenddomain"; + checkIPisLive "$meshdomain"; + + ### Get services status + readServicesStatus; + + ### Verify services active + checkIfServiceActive "$rmmstatus" "RMM Service"; + checkIfServiceActive "$daphnestatus" "Daphne Service"; + checkIfServiceActive "$celerystatus" "Celery Service"; + checkIfServiceActive "$celerybeatstatus" "CeleryBeat Service"; + checkIfServiceActive "$nginxstatus" "Nginx Service"; + checkIfServiceActive "$natsstatus" "NATS Service"; + checkIfServiceActive "$natsapistatus" "NATS-API Service"; + checkIfServiceActive "$meshcentralstatus" "MeshCentral Service"; + checkIfServiceActive "$mongodstatus" "MongoD Service"; + checkIfServiceActive "$postgresqlstatus" "Postgresql Service"; + checkIfServiceActive "$redisserverstatus" "Redis-Server Service"; + + ### Get WAN IP + wanip=$(dig @resolver4.opendns.com myip.opendns.com +short) + echo -ne "${GREEN} WAN IP is $wanip.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + + ### Check if ports are open + isPortOpen "4222" "NATS"; + isPortOpen "80" "HTTP"; + isPortOpen "443" "HTTPS"; + + ### Checking Proxy + checkProxy; + + ### Check for valid cert + checkIfCertIsValid; + + ### Generate log summary + echo -ne "${YELLOW} Getting summary output of logs.${NC}" | 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" + + printf >&2 "\n\n" + echo -ne "${YELLOW} You will have a log file called checklog.log in the directory you ran this script from.${NC}" + printf >&2 "\n\n" + + return +} \ No newline at end of file diff --git a/bash/SystemInfoFunctions.cfg b/bash/SystemInfoFunctions.cfg index 28902fdd6f..920dbf20bb 100644 --- a/bash/SystemInfoFunctions.cfg +++ b/bash/SystemInfoFunctions.cfg @@ -1,3 +1,10 @@ +################### +# CFG file info # +################### + +CFG_VERSION="5" + + ########################### # System info functions # ########################### diff --git a/bash/TroubleshootingFunctions.cfg b/bash/TroubleshootingFunctions.cfg new file mode 100644 index 0000000000..e64790a201 --- /dev/null +++ b/bash/TroubleshootingFunctions.cfg @@ -0,0 +1,130 @@ +################### +# CFG file info # +################### + +CFG_VERSION="5" + + +############################### +# Troubleshooting functions # +############################### + +# Ping to test if domain is live +pingDomain() +{ + if ping -c 1 $1 &> /dev/null + then + echo -ne "${GREEN} Verified $1${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$1 doesnt exist please create it or check for a typo.\n\nYou will have a log file called checklog.log in the directory you ran this script from.\n\nExiting." 0 0 + clear -x + exit + fi +} + +# Check IPs +checkIPisLive() +{ + locinputip=`dig @"$locdns" +short $1` + reminputip=`dig @8.8.8.8 +short $1` + + if [ "$locinputip" = "$reminputip" ]; then + echo -ne "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + echo -ne "${RED} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log + printf >&2 "\n\n" | tee -a checklog.log + echo -ne "${RED} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + fi +} + +# Check services status +readServicesStatus() +{ + rmmstatus=$(systemctl is-active rmm) + daphnestatus=$(systemctl is-active daphne) + celerystatus=$(systemctl is-active celery) + celerybeatstatus=$(systemctl is-active celerybeat) + nginxstatus=$(systemctl is-active nginx) + natsstatus=$(systemctl is-active nats) + natsapistatus=$(systemctl is-active nats-api) + meshcentralstatus=$(systemctl is-active meshcentral) + mongodstatus=$(systemctl is-active mongod) + postgresqlstatus=$(systemctl is-active postgresql) + redisserverstatus=$(systemctl is-active redis-server) +} + +# Verify services active +checkIfServiceActive() +{ + if [ $1 = active ]; then + echo -ne "${GREEN} Success $2 is Running.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + printf >&2 "\n\n" | tee -a checklog.log + echo -ne "${RED} $2 is not running. \(Tactical will not work without this\)${NC}" | tee -a checklog.log + printf >&2 "\n\n" + fi +} + +# Check for open ports +isPortOpen() +{ + if ( nc -zv $wanip $1 2>&1 >/dev/null ); then + echo -ne "${GREEN} $2 Port is open.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + echo -ne "${RED} $2 port is closed. \(you may want this if running locally only\)${NC}" | tee -a checklog.log + printf >&2 "\n\n" + fi +} + +# Check proxy +checkProxy() +{ + echo -ne "${YELLOW} Checking For Proxy.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + echo -ne "${YELLOW} ......this might take a while!!${NC}" + 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.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + echo -ne "${YELLOW} Proxy detected using Certificate.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + fi + + # Detect Proxy via IP + if [ $wanip != $remrmmip ]; then + echo -ne "${YELLOW} Proxy detected using IP.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + echo -ne "${GREEN} No Proxy detected using IP.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + fi +} + +# Check for valid cert +checkIfCertIsValid() +{ + echo -ne "${YELLOW} Checking if SSL Certificate is up to date.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + + # SSL Certificate check + cert=$(openssl verify -CAfile /etc/letsencrypt/live/$rootdomain/chain.pem /etc/letsencrypt/live/$rootdomain/cert.pem) + + if [ "$cert" == *"OK"* ]; then + echo -ne "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + else + echo -ne "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a checklog.log + printf >&2 "\n\n" + fi +} \ No newline at end of file diff --git a/bash/UpdateRestoreFunctions.cfg b/bash/UpdateRestoreFunctions.cfg new file mode 100644 index 0000000000..707c6541ea --- /dev/null +++ b/bash/UpdateRestoreFunctions.cfg @@ -0,0 +1,124 @@ +################### +# CFG file info # +################### + +CFG_VERSION="5" + + +########################################### +# Update and Restore specific functions # +########################################### + +# Check that user is same as during install +checkSameUser() +{ + strip="User=" + if [ "$1" == "update" ]; then + ORIGUSER=$(grep ${strip} /etc/systemd/system/rmm.service | sed -e "s/^${strip}//") + elif [ "$1" == "restore" ]; then + ORIGUSER=$(grep ${strip} $tmp_dir/systemd/rmm.service | sed -e "s/^${strip}//") + fi + if [ "$ORIGUSER" != "$USER" ]; then + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "You must run this update script from the same user account used during install: ${ORIGUSER}\n\nExiting." 0 0 + if [ "$1" == "restore" ]; then + rm -rf $tmp_dir + fi + clear -x + exit 1 + fi +} + +# Check if T-RMM update is necessary +checkIfUpdate() +{ + TMP_SETTINGS=$(mktemp -p "" "rmmsettings_XXXXXXXXXX") + curl -s -L "${LATEST_SETTINGS_URL}" > ${TMP_SETTINGS} + + LATEST_TRMM_VER=$(grep "^TRMM_VERSION" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') + CURRENT_TRMM_VER=$(grep "^TRMM_VERSION" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') + + if [ "${CURRENT_TRMM_VER}" == "${LATEST_TRMM_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then + printf >&2 "${GREEN}Already on latest version. Current version: ${CURRENT_TRMM_VER} Latest version: ${LATEST_TRMM_VER}${NC}\n" + rm -f $TMP_SETTINGS + exit 0 + fi +} + +# Get current versions of necessary included apps +checkAdditionalAppsVers() +{ + LATEST_MESH_VER=$(grep "^MESH_VER" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') + LATEST_PIP_VER=$(grep "^PIP_VER" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') + NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') + CURRENT_PIP_VER=$(grep "^PIP_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') +} + +# Check CHECK_NATS_LIMITNOFILE, whatever that means +checkNatsLimitNoFile() +{ + CHECK_NATS_LIMITNOFILE=$(grep LimitNOFILE /etc/systemd/system/nats.service) + if ! [ $CHECK_NATS_LIMITNOFILE ]; then + + sudo rm -f /etc/systemd/system/nats.service + createNatsService; + sudo systemctl daemon-reload + fi +} + +# Disable Redis append only +turnOffRedisAppendOnly() +{ + printf >&2 "${GREEN}Turning off redis aof${NC}\n" + sudo redis-cli config set appendonly no + sudo redis-cli config rewrite + sudo rm -f /var/lib/redis/appendonly.aof +} + +# Update MeshCentral +updateMeshCentral() +{ + 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" + sudo systemctl stop meshcentral + sudo chown "${USER}:${USER}" -R /meshcentral + cd /meshcentral + rm -rf node_modules/ + npm install meshcentral@${LATEST_MESH_VER} + sudo chown "${USER}:${USER}" -R /meshcentral + fi +} + +# Get backup location +getBackupFileLocation() +{ + backuppath="" + userconfirm="n" + + until [ "$userconfirm" == "y" ]; do + backuppath=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Path to Backup File" --inputbox "Enter the full path to the backup file, including filename:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Backup File Path" --yesno "Is this correct?\n$backuppath" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + if [ ! -f "$backuppath" ]; then + userconfirm="n" + derpDerp; + else + userconfirm="y" + fi + done + userconfirm="n" +} + +# Extract backup +extractBackup() +{ + print_green 'Unpacking backup' + tmp_dir=$(mktemp -d -t tacticalrmm-XXXXXXXXXXXXXXXXXXXXX) + + tar -xf ${1} -C $tmp_dir +} \ No newline at end of file diff --git a/bash/UserInput.cfg b/bash/UserInput.cfg new file mode 100644 index 0000000000..ccc7c63742 --- /dev/null +++ b/bash/UserInput.cfg @@ -0,0 +1,139 @@ +################### +# CFG file info # +################### + +CFG_VERSION="5" + + +################ +# User Input # +################ + +# Create usernames and passwords +generateUsersAndPass() +{ + DJANGO_SEKRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1) + ADMINURL=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 70 | head -n 1) + + dialog --cr-wrap --clear --yes-label "Automatic" --no-label "Manual" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "User and Password Generation" --yesno "Would you like to have usernames and passwords automatically randomly generated, or enter your own manually?" 0 0 + case $? in + 0 ) 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) + clear -x;; + + 1 ) userconfirm="n" + + ### Get MeshCentral admin username + until [ "$userconfirm" == "y" ]; do + meshusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --inputbox "Enter the MeshCentral Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --yesno "Is this correct?\n$meshusername" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + + ### Get MeshCentral admin password + MESHPASSWD="dont" + passinput="match" + until [ "$passinput" == "$MESHPASSWD" ]; do + MESHPASSWD=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Re-enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + if [ "$passinput" != "$MESHPASSWD" ]; then + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 + derpDerp; + else + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 + fi + done + + ### Get Postgresql admin username + until [ "$userconfirm" == "y" ]; do + pgusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --inputbox "Enter the Postgresql Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --yesno "Is this correct?\n$pgusername" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + + ### Get Postgresql admin password + pgpw="dont" + passinput="match" + until [ "$passinput" == "$pgpw" ]; do + pgpw=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Re-enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + if [ "$passinput" != "$pgpw" ]; then + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 + derpDerp; + else + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 + fi + done + clear -x;; + esac +} + +# Get host and domain info +getHostAndDomainInfo() +{ + hostsconfirm="n" + + until [ $hostsconfirm == "y" ]; do + rootdomain="none" + letsemail="none" + + ### Get root domain + while [[ $rootdomain != *[.]* ]]; do + rootdomain=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Root Domain" --inputbox "Enter the root domain (eg example.com or example.co.uk):" 10 90 3>&1 1>&2 2>&3) + rootdomain="$(translateToLowerCase $rootdomain)" + if [[ $rootdomain != *[.]* ]]; then + derpDerp; + fi + done + + ### Get backend hostname + rmmhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Backend Hostname" --inputbox "Enter the hostname for the backend (e.g. api):" 10 90 3>&1 1>&2 2>&3) + rmmhost="$(translateToLowerCase $rmmhost)" + + ### Get frontend hostname + frontendhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Frontend Hostname" --inputbox "Enter the hostname for the frontend (e.g. rmm):" 10 90 3>&1 1>&2 2>&3) + frontendhost="$(translateToLowerCase $frontendhost)" + + ### Get MeshCentral hostname + meshhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter MeshCentral Hostname" --inputbox "Enter the hostname for MeshCentral (e.g. mesh):" 10 90 3>&1 1>&2 2>&3) + meshhost="$(translateToLowerCase $meshhost)" + + ### Get Admin email + while [[ $letsemail != *[@]*[.]* ]]; do + letsemail=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Admin E-Mail Address" --inputbox "Enter a valid e-mail address for Django, MeshCentral, and LetsEncrypt:" 10 90 3>&1 1>&2 2>&3) + letsemail="$(translateToLowerCase $letsemail)" + if [[ $letsemail != *[@]*[.]* ]]; then + derpDerp; + fi + done + + ### Verify input + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Confirm Input" --yesno "Is this correct?\n\nroot domain: $rootdomain\nbackend: $rmmhost.$rootdomain\nfrontend: $frontendhost.$rootdomain\nmeshcentral: $meshhost.$rootdomain\ne-mail address: $letsemail" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + clear -x + + ### Combine host/domain entries for later use while keeping seperate entries as well + rmmdomain="$rmmhost.$rootdomain" + meshdomain="$meshhost.$rootdomain" + frontenddomain="$frontendhost.$rootdomain" +} \ No newline at end of file diff --git a/bashfunctions.cfg b/bashfunctions.cfg index f5e87f639e..7cf81c74cd 100644 --- a/bashfunctions.cfg +++ b/bashfunctions.cfg @@ -5,9 +5,9 @@ CFG_VERSION="5" -######################## -# Input verification # -######################## +############################# +# Input cleanup and error # +############################# errortrack=0 @@ -98,12 +98,12 @@ checkScriptVer() checkCfgVer() { TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") - curl -s -L "$1" > "$TMP_FILE" + curl -s -L "$1/$2" > "$TMP_FILE" NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') - if [ "$CFG_VERSION" -ne "$NEW_VER" ]; then - wget -q "$1" -O bashfunctions.cfg - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old bash function file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$2" 10 40 + if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then + wget -q "$1/$2" -O "$2" + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old bash function file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 rm -f $TMP_FILE clear -x exit 1 diff --git a/installer-util.sh b/installer-util.sh index a163ed6a23..b4e0d3f878 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -3,18 +3,20 @@ ### Menu option variables INPUT=/tmp/menu.sh.$$ menuselection="" -#declare -a menuoptions=('Test Install' 'Exit') + +### Arrays declare -a mainmenuoptions=('Installation' 'Update' 'Utilities' 'Exit') declare -a installmenuoptions=('Standard Install' 'Dev Test Prereqs' 'Dev Test Install' 'Return' 'Exit') declare -a updatemenuoptions=('Standard Update' 'Backup and Update' 'Force Update' 'Return' 'Exit') declare -a utilitymenuoptions=('Backup' 'Restore' 'Renew Certs' 'Import Certs' 'Edit UWSGI config' 'Add Fail2ban - Use at your own risk' 'Run Server Troubleshooter' 'Return' 'Exit') +declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunctions.cfg' 'UserInput.cfg' 'NetworkFunctions.cfg' 'InstallFunctions.cfg' 'DatabaseFunctions.cfg' 'CertificateFunctions.cfg' 'ConfigAndServiceFunctions.cfg' 'UpdateRestoreFunctions.cfg' 'TroubleshootingFunctions.cfg' 'ParentFunctions.cfg') ### Script Info variables REPO_OWNER="ninjamonkey198206" BRANCH="develop-installer-update" -CFG_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" +BASE_SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" SCRIPT_VERSION="66" -SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/install.sh" +SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/installer-util.sh" REPO_URL="https://github.com/${REPO_OWNER}/tacticalrmm.git" SCRIPTS_REPO_URL="https://github.com/amidaware/community-scripts.git" FRONTEND_URL="https://github.com/amidaware/tacticalrmm-web/releases/download/v${WEB_VERSION}/${webtar}" @@ -37,7 +39,7 @@ getCfgFiles() } ### Get bashfunctions file -getCfgFiles "$CFG_URL" "bashfunctions.cfg"; +getCfgFiles "$BASE_SCRIPT_URL" "bashfunctions.cfg"; ### Import functions . $PWD/bashfunctions.cfg @@ -49,16 +51,16 @@ setColors; # MiscFunctions getOSInfo; # SystemInfoFunctions ### Install script pre-reqs -installPreReqs; +installPreReqs; # InstallFunctions ### Check for new functions version, only include script name as variable -checkCfgVer "$CFG_URL" "$THIS_SCRIPT"; +checkCfgVer "$BASE_SCRIPT_URL" "bashfunctions.cfg" "$THIS_SCRIPT"; ### Check for new script version, pass script version, url, and script name variables in that order checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; ### Install additional prereqs -installAdditionalPreReqs; +installAdditionalPreReqs; # InstallFunctions ### Fallback if lsb_release -si returns anything else than Ubuntu, Debian, or Raspbian wutOSThis; # SystemInfoFunctions From 80bcbe2b63fa981a67e4c1aac50e1206d2229eb9 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 18 Jun 2022 11:33:43 -0500 Subject: [PATCH 037/203] Added security options file for rework --- bash/SystemLockdown.cfg | 163 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 bash/SystemLockdown.cfg diff --git a/bash/SystemLockdown.cfg b/bash/SystemLockdown.cfg new file mode 100644 index 0000000000..9e04b78fb4 --- /dev/null +++ b/bash/SystemLockdown.cfg @@ -0,0 +1,163 @@ +# Function to harden system against intruders +hardenOperatingSystem() +{ + echo " " + echo "############ Hardening system against intruders ############" + echo "############################################################" + + # prevent tmpfs exploits + sudo chmod 777 /etc/fstab + sudo printf "\ntmpfs /run/shm tmpfs defaults,noexec,nosuid 0 0" >> /etc/fstab + sudo chmod 644 /etc/fstab + + # enable general good security settings for ip traffic + sudo chmod 777 /etc/sysctl.conf + sudo printf "\n" >> /etc/sysctl.conf + sudo printf "\n# IP Spoofing protection" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.conf.all.rp_filter = 1" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.conf.default.rp_filter = 1" >> /etc/sysctl.conf + sudo printf "\n" >> /etc/sysctl.conf + sudo printf "\n# Ignore ICMP broadcast requests" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.icmp_echo_ignore_broadcasts = 1" >> /etc/sysctl.conf + sudo printf "\n" >> /etc/sysctl.conf + sudo printf "\n# Disable source packet routing" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.conf.all.accept_source_route = 0" >> /etc/sysctl.conf + sudo printf "\nnet.ipv6.conf.all.accept_source_route = 0" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.conf.default.accept_source_route = 0" >> /etc/sysctl.conf + sudo printf "\nnet.ipv6.conf.default.accept_source_route = 0" >> /etc/sysctl.conf + sudo printf "\n" >> /etc/sysctl.conf + sudo printf "\n# Ignore send redirects" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.conf.all.send_redirects = 0" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.conf.default.send_redirects = 0" >> /etc/sysctl.conf + sudo printf "\n" >> /etc/sysctl.conf + sudo printf "\n# Block SYN attacks" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.tcp_syncookies = 1" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.tcp_max_syn_backlog = 2048" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.tcp_synack_retries = 2" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.tcp_syn_retries = 5" >> /etc/sysctl.conf + sudo printf "\n" >> /etc/sysctl.conf + sudo printf "\n# Log Martians" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.conf.all.log_martians = 1" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.icmp_ignore_bogus_error_responses = 1" >> /etc/sysctl.conf + sudo printf "\n" >> /etc/sysctl.conf + sudo printf "\n# Ignore ICMP redirects" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.conf.all.accept_redirects = 0" >> /etc/sysctl.conf + sudo printf "\nnet.ipv6.conf.all.accept_redirects = 0" >> /etc/sysctl.conf + sudo printf "\nnet.ipv4.conf.default.accept_redirects = 0" >> /etc/sysctl.conf + sudo printf "\nnet.ipv6.conf.default.accept_redirects = 0" >> /etc/sysctl.conf + sudo printf "\n" >> /etc/sysctl.conf + sudo chmod 644 /etc/sysctl.conf + sudo sysctl -p + + # check dns first, use hosts as a backup option, prevent spoofing + sudo sed -i "s/order hosts,bind/order bind,hosts/" /etc/host.conf + + # create admin group + sudo groupadd admin + + # Add current user to admin group + sudo usermod -a -G admin $currentuser + + # Block root access to ssh and limit access to admin group + sudo sed -i "s/PermitRootLogin prohibit-password/PermitRootLogin no/" /etc/ssh/sshd_config + sudo sed -i "/PermitRootLogin no/ a DebianBanner no" /etc/ssh/sshd_config + sudo sed -i "/DebianBanner no/ a AllowGroups admin" /etc/ssh/sshd_config + + # override setting so admin is default root group + sudo dpkg-statoverride --update --add root admin 4750 /bin/su + + # rebuild kernel images with new information + sudo update-initramfs -c -k all + + # update boot menu with new images + sudo update-grub + + return +} + + +# Function to install and configure Fail2Ban, Tripwire, etc +installSecurity() +{ + echo " " + echo "############ Installing additional security software ############" + echo "#################################################################" + echo " " + + # install apps + sudo apt install -y rkhunter chkrootkit + + # set chkrootkit to scan daily + sudo sed -i 's/RUN_DAILY="false"/RUN_DAILY="true"/' /etc/chkrootkit.conf + + # set rkhunter to update and scan daily, as well as scan new installs to add to internal database + sudo sed -i 's/APT_AUTOGEN="false"/APT_AUTOGEN="true"/' /etc/default/rkhunter + sudo sed -i 's/CRON_DAILY_RUN=""/CRON_DAILY_RUN="true"/' /etc/default/rkhunter + sudo sed -i 's/CRON_DB_UPDATE=""/CRON_DB_UPDATE="true"/' /etc/default/rkhunter + + # remove common false positive from database and fix misconfig + sudo sed -i 's|#ALLOWHIDDENDIR=/etc/.java|ALLOWHIDDENDIR=/etc/.java|' /etc/rkhunter.conf + sudo sed -i 's|#ALLOWHIDDENDIR=/etc/.git|ALLOWHIDDENDIR=/etc/.git|' /etc/rkhunter.conf + sudo sed -i 's|#ALLOWHIDDENDIR=/dev/.lxc|ALLOWHIDDENDIR=/dev/.lxc|' /etc/rkhunter.conf + sudo sed -i 's|MIRRORS_MODE=1|MIRRORS_MODE=0|' /etc/rkhunter.conf + sudo sed -i 's|UPDATE_MIRRORS=0|UPDATE_MIRRORS=1|' /etc/rkhunter.conf + sudo sed -i 's|WEB_CMD="/bin/false"|WEB_CMD=""|' /etc/rkhunter.conf + + # allow local network clients to attempt logins and fail without being immediately banned + sudo sed -i -e "\$aALL: $subnetip\/$subnetmask" /etc/hosts.allow + + # update fkhunter database + sudo rkhunter --update + wait + + # update rkhunter based on new info + sudo rkhunter --propupd + wait + + # run rkhunter in non-interactive mode + sudo rkhunter --check --rwo + wait + + return +} + + +# Function to enable automatic security updates only +AutoSecurityUpdates() +{ + sudo apt install -y unattended-upgrades + + # Configure allowed automatic update sources - security only + sudo sed -i 's|"${distro_id}:${distro_codename}";|//"${distro_id}:${distro_codename}";|' /etc/apt/apt.conf.d/50unattended-upgrades + sudo sed -i 's|//Unattended-Upgrade::Mail "";|Unattended-Upgrade::Mail "root";|' /etc/apt/apt.conf.d/50unattended-upgrades + sudo sed -i 's|//Unattended-Upgrade::Remove-Unused-Dependencies "false";|Unattended-Upgrade::Remove-Unused-Dependencies "true";|' /etc/apt/apt.conf.d/50unattended-upgrades + sudo sed -i 's|// Unattended-Upgrade::OnlyOnACPower "true";|Unattended-Upgrade::OnlyOnACPower "true";|' /etc/apt/apt.conf.d/50unattended-upgrades + + # enable automatic updates + sudo truncate -s 0 /etc/apt/apt.conf.d/20auto-upgrades + sudo chmod 777 /etc/apt/apt.conf.d/20auto-upgrades + sudo printf 'APT::Periodic::Update-Package-Lists "1";' >> /etc/apt/apt.conf.d/20auto-upgrades + sudo printf "\n" >> /etc/apt/apt.conf.d/20auto-upgrades + sudo printf 'APT::Periodic::Download-Upgradeable-Packages "1";' >> /etc/apt/apt.conf.d/20auto-upgrades + sudo printf "\n" >> /etc/apt/apt.conf.d/20auto-upgrades + sudo printf 'APT::Periodic::AutocleanInterval "3";' >> /etc/apt/apt.conf.d/20auto-upgrades + sudo printf "\n" >> /etc/apt/apt.conf.d/20auto-upgrades + sudo printf 'APT::Periodic::Unattended-Upgrade "1";' >> /etc/apt/apt.conf.d/20auto-upgrades + sudo chmod 644 /etc/apt/apt.conf.d/20auto-upgrades + + # enable reboot check and email notification + sudo echo '#!/usr/bin/env bash' | sudo tee /etc/cron.hourly/reboot-check + sudo chmod 777 /etc/cron.hourly/reboot-check + sudo printf "\n\n" >> /etc/cron.hourly/reboot-check + sudo printf 'if [ -f /var/run/reboot-required ]; then' >> /etc/cron.hourly/reboot-check + sudo printf "\n\t" >> /etc/cron.hourly/reboot-check + sudo printf 'echo "A reboot is required following updates to server $(hostname -f)" | mail -s "Reboot Required" admin-email' >> /etc/cron.hourly/reboot-check + sudo printf "\nfi" >> /etc/cron.hourly/reboot-check + + sudo sed -i "s/admin-email/$smtplogin/" /etc/cron.hourly/reboot-check + + sudo chown root:root /etc/cron.hourly/reboot-check + sudo chmod 755 /etc/cron.hourly/reboot-check + + return +} \ No newline at end of file From b70f922ec3f32a7467129897e862157b791b2f96 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 19 Jun 2022 17:29:36 -0500 Subject: [PATCH 038/203] Testing function to pull separate cfg files --- installer-util.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/installer-util.sh b/installer-util.sh index b4e0d3f878..b3bbba7ec7 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -34,13 +34,19 @@ LATEST_SETTINGS_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm getCfgFiles() { if [ ! -f "$PWD/$2" ]; then - wget -q "$1/$2" -O "$2" + wget -q "$1/bash/$2" -O "$PWD/bash/$2" fi } ### Get bashfunctions file getCfgFiles "$BASE_SCRIPT_URL" "bashfunctions.cfg"; +### Get cfg files +for i in "${cfgfiles[@]}" +do + getCfgFiles "$BASE_SCRIPT_URL" "$i"; +done + ### Import functions . $PWD/bashfunctions.cfg From 6cbf194eddd10cc4bffad69432f0faa54a20722e Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 19 Jun 2022 17:37:56 -0500 Subject: [PATCH 039/203] more testing --- bashfunctions.cfg | 4 ++-- installer-util.sh | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bashfunctions.cfg b/bashfunctions.cfg index 7cf81c74cd..b425302ad1 100644 --- a/bashfunctions.cfg +++ b/bashfunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="6" ############################# @@ -98,7 +98,7 @@ checkScriptVer() checkCfgVer() { TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") - curl -s -L "$1/$2" > "$TMP_FILE" + curl -s -L "$1/$2" > ${TMP_FILE} NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then diff --git a/installer-util.sh b/installer-util.sh index b3bbba7ec7..2aaeed31c2 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -41,6 +41,7 @@ getCfgFiles() ### Get bashfunctions file getCfgFiles "$BASE_SCRIPT_URL" "bashfunctions.cfg"; +mkdir -p $PWD/bash ### Get cfg files for i in "${cfgfiles[@]}" do From ec4feaa6a09e8d9cf3a74f0cd64dcfb77432f9c8 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 19 Jun 2022 17:44:14 -0500 Subject: [PATCH 040/203] troubleshooting altered cfg version check --- installer-util.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 2aaeed31c2..1af00b4471 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -15,7 +15,7 @@ declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunction REPO_OWNER="ninjamonkey198206" BRANCH="develop-installer-update" BASE_SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" -SCRIPT_VERSION="66" +SCRIPT_VERSION="67" SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/installer-util.sh" REPO_URL="https://github.com/${REPO_OWNER}/tacticalrmm.git" SCRIPTS_REPO_URL="https://github.com/amidaware/community-scripts.git" @@ -34,19 +34,19 @@ LATEST_SETTINGS_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm getCfgFiles() { if [ ! -f "$PWD/$2" ]; then - wget -q "$1/bash/$2" -O "$PWD/bash/$2" + wget -q "$1/$2" -O "$PWD/$2" fi } ### Get bashfunctions file getCfgFiles "$BASE_SCRIPT_URL" "bashfunctions.cfg"; -mkdir -p $PWD/bash +#mkdir -p $PWD/bash ### Get cfg files -for i in "${cfgfiles[@]}" -do - getCfgFiles "$BASE_SCRIPT_URL" "$i"; -done +#for i in "${cfgfiles[@]}" +#do +# getCfgFiles "$BASE_SCRIPT_URL" "$i"; +#done ### Import functions . $PWD/bashfunctions.cfg From 1393429648543b90a1ef8d99875433d2667380f5 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 19 Jun 2022 17:58:22 -0500 Subject: [PATCH 041/203] Prepping for cfg split --- {bash => bash-cfg}/CertificateFunctions.cfg | 0 .../ConfigAndServiceFunctions.cfg | 0 {bash => bash-cfg}/DatabaseFunctions.cfg | 0 {bash => bash-cfg}/InputAndError.cfg | 0 {bash => bash-cfg}/InstallFunctions.cfg | 0 {bash => bash-cfg}/MiscFunctions.cfg | 0 {bash => bash-cfg}/NetworkFunctions.cfg | 0 {bash => bash-cfg}/ParentFunctions.cfg | 0 {bash => bash-cfg}/SystemInfoFunctions.cfg | 0 {bash => bash-cfg}/SystemLockdown.cfg | 0 .../TroubleshootingFunctions.cfg | 0 {bash => bash-cfg}/UpdateRestoreFunctions.cfg | 0 {bash => bash-cfg}/UserInput.cfg | 0 bashfunctions.cfg | 2 +- installer-util.sh | 20 +++++++++++++++++-- 15 files changed, 19 insertions(+), 3 deletions(-) rename {bash => bash-cfg}/CertificateFunctions.cfg (100%) rename {bash => bash-cfg}/ConfigAndServiceFunctions.cfg (100%) rename {bash => bash-cfg}/DatabaseFunctions.cfg (100%) rename {bash => bash-cfg}/InputAndError.cfg (100%) rename {bash => bash-cfg}/InstallFunctions.cfg (100%) rename {bash => bash-cfg}/MiscFunctions.cfg (100%) rename {bash => bash-cfg}/NetworkFunctions.cfg (100%) rename {bash => bash-cfg}/ParentFunctions.cfg (100%) rename {bash => bash-cfg}/SystemInfoFunctions.cfg (100%) rename {bash => bash-cfg}/SystemLockdown.cfg (100%) rename {bash => bash-cfg}/TroubleshootingFunctions.cfg (100%) rename {bash => bash-cfg}/UpdateRestoreFunctions.cfg (100%) rename {bash => bash-cfg}/UserInput.cfg (100%) diff --git a/bash/CertificateFunctions.cfg b/bash-cfg/CertificateFunctions.cfg similarity index 100% rename from bash/CertificateFunctions.cfg rename to bash-cfg/CertificateFunctions.cfg diff --git a/bash/ConfigAndServiceFunctions.cfg b/bash-cfg/ConfigAndServiceFunctions.cfg similarity index 100% rename from bash/ConfigAndServiceFunctions.cfg rename to bash-cfg/ConfigAndServiceFunctions.cfg diff --git a/bash/DatabaseFunctions.cfg b/bash-cfg/DatabaseFunctions.cfg similarity index 100% rename from bash/DatabaseFunctions.cfg rename to bash-cfg/DatabaseFunctions.cfg diff --git a/bash/InputAndError.cfg b/bash-cfg/InputAndError.cfg similarity index 100% rename from bash/InputAndError.cfg rename to bash-cfg/InputAndError.cfg diff --git a/bash/InstallFunctions.cfg b/bash-cfg/InstallFunctions.cfg similarity index 100% rename from bash/InstallFunctions.cfg rename to bash-cfg/InstallFunctions.cfg diff --git a/bash/MiscFunctions.cfg b/bash-cfg/MiscFunctions.cfg similarity index 100% rename from bash/MiscFunctions.cfg rename to bash-cfg/MiscFunctions.cfg diff --git a/bash/NetworkFunctions.cfg b/bash-cfg/NetworkFunctions.cfg similarity index 100% rename from bash/NetworkFunctions.cfg rename to bash-cfg/NetworkFunctions.cfg diff --git a/bash/ParentFunctions.cfg b/bash-cfg/ParentFunctions.cfg similarity index 100% rename from bash/ParentFunctions.cfg rename to bash-cfg/ParentFunctions.cfg diff --git a/bash/SystemInfoFunctions.cfg b/bash-cfg/SystemInfoFunctions.cfg similarity index 100% rename from bash/SystemInfoFunctions.cfg rename to bash-cfg/SystemInfoFunctions.cfg diff --git a/bash/SystemLockdown.cfg b/bash-cfg/SystemLockdown.cfg similarity index 100% rename from bash/SystemLockdown.cfg rename to bash-cfg/SystemLockdown.cfg diff --git a/bash/TroubleshootingFunctions.cfg b/bash-cfg/TroubleshootingFunctions.cfg similarity index 100% rename from bash/TroubleshootingFunctions.cfg rename to bash-cfg/TroubleshootingFunctions.cfg diff --git a/bash/UpdateRestoreFunctions.cfg b/bash-cfg/UpdateRestoreFunctions.cfg similarity index 100% rename from bash/UpdateRestoreFunctions.cfg rename to bash-cfg/UpdateRestoreFunctions.cfg diff --git a/bash/UserInput.cfg b/bash-cfg/UserInput.cfg similarity index 100% rename from bash/UserInput.cfg rename to bash-cfg/UserInput.cfg diff --git a/bashfunctions.cfg b/bashfunctions.cfg index b425302ad1..7dc66af592 100644 --- a/bashfunctions.cfg +++ b/bashfunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="6" +CFG_VERSION="7" ############################# diff --git a/installer-util.sh b/installer-util.sh index 1af00b4471..b340ba0439 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -15,7 +15,7 @@ declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunction REPO_OWNER="ninjamonkey198206" BRANCH="develop-installer-update" BASE_SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" -SCRIPT_VERSION="67" +SCRIPT_VERSION="68" SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/installer-util.sh" REPO_URL="https://github.com/${REPO_OWNER}/tacticalrmm.git" SCRIPTS_REPO_URL="https://github.com/amidaware/community-scripts.git" @@ -41,7 +41,11 @@ getCfgFiles() ### Get bashfunctions file getCfgFiles "$BASE_SCRIPT_URL" "bashfunctions.cfg"; -#mkdir -p $PWD/bash +### Check if directory exists, if not, create +#if [ ! -d $PWD/bash-cfg ]; then +# mkdir bash-cfg +#fi + ### Get cfg files #for i in "${cfgfiles[@]}" #do @@ -50,6 +54,18 @@ getCfgFiles "$BASE_SCRIPT_URL" "bashfunctions.cfg"; ### Import functions . $PWD/bashfunctions.cfg +. $PWD/InputAndError.cfg +. $PWD/MiscFunctions.cfg +. $PWD/SystemInfoFunctions.cfg +. $PWD/UserInput.cfg +. $PWD/NetworkFunctions.cfg +. $PWD/InstallFunctions.cfg +. $PWD/DatabaseFunctions.cfg +. $PWD/CertificateFunctions.cfg +. $PWD/ConfigAndServiceFunctions.cfg +. $PWD/UpdateRestoreFunctions.cfg +. $PWD/TroubleshootingFunctions.cfg +. $PWD/ParentFunctions.cfg ### Set colors setColors; # MiscFunctions From 4939caba78a15d189edf960acae6609724ce889e Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 19 Jun 2022 17:59:56 -0500 Subject: [PATCH 042/203] commented out cfg imports because I forgot --- installer-util.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index b340ba0439..6e35ccc29b 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -54,18 +54,18 @@ getCfgFiles "$BASE_SCRIPT_URL" "bashfunctions.cfg"; ### Import functions . $PWD/bashfunctions.cfg -. $PWD/InputAndError.cfg -. $PWD/MiscFunctions.cfg -. $PWD/SystemInfoFunctions.cfg -. $PWD/UserInput.cfg -. $PWD/NetworkFunctions.cfg -. $PWD/InstallFunctions.cfg -. $PWD/DatabaseFunctions.cfg -. $PWD/CertificateFunctions.cfg -. $PWD/ConfigAndServiceFunctions.cfg -. $PWD/UpdateRestoreFunctions.cfg -. $PWD/TroubleshootingFunctions.cfg -. $PWD/ParentFunctions.cfg +#. $PWD/InputAndError.cfg +#. $PWD/MiscFunctions.cfg +#. $PWD/SystemInfoFunctions.cfg +#. $PWD/UserInput.cfg +#. $PWD/NetworkFunctions.cfg +#. $PWD/InstallFunctions.cfg +#. $PWD/DatabaseFunctions.cfg +#. $PWD/CertificateFunctions.cfg +#. $PWD/ConfigAndServiceFunctions.cfg +#. $PWD/UpdateRestoreFunctions.cfg +#. $PWD/TroubleshootingFunctions.cfg +#. $PWD/ParentFunctions.cfg ### Set colors setColors; # MiscFunctions From add51010a304b39d5ec600f4c8f90f745a2bccf8 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 19 Jun 2022 18:01:48 -0500 Subject: [PATCH 043/203] more --- bashfunctions.cfg | 4 ++-- installer-util.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bashfunctions.cfg b/bashfunctions.cfg index 7dc66af592..c4eb4ad21e 100644 --- a/bashfunctions.cfg +++ b/bashfunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="7" +CFG_VERSION="8" ############################# @@ -103,7 +103,7 @@ checkCfgVer() if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then wget -q "$1/$2" -O "$2" - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old bash function file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 rm -f $TMP_FILE clear -x exit 1 diff --git a/installer-util.sh b/installer-util.sh index 6e35ccc29b..64df80c580 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -15,7 +15,7 @@ declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunction REPO_OWNER="ninjamonkey198206" BRANCH="develop-installer-update" BASE_SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" -SCRIPT_VERSION="68" +SCRIPT_VERSION="69" SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/installer-util.sh" REPO_URL="https://github.com/${REPO_OWNER}/tacticalrmm.git" SCRIPTS_REPO_URL="https://github.com/amidaware/community-scripts.git" From 48998be9a000f69a583f32c1179c074c5eb85cb6 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 20 Jun 2022 11:28:56 -0500 Subject: [PATCH 044/203] updated to new dir and updated cfg update --- bashfunctions.cfg | 22 ++++++- installer-util.sh | 66 +++++++++++-------- .../CertificateFunctions.cfg | 2 +- .../ConfigAndServiceFunctions.cfg | 2 +- .../DatabaseFunctions.cfg | 2 +- {bash-cfg => script-cfg}/InputAndError.cfg | 2 +- {bash-cfg => script-cfg}/InstallFunctions.cfg | 2 +- {bash-cfg => script-cfg}/MiscFunctions.cfg | 12 ++-- {bash-cfg => script-cfg}/NetworkFunctions.cfg | 2 +- {bash-cfg => script-cfg}/ParentFunctions.cfg | 2 +- .../SystemInfoFunctions.cfg | 2 +- {bash-cfg => script-cfg}/SystemLockdown.cfg | 0 .../TroubleshootingFunctions.cfg | 2 +- .../UpdateRestoreFunctions.cfg | 2 +- {bash-cfg => script-cfg}/UserInput.cfg | 2 +- 15 files changed, 77 insertions(+), 45 deletions(-) rename {bash-cfg => script-cfg}/CertificateFunctions.cfg (99%) rename {bash-cfg => script-cfg}/ConfigAndServiceFunctions.cfg (99%) rename {bash-cfg => script-cfg}/DatabaseFunctions.cfg (97%) rename {bash-cfg => script-cfg}/InputAndError.cfg (99%) rename {bash-cfg => script-cfg}/InstallFunctions.cfg (99%) rename {bash-cfg => script-cfg}/MiscFunctions.cfg (94%) rename {bash-cfg => script-cfg}/NetworkFunctions.cfg (99%) rename {bash-cfg => script-cfg}/ParentFunctions.cfg (99%) rename {bash-cfg => script-cfg}/SystemInfoFunctions.cfg (99%) rename {bash-cfg => script-cfg}/SystemLockdown.cfg (100%) rename {bash-cfg => script-cfg}/TroubleshootingFunctions.cfg (99%) rename {bash-cfg => script-cfg}/UpdateRestoreFunctions.cfg (99%) rename {bash-cfg => script-cfg}/UserInput.cfg (99%) diff --git a/bashfunctions.cfg b/bashfunctions.cfg index c4eb4ad21e..0d38f2d828 100644 --- a/bashfunctions.cfg +++ b/bashfunctions.cfg @@ -94,15 +94,33 @@ checkScriptVer() rm -f $TMP_FILE } +# Check for functions updates +#checkCfgVer() +#{ +# TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") +# curl -s -L "$1/$2" > ${TMP_FILE} +# NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') + +# if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then +# wget -q "$1/$2" -O "$2" +# dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 +# rm -f $TMP_FILE +# clear -x +# exit 1 +# fi + +# rm -f $TMP_FILE +#} + # Check for functions updates checkCfgVer() { TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") - curl -s -L "$1/$2" > ${TMP_FILE} + curl -s -L "$1/script-cfg/$2" > ${TMP_FILE} NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then - wget -q "$1/$2" -O "$2" + wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 rm -f $TMP_FILE clear -x diff --git a/installer-util.sh b/installer-util.sh index 64df80c580..a81c5e7481 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -30,42 +30,50 @@ PYTHON_VER='3.10.4' SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py' LATEST_SETTINGS_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/api/tacticalrmm/tacticalrmm/settings.py" +### Get cfg files function +#getCfgFiles() +##{ +# if [ ! -f "$PWD/$2" ]; then +# wget -q "$1/$2" -O "$PWD/$2" +# fi +#} + ### Get cfg files function getCfgFiles() { - if [ ! -f "$PWD/$2" ]; then - wget -q "$1/$2" -O "$PWD/$2" + if [ ! -f "$PWD/script-cfg/$2" ]; then + wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" fi } ### Get bashfunctions file -getCfgFiles "$BASE_SCRIPT_URL" "bashfunctions.cfg"; +#getCfgFiles "$BASE_SCRIPT_URL" "bashfunctions.cfg"; ### Check if directory exists, if not, create -#if [ ! -d $PWD/bash-cfg ]; then -# mkdir bash-cfg -#fi +if [ ! -d $PWD/script-cfg ]; then + mkdir $PWD/script-cfg +fi ### Get cfg files -#for i in "${cfgfiles[@]}" -#do -# getCfgFiles "$BASE_SCRIPT_URL" "$i"; -#done +for i in "${cfgfiles[@]}" +do + getCfgFiles "$BASE_SCRIPT_URL" "$i"; +done ### Import functions -. $PWD/bashfunctions.cfg -#. $PWD/InputAndError.cfg -#. $PWD/MiscFunctions.cfg -#. $PWD/SystemInfoFunctions.cfg -#. $PWD/UserInput.cfg -#. $PWD/NetworkFunctions.cfg -#. $PWD/InstallFunctions.cfg -#. $PWD/DatabaseFunctions.cfg -#. $PWD/CertificateFunctions.cfg -#. $PWD/ConfigAndServiceFunctions.cfg -#. $PWD/UpdateRestoreFunctions.cfg -#. $PWD/TroubleshootingFunctions.cfg -#. $PWD/ParentFunctions.cfg +#. $PWD/bashfunctions.cfg +. $PWD/script-cfg/InputAndError.cfg +. $PWD/script-cfg/MiscFunctions.cfg +. $PWD/script-cfg/SystemInfoFunctions.cfg +. $PWD/script-cfg/UserInput.cfg +. $PWD/script-cfg/NetworkFunctions.cfg +. $PWD/script-cfg/InstallFunctions.cfg +. $PWD/script-cfg/DatabaseFunctions.cfg +. $PWD/script-cfg/CertificateFunctions.cfg +. $PWD/script-cfg/ConfigAndServiceFunctions.cfg +. $PWD/script-cfg/UpdateRestoreFunctions.cfg +. $PWD/script-cfg/TroubleshootingFunctions.cfg +. $PWD/script-cfg/ParentFunctions.cfg ### Set colors setColors; # MiscFunctions @@ -76,11 +84,17 @@ getOSInfo; # SystemInfoFunctions ### Install script pre-reqs installPreReqs; # InstallFunctions -### Check for new functions version, only include script name as variable -checkCfgVer "$BASE_SCRIPT_URL" "bashfunctions.cfg" "$THIS_SCRIPT"; +### Check for new functions version, include url, filename, and script name as variables +#checkCfgVer "$BASE_SCRIPT_URL" "bashfunctions.cfg" "$THIS_SCRIPT"; # MiscFunctions + +### Check for new functions versions, include url, filename, and script name as variables +for i in "${cfgfiles[@]}" +do + checkCfgVer "$BASE_SCRIPT_URL" "$i" "$THIS_SCRIPT"; # MiscFunctions +done ### Check for new script version, pass script version, url, and script name variables in that order -checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; +checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; # MiscFunctions ### Install additional prereqs installAdditionalPreReqs; # InstallFunctions diff --git a/bash-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg similarity index 99% rename from bash-cfg/CertificateFunctions.cfg rename to script-cfg/CertificateFunctions.cfg index 94b18c98ce..d5a783879d 100644 --- a/bash-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="8" ########################### diff --git a/bash-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg similarity index 99% rename from bash-cfg/ConfigAndServiceFunctions.cfg rename to script-cfg/ConfigAndServiceFunctions.cfg index 4ffd1a65bc..dba6eaef3f 100644 --- a/bash-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="8" ####################################### diff --git a/bash-cfg/DatabaseFunctions.cfg b/script-cfg/DatabaseFunctions.cfg similarity index 97% rename from bash-cfg/DatabaseFunctions.cfg rename to script-cfg/DatabaseFunctions.cfg index a3ada48f05..13ae6cd2b6 100644 --- a/bash-cfg/DatabaseFunctions.cfg +++ b/script-cfg/DatabaseFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="8" ######################## diff --git a/bash-cfg/InputAndError.cfg b/script-cfg/InputAndError.cfg similarity index 99% rename from bash-cfg/InputAndError.cfg rename to script-cfg/InputAndError.cfg index 833e2ba009..96a4adddaf 100644 --- a/bash-cfg/InputAndError.cfg +++ b/script-cfg/InputAndError.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="8" ############################# diff --git a/bash-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg similarity index 99% rename from bash-cfg/InstallFunctions.cfg rename to script-cfg/InstallFunctions.cfg index 8fbdb43cce..9ea0a558e6 100644 --- a/bash-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="8" ####################### diff --git a/bash-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg similarity index 94% rename from bash-cfg/MiscFunctions.cfg rename to script-cfg/MiscFunctions.cfg index 5bb7150875..3e175919fb 100644 --- a/bash-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="8" ###################################################################################### @@ -54,15 +54,15 @@ checkScriptVer() } # Check for functions updates -checkMiscFuncVer() +checkCfgVer() { TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") - curl -s -L "$1" > "$TMP_FILE" + curl -s -L "$1/script-cfg/$2" > ${TMP_FILE} NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') - if [ "$CFG_VERSION" -ne "$NEW_VER" ]; then - wget -q "$1" -O MiscFunctions.cfg - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old MiscFunctions file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$2" 10 40 + if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then + wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 rm -f $TMP_FILE clear -x exit 1 diff --git a/bash-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg similarity index 99% rename from bash-cfg/NetworkFunctions.cfg rename to script-cfg/NetworkFunctions.cfg index 4cf85c841c..3db7d15a55 100644 --- a/bash-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="8" ####################### diff --git a/bash-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg similarity index 99% rename from bash-cfg/ParentFunctions.cfg rename to script-cfg/ParentFunctions.cfg index 065b72fb0b..21c40c590a 100644 --- a/bash-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="8" ###################### diff --git a/bash-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg similarity index 99% rename from bash-cfg/SystemInfoFunctions.cfg rename to script-cfg/SystemInfoFunctions.cfg index 920dbf20bb..7630410cd1 100644 --- a/bash-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="8" ########################### diff --git a/bash-cfg/SystemLockdown.cfg b/script-cfg/SystemLockdown.cfg similarity index 100% rename from bash-cfg/SystemLockdown.cfg rename to script-cfg/SystemLockdown.cfg diff --git a/bash-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg similarity index 99% rename from bash-cfg/TroubleshootingFunctions.cfg rename to script-cfg/TroubleshootingFunctions.cfg index e64790a201..d8e3c4c9ae 100644 --- a/bash-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="8" ############################### diff --git a/bash-cfg/UpdateRestoreFunctions.cfg b/script-cfg/UpdateRestoreFunctions.cfg similarity index 99% rename from bash-cfg/UpdateRestoreFunctions.cfg rename to script-cfg/UpdateRestoreFunctions.cfg index 707c6541ea..8c87734dda 100644 --- a/bash-cfg/UpdateRestoreFunctions.cfg +++ b/script-cfg/UpdateRestoreFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="8" ########################################### diff --git a/bash-cfg/UserInput.cfg b/script-cfg/UserInput.cfg similarity index 99% rename from bash-cfg/UserInput.cfg rename to script-cfg/UserInput.cfg index ccc7c63742..3c7a3af95d 100644 --- a/bash-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="5" +CFG_VERSION="8" ################ From 80e8260713f63cec102ddc113800674c66b2f6ad Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 20 Jun 2022 16:20:56 -0500 Subject: [PATCH 045/203] Finished updates for split cfg files --- installer-util.sh | 21 +++------------------ script-cfg/MiscFunctions.cfg | 11 +++++++---- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index a81c5e7481..cae3851d84 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -14,9 +14,8 @@ declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunction ### Script Info variables REPO_OWNER="ninjamonkey198206" BRANCH="develop-installer-update" -BASE_SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" SCRIPT_VERSION="69" -SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/installer-util.sh" +SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" REPO_URL="https://github.com/${REPO_OWNER}/tacticalrmm.git" SCRIPTS_REPO_URL="https://github.com/amidaware/community-scripts.git" FRONTEND_URL="https://github.com/amidaware/tacticalrmm-web/releases/download/v${WEB_VERSION}/${webtar}" @@ -30,13 +29,6 @@ PYTHON_VER='3.10.4' SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py' LATEST_SETTINGS_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/api/tacticalrmm/tacticalrmm/settings.py" -### Get cfg files function -#getCfgFiles() -##{ -# if [ ! -f "$PWD/$2" ]; then -# wget -q "$1/$2" -O "$PWD/$2" -# fi -#} ### Get cfg files function getCfgFiles() @@ -46,9 +38,6 @@ getCfgFiles() fi } -### Get bashfunctions file -#getCfgFiles "$BASE_SCRIPT_URL" "bashfunctions.cfg"; - ### Check if directory exists, if not, create if [ ! -d $PWD/script-cfg ]; then mkdir $PWD/script-cfg @@ -57,11 +46,10 @@ fi ### Get cfg files for i in "${cfgfiles[@]}" do - getCfgFiles "$BASE_SCRIPT_URL" "$i"; + getCfgFiles "$SCRIPT_URL" "$i"; done ### Import functions -#. $PWD/bashfunctions.cfg . $PWD/script-cfg/InputAndError.cfg . $PWD/script-cfg/MiscFunctions.cfg . $PWD/script-cfg/SystemInfoFunctions.cfg @@ -84,13 +72,10 @@ getOSInfo; # SystemInfoFunctions ### Install script pre-reqs installPreReqs; # InstallFunctions -### Check for new functions version, include url, filename, and script name as variables -#checkCfgVer "$BASE_SCRIPT_URL" "bashfunctions.cfg" "$THIS_SCRIPT"; # MiscFunctions - ### Check for new functions versions, include url, filename, and script name as variables for i in "${cfgfiles[@]}" do - checkCfgVer "$BASE_SCRIPT_URL" "$i" "$THIS_SCRIPT"; # MiscFunctions + checkCfgVer "$SCRIPT_URL" "$i" "$THIS_SCRIPT"; # MiscFunctions done ### Check for new script version, pass script version, url, and script name variables in that order diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 3e175919fb..c1ea20205f 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -39,11 +39,11 @@ print_green() checkScriptVer() { TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") - curl -s -L "$2" > ${TMP_FILE} + curl -s -L "$2/$3" > ${TMP_FILE} NEW_VER=$(grep "^SCRIPT_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') if [ "$1" -ne "${NEW_VER}" ]; then - wget -q "$2" -O "$3" + wget -q "$2/$3" -O "$3" dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 rm -f $TMP_FILE clear -x @@ -162,8 +162,11 @@ decideMainRepos() userconfirm="n" BRANCH="$bran" - ### Check for new functions version, only include script name as variable - checkCfgVer "$CFG_URL" "$THIS_SCRIPT"; + ### Check for new functions versions, include url, filename, and script name as variables + for i in "${cfgfiles[@]}" + do + checkCfgVer "$SCRIPT_URL" "$i" "$THIS_SCRIPT"; # MiscFunctions + done ### Check for new script version, pass script version, url, and script name variables in that order checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; } \ No newline at end of file From 1a11c0ef74be01a32e0906d11da8f055861ee219 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 20 Jun 2022 16:43:18 -0500 Subject: [PATCH 046/203] Fix for split cfg check, added cfg url --- installer-util.sh | 7 ++++--- script-cfg/MiscFunctions.cfg | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index cae3851d84..35d5d4f13d 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -15,7 +15,8 @@ declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunction REPO_OWNER="ninjamonkey198206" BRANCH="develop-installer-update" SCRIPT_VERSION="69" -SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" +CFG_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" +SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/installer-util.sh" REPO_URL="https://github.com/${REPO_OWNER}/tacticalrmm.git" SCRIPTS_REPO_URL="https://github.com/amidaware/community-scripts.git" FRONTEND_URL="https://github.com/amidaware/tacticalrmm-web/releases/download/v${WEB_VERSION}/${webtar}" @@ -46,7 +47,7 @@ fi ### Get cfg files for i in "${cfgfiles[@]}" do - getCfgFiles "$SCRIPT_URL" "$i"; + getCfgFiles "$CFG_URL" "$i"; done ### Import functions @@ -75,7 +76,7 @@ installPreReqs; # InstallFunctions ### Check for new functions versions, include url, filename, and script name as variables for i in "${cfgfiles[@]}" do - checkCfgVer "$SCRIPT_URL" "$i" "$THIS_SCRIPT"; # MiscFunctions + checkCfgVer "$CFG_URL" "$i" "$THIS_SCRIPT"; # MiscFunctions done ### Check for new script version, pass script version, url, and script name variables in that order diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index c1ea20205f..09821f2516 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -39,11 +39,11 @@ print_green() checkScriptVer() { TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") - curl -s -L "$2/$3" > ${TMP_FILE} + curl -s -L "$2" > ${TMP_FILE} NEW_VER=$(grep "^SCRIPT_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') if [ "$1" -ne "${NEW_VER}" ]; then - wget -q "$2/$3" -O "$3" + wget -q "$2" -O "$3" dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 rm -f $TMP_FILE clear -x @@ -165,7 +165,7 @@ decideMainRepos() ### Check for new functions versions, include url, filename, and script name as variables for i in "${cfgfiles[@]}" do - checkCfgVer "$SCRIPT_URL" "$i" "$THIS_SCRIPT"; # MiscFunctions + checkCfgVer "$CFG_URL" "$i" "$THIS_SCRIPT"; # MiscFunctions done ### Check for new script version, pass script version, url, and script name variables in that order checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; From 97d642c5721e707d7c45555390d629097a2d011e Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 21 Jun 2022 12:45:32 -0500 Subject: [PATCH 047/203] Added function to check tactical user --- installer-util.sh | 3 +++ script-cfg/MiscFunctions.cfg | 41 ++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/installer-util.sh b/installer-util.sh index 35d5d4f13d..33133c1ad3 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -94,6 +94,9 @@ verifySupportedOS; # SystemInfoFunctions ### Check if root checkRoot; # MiscFunctions +### Check if Tactical user exists, if not prompt to create it +checkTacticalUser; # MiscFunctions + ### Check language/locale checkLocale; # SystemInfoFunctions diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 09821f2516..1c1cdf104e 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -81,6 +81,47 @@ checkRoot() fi } +# Check if Tactical user exists, if not prompt to create it +checkTacticalUser() +{ + local tacticaluser="" + local hassudo="" + if [ -d /rmm ]; then + tacticaluser=$(stat -c '%U' /rmm) + if [ "$tacticaluser" != "${USER}" ]; then + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 + else + return + fi + elif [ "${USER}" != "tactical" ]; then + tacticaluser="$(id -u tactical > /dev/null 2>&1; echo $?)" + case $tacticaluser in + 0 ) dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 + clear -x + exit 1;; + + 1 ) print_green 'Tactical user does not exist. Creating now.' + sudo useradd -m tactical + sudo usermod -a -G sudo tactical + sudo passwd tactical + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Created" --msgbox "The Tactical user has been created.\nPlease switch users, re-download the script, and try again.\n\nExiting." 0 0 + clear -x + exit 1;; + esac + elif [ "${USER}" == "tactical" ]; then + hassudo="$(id -nG tactical | grep -w 'sudo' > /dev/null 2>&1; echo $?)" + case $hassudo in + 0 ) return;; + + 1 ) print_green 'Adding Tactical user to sudo group.' + sudo usermod -a -G sudo tactical + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Sudo Privileges Added" --msgbox "The Tactical user has been added to the sudo group.\nPlease log out of the tactical user, log back in, and try again.\n\nExiting." 0 0 + clear -x + exit 1;; + esac + fi +} + # Clone primary repo clonePrimaryRepo() { From f828ff592fdd06a9d307231ecb9213a889c96b48 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 21 Jun 2022 12:48:01 -0500 Subject: [PATCH 048/203] Fixed missing exit if not right user --- script-cfg/MiscFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 1c1cdf104e..f398e2f0ae 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -90,8 +90,8 @@ checkTacticalUser() tacticaluser=$(stat -c '%U' /rmm) if [ "$tacticaluser" != "${USER}" ]; then dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 - else - return + clear -x + exit 1 fi elif [ "${USER}" != "tactical" ]; then tacticaluser="$(id -u tactical > /dev/null 2>&1; echo $?)" From 64e1eeab391603ea661107fce51f7fdcd8429cc3 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 21 Jun 2022 15:04:12 -0500 Subject: [PATCH 049/203] Automated tactical user and pass creation --- script-cfg/MiscFunctions.cfg | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index f398e2f0ae..3b1b8e075f 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -86,6 +86,9 @@ checkTacticalUser() { local tacticaluser="" local hassudo="" + local tacpass="" + + ### Check if dir exists, if so pull tactical user if [ -d /rmm ]; then tacticaluser=$(stat -c '%U' /rmm) if [ "$tacticaluser" != "${USER}" ]; then @@ -93,6 +96,7 @@ checkTacticalUser() clear -x exit 1 fi + ### If user not tactical, check if it exists. If so, exit. If not, create it elif [ "${USER}" != "tactical" ]; then tacticaluser="$(id -u tactical > /dev/null 2>&1; echo $?)" case $tacticaluser in @@ -103,11 +107,13 @@ checkTacticalUser() 1 ) print_green 'Tactical user does not exist. Creating now.' sudo useradd -m tactical sudo usermod -a -G sudo tactical - sudo passwd tactical - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Created" --msgbox "The Tactical user has been created.\nPlease switch users, re-download the script, and try again.\n\nExiting." 0 0 + tacpass="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)" + echo "tactical:$tacpass"| sudo chpasswd + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Created" --msgbox "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting." 0 0 clear -x exit 1;; esac + ### If user is tactical, verify sudo privileges. If none, add to sudo group elif [ "${USER}" == "tactical" ]; then hassudo="$(id -nG tactical | grep -w 'sudo' > /dev/null 2>&1; echo $?)" case $hassudo in From b576975abc38eb087d8a4f4e786745e3fe620cb2 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 21 Jun 2022 15:15:57 -0500 Subject: [PATCH 050/203] Updated useradd command to match docs --- script-cfg/MiscFunctions.cfg | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 3b1b8e075f..83cab0104b 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -105,8 +105,7 @@ checkTacticalUser() exit 1;; 1 ) print_green 'Tactical user does not exist. Creating now.' - sudo useradd -m tactical - sudo usermod -a -G sudo tactical + sudo useradd -m -G sudo -s /bin/bash tactical tacpass="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)" echo "tactical:$tacpass"| sudo chpasswd dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Created" --msgbox "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting." 0 0 From ed54e9091f587b7d0e7d73f5102737e5a26571e0 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 23 Jun 2022 11:56:51 -0500 Subject: [PATCH 051/203] Cleanup and prep for automated installs --- bashfunctions.cfg | 2106 ---------------------- installer-util.sh | 12 +- script-cfg/CertificateFunctions.cfg | 21 +- script-cfg/ConfigAndServiceFunctions.cfg | 4 +- script-cfg/InstallFunctions.cfg | 49 +- script-cfg/MiscFunctions.cfg | 65 +- script-cfg/ParentFunctions.cfg | 118 +- script-cfg/SystemInfoFunctions.cfg | 6 +- script-cfg/TroubleshootingFunctions.cfg | 85 +- script-cfg/UpdateRestoreFunctions.cfg | 6 +- script-cfg/UserInput.cfg | 25 +- 11 files changed, 212 insertions(+), 2285 deletions(-) delete mode 100644 bashfunctions.cfg diff --git a/bashfunctions.cfg b/bashfunctions.cfg deleted file mode 100644 index 0d38f2d828..0000000000 --- a/bashfunctions.cfg +++ /dev/null @@ -1,2106 +0,0 @@ -################### -# CFG file info # -################### - -CFG_VERSION="8" - - -############################# -# Input cleanup and error # -############################# - -errortrack=0 - -# Translate user input to all lower case to prevent ID10T errors -translateToLowerCase() -{ - local lowercase="" - lowercase="$(echo $1 | tr '[:upper:]' '[:lower:]')" - echo "$lowercase" -} - -# Function to track ID10T errors -derpDerp() -{ - if [ "$errortrack" -lt 12 ]; then - errortrack=$((errortrack+1)) - fi - - derptext="" - - case $errortrack in - 1 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "Need some coffee?" 10 30;; - 2 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You should get some coffee." 10 35;; - 3 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You are paying attention, right?" 10 40;; - 4 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "All your typos are belong to us." 10 40;; - 5 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "We're sorry, your fingers are too fat.\n\nIf you would like to obtain a typing wand,\nplease mash your hand on the keyboard now." 15 75;; - 6 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You have got to be kidding me...\n\nThis really isn't that difficult." 15 50;; - 7 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You're doing this intentionally, aren't you?\n\nThis really isn't that difficult." 15 75;; - 8 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "Please step away from the keyboard, and back away slowly.\n\nThe instructions are literally right there." 15 75;; - 9 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "You're making me angry.\nYou wouldn't like me when I'm angry.\n\nThe instructions are literally right there." 15 75;; - 10 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "How did you even get to this point?!\n\nThe instructions are literally right there." 15 75;; - 11 ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "Seriously, just give it up.\n\nI just can't with you right now..." 15 60;; - * ) dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SHAME... SHAME... SHAME..." --msgbox "\*sigh\* Why are you still here?\n\nI just can't with you right now..." 15 60;; - esac - - return -} - -###################################################################################### -# Misc Functions, must be before any functions except input verification functions # -###################################################################################### - -# Set bash text colors -setColors() -{ - GREEN='\033[0;32m' - YELLOW='\033[1;33m' - BLUE='\033[0;34m' - RED='\033[0;31m' - NC='\033[0m' -} - -# Clear screen -cls() -{ - printf "\033c" -} - -# Purdy install text -print_green() -{ - printf >&2 "${GREEN}%0.s-${NC}" {1..80} - printf >&2 "\n" - printf >&2 "${GREEN}${1}${NC}\n" - printf >&2 "${GREEN}%0.s-${NC}" {1..80} - printf >&2 "\n" -} - -# Check for new script version -checkScriptVer() -{ - TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") - curl -s -L "$2" > ${TMP_FILE} - NEW_VER=$(grep "^SCRIPT_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') - - if [ "$1" -ne "${NEW_VER}" ]; then - wget -q "$2" -O "$3" - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 - rm -f $TMP_FILE - clear -x - exit 1 - fi - - rm -f $TMP_FILE -} - -# Check for functions updates -#checkCfgVer() -#{ -# TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") -# curl -s -L "$1/$2" > ${TMP_FILE} -# NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') - -# if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then -# wget -q "$1/$2" -O "$2" -# dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 -# rm -f $TMP_FILE -# clear -x -# exit 1 -# fi - -# rm -f $TMP_FILE -#} - -# Check for functions updates -checkCfgVer() -{ - TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") - curl -s -L "$1/script-cfg/$2" > ${TMP_FILE} - NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') - - if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then - wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 - rm -f $TMP_FILE - clear -x - exit 1 - fi - - rm -f $TMP_FILE -} - -# Check for root as user -checkRoot() -{ - if [ $EUID -eq 0 ]; then - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Do NOT run this script as root. Exiting." 0 0 - clear -x - exit 1 - fi -} - -# Clone primary repo -clonePrimaryRepo() -{ - if [ "$1" == "install" ]; then - sudo mkdir /rmm - sudo chown "${USER}:${USER}" /rmm - sudo mkdir -p /var/log/celery - sudo chown "${USER}:${USER}" /var/log/celery - git clone "$2" /rmm/ - fi - cd /rmm - git config user.email "admin@example.com" - git config user.name "Bob" - if [ "$1" == "install" ]; then - git checkout "$3" - elif [ "$1" == "update" ]; then - git fetch - git checkout "$3" - git reset --hard FETCH_HEAD - git clean -df - git pull - fi -} - -# Clone scripts repo -cloneScriptsRepo() -{ - if [ ! -d "${SCRIPTS_DIR}" ]; then - sudo mkdir -p "${SCRIPTS_DIR}" - sudo chown "${USER}:${USER}" "${SCRIPTS_DIR}" - git clone "$2" "${SCRIPTS_DIR}"/ - fi - cd "${SCRIPTS_DIR}" - git config user.email "admin@example.com" - git config user.name "Bob" - if [ "$1" == "install" ]; then - git checkout main - elif [ "$1" == "update" ]; then - git fetch - git checkout main - git reset --hard FETCH_HEAD - git clean -df - git pull - fi -} - -# Set primary repos to use -decideMainRepos() -{ - userconfirm="n" - local own="" - local bran="" - - until [ "$userconfirm" == "y" ]; do - own=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository" --inputbox "Enter the dev repo owner name.\nThis is right after github.com in the URL:" 10 90 3>&1 1>&2 2>&3) - own="$(translateToLowerCase $own)" - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository" --yesno "Is this correct?\n$own" 0 0 - case $? in - 0 ) userconfirm="y" - clear -x;; - 1 ) userconfirm="n" - derpDerp;; - esac - done - userconfirm="n" - REPO_OWNER="$own" - - until [ "$userconfirm" == "y" ]; do - bran=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository Branch" --inputbox "Enter the dev repo branch name.\nThis is right after tacticalrmm in the URL:" 10 90 3>&1 1>&2 2>&3) - bran="$(translateToLowerCase $bran)" - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository Branch" --yesno "Is this correct?\n$bran" 0 0 - case $? in - 0 ) userconfirm="y" - clear -x;; - 1 ) userconfirm="n" - derpDerp;; - esac - done - userconfirm="n" - BRANCH="$bran" - - ### Check for new functions version, only include script name as variable - checkCfgVer "$CFG_URL" "$THIS_SCRIPT"; - ### Check for new script version, pass script version, url, and script name variables in that order - checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; -} - - -########################### -# System info functions # -########################### - -# Gather OS info -getOSInfo() -{ - osname=$(lsb_release -si); osname=${osname^} - osname=$(echo "$osname" | tr '[A-Z]' '[a-z]') - fullrel=$(lsb_release -sd) - codename=$(lsb_release -sc) - relno=$(lsb_release -sr | cut -d. -f1) - fullrelno=$(lsb_release -sr) -} - -# Check OS if not recognised -wutOSThis() -{ - if [ ! "$osname" = "ubuntu" ] && [ ! "$osname" = "debian" ]; then - osname=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"') - osname=${osname^} - fi -} - -# Verify Debian or Ubuntu and version -verifySupportedOS() -{ - if ([ "$osname" = "ubuntu" ] && ([ "$fullrelno" = "20.04" ] || [ "$fullrelno" = "22.04" ])) || ([ "$osname" = "debian" ] && [ $relno -ge 10 ]); then - echo "$fullrel" - else - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 - clear -x - exit 1 - fi -} - -# Check language/locale -checkLocale() -{ - if [[ "$LANG" != *".UTF-8" ]]; then - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "System locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting." 0 0 - clear -x - exit 1 - fi -} - - -################ -# User Input # -################ - -# Create usernames and passwords -generateUsersAndPass() -{ - DJANGO_SEKRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1) - ADMINURL=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 70 | head -n 1) - - dialog --cr-wrap --clear --yes-label "Automatic" --no-label "Manual" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "User and Password Generation" --yesno "Would you like to have usernames and passwords automatically randomly generated, or enter your own manually?" 0 0 - case $? in - 0 ) 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) - clear -x;; - - 1 ) userconfirm="n" - - ### Get MeshCentral admin username - until [ "$userconfirm" == "y" ]; do - meshusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --inputbox "Enter the MeshCentral Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --yesno "Is this correct?\n$meshusername" 0 0 - case $? in - 0 ) userconfirm="y";; - - 1 ) userconfirm="n" - derpDerp;; - esac - done - userconfirm="n" - - ### Get MeshCentral admin password - MESHPASSWD="dont" - passinput="match" - until [ "$passinput" == "$MESHPASSWD" ]; do - MESHPASSWD=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Re-enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - if [ "$passinput" != "$MESHPASSWD" ]; then - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 - derpDerp; - else - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 - fi - done - - ### Get Postgresql admin username - until [ "$userconfirm" == "y" ]; do - pgusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --inputbox "Enter the Postgresql Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --yesno "Is this correct?\n$pgusername" 0 0 - case $? in - 0 ) userconfirm="y";; - - 1 ) userconfirm="n" - derpDerp;; - esac - done - userconfirm="n" - - ### Get Postgresql admin password - pgpw="dont" - passinput="match" - until [ "$passinput" == "$pgpw" ]; do - pgpw=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Re-enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - if [ "$passinput" != "$pgpw" ]; then - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 - derpDerp; - else - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 - fi - done - clear -x;; - esac -} - -# Get host and domain info -getHostAndDomainInfo() -{ - hostsconfirm="n" - - until [ $hostsconfirm == "y" ]; do - rootdomain="none" - letsemail="none" - - ### Get root domain - while [[ $rootdomain != *[.]* ]]; do - rootdomain=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Root Domain" --inputbox "Enter the root domain (eg example.com or example.co.uk):" 10 90 3>&1 1>&2 2>&3) - rootdomain="$(translateToLowerCase $rootdomain)" - if [[ $rootdomain != *[.]* ]]; then - derpDerp; - fi - done - - ### Get backend hostname - rmmhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Backend Hostname" --inputbox "Enter the hostname for the backend (e.g. api):" 10 90 3>&1 1>&2 2>&3) - rmmhost="$(translateToLowerCase $rmmhost)" - - ### Get frontend hostname - frontendhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Frontend Hostname" --inputbox "Enter the hostname for the frontend (e.g. rmm):" 10 90 3>&1 1>&2 2>&3) - frontendhost="$(translateToLowerCase $frontendhost)" - - ### Get MeshCentral hostname - meshhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter MeshCentral Hostname" --inputbox "Enter the hostname for MeshCentral (e.g. mesh):" 10 90 3>&1 1>&2 2>&3) - meshhost="$(translateToLowerCase $meshhost)" - - ### Get Admin email - while [[ $letsemail != *[@]*[.]* ]]; do - letsemail=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Admin E-Mail Address" --inputbox "Enter a valid e-mail address for Django, MeshCentral, and LetsEncrypt:" 10 90 3>&1 1>&2 2>&3) - letsemail="$(translateToLowerCase $letsemail)" - if [[ $letsemail != *[@]*[.]* ]]; then - derpDerp; - fi - done - - ### Verify input - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Confirm Input" --yesno "Is this correct?\n\nroot domain: $rootdomain\nbackend: $rmmhost.$rootdomain\nfrontend: $frontendhost.$rootdomain\nmeshcentral: $meshhost.$rootdomain\ne-mail address: $letsemail" 0 0 - case $? in - 0 ) userconfirm="y";; - - 1 ) userconfirm="n" - derpDerp;; - esac - done - clear -x - - ### Combine host/domain entries for later use while keeping seperate entries as well - rmmdomain="$rmmhost.$rootdomain" - meshdomain="$meshhost.$rootdomain" - frontenddomain="$frontendhost.$rootdomain" -} - - -####################### -# Network Functions # -####################### - -# Function to set site hostnames -setSiteHostname() -{ - local textcomp="0" - local runtimes=0 - local line1="" - local line2="" - until [ "$textcomp" == "" ]; do - runtimes=$(($runtimes+1)) - - # determine line number of localhost entry (this should always be the first entry) - line1=$(sed -n "/127.0.0.1/=" /etc/hosts) - - # determine next cumulative line number - line2=$(($line1+$runtimes)) - - # read total lines after localhost - textcomp=$(sed -n "$line2"p /etc/hosts) - - if [ "$textcomp" == "" ]; then - sudo sed -i "${runtimes} a\127.0.1.1\t$1.$2 $1" /etc/hosts - fi - done - - return -} - -# Check hosts file, add hosts -configHosts() -{ - # 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 - CHECK_LOCALHOST=$(grep "127.0.0.1 localhost" /etc/hosts) - if ! [ $CHECK_LOCALHOST ]; then - print_green 'Adding localhost to hosts file' - sudo sed -i '1i 127.0.0.1 localhost' /etc/hosts - fi - - CHECK_HOSTS=$(grep "127.0.1.1 $rmmdomain $frontenddomain $meshdomain" /etc/hosts) - if [[ $CHECK_HOSTS ]]; then - print_green 'Correcting subdomains entries' - sudo sed -i "/127.0.1.1 $rmmdomain $frontenddomain $meshdomain/d" /etc/hosts - setSiteHostname "$rmmhost" "$rootdomain"; - setSiteHostname "$frontendhost" "$rootdomain"; - setSiteHostname "$meshhost" "$rootdomain"; - else - setSiteHostname "$rmmhost" "$rootdomain"; - setSiteHostname "$frontendhost" "$rootdomain"; - setSiteHostname "$meshhost" "$rootdomain"; - fi - - BEHIND_NAT=false - IPV4=$(ip -4 addr | sed -ne 's|^.* inet \([^/]*\)/.* scope global.*$|\1|p' | head -1) - if echo "$IPV4" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then - BEHIND_NAT=true - fi -} - - -####################### -# Install Functions # -####################### - -# Install script prereqs -installPreReqs() -{ - sudo apt update && sudo apt install -y curl wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev -} - -# Install remaining prereqs -installAdditionalPreReqs() -{ - sudo apt install -y software-properties-common openssl ca-certificates apt-transport-https gcc g++ make build-essential zlib1g-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev git -} - -# Configure repos for stuff -setInstallRepos() -{ - # There is no Jammy repo yet so use Focal for Ubuntu 22.04 - if ([ "$osname" = "ubuntu" ] && [ "$fullrelno" = "20.04" ]); then - mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" - elif ([ "$osname" = "ubuntu" ] && [ "$fullrelno" = "22.04" ]); then - codename="focal" - 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 10 ]); then - mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 main" - else - codename="buster" - 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" -} - -# Install MongoDB -installMongo() -{ - wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/mongo.gpg > /dev/null - 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 - sleep 5 -} - -# Install NodeJS -installNodeJS() -{ - if [ "$1" == "update" ]; then - 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 - fi - fi - 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 - if [ "$1" == "update" ]; then - sudo chown "${USER}:${USER}" -R /meshcentral - cd /meshcentral - rm -rf node_modules/ - npm install meshcentral@${LATEST_MESH_VER} - sudo systemctl start meshcentral - fi -} - -# Install Redis -installRedis() -{ - sudo apt install -y redis -} - -# Install Python -installPython() -{ - if [ "$1" == "update" ]; then - HAS_PY310=$(python3.10 --version | grep ${PYTHON_VER}) - if ! [ $HAS_PY310 ]; then - printf >&2 "${GREEN}Updating to ${PYTHON_VER}${NC}\n" - fi - fi - - if [ "$INSTALL_TYPE" == "devinstall" ]; then - echo -e "${GREEN}Python already installed${NC}" - else - numprocs=$(nproc) - 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 $numprocs - sudo make altinstall - cd ~ - sudo rm -rf Python-${PYTHON_VER} Python-${PYTHON_VER}.tgz - if [ "$INSTALL_TYPE" == "devprep" ]; then - print_green 'All Prereqs installed' - exit - fi - fi -} - -# Install Postgresql -installPostgresql() -{ - echo "$postgresql_repo" | sudo tee /etc/apt/sources.list.d/pgdg.list - wget -qO - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/postgresql.gpg > /dev/null - sudo apt update && sudo apt install -y postgresql-14 - sleep 2 - sudo systemctl enable postgresql - sudo systemctl restart postgresql - sleep 5 -} - -# Install NATS -installNats() -{ - if [ "$1" == "update" ]; then - 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" - fi - fi - if [ "$1" == "install" ]; then - NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') - fi - nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) - wget -q 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} - if [ "$1" == "update" ]; then - sudo rm -f /usr/local/bin/nats-server - fi - 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 - rm -rf ${nats_tmp} -} - -# Install frontend -installFrontEnd() -{ - if [ "$1" == "update" ]; then - if [ -d /rmm/web ]; then - rm -rf /rmm/web - fi - - if [ ! -d /var/www/rmm ]; then - sudo mkdir -p /var/www/rmm - fi - fi - - webtar="trmm-web-v${WEB_VERSION}.tar.gz" - wget -q "$2" -O /tmp/${webtar} - - if [ "$1" == "update" ]; then - sudo rm -rf /var/www/rmm/dist - else - sudo mkdir -p /var/www/rmm - fi - sudo tar -xzf /tmp/${webtar} -C /var/www/rmm - echo "window._env_ = {PROD_URL: \"https://${rmmdomain}\"}" | sudo tee /var/www/rmm/dist/env-config.js > /dev/null - sudo chown www-data:www-data -R /var/www/rmm/dist - rm -f /tmp/${webtar} -} - -# Install Nginx -installNginx() -{ - if [ "$1" == "install" ]; then - sudo apt install -y nginx - sudo systemctl stop nginx - sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf - sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf - elif [ "$1" == "updatepart1" ]; then - ### Check Nginx config - if ! sudo nginx -t > /dev/null 2>&1; then - sudo nginx -t - echo -ne "\n" - echo -ne "${RED}You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script.${NC}\n" - echo -ne "${RED}Aborting...${NC}\n" - exit 1 - fi - elif [ "$1" == "updatepart2" ]; then - CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" /etc/nginx/nginx.conf) - if ! [ $CHECK_NGINX_WORKER_CONN ]; then - printf >&2 "${GREEN}Changing nginx worker connections to 2048${NC}\n" - sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf - fi - sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf - else - return - fi -} - -# Install NATS Api -installNatsApi() -{ - 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 -} - -# Install MeshCentral -installMeshCentral() -{ - MESH_VER=$(grep "^MESH_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') - - if [ "$1" == "install" ]; then - sudo mkdir -p /meshcentral/meshcentral-data - elif [ "$1" == "restore" ]; then - sudo tar -xzf $tmp_dir/meshcentral/mesh.tar.gz -C / - fi - sudo chown "${USER}:${USER}" -R /meshcentral - cd /meshcentral - npm install meshcentral@${MESH_VER} - sudo chown "${USER}:${USER}" -R /meshcentral -} - -# Install fail2ban -installFail2ban() -{ - sudo apt install -y fail2ban - - ### Copy default jail config to create override config - sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local - sudo truncate -s 0 /etc/fail2ban/jail.local - - ### Write default jail config override - sudo chmod 777 /etc/fail2ban/jail.local - sudo printf '[DEFAULT]' >> /etc/fail2ban/jail.local - sudo printf "\nignoreip = 127.0.0.1/8" >> /etc/fail2ban/jail.local - sudo printf "\n\n" >> /etc/fail2ban/jail.local - sudo printf '[sshd]' >> /etc/fail2ban/jail.local - sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local - sudo printf "\nport = ssh" >> /etc/fail2ban/jail.local - sudo printf "\n\n" >> /etc/fail2ban/jail.local - sudo printf '[nginx-http-auth]' >> /etc/fail2ban/jail.local - sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local - sudo printf "\n\n" >> /etc/fail2ban/jail.local - sudo printf '[nginx-botsearch]' >> /etc/fail2ban/jail.local - sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local - sudo printf "\n\n" >> /etc/fail2ban/jail.local - sudo printf '[tacticalrmm]' >> /etc/fail2ban/jail.local - sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local - sudo printf "\nport = http,https" >> /etc/fail2ban/jail.local - sudo printf "\nfilter = tacticalrmm" >> /etc/fail2ban/jail.local - sudo printf "\n" >> /etc/fail2ban/jail.local - sudo printf 'action = iptables-allports[name=tactical]' >> /etc/fail2ban/jail.local - sudo printf "\n" >> /etc/fail2ban/jail.local - sudo printf 'logpath = /rmm/api/tacticalrmm/tacticalrmm/private/log/access.log' >> /etc/fail2ban/jail.local - sudo printf "\nmaxretry = 5" >> /etc/fail2ban/jail.local - sudo printf "\nbantime = 3600" >> /etc/fail2ban/jail.local - sudo printf "\nfindtime = 3600" >> /etc/fail2ban/jail.local - sudo printf "\n\n" >> /etc/fail2ban/jail.local - sudo printf '[recidive]' >> /etc/fail2ban/jail.local - sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local - sudo printf "\nbantime = 31536000 ; 1 year" >> /etc/fail2ban/jail.local - sudo chmod 644 /etc/fail2ban/jail.local - - ### Copy default app config to create override config - sudo cp /etc/fail2ban/fail2ban.conf /etc/fail2ban/fail2ban.local - sudo truncate -s 0 /etc/fail2ban/fail2ban.local - - ### Write default app config override - sudo chmod 777 /etc/fail2ban/fail2ban.local - sudo printf '[Definition]' >> /etc/fail2ban/fail2ban.local - sudo printf "\ndbpurgeage = 31579200" >> /etc/fail2ban/fail2ban.local - sudo printf "\nloglevel = INFO" >> /etc/fail2ban/fail2ban.local - sudo chmod 644 /etc/fail2ban/fail2ban.local - - ### Add T-RMM definition - sudo echo '[Definition]' | sudo tee /etc/fail2ban/filter.d/tacticalrmm.conf - sudo chmod 777 /etc/fail2ban/filter.d/tacticalrmm.conf - sudo printf "\n" >> /etc/fail2ban/filter.d/tacticalrmm.conf - sudo printf 'failregex = ^.*400.17.*$' >> /etc/fail2ban/filter.d/tacticalrmm.conf - sudo printf "\n" >> /etc/fail2ban/filter.d/tacticalrmm.conf - sudo printf 'ignoreregex = ^.*200.*$' >> /etc/fail2ban/filter.d/tacticalrmm.conf - sudo chmod 644 /etc/fail2ban/filter.d/tacticalrmm.conf - - ### Restart Fail2ban - sudo systemctl restart fail2ban -} - - -######################## -# Database Functions # -######################## - -# Postgres DB creation -createPGDB() -{ - 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}" -} - - -########################### -# Certificate Functions # -########################### - -# Renew Certs -renewCerts() -{ - rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - local temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" - local tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" - rootdomain="$temprootdomain.$tempdotsomething" - generateCerts; - sudo systemctl restart nginx.service rmm.service celery celerybeat.service nats-api.service nats.service meshcentral.service -} - -# Import certs -importCerts() -{ - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate and your private key, in that order.\n\nTo paste the contents, type i , then right click in the window.\n\nAfter pasting the contents, type esc , then shift-: , then x , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 - sudo vim /etc/ssl/certs/fullchain.pem - sudo vim /etc/ssl/private/privkey.pem -} - -# Generate certs -generateCerts() -{ - print_green 'Getting wildcard cert' - - ### Get initial DNS text entry - sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email - - ### Keep going until successful cert issue after adding DNS txt entry - while [[ $? -ne 0 ]]; do - sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email - done -} - -# Install Certbot and get initial certs -installCertbot() -{ - ### Install Certbot - sudo apt install -y certbot - if [ "$1" == "restore" ]; then - return - fi - - if [ "$INSTALL_TYPE" == "devinstall" ]; then - echo -e "${GREEN}Certificates should be in place${NC}" - else - dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have wildcard certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 - case $? in - ### Get wildcard cert via LetsEncrypt - 0 ) generateCerts;; - - 1 ) importCerts;; - esac - fi - - ### Set symlinks to avoid security concerns and simplify Nginx config - sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem - sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem - - ### Generate DH - if [ ! -f /etc/ssl/certs/dhparam.pem ]; then - sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096 - else - return - fi -} - - -####################################### -# Config file and service functions # -####################################### - -# Generate mesh configuration -createMeshConfig() -{ - sudo cp /rmm/default-configs/mesh/config.json /meshcentral/meshcentral-data/config.json - - sudo sed -i "s/mesh.example.com/$meshdomain/" /meshcentral/meshcentral-data/config.json -} - -# Generate local settings file -createLocalSettings() -{ - sudo cp /rmm/default-configs/python/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - - sudo sed -i "s/DJANGO_SEKRET/$DJANGO_SEKRET/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/api.example.com/$rmmdomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/ADMINURL/$ADMINURL/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/rmm.example.com/$frontenddomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/pgusername/$pgusername/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/pgpw/$pgpw/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/meshusername/$meshusername/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/mesh.example.com/$meshdomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py -} - -# Backend configuration -configureBackend() -{ - SETUPTOOLS_VER=$(grep "^SETUPTOOLS_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') - WHEEL_VER=$(grep "^WHEEL_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') - userconfirm="n" - - if [ "$1" == "update" ]; then - CHECK_ADMIN_ENABLED=$(grep ADMIN_ENABLED /rmm/api/tacticalrmm/tacticalrmm/local_settings.py) - if ! [ $CHECK_ADMIN_ENABLED ]; then - sudo sed -i '$ a ADMIN_ENABLED = False' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - 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 [ "${CURRENT_PIP_VER}" != "${LATEST_PIP_VER}" ] || [ "$UPDATE_TYPE" == "forced" ]; then - rm -rf /rmm/api/env - fi - fi - - if [ "${CURRENT_PIP_VER}" == "${LATEST_PIP_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then - source /rmm/api/env/bin/activate - cd /rmm/api/tacticalrmm - pip install -r /rmm/api/tacticalrmm/requirements.txt - else - cd /rmm/api - 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 - fi - - if [ "$1" == "update" ]; then - python manage.py pre_update_tasks - celery -A tacticalrmm purge -f - python manage.py migrate - python manage.py delete_tokens - python manage.py collectstatic --no-input - python manage.py reload_nats - python manage.py load_chocos - python manage.py create_installer_user - python manage.py create_natsapi_conf - python manage.py post_update_tasks - rmmdomain=$(python manage.py get_config api) - WEB_VERSION=$(python manage.py get_config webversion) - deactivate - elif [ "$1" == "restore" ]; then - python manage.py migrate - python manage.py collectstatic --no-input - python manage.py create_natsapi_conf - python manage.py reload_nats - python manage.py post_update_tasks - rmmdomain=$(python manage.py get_config api) - WEB_VERSION=$(python manage.py get_config webversion) - deactivate - else - 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 - WEB_VERSION=$(python manage.py get_config webversion) - until [ "$userconfirm" == "y" ]; do - djangousername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Create Site/Django Admin Login" --inputbox "Please enter the RMM website and django admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Create Site/Django Admin Login" --yesno "Is this correct?\n$djangousername" 0 0 - case $? in - 0 ) userconfirm="y";; - - 1 ) userconfirm="n" - derpDerp;; - esac - done - userconfirm="n" - clear -x - python manage.py createsuperuser --username ${djangousername} --email ${letsemail} - python manage.py create_installer_user - RANDBASE=$(python manage.py generate_totp) - cls; - python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} - deactivate - read -n 1 -s -r -p "Press any key to continue..." - fi -} - -# Set uwsgi procs -setUwsgiProcs() -{ - uwsgiprocs=4 - uwsgithreads=4 - if [[ "$numprocs" == "1" ]]; then - uwsgiprocs=2 - uwsgithreads=2 - else - uwsgiprocs=$numprocs - uwsgithreads=$numprocs - fi -} - -# Create UWSGI config -createUwsgiConf() -{ - sudo cp /rmm/default-configs/uwsgi/app.ini /rmm/api/tacticalrmm/app.ini - - sudo sed -i "s/uwsgiprocs/$uwsgiprocs/" /rmm/api/tacticalrmm/app.ini - sudo sed -i "s/uwsgithreads/$uwsgithreads/" /rmm/api/tacticalrmm/app.ini -} - -# Create UWSGI service -createUwsgiService() -{ - sudo cp /rmm/service-definitions/rmm.service /etc/systemd/system/rmm.service - - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/rmm.service -} - -# Create Daphne service -createDaphneService() -{ - sudo cp /rmm/service-definitions/daphne.service /etc/systemd/system/daphne.service - - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/daphne.service -} - -# Create NATS service -createNatsService() -{ - sudo cp /rmm/service-definitions/nats.service /etc/systemd/system/nats.service - - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats.service -} - -# Create NATS service -createNatsApiService() -{ - sudo cp /rmm/service-definitions/nats-api.service /etc/systemd/system/nats-api.service - - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats-api.service -} - -# Create backend nginx conf -createBackendNginxConf() -{ - sudo cp /rmm/default-configs/nginx/rmm.conf /etc/nginx/sites-available/rmm.conf - - sudo sed -i "s/api.example.com/$rmmdomain/" /etc/nginx/sites-available/rmm.conf - sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/rmm.conf -} - -# Create Mesh nginx conf -createMeshNginxConf() -{ - sudo cp /rmm/default-configs/nginx/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf - - sudo sed -i "s/mesh.example.com/$meshdomain/" /etc/nginx/sites-available/meshcentral.conf -} - -# Create Celery service -createCeleryService() -{ - sudo cp /rmm/service-definitions/celery.service /etc/systemd/system/celery.service - - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/celery.service -} - -# Create Celery config -createCeleryConf() -{ - sudo cp /rmm/default-configs/celery/celery.conf /etc/conf.d/celery.conf -} - -# Create CeleryBeat service -createCeleryBeatService() -{ - sudo cp /rmm/service-definitions/celerybeat.service /etc/systemd/system/celerybeat.service - - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/celerybeat.service -} - -# Create MeshCentral service -createMeshCentralService() -{ - sudo cp /rmm/service-definitions/meshcentral.service /etc/systemd/system/meshcentral.service - - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/meshcentral.service -} - -# Create Frontend Nginx config -createFrontendNginxConf() -{ - sudo cp /rmm/default-configs/nginx/frontend.conf /etc/nginx/sites-available/frontend.conf - - sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/frontend.conf -} - -# Enable MeshCentral service -enableMeshService() -{ - if [ "$1" != "update" ]; then - sudo systemctl enable meshcentral - fi - sudo systemctl restart meshcentral - sleep 3 - - # The first time we start meshcentral, it will need some time to generate certs and install plugins. - # This will take anywhere from a few seconds to a few minutes depending on the server's hardware - # We will know it's ready once the last line of the systemd service stdout is 'MeshCentral HTTP server running on port.....' - 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 - done -} - -# Generate Mesh Token -generateMeshToken() -{ - MESHTOKENKEY="$(node /meshcentral/node_modules/meshcentral --logintokenkey)" - - sudo sed -i '$ a MESH_TOKEN_KEY = "MESHTOKENKEY"' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/MESHTOKENKEY/$MESHTOKENKEY/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py -} - -# Configure Mesh user and group, restart service -configMeshUserGroup() -{ - sudo systemctl stop meshcentral - sleep 1 - cd /meshcentral - - node node_modules/meshcentral --createaccount ${meshusername} --pass ${MESHPASSWD} --email ${letsemail} - sleep 1 - node node_modules/meshcentral --adminaccount ${meshusername} - - sudo systemctl start meshcentral - 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 - done - - node node_modules/meshcentral/meshctrl.js --url wss://${meshdomain} --loginuser ${meshusername} --loginpass ${MESHPASSWD} AddDeviceGroup --name TacticalRMM - sleep 1 -} - -# Configure and enable NATS service -enableNatsService() -{ - sudo systemctl enable nats.service - cd /rmm/api/tacticalrmm - source /rmm/api/env/bin/activate - python manage.py initial_db_setup - python manage.py reload_nats - deactivate - sudo systemctl start nats.service - - sleep 1 - sudo systemctl enable nats-api.service - sudo systemctl start nats-api.service -} - -# Change UWSGI settings -changeUWSGIProcs() -{ - local countconfirm="n" - - ### Get UWSGI Processes value - until [ $countconfirm == "y" ]; do - uwsgiprocs=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Process Count" --inputbox "Enter the desired UWSGI Process Count, usually the same as CPU core count:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Process Count" --yesno "Is this correct?\n$uwsgiprocs" 0 0 - case $? in - 0 ) countconfirm="y";; - - 1 ) countconfirm="n" - derpDerp;; - esac - done - countconfirm="n" - - ### Get UWSGI Threads value - until [ $countconfirm == "y" ]; do - uwsgithreads=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Thread Count" --inputbox "Enter the desired UWSGI Process Count, usually the same as CPU core count:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Thread Count" --yesno "Is this correct?\n$uwsgithreads" 0 0 - case $? in - 0 ) countconfirm="y";; - - 1 ) countconfirm="n" - derpDerp;; - esac - done - countconfirm="n" - - ### Stop rmm service, copy default file, edit processes/threads, start service - sudo systemctl stop rmm - createUwsgiConf; - sudo systemctl start rmm -} - -########################################### -# Update and Restore specific functions # -########################################### - -# Check that user is same as during install -checkSameUser() -{ - strip="User=" - if [ "$1" == "update" ]; then - ORIGUSER=$(grep ${strip} /etc/systemd/system/rmm.service | sed -e "s/^${strip}//") - elif [ "$1" == "restore" ]; then - ORIGUSER=$(grep ${strip} $tmp_dir/systemd/rmm.service | sed -e "s/^${strip}//") - fi - if [ "$ORIGUSER" != "$USER" ]; then - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "You must run this update script from the same user account used during install: ${ORIGUSER}\n\nExiting." 0 0 - if [ "$1" == "restore" ]; then - rm -rf $tmp_dir - fi - clear -x - exit 1 - fi -} - -# Check if T-RMM update is necessary -checkIfUpdate() -{ - TMP_SETTINGS=$(mktemp -p "" "rmmsettings_XXXXXXXXXX") - curl -s -L "${LATEST_SETTINGS_URL}" > ${TMP_SETTINGS} - - LATEST_TRMM_VER=$(grep "^TRMM_VERSION" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') - CURRENT_TRMM_VER=$(grep "^TRMM_VERSION" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') - - if [ "${CURRENT_TRMM_VER}" == "${LATEST_TRMM_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then - printf >&2 "${GREEN}Already on latest version. Current version: ${CURRENT_TRMM_VER} Latest version: ${LATEST_TRMM_VER}${NC}\n" - rm -f $TMP_SETTINGS - exit 0 - fi -} - -# Get current versions of necessary included apps -checkAdditionalAppsVers() -{ - LATEST_MESH_VER=$(grep "^MESH_VER" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') - LATEST_PIP_VER=$(grep "^PIP_VER" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') - NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') - CURRENT_PIP_VER=$(grep "^PIP_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') -} - -# Check CHECK_NATS_LIMITNOFILE, whatever that means -checkNatsLimitNoFile() -{ - CHECK_NATS_LIMITNOFILE=$(grep LimitNOFILE /etc/systemd/system/nats.service) - if ! [ $CHECK_NATS_LIMITNOFILE ]; then - - sudo rm -f /etc/systemd/system/nats.service - createNatsService; - sudo systemctl daemon-reload - fi -} - -# Disable Redis append only -turnOffRedisAppendOnly() -{ - printf >&2 "${GREEN}Turning off redis aof${NC}\n" - sudo redis-cli config set appendonly no - sudo redis-cli config rewrite - sudo rm -f /var/lib/redis/appendonly.aof -} - -# Update MeshCentral -updateMeshCentral() -{ - 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" - sudo systemctl stop meshcentral - sudo chown "${USER}:${USER}" -R /meshcentral - cd /meshcentral - rm -rf node_modules/ - npm install meshcentral@${LATEST_MESH_VER} - sudo chown "${USER}:${USER}" -R /meshcentral - fi -} - -# Get backup location -getBackupFileLocation() -{ - backuppath="" - userconfirm="n" - - until [ "$userconfirm" == "y" ]; do - backuppath=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Path to Backup File" --inputbox "Enter the full path to the backup file, including filename:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Backup File Path" --yesno "Is this correct?\n$backuppath" 0 0 - case $? in - 0 ) userconfirm="y";; - - 1 ) userconfirm="n" - derpDerp;; - esac - if [ ! -f "$backuppath" ]; then - userconfirm="n" - derpDerp; - else - userconfirm="y" - fi - done - userconfirm="n" -} - -# Extract backup -extractBackup() -{ - print_green 'Unpacking backup' - tmp_dir=$(mktemp -d -t tacticalrmm-XXXXXXXXXXXXXXXXXXXXX) - - tar -xf ${1} -C $tmp_dir -} - - -############################### -# Troubleshooting functions # -############################### - -# Ping to test if domain is live -pingDomain() -{ - if ping -c 1 $1 &> /dev/null - then - echo -ne "${GREEN} Verified $1${NC}" | tee -a checklog.log - printf >&2 "\n\n" - else - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$1 doesnt exist please create it or check for a typo.\n\nYou will have a log file called checklog.log in the directory you ran this script from.\n\nExiting." 0 0 - clear -x - exit - fi -} - -# Check IPs -checkIPisLive() -{ - locinputip=`dig @"$locdns" +short $1` - reminputip=`dig @8.8.8.8 +short $1` - - if [ "$locinputip" = "$reminputip" ]; then - echo -ne "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log - printf >&2 "\n\n" - else - echo -ne "${RED} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log - printf >&2 "\n\n" | tee -a checklog.log - echo -ne "${RED} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - fi -} - -# Check services status -readServicesStatus() -{ - rmmstatus=$(systemctl is-active rmm) - daphnestatus=$(systemctl is-active daphne) - celerystatus=$(systemctl is-active celery) - celerybeatstatus=$(systemctl is-active celerybeat) - nginxstatus=$(systemctl is-active nginx) - natsstatus=$(systemctl is-active nats) - natsapistatus=$(systemctl is-active nats-api) - meshcentralstatus=$(systemctl is-active meshcentral) - mongodstatus=$(systemctl is-active mongod) - postgresqlstatus=$(systemctl is-active postgresql) - redisserverstatus=$(systemctl is-active redis-server) -} - -# Verify services active -checkIfServiceActive() -{ - if [ $1 = active ]; then - echo -ne "${GREEN} Success $2 is Running.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - else - printf >&2 "\n\n" | tee -a checklog.log - echo -ne "${RED} $2 is not running. \(Tactical will not work without this\)${NC}" | tee -a checklog.log - printf >&2 "\n\n" - fi -} - -# Check for open ports -isPortOpen() -{ - if ( nc -zv $wanip $1 2>&1 >/dev/null ); then - echo -ne "${GREEN} $2 Port is open.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - else - echo -ne "${RED} $2 port is closed. \(you may want this if running locally only\)${NC}" | tee -a checklog.log - printf >&2 "\n\n" - fi -} - -# Check proxy -checkProxy() -{ - echo -ne "${YELLOW} Checking For Proxy.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - echo -ne "${YELLOW} ......this might take a while!!${NC}" - 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.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - else - echo -ne "${YELLOW} Proxy detected using Certificate.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - fi - - # Detect Proxy via IP - if [ $wanip != $remrmmip ]; then - echo -ne "${YELLOW} Proxy detected using IP.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - else - echo -ne "${GREEN} No Proxy detected using IP.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - fi -} - -# Check for valid cert -checkIfCertIsValid() -{ - echo -ne "${YELLOW} Checking if SSL Certificate is up to date.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - - # SSL Certificate check - cert=$(openssl verify -CAfile /etc/letsencrypt/live/$rootdomain/chain.pem /etc/letsencrypt/live/$rootdomain/cert.pem) - - if [ "$cert" == *"OK"* ]; then - echo -ne "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - else - echo -ne "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - fi -} - - -###################### -# Parent Functions # -###################### - -# Main install function -mainInstall() -{ - ### Repo info for Postegres and Mongo - setInstallRepos; - - ### Create usernames and passwords - generateUsersAndPass; - - ### This does... something - cls; - - ### Get host/domain info - getHostAndDomainInfo; - - ### Configure hosts file - print_green 'Configuring Hosts file' - configHosts; - - ### Certificate generation - print_green 'Installing Certbot' - installCertbot; - - ### Install Nginx - print_green 'Installing Nginx' - installNginx; - - ### Install NodeJS - print_green 'Installing NodeJS' - installNodeJS; - - ### Install and enable MongoDB - print_green 'Installing MongoDB' - installMongo; - - ### Install Python - print_green "Installing Python ${PYTHON_VER}" - installPython; - - ### Installing Redis - print_green 'Installing redis' - installRedis; - - ### Install and enable Postgresql - print_green 'Installing postgresql' - installPostgresql; - - ### Postgres DB creation - print_green 'Creating database for the rmm' - createPGDB; - - ### Clone main repo - print_green 'Cloning primary repo' - clonePrimaryRepo "install" "$REPO_URL" "$BRANCH"; - - ### Clone scripts repo - print_green 'Cloning community scripts repo' - cloneScriptsRepo "install" "$SCRIPTS_REPO_URL"; - - ### Installing NATS - print_green 'Installing NATS' - installNats "$INSTALL_TYPE"; - - ### Install MeshCentral - print_green 'Installing MeshCentral' - installMeshCentral "install"; - - ### Create MeshCentral config - print_green 'Generating MeshCentral Config' - createMeshConfig; - - ### Create local settings file - print_green 'Generating Local Settings' - createLocalSettings; - - ### Install NATS-API and correct permissions - print_green 'Installing NATS API' - installNatsApi; - - ### Install backend, configure primary admin user, setup admin 2fa - print_green 'Installing the backend' - configureBackend "install"; - - ### Determine Proc setting for UWSGI - print_green 'Optimizing UWSGI for number of processors' - setUwsgiProcs; - - ### Create UWSGI config - print_green 'Creating UWSGI configuration' - createUwsgiConf; - - ### Create RMM UWSGI systemd service - print_green 'Creating UWSGI service' - createUwsgiService; - - ### Create Daphne systemd service - print_green 'Creating Daphne service' - createDaphneService; - - ### Create NATS systemd service - print_green 'Creating NATS service' - createNatsService; - - ### Create NATS-api systemd service - print_green 'Creating NATS-API service' - createNatsApiService; - - ### Create Backend Nginx site config - print_green 'Creating Backend Nginx config' - createBackendNginxConf; - - ### Create MeshCentral Nginx configuration - print_green 'Creating MeshCentral Nginx config' - createMeshNginxConf; - - ### Enable Mesh and RMM sites - sudo ln -s /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-enabled/rmm.conf - sudo ln -s /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-enabled/meshcentral.conf - - ### Create conf directory - sudo mkdir /etc/conf.d - - ### Create Celery systemd service - print_green 'Creating Celery service' - createCeleryService; - - ### Configure Celery service - print_green 'Creating Celery config' - createCeleryConf; - - ### Create CeleryBeat systemd service - print_green 'Creating CeleryBeat service' - createCeleryBeatService; - - ### Correct conf dir ownership - sudo chown "${USER}:${USER}" -R /etc/conf.d/ - - ### Create MeshCentral systemd service - print_green 'Creating MeshCentral service' - createMeshCentralService; - - ### Update services info - sudo systemctl daemon-reload - - ### Verify and correct permissions - if [ -d ~/.npm ]; then - sudo chown -R "${USER}:${GROUP}" ~/.npm - fi - - if [ -d ~/.config ]; then - sudo chown -R "${USER}:${GROUP}" ~/.config - fi - - ### Install frontend - print_green 'Installing the frontend' - installFrontEnd "install" "$FRONTEND_URL"; - - ### Set front end Nginx config and enable - print_green 'Creating Frontend Nginx config' - createFrontendNginxConf; - - ### Enable Frontend site - sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf - - ### Enable RMM, Daphne, Celery, and Nginx services - print_green 'Enabling Services' - - for i in rmm.service daphne.service celery.service celerybeat.service nginx - do - sudo systemctl enable ${i} - sudo systemctl stop ${i} - sudo systemctl start ${i} - done - sleep 5 - - ### Enable MeshCentral service - print_green 'Starting meshcentral and waiting for it to install plugins' - enableMeshService; - - ### Generating MeshCentral key - print_green 'Generating meshcentral login token key' - generateMeshToken; - - ### Configuring MeshCentral admin user and device group, restart service - print_green 'Creating meshcentral account and group' - configMeshUserGroup; - - ### Enable and configure NATS service - print_green 'Starting NATS service' - enableNatsService; - - ### Disable django admin - sed -i 's/ADMIN_ENABLED = True/ADMIN_ENABLED = False/g' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - - ### Restart core services - print_green 'Restarting services' - - for i in rmm.service daphne.service celery.service celerybeat.service - do - sudo systemctl stop ${i} - sudo systemctl start ${i} - done - - ### Yay, we're done! - printf >&2 "${YELLOW}%0.s*${NC}" {1..80} - printf >&2 "\n\n" - printf >&2 "${YELLOW}Installation complete!${NC}\n\n" - printf >&2 "${YELLOW}Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n\n" - printf >&2 "${YELLOW}Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n\n" - printf >&2 "${YELLOW}MeshCentral username: ${GREEN}${meshusername}${NC}\n" - printf >&2 "${YELLOW}MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n\n" - - if [ "$BEHIND_NAT" = true ]; then - echo -ne "${YELLOW}Read below if your router does NOT support Hairpin NAT${NC}\n\n" - echo -ne "${GREEN}If you will be accessing the web interface of the RMM from the same LAN as this server,${NC}\n" - echo -ne "${GREEN}you'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" - echo -ne "${GREEN}This also applies to any agents that will be on the same local network as the rmm.${NC}\n" - echo -ne "${GREEN}You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp.${NC}\n\n" - fi - - printf >&2 "${YELLOW}Please refer to the github README for next steps${NC}\n\n" - printf >&2 "${YELLOW}%0.s*${NC}" {1..80} - printf >&2 "\n" - - return -} - -# Update function -updateTRMM() -{ - ### Check if user is same as during installation - checkSameUser "update"; - - ### Get current release version and check if update is necessary - checkIfUpdate; - - ### Get current versions of necessary included apps - checkAdditionalAppsVers; - - ### Clear screen - cls; - - ### Check CHECK_NATS_LIMITNOFILE, whatever that means - checkNatsLimitNoFile; - - ### Check Nginx config - installNginx "updatepart1"; - - ### Stop services - for i in nginx nats-api nats rmm daphne celery celerybeat - do - printf >&2 "${GREEN}Stopping ${i} service...${NC}\n" - sudo systemctl stop ${i} - done - - ### Rebuild uwsgi config - rm -f /rmm/api/tacticalrmm/app.ini - setUwsgiProcs; - createUwsgiConf; - - ### Check if Python is up to date, if not, update - installPython "update"; - - ### Check if NATS is up to date, if not, update - installNats "update"; - - ### This does stuff - if [ -d ~/.npm ]; then - sudo rm -rf ~/.npm - fi - - if [ -d ~/.cache ]; then - sudo rm -rf ~/.cache - fi - - if [ -d ~/.config ]; then - sudo chown -R "${USER}:${GROUP}" ~/.config - fi - - ### Check NodeJS version, update if needed and update MeshCentral - print_green 'Updating NodeJS' - installNodeJS "update"; - - ### Pull domain info from existing Nginx confs - rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - - ### Set symlinks to avoid security concerns and simplify Nginx config - sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem - sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem - - ### Update from main repo - print_green 'Cloning primary repo' - clonePrimaryRepo "update" "$REPO_URL" "$BRANCH"; - - ### Update from community-scripts repo - print_green 'Cloning community scripts repo' - cloneScriptsRepo "update" "$SCRIPTS_REPO_URL"; - - ### Apply updated Ownership and perms - sudo chown "${USER}:${USER}" -R /rmm - sudo chown "${USER}:${USER}" -R ${SCRIPTS_DIR} - sudo chown "${USER}:${USER}" /var/log/celery - sudo chown "${USER}:${USER}" -R /etc/conf.d/ - - ### Check additional Nginx settings and update - installNginx "updatepart2"; - - ### Update Nginx conf files - createMeshNginxConf; - createFrontendNginxConf; - createBackendNginxConf; - - ### Reconfigure backend - createCeleryConf; - configureBackend "update"; - - ### Disable Redis append only - turnOffRedisAppendOnly; - - ### Update Frontend - installFrontEnd "update" "$FRONTEND_URL"; - - ### Start services - for i in nats nats-api rmm daphne celery celerybeat nginx - do - printf >&2 "${GREEN}Starting ${i} service${NC}\n" - sudo systemctl start ${i} - done - sleep 1 - - ### Push agent updates - /rmm/api/env/bin/python /rmm/api/tacticalrmm/manage.py update_agents - - ### Update MeshCentral if necessary - updateMeshCentral; - createMeshConfig; - enableMeshService "update"; - - ### Cleanup - rm -f $TMP_SETTINGS - - ### Bye-bye - printf >&2 "${GREEN}Update finished!${NC}\n" - - return -} - -# Backup Function -backupTRMM() -{ - ### Pull Postgres info - POSTGRES_USER=$(grep -w USER /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//') - POSTGRES_PW=$(grep -w PASSWORD /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//') - - ### Check if rmmbackup folder exists, if not create it - if [ ! -d /rmmbackups ]; then - sudo mkdir /rmmbackups - sudo chown "${USER}:${USER}" /rmmbackups - fi - - ### Remove old MeshCentral backups - if [ -d /meshcentral/meshcentral-backup ]; then - rm -rf /meshcentral/meshcentral-backup/* - fi - - ### Remove old MeshCentral DB backups - if [ -d /meshcentral/meshcentral-coredumps ]; then - rm -f /meshcentral/meshcentral-coredumps/* - fi - - ### Set info for backup and folders - dt_now=$(date '+%Y_%m_%d__%H_%M_%S') - tmp_dir=$(mktemp -d -t tacticalrmm-XXXXXXXXXXXXXXXXXXXXX) - sysd="/etc/systemd/system" - - ### Create temp backup subdirectories - mkdir -p ${tmp_dir}/meshcentral/mongo - mkdir ${tmp_dir}/postgres - mkdir ${tmp_dir}/certs - mkdir ${tmp_dir}/nginx - mkdir ${tmp_dir}/systemd - mkdir ${tmp_dir}/rmm - mkdir ${tmp_dir}/confd - - ### Dump Postgres database - pg_dump --dbname=postgresql://"${POSTGRES_USER}":"${POSTGRES_PW}"@127.0.0.1:5432/tacticalrmm | gzip -9 > ${tmp_dir}/postgres/db-${dt_now}.psql.gz - - ### Backup Mesh stuff - tar -czvf ${tmp_dir}/meshcentral/mesh.tar.gz --exclude=/meshcentral/node_modules /meshcentral - mongodump --gzip --out=${tmp_dir}/meshcentral/mongo - - ### Backup certs - sudo tar -czvf ${tmp_dir}/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt . - - ### Backup Nginx configs - sudo tar -czvf ${tmp_dir}/nginx/etc-nginx.tar.gz -C /etc/nginx . - - ### Backup other config files - sudo tar -czvf ${tmp_dir}/confd/etc-confd.tar.gz -C /etc/conf.d . - - ### Copy service files - sudo cp ${sysd}/rmm.service ${sysd}/celery.service ${sysd}/celerybeat.service ${sysd}/meshcentral.service ${sysd}/nats.service ${sysd}/daphne.service ${tmp_dir}/systemd/ - if [ -f "${sysd}/nats-api.service" ]; then - sudo cp ${sysd}/nats-api.service ${tmp_dir}/systemd/ - fi - - 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/ - - tar -cf /rmmbackups/rmm-backup-${dt_now}.tar -C ${tmp_dir} . - - ### Remove temp files/folders - rm -rf ${tmp_dir} - - echo -ne "${GREEN}Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar${NC}\n" - - return -} - -# Restore T-RMM -restoreTRMM() -{ - ### Repo info for Postegres and Mongo - setInstallRepos; - - ### Get backup file location - getBackupFileLocation; - - ### Extract backup - extractBackup "$backuppath"; - - ### Check if original user - checkSameUser "restore"; - - ### Install NodeJS - print_green 'Installing NodeJS' - installNodeJS "install"; - - ### Install Nginx - print_green 'Installing Nginx' - installNginx "install"; - - ### Restore Nginx configuration - print_green 'Restoring Nginx configuration' - - sudo rm -rf /etc/nginx - sudo mkdir /etc/nginx - sudo tar -xzf $tmp_dir/nginx/etc-nginx.tar.gz -C /etc/nginx - sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf - rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - local temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" - local tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" - rootdomain="$temprootdomain.$tempdotsomething" - - ### Restore hosts config - configHosts; - - ### Restore Certbot - print_green 'Installing Certbot' - installCertbot "restore"; - - ### Restoring existing certs - 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 - - ### Set symlinks to avoid security concerns and simplify Nginx config - sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem - sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem - - ### Recreate Nginx conf files - createMeshNginxConf; - createFrontendNginxConf; - createBackendNginxConf; - - ### Restore Celery configs - print_green 'Restoring celery configs' - - sudo mkdir /etc/conf.d - sudo tar -xzf $tmp_dir/confd/etc-confd.tar.gz -C /etc/conf.d - sudo chown "${USER}:${USER}" -R /etc/conf.d - - ### Restoring services - print_green 'Restoring systemd services' - - sudo cp $tmp_dir/systemd/* /etc/systemd/system/ - sudo systemctl daemon-reload - - ### Install Python - print_green "Installing Python ${PYTHON_VER}" - installPython; - - ### Installing Redis - print_green 'Installing redis' - installRedis; - - ### Install and enable Postgresql - print_green 'Installing postgresql' - installPostgresql; - - ### Install and enable MongoDB - print_green 'Installing MongoDB' - installMongo; - - ### Restore Mongo database - print_green 'Restoring MongoDB' - mongorestore --gzip $tmp_dir/meshcentral/mongo - - ### Clone main repo - print_green 'Cloning primary repo' - clonePrimaryRepo "install" "$REPO_URL" "$BRANCH"; - - ### Clone scripts repo - print_green 'Cloning community scripts repo' - cloneScriptsRepo "install" "$SCRIPTS_REPO_URL"; - - ### Installing NATS - print_green 'Installing NATS' - installNats "install"; - - ### Restore MeshCentral - print_green 'Restoring MeshCentral' - installMeshCentral "restore"; - - ### Restore UWSGI - print_green 'Optimizing UWSGI for number of processors' - setUwsgiProcs; - print_green 'Creating UWSGI configuration' - createUwsgiConf; - - ### Restoring other misc stuff - cp $tmp_dir/rmm/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/ - cp $tmp_dir/rmm/env /rmm/web/.env - gzip -d $tmp_dir/rmm/debug.log.gz - cp $tmp_dir/rmm/django_debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/ - - ### Install NATS-API - print_green 'Installing NATS API' - installNatsApi; - - ### Restore Postgres database - print_green 'Restoring the Postgres 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" - createPGDB; - - gzip -d $tmp_dir/postgres/*.psql.gz - PGPASSWORD="${pgpw} psql -h localhost -U ${pgusername} -d tacticalrmm -f $tmp_dir/postgres/db*.psql" - - ### Restore Backend - print_green 'Restoring the backend' - configureBackend "restore"; - - ### Start NATS - print_green 'Start NATS' - sudo systemctl enable nats.service - sudo systemctl start nats.service - - ### Install frontend - print_green 'Installing the frontend' - installFrontEnd; - - # reset perms - sudo chown "${USER}:${USER}" -R /rmm - sudo chown "${USER}:${USER}" /var/log/celery - sudo chown "${USER}:${USER}" -R /etc/conf.d/ - sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.npm - sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.config - sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.cache - - ### Update services info - sudo systemctl daemon-reload - - ### Enable RMM, Daphne, Celery, Nats-api, and Nginx services - print_green 'Enabling Services' - - for i in celery.service celerybeat.service rmm.service daphne.service nats-api.service nginx - do - sudo systemctl enable ${i} - sudo systemctl stop ${i} - sudo systemctl start ${i} - done - sleep 5 - - ### Start MeshCentral - print_green 'Starting meshcentral' - sudo systemctl enable meshcentral - sudo systemctl start meshcentral - - ### Done!!!! - printf >&2 "${YELLOW}%0.s*${NC}" {1..80} - printf >&2 "\n\n" - printf >&2 "${YELLOW}Restore complete!${NC}\n\n" - printf >&2 "${YELLOW}%0.s*${NC}" {1..80} - printf >&2 "\n" - - return -} - -# Troubleshooting utility -troubleShoot() -{ - ### Resolve Locally used DNS server - locdns=$(resolvectl | grep 'Current DNS Server:' | cut -d: -f2 | awk '{ print $1}') - - ### Prompt for host, domain, and email info - getHostAndDomainInfo; - - ### Verify domains are live - pingDomain "$rmmdomain"; - pingDomain "$frontenddomain"; - pingDomain "$meshdomain"; - - ### Verify IPs - echo -ne "${YELLOW} Checking IPs${NC}" | tee -a checklog.log - printf >&2 "\n\n" - checkIPisLive "$rmmdomain"; - remapiip="${reminputip}" - checkIPisLive "$frontenddomain"; - checkIPisLive "$meshdomain"; - - ### Get services status - readServicesStatus; - - ### Verify services active - checkIfServiceActive "$rmmstatus" "RMM Service"; - checkIfServiceActive "$daphnestatus" "Daphne Service"; - checkIfServiceActive "$celerystatus" "Celery Service"; - checkIfServiceActive "$celerybeatstatus" "CeleryBeat Service"; - checkIfServiceActive "$nginxstatus" "Nginx Service"; - checkIfServiceActive "$natsstatus" "NATS Service"; - checkIfServiceActive "$natsapistatus" "NATS-API Service"; - checkIfServiceActive "$meshcentralstatus" "MeshCentral Service"; - checkIfServiceActive "$mongodstatus" "MongoD Service"; - checkIfServiceActive "$postgresqlstatus" "Postgresql Service"; - checkIfServiceActive "$redisserverstatus" "Redis-Server Service"; - - ### Get WAN IP - wanip=$(dig @resolver4.opendns.com myip.opendns.com +short) - echo -ne "${GREEN} WAN IP is $wanip.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - - ### Check if ports are open - isPortOpen "4222" "NATS"; - isPortOpen "80" "HTTP"; - isPortOpen "443" "HTTPS"; - - ### Checking Proxy - checkProxy; - - ### Check for valid cert - checkIfCertIsValid; - - ### Generate log summary - echo -ne "${YELLOW} Getting summary output of logs.${NC}" | 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" - - printf >&2 "\n\n" - echo -ne "${YELLOW} You will have a log file called checklog.log in the directory you ran this script from.${NC}" - printf >&2 "\n\n" - - return -} diff --git a/installer-util.sh b/installer-util.sh index 33133c1ad3..81a3ca6c36 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -158,7 +158,8 @@ utilityMenu() case $menuselection in 1 ) backupTRMM;; - 2 ) restoreTRMM;; + 2 ) INSTALL_TYPE="restore" + restoreTRMM;; 3 ) renewCerts;; 4 ) importCerts;; 5 ) changeUWSGIProcs;; @@ -189,12 +190,15 @@ updateMenu() menuselection=$(<"${INPUT}") case $menuselection in - 1 ) UPDATE_TYPE="standard" + 1 ) INSTALL_TYPE="update" + UPDATE_TYPE="standard" updateTRMM;; - 2 ) UPDATE_TYPE="standard" + 2 ) INSTALL_TYPE="update" + UPDATE_TYPE="standard" backupTRMM updateTRMM;; - 3 ) UPDATE_TYPE="forced" + 3 ) INSTALL_TYPE="update" + UPDATE_TYPE="forced" updateTRMM;; 4 ) return;; 5 ) [ -f $INPUT ] && rm $INPUT diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index d5a783879d..baa628c707 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -12,10 +12,13 @@ CFG_VERSION="8" # Renew Certs renewCerts() { + # Pull domain info rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') local temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" local tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" rootdomain="$temprootdomain.$tempdotsomething" + + # generate certs and restart services generateCerts; sudo systemctl restart nginx.service rmm.service celery celerybeat.service nats-api.service nats.service meshcentral.service } @@ -33,10 +36,10 @@ generateCerts() { print_green 'Getting wildcard cert' - ### Get initial DNS text entry + # Get initial DNS text entry sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email - ### Keep going until successful cert issue after adding DNS txt entry + # Keep going until successful cert issue after adding DNS txt entry while [[ $? -ne 0 ]]; do sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email done @@ -45,29 +48,29 @@ generateCerts() # Install Certbot and get initial certs installCertbot() { - ### Install Certbot + # Install Certbot sudo apt install -y certbot if [ "$1" == "restore" ]; then return fi - if [ "$INSTALL_TYPE" == "devinstall" ]; then - echo -e "${GREEN}Certificates should be in place${NC}" + if [ "$1" == "devinstall" ]; then + print_green "Certificates should be in place" else dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have wildcard certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 case $? in - ### Get wildcard cert via LetsEncrypt + # Get wildcard cert via LetsEncrypt 0 ) generateCerts;; - + # Import certs using vim 1 ) importCerts;; esac fi - ### Set symlinks to avoid security concerns and simplify Nginx config + # Set symlinks to avoid security concerns and simplify Nginx config sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem - ### Generate DH + # Generate DH if it doesn't exist if [ ! -f /etc/ssl/certs/dhparam.pem ]; then sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096 else diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index dba6eaef3f..14b26820fd 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -242,7 +242,7 @@ enableMeshService() # We will know it's ready once the last line of the systemd service stdout is 'MeshCentral HTTP server running on port.....' 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" + print_yellow "Mesh Central not ready yet..." sleep 3 done } @@ -272,7 +272,7 @@ configMeshUserGroup() 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" + print_yellow "Mesh Central not ready yet..." sleep 3 done diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 9ea0a558e6..4ea276e6c6 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -25,13 +25,13 @@ installAdditionalPreReqs() setInstallRepos() { # There is no Jammy repo yet so use Focal for Ubuntu 22.04 - if ([ "$osname" = "ubuntu" ] && [ "$fullrelno" = "20.04" ]); then + if ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "20.04" ]); then mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" - elif ([ "$osname" = "ubuntu" ] && [ "$fullrelno" = "22.04" ]); then + elif ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "22.04" ]); then codename="focal" 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 10 ]); then + elif ([ "$osname" == "debian" ] && [ $relno -eq 10 ]); then mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 main" else codename="buster" @@ -58,7 +58,7 @@ installNodeJS() if [ "$1" == "update" ]; then HAS_NODE16=$(node --version | grep v16) if ! [ $HAS_NODE16 ]; then - printf >&2 "${GREEN}Updating NodeJS to v16${NC}\n" + print_green "Updating NodeJS to v16" rm -rf /rmm/web/node_modules sudo systemctl stop meshcentral sudo apt remove -y nodejs @@ -72,7 +72,7 @@ installNodeJS() sudo chown "${USER}:${USER}" -R /meshcentral cd /meshcentral rm -rf node_modules/ - npm install meshcentral@${LATEST_MESH_VER} + npm install meshcentral@"${LATEST_MESH_VER}" sudo systemctl start meshcentral fi } @@ -89,12 +89,12 @@ installPython() if [ "$1" == "update" ]; then HAS_PY310=$(python3.10 --version | grep ${PYTHON_VER}) if ! [ $HAS_PY310 ]; then - printf >&2 "${GREEN}Updating to ${PYTHON_VER}${NC}\n" + print_green "Updating to ${PYTHON_VER}" fi fi - if [ "$INSTALL_TYPE" == "devinstall" ]; then - echo -e "${GREEN}Python already installed${NC}" + if [ "$1" == "devinstall" ]; then + print_green "Python already installed" else numprocs=$(nproc) cd ~ @@ -106,7 +106,7 @@ installPython() sudo make altinstall cd ~ sudo rm -rf Python-${PYTHON_VER} Python-${PYTHON_VER}.tgz - if [ "$INSTALL_TYPE" == "devprep" ]; then + if [ "$1" == "devprep" ]; then print_green 'All Prereqs installed' exit fi @@ -131,10 +131,10 @@ installNats() if [ "$1" == "update" ]; then 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" + print_green "Updating nats to v${NATS_SERVER_VER}" fi fi - if [ "$1" == "install" ]; then + if [ "$1" == "install" ] || [ "$1" == "devinstall" ] || [ "$1" == "restore" ]; then NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') fi nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) @@ -179,7 +179,7 @@ installFrontEnd() # Install Nginx installNginx() { - if [ "$1" == "install" ]; then + if [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then sudo apt install -y nginx sudo systemctl stop nginx sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf @@ -188,20 +188,31 @@ installNginx() ### Check Nginx config if ! sudo nginx -t > /dev/null 2>&1; then sudo nginx -t - echo -ne "\n" - echo -ne "${RED}You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script.${NC}\n" - echo -ne "${RED}Aborting...${NC}\n" + print_red "You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script." + print_red "Aborting..." exit 1 fi elif [ "$1" == "updatepart2" ]; then CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" /etc/nginx/nginx.conf) if ! [ $CHECK_NGINX_WORKER_CONN ]; then - printf >&2 "${GREEN}Changing nginx worker connections to 2048${NC}\n" + print_green "Changing nginx worker connections to 2048" sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf fi sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf - else - return + elif [ "$1" == "restore" ]; then + sudo apt install -y nginx + sudo systemctl stop nginx + sudo rm -rf /etc/nginx + sudo mkdir /etc/nginx + sudo tar -xzf $tmp_dir/nginx/etc-nginx.tar.gz -C /etc/nginx + sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf + sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf + rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + local temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" + local tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" + rootdomain="$temprootdomain.$tempdotsomething" fi } @@ -218,7 +229,7 @@ installMeshCentral() { MESH_VER=$(grep "^MESH_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') - if [ "$1" == "install" ]; then + if [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then sudo mkdir -p /meshcentral/meshcentral-data elif [ "$1" == "restore" ]; then sudo tar -xzf $tmp_dir/meshcentral/mesh.tar.gz -C / diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 83cab0104b..4077582751 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -14,7 +14,6 @@ setColors() { GREEN='\033[0;32m' YELLOW='\033[1;33m' - BLUE='\033[0;34m' RED='\033[0;31m' NC='\033[0m' } @@ -25,7 +24,7 @@ cls() printf "\033c" } -# Purdy install text +# Purdy install text in green print_green() { printf >&2 "${GREEN}%0.s-${NC}" {1..80} @@ -35,13 +34,35 @@ print_green() printf >&2 "\n" } +# Purdy install text in red +print_red() +{ + printf >&2 "${RED}%0.s-${NC}" {1..80} + printf >&2 "\n" + printf >&2 "${RED}${1}${NC}\n" + printf >&2 "${RED}%0.s-${NC}" {1..80} + printf >&2 "\n" +} + +# Purdy install text in yellow +print_yellow() +{ + printf >&2 "${YELLOW}%0.s-${NC}" {1..80} + printf >&2 "\n" + printf >&2 "${YELLOW}${1}${NC}\n" + printf >&2 "${YELLOW}%0.s-${NC}" {1..80} + printf >&2 "\n" +} + # Check for new script version checkScriptVer() { + # create temp file and download current script to use for comparison TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") curl -s -L "$2" > ${TMP_FILE} NEW_VER=$(grep "^SCRIPT_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') - + + # download new file if available if [ "$1" -ne "${NEW_VER}" ]; then wget -q "$2" -O "$3" dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 @@ -56,10 +77,12 @@ checkScriptVer() # Check for functions updates checkCfgVer() { + # create temp file and download current file to use for comparison TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") curl -s -L "$1/script-cfg/$2" > ${TMP_FILE} NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') + # download new file if available if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 @@ -74,6 +97,7 @@ checkCfgVer() # Check for root as user checkRoot() { + # if user is root, exit if [ $EUID -eq 0 ]; then dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Do NOT run this script as root. Exiting." 0 0 clear -x @@ -88,7 +112,7 @@ checkTacticalUser() local hassudo="" local tacpass="" - ### Check if dir exists, if so pull tactical user + # Check if dir exists, if so pull tactical user if [ -d /rmm ]; then tacticaluser=$(stat -c '%U' /rmm) if [ "$tacticaluser" != "${USER}" ]; then @@ -96,7 +120,8 @@ checkTacticalUser() clear -x exit 1 fi - ### If user not tactical, check if it exists. If so, exit. If not, create it + + # If user not tactical, check if it exists. If so, exit. If not, create it elif [ "${USER}" != "tactical" ]; then tacticaluser="$(id -u tactical > /dev/null 2>&1; echo $?)" case $tacticaluser in @@ -104,7 +129,7 @@ checkTacticalUser() clear -x exit 1;; - 1 ) print_green 'Tactical user does not exist. Creating now.' + 1 ) print_yellow 'Tactical user does not exist. Creating now.' sudo useradd -m -G sudo -s /bin/bash tactical tacpass="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)" echo "tactical:$tacpass"| sudo chpasswd @@ -112,7 +137,8 @@ checkTacticalUser() clear -x exit 1;; esac - ### If user is tactical, verify sudo privileges. If none, add to sudo group + + # If user is tactical, verify sudo privileges. If none, add to sudo group elif [ "${USER}" == "tactical" ]; then hassudo="$(id -nG tactical | grep -w 'sudo' > /dev/null 2>&1; echo $?)" case $hassudo in @@ -130,18 +156,24 @@ checkTacticalUser() # Clone primary repo clonePrimaryRepo() { - if [ "$1" == "install" ]; then + # use only if called from standard or dev install, or restore + if [ "$1" == "install" ] || [ "$1" == "devinstall" ] || [ "$1" == "restore" ]; then sudo mkdir /rmm sudo chown "${USER}:${USER}" /rmm sudo mkdir -p /var/log/celery sudo chown "${USER}:${USER}" /var/log/celery git clone "$2" /rmm/ fi + cd /rmm git config user.email "admin@example.com" git config user.name "Bob" - if [ "$1" == "install" ]; then + + # use only if called from standard or dev install, or restore + if [ "$1" == "install" ] || [ "$1" == "devinstall" ] || [ "$1" == "restore" ]; then git checkout "$3" + + # use only if called from update elif [ "$1" == "update" ]; then git fetch git checkout "$3" @@ -154,6 +186,7 @@ clonePrimaryRepo() # Clone scripts repo cloneScriptsRepo() { + # if directory exists, skip, else create it if [ ! -d "${SCRIPTS_DIR}" ]; then sudo mkdir -p "${SCRIPTS_DIR}" sudo chown "${USER}:${USER}" "${SCRIPTS_DIR}" @@ -162,8 +195,12 @@ cloneScriptsRepo() cd "${SCRIPTS_DIR}" git config user.email "admin@example.com" git config user.name "Bob" - if [ "$1" == "install" ]; then + + # use only if called from standard or dev install, or restore + if [ "$1" == "install" ] || [ "$1" == "devinstall" ] || [ "$1" == "restore" ]; then git checkout main + + # use only if called from update elif [ "$1" == "update" ]; then git fetch git checkout main @@ -180,6 +217,7 @@ decideMainRepos() local own="" local bran="" + # prompt for repo owner info and verify before proceeding until [ "$userconfirm" == "y" ]; do own=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository" --inputbox "Enter the dev repo owner name.\nThis is right after github.com in the URL:" 10 90 3>&1 1>&2 2>&3) own="$(translateToLowerCase $own)" @@ -194,6 +232,7 @@ decideMainRepos() userconfirm="n" REPO_OWNER="$own" + # prompt for branch info and verify before proceeding until [ "$userconfirm" == "y" ]; do bran=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository Branch" --inputbox "Enter the dev repo branch name.\nThis is right after tacticalrmm in the URL:" 10 90 3>&1 1>&2 2>&3) bran="$(translateToLowerCase $bran)" @@ -208,11 +247,11 @@ decideMainRepos() userconfirm="n" BRANCH="$bran" - ### Check for new functions versions, include url, filename, and script name as variables + # Check for new functions versions, include url, filename, and script name as variables for i in "${cfgfiles[@]}" do - checkCfgVer "$CFG_URL" "$i" "$THIS_SCRIPT"; # MiscFunctions + checkCfgVer "$CFG_URL" "$i" "$THIS_SCRIPT"; done - ### Check for new script version, pass script version, url, and script name variables in that order + # Check for new script version, pass script version, url, and script name variables in that order checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; } \ No newline at end of file diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 21c40c590a..46f7cb36a5 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -30,11 +30,11 @@ mainInstall() ### Certificate generation print_green 'Installing Certbot' - installCertbot; + installCertbot "$INSTALL_TYPE"; ### Install Nginx print_green 'Installing Nginx' - installNginx; + installNginx "$INSTALL_TYPE"; ### Install NodeJS print_green 'Installing NodeJS' @@ -46,7 +46,7 @@ mainInstall() ### Install Python print_green "Installing Python ${PYTHON_VER}" - installPython; + installPython "$INSTALL_TYPE"; ### Installing Redis print_green 'Installing redis' @@ -62,11 +62,11 @@ mainInstall() ### Clone main repo print_green 'Cloning primary repo' - clonePrimaryRepo "install" "$REPO_URL" "$BRANCH"; + clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; ### Clone scripts repo print_green 'Cloning community scripts repo' - cloneScriptsRepo "install" "$SCRIPTS_REPO_URL"; + cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; ### Installing NATS print_green 'Installing NATS' @@ -74,7 +74,7 @@ mainInstall() ### Install MeshCentral print_green 'Installing MeshCentral' - installMeshCentral "install"; + installMeshCentral "$INSTALL_TYPE"; ### Create MeshCentral config print_green 'Generating MeshCentral Config' @@ -90,7 +90,7 @@ mainInstall() ### Install backend, configure primary admin user, setup admin 2fa print_green 'Installing the backend' - configureBackend "install"; + configureBackend; ### Determine Proc setting for UWSGI print_green 'Optimizing UWSGI for number of processors' @@ -164,7 +164,7 @@ mainInstall() ### Install frontend print_green 'Installing the frontend' - installFrontEnd "install" "$FRONTEND_URL"; + installFrontEnd "$INSTALL_TYPE" "$FRONTEND_URL"; ### Set front end Nginx config and enable print_green 'Creating Frontend Nginx config' @@ -213,25 +213,20 @@ mainInstall() done ### Yay, we're done! - printf >&2 "${YELLOW}%0.s*${NC}" {1..80} - printf >&2 "\n\n" - printf >&2 "${YELLOW}Installation complete!${NC}\n\n" + print_yellow "Installation complete!" printf >&2 "${YELLOW}Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n\n" printf >&2 "${YELLOW}Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n\n" printf >&2 "${YELLOW}MeshCentral username: ${GREEN}${meshusername}${NC}\n" printf >&2 "${YELLOW}MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n\n" if [ "$BEHIND_NAT" = true ]; then - echo -ne "${YELLOW}Read below if your router does NOT support Hairpin NAT${NC}\n\n" - echo -ne "${GREEN}If you will be accessing the web interface of the RMM from the same LAN as this server,${NC}\n" - echo -ne "${GREEN}you'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" - echo -ne "${GREEN}This also applies to any agents that will be on the same local network as the rmm.${NC}\n" - echo -ne "${GREEN}You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp.${NC}\n\n" + print_yellow "Read below if your router does NOT support Hairpin NAT:" + print_green "If you will be accessing the web interface of the RMM from the same LAN as this server,\nyou'll need to make sure your 3 subdomains resolve to ${IPV4}" + print_green "This also applies to any agents that will be on the same local network as the rmm." + print_green "You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp." fi - printf >&2 "${YELLOW}Please refer to the github README for next steps${NC}\n\n" - printf >&2 "${YELLOW}%0.s*${NC}" {1..80} - printf >&2 "\n" + print_yellow "Please refer to the github README for next steps." return } @@ -240,7 +235,7 @@ mainInstall() updateTRMM() { ### Check if user is same as during installation - checkSameUser "update"; + checkSameUser "$INSTALL_TYPE"; ### Get current release version and check if update is necessary checkIfUpdate; @@ -260,8 +255,8 @@ updateTRMM() ### Stop services for i in nginx nats-api nats rmm daphne celery celerybeat do - printf >&2 "${GREEN}Stopping ${i} service...${NC}\n" - sudo systemctl stop ${i} + print_green "Stopping ${i} service..." + sudo systemctl stop "${i}" done ### Rebuild uwsgi config @@ -270,10 +265,10 @@ updateTRMM() createUwsgiConf; ### Check if Python is up to date, if not, update - installPython "update"; + installPython "$INSTALL_TYPE"; ### Check if NATS is up to date, if not, update - installNats "update"; + installNats "$INSTALL_TYPE"; ### This does stuff if [ -d ~/.npm ]; then @@ -290,7 +285,7 @@ updateTRMM() ### Check NodeJS version, update if needed and update MeshCentral print_green 'Updating NodeJS' - installNodeJS "update"; + installNodeJS "$INSTALL_TYPE"; ### Pull domain info from existing Nginx confs rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') @@ -303,11 +298,11 @@ updateTRMM() ### Update from main repo print_green 'Cloning primary repo' - clonePrimaryRepo "update" "$REPO_URL" "$BRANCH"; + clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; ### Update from community-scripts repo print_green 'Cloning community scripts repo' - cloneScriptsRepo "update" "$SCRIPTS_REPO_URL"; + cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; ### Apply updated Ownership and perms sudo chown "${USER}:${USER}" -R /rmm @@ -325,19 +320,19 @@ updateTRMM() ### Reconfigure backend createCeleryConf; - configureBackend "update"; + configureBackend "$INSTALL_TYPE"; ### Disable Redis append only turnOffRedisAppendOnly; ### Update Frontend - installFrontEnd "update" "$FRONTEND_URL"; + installFrontEnd "$INSTALL_TYPE" "$FRONTEND_URL"; ### Start services for i in nats nats-api rmm daphne celery celerybeat nginx do - printf >&2 "${GREEN}Starting ${i} service${NC}\n" - sudo systemctl start ${i} + print_green "Starting ${i} service" + sudo systemctl start "${i}" done sleep 1 @@ -347,13 +342,13 @@ updateTRMM() ### Update MeshCentral if necessary updateMeshCentral; createMeshConfig; - enableMeshService "update"; + enableMeshService "$INSTALL_TYPE"; ### Cleanup rm -f $TMP_SETTINGS ### Bye-bye - printf >&2 "${GREEN}Update finished!${NC}\n" + print_green "Update finished!" return } @@ -425,7 +420,7 @@ backupTRMM() ### Remove temp files/folders rm -rf ${tmp_dir} - echo -ne "${GREEN}Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar${NC}\n" + print_green "Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar" return } @@ -443,36 +438,22 @@ restoreTRMM() extractBackup "$backuppath"; ### Check if original user - checkSameUser "restore"; + checkSameUser "$INSTALL_TYPE"; ### Install NodeJS print_green 'Installing NodeJS' - installNodeJS "install"; - - ### Install Nginx - print_green 'Installing Nginx' - installNginx "install"; - - ### Restore Nginx configuration - print_green 'Restoring Nginx configuration' + installNodeJS; - sudo rm -rf /etc/nginx - sudo mkdir /etc/nginx - sudo tar -xzf $tmp_dir/nginx/etc-nginx.tar.gz -C /etc/nginx - sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf - rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - local temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" - local tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" - rootdomain="$temprootdomain.$tempdotsomething" + ### Install Nginx and restore Nginx configuration + print_green 'Installing Nginx and restoring configuration' + installNginx "$INSTALL_TYPE"; ### Restore hosts config configHosts; ### Restore Certbot print_green 'Installing Certbot' - installCertbot "restore"; + installCertbot "$INSTALL_TYPE"; ### Restoring existing certs print_green 'Restoring certs' @@ -525,19 +506,19 @@ restoreTRMM() ### Clone main repo print_green 'Cloning primary repo' - clonePrimaryRepo "install" "$REPO_URL" "$BRANCH"; + clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; ### Clone scripts repo print_green 'Cloning community scripts repo' - cloneScriptsRepo "install" "$SCRIPTS_REPO_URL"; + cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; ### Installing NATS print_green 'Installing NATS' - installNats "install"; + installNats "$INSTALL_TYPE"; ### Restore MeshCentral print_green 'Restoring MeshCentral' - installMeshCentral "restore"; + installMeshCentral "$INSTALL_TYPE"; ### Restore UWSGI print_green 'Optimizing UWSGI for number of processors' @@ -569,7 +550,7 @@ restoreTRMM() ### Restore Backend print_green 'Restoring the backend' - configureBackend "restore"; + configureBackend "$INSTALL_TYPE"; ### Start NATS print_green 'Start NATS' @@ -608,11 +589,7 @@ restoreTRMM() sudo systemctl start meshcentral ### Done!!!! - printf >&2 "${YELLOW}%0.s*${NC}" {1..80} - printf >&2 "\n\n" - printf >&2 "${YELLOW}Restore complete!${NC}\n\n" - printf >&2 "${YELLOW}%0.s*${NC}" {1..80} - printf >&2 "\n" + print_green 'Restore complete!' return } @@ -632,8 +609,8 @@ troubleShoot() pingDomain "$meshdomain"; ### Verify IPs - echo -ne "${YELLOW} Checking IPs${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "${GREEN} Checking IPs${NC}" | tee -a checklog.log + printf >&2 "\n\n" checkIPisLive "$rmmdomain"; remapiip="${reminputip}" checkIPisLive "$frontenddomain"; @@ -657,7 +634,7 @@ troubleShoot() ### Get WAN IP wanip=$(dig @resolver4.opendns.com myip.opendns.com +short) - echo -ne "${GREEN} WAN IP is $wanip.${NC}" | tee -a checklog.log + echo -e "${GREEN} WAN IP is $wanip.${NC}" | tee -a checklog.log printf >&2 "\n\n" ### Check if ports are open @@ -672,16 +649,15 @@ troubleShoot() checkIfCertIsValid; ### Generate log summary - echo -ne "${YELLOW} Getting summary output of logs.${NC}" | tee -a checklog.log + echo -e "${GREEN} Getting summary output of logs.${NC}" | 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} You will have a log file called checklog.log in the directory you ran this script from.${NC}" - printf >&2 "\n\n" + print_yellow "You will have a log file called checklog.log in the directory you ran this script from." return } \ No newline at end of file diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 7630410cd1..82364377ff 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -23,7 +23,7 @@ getOSInfo() # Check OS if not recognised wutOSThis() { - if [ ! "$osname" = "ubuntu" ] && [ ! "$osname" = "debian" ]; then + if [ ! "$osname" == "ubuntu" ] && [ ! "$osname" == "debian" ]; then osname=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"') osname=${osname^} fi @@ -32,8 +32,8 @@ wutOSThis() # Verify Debian or Ubuntu and version verifySupportedOS() { - if ([ "$osname" = "ubuntu" ] && ([ "$fullrelno" = "20.04" ] || [ "$fullrelno" = "22.04" ])) || ([ "$osname" = "debian" ] && [ $relno -ge 10 ]); then - echo "$fullrel" + if ([ "$osname" == "ubuntu" ] && ([ "$fullrelno" == "20.04" ] || [ "$fullrelno" == "22.04" ])) || ([ "$osname" == "debian" ] && [ $relno -ge 10 ]); then + print_green "$fullrel" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 clear -x diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index d8e3c4c9ae..d0e106754e 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -12,10 +12,9 @@ CFG_VERSION="8" # Ping to test if domain is live pingDomain() { - if ping -c 1 $1 &> /dev/null - then - echo -ne "${GREEN} Verified $1${NC}" | tee -a checklog.log - printf >&2 "\n\n" + if ( ping -c 1 $1 &> /dev/null ); then + echo -e "${GREEN} Verified $1${NC}" | tee -a checklog.log + printf >&2 "\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$1 doesnt exist please create it or check for a typo.\n\nYou will have a log file called checklog.log in the directory you ran this script from.\n\nExiting." 0 0 clear -x @@ -29,14 +28,14 @@ checkIPisLive() locinputip=`dig @"$locdns" +short $1` reminputip=`dig @8.8.8.8 +short $1` - if [ "$locinputip" = "$reminputip" ]; then - echo -ne "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log - printf >&2 "\n\n" + if [ "$locinputip" == "$reminputip" ]; then + echo -e "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log + printf >&2 "\n" else - echo -ne "${RED} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log - printf >&2 "\n\n" | tee -a checklog.log - echo -ne "${RED} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "${RED} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log + printf >&2 "\n" | tee -a checklog.log + echo -e "${RED} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}" | tee -a checklog.log + printf >&2 "\n" fi } @@ -60,12 +59,11 @@ readServicesStatus() checkIfServiceActive() { if [ $1 = active ]; then - echo -ne "${GREEN} Success $2 is Running.${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "${GREEN} Success $2 is Running.${NC}" | tee -a checklog.log + printf >&2 "\n" else - printf >&2 "\n\n" | tee -a checklog.log - echo -ne "${RED} $2 is not running. \(Tactical will not work without this\)${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "${RED} $2 is not running. \(Tactical will not work without this\)${NC}" | tee -a checklog.log + printf >&2 "\n" fi } @@ -73,58 +71,57 @@ checkIfServiceActive() isPortOpen() { if ( nc -zv $wanip $1 2>&1 >/dev/null ); then - echo -ne "${GREEN} $2 Port is open.${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "${GREEN} $2 Port is open.${NC}" | tee -a checklog.log + printf >&2 "\n" else - echo -ne "${RED} $2 port is closed. \(you may want this if running locally only\)${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "${RED} $2 port is closed. \(you may want this if running locally only\)${NC}" | tee -a checklog.log + printf >&2 "\n" fi } # Check proxy checkProxy() { - echo -ne "${YELLOW} Checking For Proxy.${NC}" | tee -a checklog.log - printf >&2 "\n\n" - echo -ne "${YELLOW} ......this might take a while!!${NC}" - printf >&2 "\n\n" + echo -e "${YELLOW} Checking For Proxy.${NC}" | tee -a checklog.log + printf >&2 "\n" + print_yellow "......this might take a while!!" # 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) + 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.${NC}" | tee -a checklog.log - printf >&2 "\n\n" + if [[ "$proxyext" == "$proxyint" ]]; then + echo -e "${GREEN} No Proxy detected using Certificate.${NC}" | tee -a checklog.log + printf >&2 "\n" else - echo -ne "${YELLOW} Proxy detected using Certificate.${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "${YELLOW} Proxy detected using Certificate.${NC}" | tee -a checklog.log + printf >&2 "\n" fi # Detect Proxy via IP - if [ $wanip != $remrmmip ]; then - echo -ne "${YELLOW} Proxy detected using IP.${NC}" | tee -a checklog.log - printf >&2 "\n\n" + if [ "$wanip" != "$remrmmip" ]; then + echo -e "${YELLOW} Proxy detected using IP.${NC}" | tee -a checklog.log + printf >&2 "\n" else - echo -ne "${GREEN} No Proxy detected using IP.${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "${GREEN} No Proxy detected using IP.${NC}" | tee -a checklog.log + printf >&2 "\n" fi } # Check for valid cert checkIfCertIsValid() { - echo -ne "${YELLOW} Checking if SSL Certificate is up to date.${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "${YELLOW} Checking if SSL Certificate is up to date.${NC}" | tee -a checklog.log + printf >&2 "\n" # SSL Certificate check - cert=$(openssl verify -CAfile /etc/letsencrypt/live/$rootdomain/chain.pem /etc/letsencrypt/live/$rootdomain/cert.pem) + cert="$(openssl verify -CAfile /etc/letsencrypt/live/$rootdomain/chain.pem /etc/letsencrypt/live/$rootdomain/cert.pem)" - if [ "$cert" == *"OK"* ]; then - echo -ne "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log - printf >&2 "\n\n" + if [[ "$cert" == *"OK"* ]]; then + echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log + printf >&2 "\n" else - echo -ne "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a checklog.log + printf >&2 "\n" fi } \ No newline at end of file diff --git a/script-cfg/UpdateRestoreFunctions.cfg b/script-cfg/UpdateRestoreFunctions.cfg index 8c87734dda..b50e700ff5 100644 --- a/script-cfg/UpdateRestoreFunctions.cfg +++ b/script-cfg/UpdateRestoreFunctions.cfg @@ -38,7 +38,7 @@ checkIfUpdate() CURRENT_TRMM_VER=$(grep "^TRMM_VERSION" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') if [ "${CURRENT_TRMM_VER}" == "${LATEST_TRMM_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then - printf >&2 "${GREEN}Already on latest version. Current version: ${CURRENT_TRMM_VER} Latest version: ${LATEST_TRMM_VER}${NC}\n" + print_green "Already on latest version. Current version: ${CURRENT_TRMM_VER} Latest version: ${LATEST_TRMM_VER}\n" rm -f $TMP_SETTINGS exit 0 fi @@ -68,7 +68,7 @@ checkNatsLimitNoFile() # Disable Redis append only turnOffRedisAppendOnly() { - printf >&2 "${GREEN}Turning off redis aof${NC}\n" + print_green "Turning off redis aof\n" sudo redis-cli config set appendonly no sudo redis-cli config rewrite sudo rm -f /var/lib/redis/appendonly.aof @@ -79,7 +79,7 @@ updateMeshCentral() { 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" + print_green "Updating meshcentral from ${CURRENT_MESH_VER} to ${LATEST_MESH_VER}\n" sudo systemctl stop meshcentral sudo chown "${USER}:${USER}" -R /meshcentral cd /meshcentral diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index 3c7a3af95d..9bfb6878e8 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -12,11 +12,14 @@ CFG_VERSION="8" # Create usernames and passwords generateUsersAndPass() { + # generate django key and admin url DJANGO_SEKRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1) ADMINURL=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 70 | head -n 1) + # prompt to see if user wants to manually enter info or have it generated dialog --cr-wrap --clear --yes-label "Automatic" --no-label "Manual" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "User and Password Generation" --yesno "Would you like to have usernames and passwords automatically randomly generated, or enter your own manually?" 0 0 case $? in + # auto gen info for user 0 ) 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) @@ -25,7 +28,7 @@ generateUsersAndPass() 1 ) userconfirm="n" - ### Get MeshCentral admin username + # Get MeshCentral admin username until [ "$userconfirm" == "y" ]; do meshusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --inputbox "Enter the MeshCentral Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --yesno "Is this correct?\n$meshusername" 0 0 @@ -38,7 +41,7 @@ generateUsersAndPass() done userconfirm="n" - ### Get MeshCentral admin password + # Get MeshCentral admin password MESHPASSWD="dont" passinput="match" until [ "$passinput" == "$MESHPASSWD" ]; do @@ -52,7 +55,7 @@ generateUsersAndPass() fi done - ### Get Postgresql admin username + # Get Postgresql admin username until [ "$userconfirm" == "y" ]; do pgusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --inputbox "Enter the Postgresql Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --yesno "Is this correct?\n$pgusername" 0 0 @@ -65,7 +68,7 @@ generateUsersAndPass() done userconfirm="n" - ### Get Postgresql admin password + # Get Postgresql admin password pgpw="dont" passinput="match" until [ "$passinput" == "$pgpw" ]; do @@ -91,7 +94,7 @@ getHostAndDomainInfo() rootdomain="none" letsemail="none" - ### Get root domain + # Get root domain while [[ $rootdomain != *[.]* ]]; do rootdomain=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Root Domain" --inputbox "Enter the root domain (eg example.com or example.co.uk):" 10 90 3>&1 1>&2 2>&3) rootdomain="$(translateToLowerCase $rootdomain)" @@ -100,19 +103,19 @@ getHostAndDomainInfo() fi done - ### Get backend hostname + # Get backend hostname rmmhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Backend Hostname" --inputbox "Enter the hostname for the backend (e.g. api):" 10 90 3>&1 1>&2 2>&3) rmmhost="$(translateToLowerCase $rmmhost)" - ### Get frontend hostname + # Get frontend hostname frontendhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Frontend Hostname" --inputbox "Enter the hostname for the frontend (e.g. rmm):" 10 90 3>&1 1>&2 2>&3) frontendhost="$(translateToLowerCase $frontendhost)" - ### Get MeshCentral hostname + # Get MeshCentral hostname meshhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter MeshCentral Hostname" --inputbox "Enter the hostname for MeshCentral (e.g. mesh):" 10 90 3>&1 1>&2 2>&3) meshhost="$(translateToLowerCase $meshhost)" - ### Get Admin email + # Get Admin email while [[ $letsemail != *[@]*[.]* ]]; do letsemail=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Admin E-Mail Address" --inputbox "Enter a valid e-mail address for Django, MeshCentral, and LetsEncrypt:" 10 90 3>&1 1>&2 2>&3) letsemail="$(translateToLowerCase $letsemail)" @@ -121,7 +124,7 @@ getHostAndDomainInfo() fi done - ### Verify input + # Verify input dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Confirm Input" --yesno "Is this correct?\n\nroot domain: $rootdomain\nbackend: $rmmhost.$rootdomain\nfrontend: $frontendhost.$rootdomain\nmeshcentral: $meshhost.$rootdomain\ne-mail address: $letsemail" 0 0 case $? in 0 ) userconfirm="y";; @@ -132,7 +135,7 @@ getHostAndDomainInfo() done clear -x - ### Combine host/domain entries for later use while keeping seperate entries as well + # Combine host/domain entries for later use while keeping seperate entries as well rmmdomain="$rmmhost.$rootdomain" meshdomain="$meshhost.$rootdomain" frontenddomain="$frontendhost.$rootdomain" From 6983a1a4f5fdec2d85aa4871181a3eea8815b003 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 23 Jun 2022 15:51:07 -0500 Subject: [PATCH 052/203] more prepwork for automated installations --- installer-util.sh | 62 ++++++++++++++++++++++++++++++++++++ script-cfg/MiscFunctions.cfg | 21 ++++++++++++ 2 files changed, 83 insertions(+) diff --git a/installer-util.sh b/installer-util.sh index 81a3ca6c36..1f00ab3ab7 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -30,6 +30,17 @@ PYTHON_VER='3.10.4' SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py' LATEST_SETTINGS_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/api/tacticalrmm/tacticalrmm/settings.py" +### Variables required for automated install +autoinstall="" +rmmhost="" +frontendhost="" +meshhost="" +letsemail="" +rootdomain="" +sslcacert="" +sslkey="" +sslcert="" + ### Get cfg files function getCfgFiles() @@ -64,6 +75,57 @@ done . $PWD/script-cfg/TroubleshootingFunctions.cfg . $PWD/script-cfg/ParentFunctions.cfg +### Get commandline input function +getCommandLineArgs() +{ + while getopts "auto:api:branch:ca:cert:domain:email:help:key:mesh:repo:rmm:" option; do + case $option in + auto ) autoinstall="1" + INSTALL_TYPE="${OPTARG}";; + api ) rmmhost="${OPTARG}";; + branch ) BRANCH="${OPTARG}";; + ca ) sslcacert="${OPTARG}";; + cert ) sslcert="${OPTARG}";; + domain ) rootdomain="${OPTARG}";; + email ) letsemail="${OPTARG}";; + help ) helpText + exit;; + key ) sslkey="${OPTARG}";; + mesh ) meshhost="${OPTARG}";; + repo ) REPO_OWNER="${OPTARG}";; + rmm ) frontendhost="${OPTARG}";; + \?) echo -e "Error: Invalid option" + clear -x + exit 1;; + esac + done + + if [ "$autoinstall" == "1" ]; then + if [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$letsemail" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ]; then + echo -e "Error: To perform an automated installation, you must provide all required information." + echo -e "\n" + echo -e "api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, and Private key path are all required." + echo -e "\n" + echo -e "Run ./$THIS_SCRIPT -h for further details." + clear -x + exit 1 + elif [ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]; then + if [ "$REPO_OWNER" == "amidaware" ] || [ "$BRANCH" == "master" ]; then + echo -e "Error: You've selected a developer installation type, but not changed the repo, branch, or both." + echo -e "\n" + echo -e "Run ./$THIS_SCRIPT -h for details on how to select them." + clear -x + exit 1 + fi + else + return + fi + fi +} + +### Get commandline input +getCommandLineArgs; + ### Set colors setColors; # MiscFunctions diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 4077582751..6a1b7efd5d 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -54,6 +54,27 @@ print_yellow() printf >&2 "\n" } +# Command-line help function +helpText() +{ + echo -e 'Syntax: ./installer-util.sh [ -auto|api|branch|ca|cert|email|help|key|mesh|repo|rmm]' + echo -e "" + echo -e "Options:" + echo -e "" + echo -e "auto Select type of automated installation. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC}, or${YELLOW} devinstall${NC}" + echo -e "api Provide the api hostname/subdomain, eg ${YELLOW}api${NC}.example.com" + echo -e "branch If performing a dev install, this will select the branch. eg, https://github.com/amidaware/tacticalrmm/${YELLOW}branch${NC}/.git" + echo -e "ca Path to SSL CA certificate for import. Must be in .pem format" + echo -e "cert Path to SSL certificate for import. Must be in .pem format" + echo -e "domain Provide the root domain, eg rmm.${YELLOW}example.com${NC}" + echo -e "email Provide a valid email address for LetsEncrypt cert generation" + echo -e "help Show this help text" + echo -e "key Path to SSL private key for import. Must be in .pem format" + echo -e "mesh Provide the mesh hostname/subdomain, eg ${YELLOW}mesh${NC}.example.com" + echo -e "repo If performing a dev install, this will select the repo owner. eg, https://github.com/${YELLOW}repo-owner${NC}/tacticalrmm/master/.git" + echo -e "rmm Provide the rmm hostname/subdomain, eg ${YELLOW}rmm${NC}.example.com" +} + # Check for new script version checkScriptVer() { From c851aad5160c32b9ad0b98afdcb05a1bf0dcd763 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 23 Jun 2022 17:38:55 -0500 Subject: [PATCH 053/203] Updated install and other functions for automation --- installer-util.sh | 84 ++++----- script-cfg/CertificateFunctions.cfg | 9 +- script-cfg/ConfigAndServiceFunctions.cfg | 24 +-- script-cfg/MiscFunctions.cfg | 47 ++++- script-cfg/SystemInfoFunctions.cfg | 12 +- script-cfg/UserInput.cfg | 219 ++++++++++++----------- 6 files changed, 230 insertions(+), 165 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 1f00ab3ab7..11540aca49 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -1,17 +1,17 @@ #!/usr/bin/env bash -### Menu option variables +# Menu option variables INPUT=/tmp/menu.sh.$$ menuselection="" -### Arrays +# Arrays declare -a mainmenuoptions=('Installation' 'Update' 'Utilities' 'Exit') declare -a installmenuoptions=('Standard Install' 'Dev Test Prereqs' 'Dev Test Install' 'Return' 'Exit') declare -a updatemenuoptions=('Standard Update' 'Backup and Update' 'Force Update' 'Return' 'Exit') declare -a utilitymenuoptions=('Backup' 'Restore' 'Renew Certs' 'Import Certs' 'Edit UWSGI config' 'Add Fail2ban - Use at your own risk' 'Run Server Troubleshooter' 'Return' 'Exit') declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunctions.cfg' 'UserInput.cfg' 'NetworkFunctions.cfg' 'InstallFunctions.cfg' 'DatabaseFunctions.cfg' 'CertificateFunctions.cfg' 'ConfigAndServiceFunctions.cfg' 'UpdateRestoreFunctions.cfg' 'TroubleshootingFunctions.cfg' 'ParentFunctions.cfg') -### Script Info variables +# Script Info variables REPO_OWNER="ninjamonkey198206" BRANCH="develop-installer-update" SCRIPT_VERSION="69" @@ -22,7 +22,7 @@ SCRIPTS_REPO_URL="https://github.com/amidaware/community-scripts.git" FRONTEND_URL="https://github.com/amidaware/tacticalrmm-web/releases/download/v${WEB_VERSION}/${webtar}" THIS_SCRIPT=$(readlink -f "$0") -### Misc info variables +# Misc info variables INSTALL_TYPE="install" UPDATE_TYPE="standard" SCRIPTS_DIR='/opt/trmm-community-scripts' @@ -30,7 +30,7 @@ PYTHON_VER='3.10.4' SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py' LATEST_SETTINGS_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/api/tacticalrmm/tacticalrmm/settings.py" -### Variables required for automated install +# Variables required for automated install autoinstall="" rmmhost="" frontendhost="" @@ -40,9 +40,9 @@ rootdomain="" sslcacert="" sslkey="" sslcert="" +trmmuser="" - -### Get cfg files function +# Get cfg files function getCfgFiles() { if [ ! -f "$PWD/script-cfg/$2" ]; then @@ -50,18 +50,18 @@ getCfgFiles() fi } -### Check if directory exists, if not, create +# Check if directory exists, if not, create if [ ! -d $PWD/script-cfg ]; then mkdir $PWD/script-cfg fi -### Get cfg files +# Get cfg files for i in "${cfgfiles[@]}" do getCfgFiles "$CFG_URL" "$i"; done -### Import functions +# Import functions . $PWD/script-cfg/InputAndError.cfg . $PWD/script-cfg/MiscFunctions.cfg . $PWD/script-cfg/SystemInfoFunctions.cfg @@ -75,10 +75,10 @@ done . $PWD/script-cfg/TroubleshootingFunctions.cfg . $PWD/script-cfg/ParentFunctions.cfg -### Get commandline input function +# Get commandline input function getCommandLineArgs() { - while getopts "auto:api:branch:ca:cert:domain:email:help:key:mesh:repo:rmm:" option; do + while getopts "auto:api:branch:ca:cert:domain:email:help:key:mesh:repo:rmm:username:" option; do case $option in auto ) autoinstall="1" INSTALL_TYPE="${OPTARG}";; @@ -94,6 +94,7 @@ getCommandLineArgs() mesh ) meshhost="${OPTARG}";; repo ) REPO_OWNER="${OPTARG}";; rmm ) frontendhost="${OPTARG}";; + username ) trmmuser="${OPTARG}";; \?) echo -e "Error: Invalid option" clear -x exit 1;; @@ -101,19 +102,19 @@ getCommandLineArgs() done if [ "$autoinstall" == "1" ]; then - if [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$letsemail" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ]; then + if [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$letsemail" ]; then echo -e "Error: To perform an automated installation, you must provide all required information." echo -e "\n" - echo -e "api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, and Private key path are all required." + echo -e "api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username are all required." echo -e "\n" - echo -e "Run ./$THIS_SCRIPT -h for further details." + echo -e "Run .$THIS_SCRIPT -h for further details." clear -x exit 1 elif [ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]; then if [ "$REPO_OWNER" == "amidaware" ] || [ "$BRANCH" == "master" ]; then echo -e "Error: You've selected a developer installation type, but not changed the repo, branch, or both." echo -e "\n" - echo -e "Run ./$THIS_SCRIPT -h for details on how to select them." + echo -e "Run .$THIS_SCRIPT -h for details on how to select them." clear -x exit 1 fi @@ -123,16 +124,16 @@ getCommandLineArgs() fi } -### Get commandline input +# Get commandline input getCommandLineArgs; -### Set colors +# Set colors setColors; # MiscFunctions -### Gather OS info +# Gather OS info getOSInfo; # SystemInfoFunctions -### Install script pre-reqs +# Install script pre-reqs installPreReqs; # InstallFunctions ### Check for new functions versions, include url, filename, and script name as variables @@ -276,26 +277,29 @@ updateMenu() # Main menu mainMenu() { - until [ "$menuselection" = "0" ]; do - dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Main Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections." 0 0 0 \ - 1 "${mainmenuoptions[0]}" \ - 2 "${mainmenuoptions[1]}" \ - 3 "${mainmenuoptions[2]}" \ - 4 "${mainmenuoptions[3]}" 2>"${INPUT}" - - menuselection=$(<"${INPUT}") - - case $menuselection in - 1 ) installMenu;; - 2 ) updateMenu;; - 3 ) utilityMenu;; - 4 ) [ -f $INPUT ] && rm $INPUT - clear -x - exit;; - * ) derpDerp;; - esac - done - + if [ "$autoinstall" == "1" ]; then + mainInstall; + else + until [ "$menuselection" = "0" ]; do + dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Main Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections." 0 0 0 \ + 1 "${mainmenuoptions[0]}" \ + 2 "${mainmenuoptions[1]}" \ + 3 "${mainmenuoptions[2]}" \ + 4 "${mainmenuoptions[3]}" 2>"${INPUT}" + + menuselection=$(<"${INPUT}") + + case $menuselection in + 1 ) installMenu;; + 2 ) updateMenu;; + 3 ) utilityMenu;; + 4 ) [ -f $INPUT ] && rm $INPUT + clear -x + exit;; + * ) derpDerp;; + esac + done + fi return } diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index baa628c707..5aa43ee04e 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -56,7 +56,7 @@ installCertbot() if [ "$1" == "devinstall" ]; then print_green "Certificates should be in place" - else + elif [ "$autoinstall" != "1" ]; then dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have wildcard certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 case $? in # Get wildcard cert via LetsEncrypt @@ -64,11 +64,16 @@ installCertbot() # Import certs using vim 1 ) importCerts;; esac + elif [ "$autoinstall" == "1" ]; then + sudo mkdir -p /etc/letsencrypt/live/${rootdomain} + sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem + sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem + sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem fi # Set symlinks to avoid security concerns and simplify Nginx config sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem - sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem + sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem # Generate DH if it doesn't exist if [ ! -f /etc/ssl/certs/dhparam.pem ]; then diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 14b26820fd..d5e4b7fb64 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -96,16 +96,20 @@ configureBackend() python manage.py load_chocos python manage.py load_community_scripts WEB_VERSION=$(python manage.py get_config webversion) - until [ "$userconfirm" == "y" ]; do - djangousername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Create Site/Django Admin Login" --inputbox "Please enter the RMM website and django admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Create Site/Django Admin Login" --yesno "Is this correct?\n$djangousername" 0 0 - case $? in - 0 ) userconfirm="y";; - - 1 ) userconfirm="n" - derpDerp;; - esac - done + if [ "$autoinstall" == "1" ]; then + djangousername="$trmmuser" + else + until [ "$userconfirm" == "y" ]; do + djangousername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Create Site/Django Admin Login" --inputbox "Please enter the RMM website and django admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Create Site/Django Admin Login" --yesno "Is this correct?\n$djangousername" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + fi userconfirm="n" clear -x python manage.py createsuperuser --username ${djangousername} --email ${letsemail} diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 6a1b7efd5d..145ce1a54b 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -64,15 +64,16 @@ helpText() echo -e "auto Select type of automated installation. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC}, or${YELLOW} devinstall${NC}" echo -e "api Provide the api hostname/subdomain, eg ${YELLOW}api${NC}.example.com" echo -e "branch If performing a dev install, this will select the branch. eg, https://github.com/amidaware/tacticalrmm/${YELLOW}branch${NC}/.git" - echo -e "ca Path to SSL CA certificate for import. Must be in .pem format" + echo -e "ca Path to SSL CA Chain certificate for import. Must be in .pem format" echo -e "cert Path to SSL certificate for import. Must be in .pem format" echo -e "domain Provide the root domain, eg rmm.${YELLOW}example.com${NC}" - echo -e "email Provide a valid email address for LetsEncrypt cert generation" + echo -e "email Provide a valid email address for LetsEncrypt cert generation and primary T-RMM user" echo -e "help Show this help text" echo -e "key Path to SSL private key for import. Must be in .pem format" echo -e "mesh Provide the mesh hostname/subdomain, eg ${YELLOW}mesh${NC}.example.com" echo -e "repo If performing a dev install, this will select the repo owner. eg, https://github.com/${YELLOW}repo-owner${NC}/tacticalrmm/master/.git" echo -e "rmm Provide the rmm hostname/subdomain, eg ${YELLOW}rmm${NC}.example.com" + echo -e "username Provide the username for the primary T-RMM user" } # Check for new script version @@ -86,7 +87,11 @@ checkScriptVer() # download new file if available if [ "$1" -ne "${NEW_VER}" ]; then wget -q "$2" -O "$3" - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 + if [ "$autoinstall" == "1" ]; then + print_red "Error.\n\nOld $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 + fi rm -f $TMP_FILE clear -x exit 1 @@ -106,7 +111,11 @@ checkCfgVer() # download new file if available if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 + if [ "$autoinstall" == "1" ]; then + print_red "Error.\n\nOld $2 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 + fi rm -f $TMP_FILE clear -x exit 1 @@ -120,7 +129,11 @@ checkRoot() { # if user is root, exit if [ $EUID -eq 0 ]; then - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Do NOT run this script as root. Exiting." 0 0 + if [ "$autoinstall" == "1" ]; then + print_red "Error.\n\nDo NOT run this script as root.\n\nExiting." + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Do NOT run this script as root. Exiting." 0 0 + fi clear -x exit 1 fi @@ -137,7 +150,11 @@ checkTacticalUser() if [ -d /rmm ]; then tacticaluser=$(stat -c '%U' /rmm) if [ "$tacticaluser" != "${USER}" ]; then - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 + if [ "$autoinstall" == "1" ]; then + print_red "Error.\n\nThis script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 + fi clear -x exit 1 fi @@ -146,7 +163,11 @@ checkTacticalUser() elif [ "${USER}" != "tactical" ]; then tacticaluser="$(id -u tactical > /dev/null 2>&1; echo $?)" case $tacticaluser in - 0 ) dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 + 0 ) if [ "$autoinstall" == "1" ]; then + print_red "Error.\n\nThis script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 + fi clear -x exit 1;; @@ -154,7 +175,11 @@ checkTacticalUser() sudo useradd -m -G sudo -s /bin/bash tactical tacpass="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)" echo "tactical:$tacpass"| sudo chpasswd - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Created" --msgbox "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting." 0 0 + if [ "$autoinstall" == "1" ]; then + print_red "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting." + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Created" --msgbox "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting." 0 0 + fi clear -x exit 1;; esac @@ -167,7 +192,11 @@ checkTacticalUser() 1 ) print_green 'Adding Tactical user to sudo group.' sudo usermod -a -G sudo tactical - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Sudo Privileges Added" --msgbox "The Tactical user has been added to the sudo group.\nPlease log out of the tactical user, log back in, and try again.\n\nExiting." 0 0 + if [ "$autoinstall" == "1" ]; then + print_red "The Tactical user has been added to the sudo group.\nPlease log out of the tactical user, log back in, and try again.\n\nExiting." + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Sudo Privileges Added" --msgbox "The Tactical user has been added to the sudo group.\nPlease log out of the tactical user, log back in, and try again.\n\nExiting." 0 0 + fi clear -x exit 1;; esac diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 82364377ff..7b2664b9c8 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -35,7 +35,11 @@ verifySupportedOS() if ([ "$osname" == "ubuntu" ] && ([ "$fullrelno" == "20.04" ] || [ "$fullrelno" == "22.04" ])) || ([ "$osname" == "debian" ] && [ $relno -ge 10 ]); then print_green "$fullrel" else - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 + if [ "$autoinstall" == "1" ]; then + print_red "Error.\n\nSupported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 + fi clear -x exit 1 fi @@ -45,7 +49,11 @@ verifySupportedOS() checkLocale() { if [[ "$LANG" != *".UTF-8" ]]; then - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "System locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting." 0 0 + if [ "$autoinstall" == "1" ]; then + print_red "Error.\n\nSystem locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting." + else + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "System locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting." 0 0 + fi clear -x exit 1 fi diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index 9bfb6878e8..3a6f569921 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -17,123 +17,138 @@ generateUsersAndPass() ADMINURL=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 70 | head -n 1) # prompt to see if user wants to manually enter info or have it generated - dialog --cr-wrap --clear --yes-label "Automatic" --no-label "Manual" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "User and Password Generation" --yesno "Would you like to have usernames and passwords automatically randomly generated, or enter your own manually?" 0 0 - case $? in - # auto gen info for user - 0 ) 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) - clear -x;; - - 1 ) userconfirm="n" - - # Get MeshCentral admin username - until [ "$userconfirm" == "y" ]; do - meshusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --inputbox "Enter the MeshCentral Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --yesno "Is this correct?\n$meshusername" 0 0 - case $? in - 0 ) userconfirm="y";; - - 1 ) userconfirm="n" - derpDerp;; - esac - done - userconfirm="n" - - # Get MeshCentral admin password - MESHPASSWD="dont" - passinput="match" - until [ "$passinput" == "$MESHPASSWD" ]; do - MESHPASSWD=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Re-enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - if [ "$passinput" != "$MESHPASSWD" ]; then - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 - derpDerp; - else - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 - fi - done + if [ "$autoinstall" == "1" ]; then + 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) + else + dialog --cr-wrap --clear --yes-label "Automatic" --no-label "Manual" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "User and Password Generation" --yesno "Would you like to have usernames and passwords automatically randomly generated, or enter your own manually?" 0 0 + case $? in + # auto gen info for user + 0 ) 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) + clear -x;; - # Get Postgresql admin username - until [ "$userconfirm" == "y" ]; do - pgusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --inputbox "Enter the Postgresql Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --yesno "Is this correct?\n$pgusername" 0 0 - case $? in - 0 ) userconfirm="y";; + 1 ) userconfirm="n" - 1 ) userconfirm="n" - derpDerp;; - esac - done - userconfirm="n" - - # Get Postgresql admin password - pgpw="dont" - passinput="match" - until [ "$passinput" == "$pgpw" ]; do - pgpw=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Re-enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - if [ "$passinput" != "$pgpw" ]; then - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 - derpDerp; - else - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 - fi - done - clear -x;; - esac + # Get MeshCentral admin username + until [ "$userconfirm" == "y" ]; do + meshusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --inputbox "Enter the MeshCentral Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --yesno "Is this correct?\n$meshusername" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + + # Get MeshCentral admin password + MESHPASSWD="dont" + passinput="match" + until [ "$passinput" == "$MESHPASSWD" ]; do + MESHPASSWD=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Re-enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + if [ "$passinput" != "$MESHPASSWD" ]; then + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 + derpDerp; + else + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 + fi + done + + # Get Postgresql admin username + until [ "$userconfirm" == "y" ]; do + pgusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --inputbox "Enter the Postgresql Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --yesno "Is this correct?\n$pgusername" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + + # Get Postgresql admin password + pgpw="dont" + passinput="match" + until [ "$passinput" == "$pgpw" ]; do + pgpw=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Re-enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + if [ "$passinput" != "$pgpw" ]; then + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 + derpDerp; + else + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 + fi + done + clear -x;; + esac + fi } # Get host and domain info getHostAndDomainInfo() { - hostsconfirm="n" + if [ "$autoinstall" == "1" ]; then + rootdomain="$(translateToLowerCase $rootdomain)" + rmmhost="$(translateToLowerCase $rmmhost)" + frontendhost="$(translateToLowerCase $frontendhost)" + meshhost="$(translateToLowerCase $meshhost)" + letsemail="$(translateToLowerCase $letsemail)" + else + hostsconfirm="n" - until [ $hostsconfirm == "y" ]; do - rootdomain="none" - letsemail="none" + until [ $hostsconfirm == "y" ]; do + rootdomain="none" + letsemail="none" - # Get root domain - while [[ $rootdomain != *[.]* ]]; do - rootdomain=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Root Domain" --inputbox "Enter the root domain (eg example.com or example.co.uk):" 10 90 3>&1 1>&2 2>&3) - rootdomain="$(translateToLowerCase $rootdomain)" - if [[ $rootdomain != *[.]* ]]; then - derpDerp; - fi - done + # Get root domain + while [[ $rootdomain != *[.]* ]]; do + rootdomain=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Root Domain" --inputbox "Enter the root domain (eg example.com or example.co.uk):" 10 90 3>&1 1>&2 2>&3) + rootdomain="$(translateToLowerCase $rootdomain)" + if [[ $rootdomain != *[.]* ]]; then + derpDerp; + fi + done - # Get backend hostname - rmmhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Backend Hostname" --inputbox "Enter the hostname for the backend (e.g. api):" 10 90 3>&1 1>&2 2>&3) - rmmhost="$(translateToLowerCase $rmmhost)" + # Get backend hostname + rmmhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Backend Hostname" --inputbox "Enter the hostname for the backend (e.g. api):" 10 90 3>&1 1>&2 2>&3) + rmmhost="$(translateToLowerCase $rmmhost)" - # Get frontend hostname - frontendhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Frontend Hostname" --inputbox "Enter the hostname for the frontend (e.g. rmm):" 10 90 3>&1 1>&2 2>&3) - frontendhost="$(translateToLowerCase $frontendhost)" + # Get frontend hostname + frontendhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Frontend Hostname" --inputbox "Enter the hostname for the frontend (e.g. rmm):" 10 90 3>&1 1>&2 2>&3) + frontendhost="$(translateToLowerCase $frontendhost)" - # Get MeshCentral hostname - meshhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter MeshCentral Hostname" --inputbox "Enter the hostname for MeshCentral (e.g. mesh):" 10 90 3>&1 1>&2 2>&3) - meshhost="$(translateToLowerCase $meshhost)" + # Get MeshCentral hostname + meshhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter MeshCentral Hostname" --inputbox "Enter the hostname for MeshCentral (e.g. mesh):" 10 90 3>&1 1>&2 2>&3) + meshhost="$(translateToLowerCase $meshhost)" - # Get Admin email - while [[ $letsemail != *[@]*[.]* ]]; do - letsemail=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Admin E-Mail Address" --inputbox "Enter a valid e-mail address for Django, MeshCentral, and LetsEncrypt:" 10 90 3>&1 1>&2 2>&3) - letsemail="$(translateToLowerCase $letsemail)" - if [[ $letsemail != *[@]*[.]* ]]; then - derpDerp; - fi - done + # Get Admin email + while [[ $letsemail != *[@]*[.]* ]]; do + letsemail=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Admin E-Mail Address" --inputbox "Enter a valid e-mail address for Django, MeshCentral, and LetsEncrypt:" 10 90 3>&1 1>&2 2>&3) + letsemail="$(translateToLowerCase $letsemail)" + if [[ $letsemail != *[@]*[.]* ]]; then + derpDerp; + fi + done - # Verify input - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Confirm Input" --yesno "Is this correct?\n\nroot domain: $rootdomain\nbackend: $rmmhost.$rootdomain\nfrontend: $frontendhost.$rootdomain\nmeshcentral: $meshhost.$rootdomain\ne-mail address: $letsemail" 0 0 - case $? in - 0 ) userconfirm="y";; + # Verify input + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Confirm Input" --yesno "Is this correct?\n\nroot domain: $rootdomain\nbackend: $rmmhost.$rootdomain\nfrontend: $frontendhost.$rootdomain\nmeshcentral: $meshhost.$rootdomain\ne-mail address: $letsemail" 0 0 + case $? in + 0 ) userconfirm="y";; - 1 ) userconfirm="n" - derpDerp;; - esac - done - clear -x + 1 ) userconfirm="n" + derpDerp;; + esac + done + clear -x + fi # Combine host/domain entries for later use while keeping seperate entries as well rmmdomain="$rmmhost.$rootdomain" From ca8886a23e02180f89f485d64dd0d4ee48909ef3 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 24 Jun 2022 13:13:26 -0500 Subject: [PATCH 054/203] More updates for automated commandline installs --- installer-util.sh | 59 ++- script-cfg/CertificateFunctions.cfg | 6 +- script-cfg/ConfigAndServiceFunctions.cfg | 34 +- script-cfg/InstallFunctions.cfg | 45 +- script-cfg/MiscFunctions.cfg | 23 +- script-cfg/NetworkFunctions.cfg | 4 +- script-cfg/ParentFunctions.cfg | 597 +++++++++++++++-------- script-cfg/SystemInfoFunctions.cfg | 9 +- script-cfg/TroubleshootingFunctions.cfg | 1 + script-cfg/UpdateRestoreFunctions.cfg | 13 +- 10 files changed, 501 insertions(+), 290 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 11540aca49..0f95f6448a 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -41,6 +41,7 @@ sslcacert="" sslkey="" sslcert="" trmmuser="" +trmmpass="" # Get cfg files function getCfgFiles() @@ -78,7 +79,7 @@ done # Get commandline input function getCommandLineArgs() { - while getopts "auto:api:branch:ca:cert:domain:email:help:key:mesh:repo:rmm:username:" option; do + while getopts "auto:api:branch:ca:cert:domain:email:help:key:mesh:pass:repo:rmm:username:" option; do case $option in auto ) autoinstall="1" INSTALL_TYPE="${OPTARG}";; @@ -92,6 +93,7 @@ getCommandLineArgs() exit;; key ) sslkey="${OPTARG}";; mesh ) meshhost="${OPTARG}";; + pass ) trmmpass="${OPTARG}";; repo ) REPO_OWNER="${OPTARG}";; rmm ) frontendhost="${OPTARG}";; username ) trmmuser="${OPTARG}";; @@ -102,10 +104,10 @@ getCommandLineArgs() done if [ "$autoinstall" == "1" ]; then - if [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$letsemail" ]; then + if [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]; then echo -e "Error: To perform an automated installation, you must provide all required information." echo -e "\n" - echo -e "api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username are all required." + echo -e "api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required." echo -e "\n" echo -e "Run .$THIS_SCRIPT -h for further details." clear -x @@ -128,42 +130,53 @@ getCommandLineArgs() getCommandLineArgs; # Set colors -setColors; # MiscFunctions +# MiscFunctions +setColors; # Gather OS info -getOSInfo; # SystemInfoFunctions +# SystemInfoFunctions +getOSInfo; # Install script pre-reqs -installPreReqs; # InstallFunctions +# InstallFunctions +installPreReqs; -### Check for new functions versions, include url, filename, and script name as variables +# Check for new functions versions, include url, filename, and script name as variables for i in "${cfgfiles[@]}" do - checkCfgVer "$CFG_URL" "$i" "$THIS_SCRIPT"; # MiscFunctions + # MiscFunctions + checkCfgVer "$CFG_URL" "$i" "$THIS_SCRIPT"; done -### Check for new script version, pass script version, url, and script name variables in that order -checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; # MiscFunctions +# Check for new script version, pass script version, url, and script name variables in that order +# MiscFunctions +checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; -### Install additional prereqs -installAdditionalPreReqs; # InstallFunctions +# Install additional prereqs +# InstallFunctions +installAdditionalPreReqs; -### Fallback if lsb_release -si returns anything else than Ubuntu, Debian, or Raspbian -wutOSThis; # SystemInfoFunctions +# Fallback if lsb_release -si returns anything else than Ubuntu, Debian, or Raspbian +# SystemInfoFunctions +wutOSThis; -### Verify compatible OS and version -verifySupportedOS; # SystemInfoFunctions +# Verify compatible OS and version +# SystemInfoFunctions +verifySupportedOS; -### Check if root -checkRoot; # MiscFunctions +# Check if root +# MiscFunctions +checkRoot; -### Check if Tactical user exists, if not prompt to create it -checkTacticalUser; # MiscFunctions +# Check if Tactical user exists, if not prompt to create it +# MiscFunctions +checkTacticalUser; -### Check language/locale -checkLocale; # SystemInfoFunctions +# Check language/locale +# SystemInfoFunctions +checkLocale; -### Prevents logging issues with some VPS providers like Vultr if this is a freshly provisioned instance that hasn't been rebooted yet +# 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 #################### diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 5aa43ee04e..c4ea416eb9 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -34,7 +34,8 @@ importCerts() # Generate certs generateCerts() { - print_green 'Getting wildcard cert' + # MiscFunctions + print_green 'Getting wildcard cert'; # Get initial DNS text entry sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email @@ -55,7 +56,8 @@ installCertbot() fi if [ "$1" == "devinstall" ]; then - print_green "Certificates should be in place" + # MiscFunctions + print_green "Certificates should be in place"; elif [ "$autoinstall" != "1" ]; then dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have wildcard certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 case $? in diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index d5e4b7fb64..e74b727391 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -98,6 +98,7 @@ configureBackend() WEB_VERSION=$(python manage.py get_config webversion) if [ "$autoinstall" == "1" ]; then djangousername="$trmmuser" + echo "from accounts.models import User; User.objects.create_superuser('${trmmuser}', '${letsemail}', '${trmmpass}') if not User.objects.filter(username='${trmmuser}').exists() else 0;" | python manage.py shell else until [ "$userconfirm" == "y" ]; do djangousername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Create Site/Django Admin Login" --inputbox "Please enter the RMM website and django admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) @@ -109,16 +110,19 @@ configureBackend() derpDerp;; esac done + + userconfirm="n" + clear -x + python manage.py createsuperuser --username ${djangousername} --email ${letsemail} + python manage.py create_installer_user + + RANDBASE=$(python manage.py generate_totp) + # Misc functions + cls; + python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} + deactivate + read -n 1 -s -r -p "Press any key to continue..." fi - userconfirm="n" - clear -x - python manage.py createsuperuser --username ${djangousername} --email ${letsemail} - python manage.py create_installer_user - RANDBASE=$(python manage.py generate_totp) - cls; - python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} - deactivate - read -n 1 -s -r -p "Press any key to continue..." fi } @@ -246,7 +250,8 @@ enableMeshService() # We will know it's ready once the last line of the systemd service stdout is 'MeshCentral HTTP server running on port.....' while ! [[ $CHECK_MESH_READY ]]; do CHECK_MESH_READY=$(sudo journalctl -u meshcentral.service -b --no-pager | grep "MeshCentral HTTP server running on port") - print_yellow "Mesh Central not ready yet..." + # Misc functions + print_yellow "Mesh Central not ready yet..."; sleep 3 done } @@ -276,7 +281,8 @@ configMeshUserGroup() while ! [[ $CHECK_MESH_READY2 ]]; do CHECK_MESH_READY2=$(sudo journalctl -u meshcentral.service -b --no-pager | grep "MeshCentral HTTP server running on port") - print_yellow "Mesh Central not ready yet..." + # Misc functions + print_yellow "Mesh Central not ready yet..."; sleep 3 done @@ -305,7 +311,7 @@ changeUWSGIProcs() { local countconfirm="n" - ### Get UWSGI Processes value + # Get UWSGI Processes value until [ $countconfirm == "y" ]; do uwsgiprocs=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Process Count" --inputbox "Enter the desired UWSGI Process Count, usually the same as CPU core count:" 10 90 3>&1 1>&2 2>&3) dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Process Count" --yesno "Is this correct?\n$uwsgiprocs" 0 0 @@ -318,7 +324,7 @@ changeUWSGIProcs() done countconfirm="n" - ### Get UWSGI Threads value + # Get UWSGI Threads value until [ $countconfirm == "y" ]; do uwsgithreads=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Thread Count" --inputbox "Enter the desired UWSGI Process Count, usually the same as CPU core count:" 10 90 3>&1 1>&2 2>&3) dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Thread Count" --yesno "Is this correct?\n$uwsgithreads" 0 0 @@ -331,7 +337,7 @@ changeUWSGIProcs() done countconfirm="n" - ### Stop rmm service, copy default file, edit processes/threads, start service + # Stop rmm service, copy default file, edit processes/threads, start service sudo systemctl stop rmm createUwsgiConf; sudo systemctl start rmm diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 4ea276e6c6..1f0753f8fc 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -58,7 +58,8 @@ installNodeJS() if [ "$1" == "update" ]; then HAS_NODE16=$(node --version | grep v16) if ! [ $HAS_NODE16 ]; then - print_green "Updating NodeJS to v16" + # Misc functions + print_green "Updating NodeJS to v16"; rm -rf /rmm/web/node_modules sudo systemctl stop meshcentral sudo apt remove -y nodejs @@ -89,12 +90,14 @@ installPython() if [ "$1" == "update" ]; then HAS_PY310=$(python3.10 --version | grep ${PYTHON_VER}) if ! [ $HAS_PY310 ]; then - print_green "Updating to ${PYTHON_VER}" + # Misc functions + print_green "Updating to ${PYTHON_VER}"; fi fi if [ "$1" == "devinstall" ]; then - print_green "Python already installed" + # Misc functions + print_green "Python already installed"; else numprocs=$(nproc) cd ~ @@ -107,7 +110,8 @@ installPython() cd ~ sudo rm -rf Python-${PYTHON_VER} Python-${PYTHON_VER}.tgz if [ "$1" == "devprep" ]; then - print_green 'All Prereqs installed' + # Misc functions + print_green 'All Prereqs installed'; exit fi fi @@ -131,7 +135,8 @@ installNats() if [ "$1" == "update" ]; then HAS_LATEST_NATS=$(/usr/local/bin/nats-server -version | grep "${NATS_SERVER_VER}") if ! [ $HAS_LATEST_NATS ]; then - print_green "Updating nats to v${NATS_SERVER_VER}" + # Misc functions + print_green "Updating nats to v${NATS_SERVER_VER}"; fi fi if [ "$1" == "install" ] || [ "$1" == "devinstall" ] || [ "$1" == "restore" ]; then @@ -185,17 +190,19 @@ installNginx() sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf elif [ "$1" == "updatepart1" ]; then - ### Check Nginx config + # Check Nginx config if ! sudo nginx -t > /dev/null 2>&1; then sudo nginx -t - print_red "You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script." - print_red "Aborting..." + # Misc functions + print_red "You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script."; + print_red "Aborting..."; exit 1 fi elif [ "$1" == "updatepart2" ]; then CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" /etc/nginx/nginx.conf) if ! [ $CHECK_NGINX_WORKER_CONN ]; then - print_green "Changing nginx worker connections to 2048" + # Misc functions + print_green "Changing nginx worker connections to 2048"; sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf fi sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf @@ -207,12 +214,8 @@ installNginx() sudo tar -xzf $tmp_dir/nginx/etc-nginx.tar.gz -C /etc/nginx sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf - rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - local temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" - local tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" - rootdomain="$temprootdomain.$tempdotsomething" + # Misc functions + getExistingDomainInfo; fi } @@ -245,11 +248,11 @@ installFail2ban() { sudo apt install -y fail2ban - ### Copy default jail config to create override config + # Copy default jail config to create override config sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local sudo truncate -s 0 /etc/fail2ban/jail.local - ### Write default jail config override + # Write default jail config override sudo chmod 777 /etc/fail2ban/jail.local sudo printf '[DEFAULT]' >> /etc/fail2ban/jail.local sudo printf "\nignoreip = 127.0.0.1/8" >> /etc/fail2ban/jail.local @@ -281,18 +284,18 @@ installFail2ban() sudo printf "\nbantime = 31536000 ; 1 year" >> /etc/fail2ban/jail.local sudo chmod 644 /etc/fail2ban/jail.local - ### Copy default app config to create override config + # Copy default app config to create override config sudo cp /etc/fail2ban/fail2ban.conf /etc/fail2ban/fail2ban.local sudo truncate -s 0 /etc/fail2ban/fail2ban.local - ### Write default app config override + # Write default app config override sudo chmod 777 /etc/fail2ban/fail2ban.local sudo printf '[Definition]' >> /etc/fail2ban/fail2ban.local sudo printf "\ndbpurgeage = 31579200" >> /etc/fail2ban/fail2ban.local sudo printf "\nloglevel = INFO" >> /etc/fail2ban/fail2ban.local sudo chmod 644 /etc/fail2ban/fail2ban.local - ### Add T-RMM definition + # Add T-RMM definition sudo echo '[Definition]' | sudo tee /etc/fail2ban/filter.d/tacticalrmm.conf sudo chmod 777 /etc/fail2ban/filter.d/tacticalrmm.conf sudo printf "\n" >> /etc/fail2ban/filter.d/tacticalrmm.conf @@ -301,6 +304,6 @@ installFail2ban() sudo printf 'ignoreregex = ^.*200.*$' >> /etc/fail2ban/filter.d/tacticalrmm.conf sudo chmod 644 /etc/fail2ban/filter.d/tacticalrmm.conf - ### Restart Fail2ban + # Restart Fail2ban sudo systemctl restart fail2ban } \ No newline at end of file diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 145ce1a54b..cb6d2fac6c 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -71,9 +71,10 @@ helpText() echo -e "help Show this help text" echo -e "key Path to SSL private key for import. Must be in .pem format" echo -e "mesh Provide the mesh hostname/subdomain, eg ${YELLOW}mesh${NC}.example.com" + echo -e "pass Provide the password for the initial T-RMM user" echo -e "repo If performing a dev install, this will select the repo owner. eg, https://github.com/${YELLOW}repo-owner${NC}/tacticalrmm/master/.git" echo -e "rmm Provide the rmm hostname/subdomain, eg ${YELLOW}rmm${NC}.example.com" - echo -e "username Provide the username for the primary T-RMM user" + echo -e "username Provide the username for the initial T-RMM user" } # Check for new script version @@ -151,7 +152,7 @@ checkTacticalUser() tacticaluser=$(stat -c '%U' /rmm) if [ "$tacticaluser" != "${USER}" ]; then if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nThis script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." + print_red "Error.\n\nThis script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting."; else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 fi @@ -164,7 +165,7 @@ checkTacticalUser() tacticaluser="$(id -u tactical > /dev/null 2>&1; echo $?)" case $tacticaluser in 0 ) if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nThis script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." + print_red "Error.\n\nThis script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting."; else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 fi @@ -176,7 +177,7 @@ checkTacticalUser() tacpass="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)" echo "tactical:$tacpass"| sudo chpasswd if [ "$autoinstall" == "1" ]; then - print_red "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting." + print_red "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting."; else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Created" --msgbox "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting." 0 0 fi @@ -304,4 +305,18 @@ decideMainRepos() done # Check for new script version, pass script version, url, and script name variables in that order checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; +} + +# Pull domain info from existing installation +getExistingDomainInfo() +{ + local temprootdomain="" + local tempdotsomething="" + + rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" + tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" + rootdomain="$temprootdomain.$tempdotsomething" } \ No newline at end of file diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index 3db7d15a55..618323bde8 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -46,13 +46,13 @@ configHosts() # this also allows the install script to properly finish even if DNS has not fully propagated CHECK_LOCALHOST=$(grep "127.0.0.1 localhost" /etc/hosts) if ! [ $CHECK_LOCALHOST ]; then - print_green 'Adding localhost to hosts file' + print_green 'Adding localhost to hosts file'; # Misc functions sudo sed -i '1i 127.0.0.1 localhost' /etc/hosts fi CHECK_HOSTS=$(grep "127.0.1.1 $rmmdomain $frontenddomain $meshdomain" /etc/hosts) if [[ $CHECK_HOSTS ]]; then - print_green 'Correcting subdomains entries' + print_green 'Correcting subdomains entries'; # Misc functions sudo sed -i "/127.0.1.1 $rmmdomain $frontenddomain $meshdomain/d" /etc/hosts setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 46f7cb36a5..9ff453145a 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -12,148 +12,210 @@ CFG_VERSION="8" # Main install function mainInstall() { - ### Repo info for Postegres and Mongo + # Repo info for Postegres and Mongo + # InstallFunctions setInstallRepos; - ### Create usernames and passwords + # Create usernames and passwords + # User Input generateUsersAndPass; - ### This does... something + # This does... something + # Misc functions cls; - ### Get host/domain info + # Get host/domain info + # User Input getHostAndDomainInfo; - ### Configure hosts file - print_green 'Configuring Hosts file' + # Configure hosts file + # Misc functions + print_green 'Configuring Hosts file'; + # Network functions configHosts; - ### Certificate generation - print_green 'Installing Certbot' + # Certificate generation + # Misc functions + print_green 'Installing Certbot'; + # InstallFunctions installCertbot "$INSTALL_TYPE"; - ### Install Nginx - print_green 'Installing Nginx' + # Install Nginx + # Misc functions + print_green 'Installing Nginx'; + # InstallFunctions installNginx "$INSTALL_TYPE"; - ### Install NodeJS - print_green 'Installing NodeJS' + # Install NodeJS + # Misc functions + print_green 'Installing NodeJS'; + # InstallFunctions installNodeJS; - ### Install and enable MongoDB - print_green 'Installing MongoDB' + # Install and enable MongoDB + # Misc functions + print_green 'Installing MongoDB'; + # InstallFunctions installMongo; - ### Install Python - print_green "Installing Python ${PYTHON_VER}" + # Install Python + # Misc functions + print_green "Installing Python ${PYTHON_VER}"; + # InstallFunctions installPython "$INSTALL_TYPE"; - ### Installing Redis - print_green 'Installing redis' + # Installing Redis + # Misc functions + print_green 'Installing redis'; + # InstallFunctions installRedis; - ### Install and enable Postgresql - print_green 'Installing postgresql' + # Install and enable Postgresql + # Misc functions + print_green 'Installing postgresql'; + # InstallFunctions installPostgresql; - ### Postgres DB creation - print_green 'Creating database for the rmm' + # Postgres DB creation + # Misc functions + print_green 'Creating database for the rmm'; + # Database functions createPGDB; - ### Clone main repo - print_green 'Cloning primary repo' + # Clone main repo + # Misc functions + print_green 'Cloning primary repo'; + # Misc functions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; - ### Clone scripts repo - print_green 'Cloning community scripts repo' + # Clone scripts repo + # Misc functions + print_green 'Cloning community scripts repo'; + # Misc functions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; - ### Installing NATS - print_green 'Installing NATS' + # Installing NATS + # Misc functions + print_green 'Installing NATS'; + # InstallFunctions installNats "$INSTALL_TYPE"; - ### Install MeshCentral - print_green 'Installing MeshCentral' + # Install MeshCentral + # Misc functions + print_green 'Installing MeshCentral'; + # InstallFunctions installMeshCentral "$INSTALL_TYPE"; - ### Create MeshCentral config - print_green 'Generating MeshCentral Config' + # Create MeshCentral config + # Misc functions + print_green 'Generating MeshCentral Config'; + # Config and Service functions createMeshConfig; - ### Create local settings file - print_green 'Generating Local Settings' + # Create local settings file + # Misc functions + print_green 'Generating Local Settings'; + # Config and Service functions createLocalSettings; - ### Install NATS-API and correct permissions - print_green 'Installing NATS API' + # Install NATS-API and correct permissions + # Misc functions + print_green 'Installing NATS API'; + # InstallFunctions installNatsApi; - ### Install backend, configure primary admin user, setup admin 2fa - print_green 'Installing the backend' + # Install backend, configure primary admin user, setup admin 2fa + # Misc functions + print_green 'Installing the backend'; + # Config and Service functions configureBackend; - ### Determine Proc setting for UWSGI - print_green 'Optimizing UWSGI for number of processors' + # Determine Proc setting for UWSGI + # Misc functions + print_green 'Optimizing UWSGI for number of processors'; + # Config and Service functions setUwsgiProcs; - ### Create UWSGI config - print_green 'Creating UWSGI configuration' + # Create UWSGI config + # Misc functions + print_green 'Creating UWSGI configuration'; + # Config and Service functions createUwsgiConf; - ### Create RMM UWSGI systemd service - print_green 'Creating UWSGI service' + # Create RMM UWSGI systemd service + # Misc functions + print_green 'Creating UWSGI service'; + # Config and Service functions createUwsgiService; - ### Create Daphne systemd service - print_green 'Creating Daphne service' + # Create Daphne systemd service + # Misc functions + print_green 'Creating Daphne service'; + # Config and Service functions createDaphneService; - ### Create NATS systemd service - print_green 'Creating NATS service' + # Create NATS systemd service + # Misc functions + print_green 'Creating NATS service'; + # Config and Service functions createNatsService; - ### Create NATS-api systemd service - print_green 'Creating NATS-API service' + # Create NATS-api systemd service + # Misc functions + print_green 'Creating NATS-API service'; + # Config and Service functions createNatsApiService; - ### Create Backend Nginx site config - print_green 'Creating Backend Nginx config' + # Create Backend Nginx site config + # Misc functions + print_green 'Creating Backend Nginx config'; + # Config and Service functions createBackendNginxConf; - ### Create MeshCentral Nginx configuration - print_green 'Creating MeshCentral Nginx config' + # Create MeshCentral Nginx configuration + # Misc functions + print_green 'Creating MeshCentral Nginx config'; + # Config and Service functions createMeshNginxConf; - ### Enable Mesh and RMM sites + # Enable Mesh and RMM sites sudo ln -s /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-enabled/rmm.conf sudo ln -s /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-enabled/meshcentral.conf - ### Create conf directory + # Create conf directory sudo mkdir /etc/conf.d - ### Create Celery systemd service - print_green 'Creating Celery service' + # Create Celery systemd service + # Misc functions + print_green 'Creating Celery service'; + # Config and Service functions createCeleryService; - ### Configure Celery service - print_green 'Creating Celery config' + # Configure Celery service + # Misc functions + print_green 'Creating Celery config'; + # Config and Service functions createCeleryConf; - ### Create CeleryBeat systemd service - print_green 'Creating CeleryBeat service' + # Create CeleryBeat systemd service + # Misc functions + print_green 'Creating CeleryBeat service'; + # Config and Service functions createCeleryBeatService; - ### Correct conf dir ownership + # Correct conf dir ownership sudo chown "${USER}:${USER}" -R /etc/conf.d/ - ### Create MeshCentral systemd service - print_green 'Creating MeshCentral service' + # Create MeshCentral systemd service + # Misc functions + print_green 'Creating MeshCentral service'; + # Config and Service functions createMeshCentralService; - ### Update services info + # Update services info sudo systemctl daemon-reload - ### Verify and correct permissions + # Verify and correct permissions if [ -d ~/.npm ]; then sudo chown -R "${USER}:${GROUP}" ~/.npm fi @@ -162,19 +224,24 @@ mainInstall() sudo chown -R "${USER}:${GROUP}" ~/.config fi - ### Install frontend - print_green 'Installing the frontend' + # Install frontend + # Misc functions + print_green 'Installing the frontend'; + # InstallFunctions installFrontEnd "$INSTALL_TYPE" "$FRONTEND_URL"; - ### Set front end Nginx config and enable - print_green 'Creating Frontend Nginx config' + # Set front end Nginx config and enable + # Misc functions + print_green 'Creating Frontend Nginx config'; + # Config and Service functions createFrontendNginxConf; - ### Enable Frontend site + # Enable Frontend site sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf - ### Enable RMM, Daphne, Celery, and Nginx services - print_green 'Enabling Services' + # Enable RMM, Daphne, Celery, and Nginx services + # Misc functions + print_green 'Enabling Services'; for i in rmm.service daphne.service celery.service celerybeat.service nginx do @@ -184,27 +251,36 @@ mainInstall() done sleep 5 - ### Enable MeshCentral service - print_green 'Starting meshcentral and waiting for it to install plugins' + # Enable MeshCentral service + # Misc functions + print_green 'Starting meshcentral and waiting for it to install plugins'; + # Config and Service functions enableMeshService; - ### Generating MeshCentral key - print_green 'Generating meshcentral login token key' + # Generating MeshCentral key + # Misc functions + print_green 'Generating meshcentral login token key'; + # Config and Service functions generateMeshToken; - ### Configuring MeshCentral admin user and device group, restart service - print_green 'Creating meshcentral account and group' + # Configuring MeshCentral admin user and device group, restart service + # Misc functions + print_green 'Creating meshcentral account and group'; + # Config and Service functions configMeshUserGroup; - ### Enable and configure NATS service - print_green 'Starting NATS service' + # Enable and configure NATS service + # Misc functions + print_green 'Starting NATS service'; + # Config and Service functions enableNatsService; - ### Disable django admin + # Disable django admin sed -i 's/ADMIN_ENABLED = True/ADMIN_ENABLED = False/g' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - ### Restart core services - print_green 'Restarting services' + # Restart core services + # Misc functions + print_green 'Restarting services'; for i in rmm.service daphne.service celery.service celerybeat.service do @@ -212,21 +288,23 @@ mainInstall() sudo systemctl start ${i} done - ### Yay, we're done! - print_yellow "Installation complete!" + # Yay, we're done! + # Misc functions + print_yellow "Installation complete!"; printf >&2 "${YELLOW}Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n\n" printf >&2 "${YELLOW}Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n\n" printf >&2 "${YELLOW}MeshCentral username: ${GREEN}${meshusername}${NC}\n" printf >&2 "${YELLOW}MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n\n" if [ "$BEHIND_NAT" = true ]; then - print_yellow "Read below if your router does NOT support Hairpin NAT:" - print_green "If you will be accessing the web interface of the RMM from the same LAN as this server,\nyou'll need to make sure your 3 subdomains resolve to ${IPV4}" - print_green "This also applies to any agents that will be on the same local network as the rmm." - print_green "You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp." + # Misc functions + print_yellow "Read below if your router does NOT support Hairpin NAT:"; + print_green "If you will be accessing the web interface of the RMM from the same LAN as this server,\nyou'll need to make sure your 3 subdomains resolve to ${IPV4}"; + print_green "This also applies to any agents that will be on the same local network as the rmm."; + print_green "You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp."; fi - - print_yellow "Please refer to the github README for next steps." + # Misc functions + print_yellow "Please refer to the github README for next steps."; return } @@ -234,43 +312,54 @@ mainInstall() # Update function updateTRMM() { - ### Check if user is same as during installation + # Check if user is same as during installation + # UpdateRestoreFunctions checkSameUser "$INSTALL_TYPE"; - ### Get current release version and check if update is necessary + # Get current release version and check if update is necessary + # UpdateRestoreFunctions checkIfUpdate; - ### Get current versions of necessary included apps + # Get current versions of necessary included apps + # UpdateRestoreFunctions checkAdditionalAppsVers; - ### Clear screen + # Clear screen + # Misc functions cls; - ### Check CHECK_NATS_LIMITNOFILE, whatever that means + # Check CHECK_NATS_LIMITNOFILE, whatever that means + # UpdateRestoreFunctions checkNatsLimitNoFile; - ### Check Nginx config + # Check Nginx config + # InstallFunctions installNginx "updatepart1"; - ### Stop services + # Stop services for i in nginx nats-api nats rmm daphne celery celerybeat do - print_green "Stopping ${i} service..." + # Misc functions + print_green "Stopping ${i} service..."; sudo systemctl stop "${i}" done - ### Rebuild uwsgi config + # Rebuild uwsgi config rm -f /rmm/api/tacticalrmm/app.ini + # Config and Service functions setUwsgiProcs; - createUwsgiConf; + # Config and Service functions + createUwsgiConf; # Config and Service functions - ### Check if Python is up to date, if not, update + # Check if Python is up to date, if not, update + # InstallFunctions installPython "$INSTALL_TYPE"; - ### Check if NATS is up to date, if not, update + # Check if NATS is up to date, if not, update + # InstallFunctions installNats "$INSTALL_TYPE"; - ### This does stuff + # This does stuff if [ -d ~/.npm ]; then sudo rm -rf ~/.npm fi @@ -283,72 +372,89 @@ updateTRMM() sudo chown -R "${USER}:${GROUP}" ~/.config fi - ### Check NodeJS version, update if needed and update MeshCentral - print_green 'Updating NodeJS' + # Check NodeJS version, update if needed and update MeshCentral + # Misc functions + print_green 'Updating NodeJS'; + # InstallFunctions installNodeJS "$INSTALL_TYPE"; - ### Pull domain info from existing Nginx confs - rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + # Pull domain info from existing Nginx confs + # Misc functions + getExistingDomainInfo; - ### Set symlinks to avoid security concerns and simplify Nginx config + # Set symlinks to avoid security concerns and simplify Nginx config sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem - ### Update from main repo - print_green 'Cloning primary repo' + # Update from main repo + # Misc functions + print_green 'Cloning primary repo'; + # Misc functions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; - ### Update from community-scripts repo - print_green 'Cloning community scripts repo' + # Update from community-scripts repo + # Misc functions + print_green 'Cloning community scripts repo'; + # Misc functions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; - ### Apply updated Ownership and perms + # Apply updated Ownership and perms sudo chown "${USER}:${USER}" -R /rmm sudo chown "${USER}:${USER}" -R ${SCRIPTS_DIR} sudo chown "${USER}:${USER}" /var/log/celery sudo chown "${USER}:${USER}" -R /etc/conf.d/ - ### Check additional Nginx settings and update + # Check additional Nginx settings and update + # InstallFunctions installNginx "updatepart2"; - ### Update Nginx conf files + # Update Nginx conf files + # Config and Service functions createMeshNginxConf; + # Config and Service functions createFrontendNginxConf; + # Config and Service functions createBackendNginxConf; - ### Reconfigure backend + # Reconfigure backend + # Config and Service functions createCeleryConf; + # Config and Service functions configureBackend "$INSTALL_TYPE"; - ### Disable Redis append only + # Disable Redis append only + # UpdateRestoreFunctions turnOffRedisAppendOnly; - ### Update Frontend + # Update Frontend + # InstallFunctions installFrontEnd "$INSTALL_TYPE" "$FRONTEND_URL"; - ### Start services + # Start services for i in nats nats-api rmm daphne celery celerybeat nginx do - print_green "Starting ${i} service" + # Misc functions + print_green "Starting ${i} service"; sudo systemctl start "${i}" done sleep 1 - ### Push agent updates + # Push agent updates /rmm/api/env/bin/python /rmm/api/tacticalrmm/manage.py update_agents - ### Update MeshCentral if necessary + # Update MeshCentral if necessary updateMeshCentral; + # Config and Service functions createMeshConfig; + # Config and Service functions enableMeshService "$INSTALL_TYPE"; - ### Cleanup + # Cleanup rm -f $TMP_SETTINGS - ### Bye-bye - print_green "Update finished!" + # Bye-bye + # Misc functions + print_green "Update finished!"; return } @@ -356,32 +462,32 @@ updateTRMM() # Backup Function backupTRMM() { - ### Pull Postgres info + # Pull Postgres info POSTGRES_USER=$(grep -w USER /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//') POSTGRES_PW=$(grep -w PASSWORD /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//') - ### Check if rmmbackup folder exists, if not create it + # Check if rmmbackup folder exists, if not create it if [ ! -d /rmmbackups ]; then sudo mkdir /rmmbackups sudo chown "${USER}:${USER}" /rmmbackups fi - ### Remove old MeshCentral backups + # Remove old MeshCentral backups if [ -d /meshcentral/meshcentral-backup ]; then rm -rf /meshcentral/meshcentral-backup/* fi - ### Remove old MeshCentral DB backups + # Remove old MeshCentral DB backups if [ -d /meshcentral/meshcentral-coredumps ]; then rm -f /meshcentral/meshcentral-coredumps/* fi - ### Set info for backup and folders + # Set info for backup and folders dt_now=$(date '+%Y_%m_%d__%H_%M_%S') tmp_dir=$(mktemp -d -t tacticalrmm-XXXXXXXXXXXXXXXXXXXXX) sysd="/etc/systemd/system" - ### Create temp backup subdirectories + # Create temp backup subdirectories mkdir -p ${tmp_dir}/meshcentral/mongo mkdir ${tmp_dir}/postgres mkdir ${tmp_dir}/certs @@ -390,23 +496,23 @@ backupTRMM() mkdir ${tmp_dir}/rmm mkdir ${tmp_dir}/confd - ### Dump Postgres database + # Dump Postgres database pg_dump --dbname=postgresql://"${POSTGRES_USER}":"${POSTGRES_PW}"@127.0.0.1:5432/tacticalrmm | gzip -9 > ${tmp_dir}/postgres/db-${dt_now}.psql.gz - ### Backup Mesh stuff + # Backup Mesh stuff tar -czvf ${tmp_dir}/meshcentral/mesh.tar.gz --exclude=/meshcentral/node_modules /meshcentral mongodump --gzip --out=${tmp_dir}/meshcentral/mongo - ### Backup certs + # Backup certs sudo tar -czvf ${tmp_dir}/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt . - ### Backup Nginx configs + # Backup Nginx configs sudo tar -czvf ${tmp_dir}/nginx/etc-nginx.tar.gz -C /etc/nginx . - ### Backup other config files + # Backup other config files sudo tar -czvf ${tmp_dir}/confd/etc-confd.tar.gz -C /etc/conf.d . - ### Copy service files + # Copy service files sudo cp ${sysd}/rmm.service ${sysd}/celery.service ${sysd}/celerybeat.service ${sysd}/meshcentral.service ${sysd}/nats.service ${sysd}/daphne.service ${tmp_dir}/systemd/ if [ -f "${sysd}/nats-api.service" ]; then sudo cp ${sysd}/nats-api.service ${tmp_dir}/systemd/ @@ -417,10 +523,10 @@ backupTRMM() tar -cf /rmmbackups/rmm-backup-${dt_now}.tar -C ${tmp_dir} . - ### Remove temp files/folders + # Remove temp files/folders rm -rf ${tmp_dir} - - print_green "Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar" + # Misc functions + print_green "Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar"; return } @@ -428,137 +534,184 @@ backupTRMM() # Restore T-RMM restoreTRMM() { - ### Repo info for Postegres and Mongo + # Repo info for Postegres and Mongo + # InstallFunctions setInstallRepos; - ### Get backup file location + # Get backup file location + # UpdateRestoreFunctions getBackupFileLocation; - ### Extract backup + # Extract backup + # UpdateRestoreFunctions extractBackup "$backuppath"; - ### Check if original user + # Check if original user + # UpdateRestoreFunctions checkSameUser "$INSTALL_TYPE"; - ### Install NodeJS - print_green 'Installing NodeJS' + # Install NodeJS + # Misc functions + print_green 'Installing NodeJS'; + # InstallFunctions installNodeJS; - ### Install Nginx and restore Nginx configuration - print_green 'Installing Nginx and restoring configuration' + # Install Nginx and restore Nginx configuration + # Misc functions + print_green 'Installing Nginx and restoring configuration'; + # InstallFunctions installNginx "$INSTALL_TYPE"; - ### Restore hosts config + # Restore hosts config + # Network functions configHosts; - ### Restore Certbot - print_green 'Installing Certbot' + # Restore Certbot + # Misc functions + print_green 'Installing Certbot'; + # InstallFunctions installCertbot "$INSTALL_TYPE"; - ### Restoring existing certs - print_green 'Restoring certs' + # Restoring existing certs + # Misc functions + 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 - ### Set symlinks to avoid security concerns and simplify Nginx config + # Set symlinks to avoid security concerns and simplify Nginx config sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem - ### Recreate Nginx conf files + # Recreate Nginx conf files + # Config and Service functions createMeshNginxConf; + # Config and Service functions createFrontendNginxConf; + # Config and Service functions createBackendNginxConf; - ### Restore Celery configs - print_green 'Restoring celery configs' + # Restore Celery configs + # Misc functions + print_green 'Restoring celery configs'; sudo mkdir /etc/conf.d sudo tar -xzf $tmp_dir/confd/etc-confd.tar.gz -C /etc/conf.d sudo chown "${USER}:${USER}" -R /etc/conf.d - ### Restoring services - print_green 'Restoring systemd services' + # Restoring services + # Misc functions + print_green 'Restoring systemd services'; sudo cp $tmp_dir/systemd/* /etc/systemd/system/ sudo systemctl daemon-reload - ### Install Python - print_green "Installing Python ${PYTHON_VER}" + # Install Python + # Misc functions + print_green "Installing Python ${PYTHON_VER}"; + # InstallFunctions installPython; - ### Installing Redis - print_green 'Installing redis' + # Installing Redis + # Misc functions + print_green 'Installing redis'; + # InstallFunctions installRedis; - ### Install and enable Postgresql - print_green 'Installing postgresql' + # Install and enable Postgresql + # Misc functions + print_green 'Installing postgresql'; + # InstallFunctions installPostgresql; - ### Install and enable MongoDB - print_green 'Installing MongoDB' + # Install and enable MongoDB + # Misc functions + print_green 'Installing MongoDB'; + # InstallFunctions installMongo; - ### Restore Mongo database - print_green 'Restoring MongoDB' + # Restore Mongo database + # Misc functions + print_green 'Restoring MongoDB'; mongorestore --gzip $tmp_dir/meshcentral/mongo - ### Clone main repo - print_green 'Cloning primary repo' + # Clone main repo + # Misc functions + print_green 'Cloning primary repo'; + # Misc functions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; - ### Clone scripts repo - print_green 'Cloning community scripts repo' + # Clone scripts repo + # Misc functions + print_green 'Cloning community scripts repo'; + # Misc functions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; - ### Installing NATS - print_green 'Installing NATS' + # Installing NATS + # Misc functions + print_green 'Installing NATS'; + # InstallFunctions installNats "$INSTALL_TYPE"; - ### Restore MeshCentral - print_green 'Restoring MeshCentral' + # Restore MeshCentral + # Misc functions + print_green 'Restoring MeshCentral'; + # InstallFunctions installMeshCentral "$INSTALL_TYPE"; - ### Restore UWSGI - print_green 'Optimizing UWSGI for number of processors' + # Restore UWSGI + # Misc functions + print_green 'Optimizing UWSGI for number of processors'; + # Config and Service functions setUwsgiProcs; - print_green 'Creating UWSGI configuration' + # Misc functions + print_green 'Creating UWSGI configuration'; + # Config and Service functions createUwsgiConf; - ### Restoring other misc stuff + # Restoring other misc stuff cp $tmp_dir/rmm/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/ cp $tmp_dir/rmm/env /rmm/web/.env gzip -d $tmp_dir/rmm/debug.log.gz cp $tmp_dir/rmm/django_debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/ - ### Install NATS-API - print_green 'Installing NATS API' + # Install NATS-API + # Misc functions + print_green 'Installing NATS API'; + # InstallFunctions installNatsApi; - ### Restore Postgres database - print_green 'Restoring the Postgres database' + # Restore Postgres database + # Misc functions + print_green 'Restoring the Postgres 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" + # Database functions createPGDB; gzip -d $tmp_dir/postgres/*.psql.gz PGPASSWORD="${pgpw} psql -h localhost -U ${pgusername} -d tacticalrmm -f $tmp_dir/postgres/db*.psql" - ### Restore Backend - print_green 'Restoring the backend' + # Restore Backend + # Misc functions + print_green 'Restoring the backend'; + # Config and Service functions configureBackend "$INSTALL_TYPE"; - ### Start NATS - print_green 'Start NATS' + # Start NATS + # Misc functions + print_green 'Start NATS'; sudo systemctl enable nats.service sudo systemctl start nats.service - ### Install frontend - print_green 'Installing the frontend' + # Install frontend + # Misc functions + print_green 'Installing the frontend'; + # InstallFunctions installFrontEnd; # reset perms @@ -569,11 +722,12 @@ restoreTRMM() sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.config sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.cache - ### Update services info + # Update services info sudo systemctl daemon-reload - ### Enable RMM, Daphne, Celery, Nats-api, and Nginx services - print_green 'Enabling Services' + # Enable RMM, Daphne, Celery, Nats-api, and Nginx services + # Misc functions + print_green 'Enabling Services'; for i in celery.service celerybeat.service rmm.service daphne.service nats-api.service nginx do @@ -583,13 +737,15 @@ restoreTRMM() done sleep 5 - ### Start MeshCentral - print_green 'Starting meshcentral' + # Start MeshCentral + # Misc functions + print_green 'Starting meshcentral'; sudo systemctl enable meshcentral sudo systemctl start meshcentral - ### Done!!!! - print_green 'Restore complete!' + # Done!!!! + # Misc functions + print_green 'Restore complete!'; return } @@ -597,29 +753,33 @@ restoreTRMM() # Troubleshooting utility troubleShoot() { - ### Resolve Locally used DNS server + # Resolve Locally used DNS server locdns=$(resolvectl | grep 'Current DNS Server:' | cut -d: -f2 | awk '{ print $1}') - ### Prompt for host, domain, and email info - getHostAndDomainInfo; + # Get existing domain info + # Misc functions + getExistingDomainInfo; - ### Verify domains are live + # Verify domains are live + # Troubleshooting functions pingDomain "$rmmdomain"; pingDomain "$frontenddomain"; pingDomain "$meshdomain"; - ### Verify IPs + # Verify IPs echo -e "${GREEN} Checking IPs${NC}" | tee -a checklog.log printf >&2 "\n\n" + # Troubleshooting functions checkIPisLive "$rmmdomain"; remapiip="${reminputip}" checkIPisLive "$frontenddomain"; checkIPisLive "$meshdomain"; - ### Get services status + # Get services status readServicesStatus; - ### Verify services active + # Verify services active + # Troubleshooting functions - ALL checkIfServiceActive "$rmmstatus" "RMM Service"; checkIfServiceActive "$daphnestatus" "Daphne Service"; checkIfServiceActive "$celerystatus" "Celery Service"; @@ -632,23 +792,26 @@ troubleShoot() checkIfServiceActive "$postgresqlstatus" "Postgresql Service"; checkIfServiceActive "$redisserverstatus" "Redis-Server Service"; - ### Get WAN IP + # Get WAN IP wanip=$(dig @resolver4.opendns.com myip.opendns.com +short) echo -e "${GREEN} WAN IP is $wanip.${NC}" | tee -a checklog.log printf >&2 "\n\n" - ### Check if ports are open + # Check if ports are open + # Troubleshooting functions isPortOpen "4222" "NATS"; isPortOpen "80" "HTTP"; isPortOpen "443" "HTTPS"; - ### Checking Proxy + # Checking Proxy + # Troubleshooting functions checkProxy; - ### Check for valid cert + # Check for valid cert + # Troubleshooting functions checkIfCertIsValid; - ### Generate log summary + # Generate log summary echo -e "${GREEN} Getting summary output of logs.${NC}" | tee -a checklog.log printf >&2 "\n\n" @@ -656,8 +819,8 @@ troubleShoot() printf >&2 "\n\n" tail /rmm/api/tacticalrmm/tacticalrmm/private/log/error.log | tee -a checklog.log printf >&2 "\n\n" - - print_yellow "You will have a log file called checklog.log in the directory you ran this script from." + # Misc functions + print_yellow "You will have a log file called checklog.log in the directory you ran this script from."; return } \ No newline at end of file diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 7b2664b9c8..b9fbb28636 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -33,10 +33,12 @@ wutOSThis() verifySupportedOS() { if ([ "$osname" == "ubuntu" ] && ([ "$fullrelno" == "20.04" ] || [ "$fullrelno" == "22.04" ])) || ([ "$osname" == "debian" ] && [ $relno -ge 10 ]); then - print_green "$fullrel" + # MiscFunctions + print_green "$fullrel"; else if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nSupported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." + # MiscFunctions + print_red "Error.\n\nSupported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting."; else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 fi @@ -50,7 +52,8 @@ checkLocale() { if [[ "$LANG" != *".UTF-8" ]]; then if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nSystem locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting." + # MiscFunctions + print_red "Error.\n\nSystem locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting."; else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "System locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting." 0 0 fi diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index d0e106754e..bd2933a80e 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -84,6 +84,7 @@ checkProxy() { echo -e "${YELLOW} Checking For Proxy.${NC}" | tee -a checklog.log printf >&2 "\n" + # Misc functions print_yellow "......this might take a while!!" # Detect Proxy via cert diff --git a/script-cfg/UpdateRestoreFunctions.cfg b/script-cfg/UpdateRestoreFunctions.cfg index b50e700ff5..cf4a22c1c1 100644 --- a/script-cfg/UpdateRestoreFunctions.cfg +++ b/script-cfg/UpdateRestoreFunctions.cfg @@ -38,7 +38,8 @@ checkIfUpdate() CURRENT_TRMM_VER=$(grep "^TRMM_VERSION" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') if [ "${CURRENT_TRMM_VER}" == "${LATEST_TRMM_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then - print_green "Already on latest version. Current version: ${CURRENT_TRMM_VER} Latest version: ${LATEST_TRMM_VER}\n" + # MiscFunctions + print_green "Already on latest version. Current version: ${CURRENT_TRMM_VER} Latest version: ${LATEST_TRMM_VER}\n"; rm -f $TMP_SETTINGS exit 0 fi @@ -60,6 +61,7 @@ checkNatsLimitNoFile() if ! [ $CHECK_NATS_LIMITNOFILE ]; then sudo rm -f /etc/systemd/system/nats.service + # Config and Service functions createNatsService; sudo systemctl daemon-reload fi @@ -68,7 +70,8 @@ checkNatsLimitNoFile() # Disable Redis append only turnOffRedisAppendOnly() { - print_green "Turning off redis aof\n" + # MiscFunctions + print_green "Turning off redis aof\n"; sudo redis-cli config set appendonly no sudo redis-cli config rewrite sudo rm -f /var/lib/redis/appendonly.aof @@ -79,7 +82,8 @@ updateMeshCentral() { 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 - print_green "Updating meshcentral from ${CURRENT_MESH_VER} to ${LATEST_MESH_VER}\n" + # MiscFunctions + print_green "Updating meshcentral from ${CURRENT_MESH_VER} to ${LATEST_MESH_VER}\n"; sudo systemctl stop meshcentral sudo chown "${USER}:${USER}" -R /meshcentral cd /meshcentral @@ -117,7 +121,8 @@ getBackupFileLocation() # Extract backup extractBackup() { - print_green 'Unpacking backup' + # MiscFunctions + print_green 'Unpacking backup'; tmp_dir=$(mktemp -d -t tacticalrmm-XXXXXXXXXXXXXXXXXXXXX) tar -xf ${1} -C $tmp_dir From 5a8bf09101a275875bd0bcb3f850532ad6576cd3 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 24 Jun 2022 13:15:50 -0500 Subject: [PATCH 055/203] minor fixes to comments --- script-cfg/MiscFunctions.cfg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index cb6d2fac6c..ecda94673c 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -89,7 +89,7 @@ checkScriptVer() if [ "$1" -ne "${NEW_VER}" ]; then wget -q "$2" -O "$3" if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nOld $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" + print_red "Error.\n\nOld $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3"; else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 fi @@ -113,7 +113,7 @@ checkCfgVer() if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nOld $2 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" + print_red "Error.\n\nOld $2 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3"; else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 fi @@ -131,7 +131,7 @@ checkRoot() # if user is root, exit if [ $EUID -eq 0 ]; then if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nDo NOT run this script as root.\n\nExiting." + print_red "Error.\n\nDo NOT run this script as root.\n\nExiting."; else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Do NOT run this script as root. Exiting." 0 0 fi @@ -165,7 +165,7 @@ checkTacticalUser() tacticaluser="$(id -u tactical > /dev/null 2>&1; echo $?)" case $tacticaluser in 0 ) if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nThis script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting."; + print_red "Error.\n\nThis script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 fi From 0aa12c0a6fffcac6958be362d8893138b5065739 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 24 Jun 2022 15:01:20 -0500 Subject: [PATCH 056/203] Finished (?) catches for wrong command line args --- installer-util.sh | 74 +++++++++++++++++++++++++----------- script-cfg/MiscFunctions.cfg | 10 ++--- script-cfg/UserInput.cfg | 34 +++++++++++++---- 3 files changed, 84 insertions(+), 34 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 0f95f6448a..f2a7ee7d7e 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -79,23 +79,23 @@ done # Get commandline input function getCommandLineArgs() { - while getopts "auto:api:branch:ca:cert:domain:email:help:key:mesh:pass:repo:rmm:username:" option; do + while getopts "auto:api:branch:ca:cert:domain:email:h:key:mesh:pass:repo:rmm:username:" option; do case $option in auto ) autoinstall="1" - INSTALL_TYPE="${OPTARG}";; - api ) rmmhost="${OPTARG}";; - branch ) BRANCH="${OPTARG}";; + INSTALL_TYPE="$(translateToLowerCase ${OPTARG})";; + api ) rmmhost="$(translateToLowerCase ${OPTARG})";; + branch ) BRANCH="$(translateToLowerCase ${OPTARG})";; ca ) sslcacert="${OPTARG}";; cert ) sslcert="${OPTARG}";; - domain ) rootdomain="${OPTARG}";; - email ) letsemail="${OPTARG}";; - help ) helpText + domain ) rootdomain="$(translateToLowerCase ${OPTARG})";; + email ) letsemail="$(translateToLowerCase ${OPTARG})";; + h ) helpText exit;; key ) sslkey="${OPTARG}";; - mesh ) meshhost="${OPTARG}";; + mesh ) meshhost="$(translateToLowerCase ${OPTARG})";; pass ) trmmpass="${OPTARG}";; - repo ) REPO_OWNER="${OPTARG}";; - rmm ) frontendhost="${OPTARG}";; + repo ) REPO_OWNER="$(translateToLowerCase ${OPTARG})";; + rmm ) frontendhost="$(translateToLowerCase ${OPTARG})";; username ) trmmuser="${OPTARG}";; \?) echo -e "Error: Invalid option" clear -x @@ -104,25 +104,55 @@ getCommandLineArgs() done if [ "$autoinstall" == "1" ]; then - if [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]; then + # Check all required input is available + if [ -z "$INSTALL_TYPE" ] || [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]; then echo -e "Error: To perform an automated installation, you must provide all required information." echo -e "\n" - echo -e "api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required." + echo -e "install type, api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required." echo -e "\n" echo -e "Run .$THIS_SCRIPT -h for further details." clear -x exit 1 - elif [ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]; then - if [ "$REPO_OWNER" == "amidaware" ] || [ "$BRANCH" == "master" ]; then - echo -e "Error: You've selected a developer installation type, but not changed the repo, branch, or both." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for details on how to select them." - clear -x - exit 1 - fi - else - return fi + + # Check that install type is valid + if [ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ]; then + echo -e "Error: You've selected an invalid installation type." + echo -e "\n" + echo -e "Run .$THIS_SCRIPT -h for details on the available options." + clear -x + exit 1 + fi + + # Check that repo and branch match install type + if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]) && [ "$BRANCH" == "master" ]; then + echo -e "Error: You've selected a developer installation type, but not changed the repo, branch, or both." + echo -e "\n" + echo -e "Run .$THIS_SCRIPT -h for details on how to select them." + clear -x + exit 1 + fi + + # Check root domain is valid format + if [[ $rootdomain != *[.]* ]]; then + echo -e "Error: You've entered an invalid root domain." + echo -e "\n" + echo -e "Run .$THIS_SCRIPT -h for details on the correct format." + clear -x + exit 1 + fi + + # Check subdomains are valid format + # User Input + subdomainCheck "$rmmhost" "api"; + subdomainCheck "$meshhost" "mesh"; + subdomainCheck "$frontendhost" "rmm"; + + # Check that cert file exists + # User Input + checkCertExists "$sslcacert" "CA Chain"; + checkCertExists "$sslcert" "Fullchain Cert"; + checkCertExists "$sslkey" "Private Key"; fi } diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index ecda94673c..92ec9e50e4 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -57,19 +57,19 @@ print_yellow() # Command-line help function helpText() { - echo -e 'Syntax: ./installer-util.sh [ -auto|api|branch|ca|cert|email|help|key|mesh|repo|rmm]' + echo -e 'Syntax: ./installer-util.sh [ -auto|api|branch|ca|cert|domain|email|help|key|mesh|pass|repo|rmm|username]' echo -e "" echo -e "Options:" echo -e "" echo -e "auto Select type of automated installation. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC}, or${YELLOW} devinstall${NC}" echo -e "api Provide the api hostname/subdomain, eg ${YELLOW}api${NC}.example.com" echo -e "branch If performing a dev install, this will select the branch. eg, https://github.com/amidaware/tacticalrmm/${YELLOW}branch${NC}/.git" - echo -e "ca Path to SSL CA Chain certificate for import. Must be in .pem format" - echo -e "cert Path to SSL certificate for import. Must be in .pem format" + echo -e "ca Full path to SSL CA Chain certificate for import. Must be in .pem format. Include the filename." + echo -e "cert Full path to SSL certificate for import. Must be in .pem format. Include the filename." echo -e "domain Provide the root domain, eg rmm.${YELLOW}example.com${NC}" echo -e "email Provide a valid email address for LetsEncrypt cert generation and primary T-RMM user" - echo -e "help Show this help text" - echo -e "key Path to SSL private key for import. Must be in .pem format" + echo -e "h Show this help text" + echo -e "key Full path to SSL private key for import. Must be in .pem format. Include the filename." echo -e "mesh Provide the mesh hostname/subdomain, eg ${YELLOW}mesh${NC}.example.com" echo -e "pass Provide the password for the initial T-RMM user" echo -e "repo If performing a dev install, this will select the repo owner. eg, https://github.com/${YELLOW}repo-owner${NC}/tacticalrmm/master/.git" diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index 3a6f569921..ec16bafaba 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -92,16 +92,36 @@ generateUsersAndPass() fi } +# Check subdomain provided is valid format +subdomainCheck() +{ + if [[ $1 = *[.]*[.]* ]] || [[ $1 = *[.]* ]]; then + echo -e "Error: The $2 hostname/subdomain you provided is in the incorrect format." + echo -e "\n" + echo -e "Do not include the root domain." + echo -e "\n" + echo -e "Run .$THIS_SCRIPT -h for further details." + clear -x + exit 1 + fi +} + +# Check cert file exists +checkCertExists() +{ + if [ ! -f "$1" ]; then + echo -e "Error: The $2 path and/or filename you provided is invalid." + echo -e "\n" + echo -e "Run .$THIS_SCRIPT -h for further details." + clear -x + exit 1 + fi +} + # Get host and domain info getHostAndDomainInfo() { - if [ "$autoinstall" == "1" ]; then - rootdomain="$(translateToLowerCase $rootdomain)" - rmmhost="$(translateToLowerCase $rmmhost)" - frontendhost="$(translateToLowerCase $frontendhost)" - meshhost="$(translateToLowerCase $meshhost)" - letsemail="$(translateToLowerCase $letsemail)" - else + if [ "$autoinstall" != "1" ]; then hostsconfirm="n" until [ $hostsconfirm == "y" ]; do From cd6ea6ff1012284efa87cd57e57736e0dfb828ec Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 24 Jun 2022 15:04:45 -0500 Subject: [PATCH 057/203] Added missing email address commandline check --- installer-util.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/installer-util.sh b/installer-util.sh index f2a7ee7d7e..7b62baaa17 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -142,6 +142,15 @@ getCommandLineArgs() exit 1 fi + # Check that email address format is valid + if [[ $letsemail != *[@]*[.]* ]]; then + echo -e "Error: You've entered an invalid email address." + echo -e "\n" + echo -e "Run .$THIS_SCRIPT -h for details on the correct format." + clear -x + exit 1 + fi + # Check subdomains are valid format # User Input subdomainCheck "$rmmhost" "api"; From 6b74bd59141fcd77fc5d5d084fe0b51834b4412a Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 24 Jun 2022 15:18:19 -0500 Subject: [PATCH 058/203] Added check to automated cert function --- script-cfg/CertificateFunctions.cfg | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index c4ea416eb9..cdb3aff17f 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -67,7 +67,9 @@ installCertbot() 1 ) importCerts;; esac elif [ "$autoinstall" == "1" ]; then - sudo mkdir -p /etc/letsencrypt/live/${rootdomain} + if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then + sudo mkdir -p /etc/letsencrypt/live/${rootdomain} + fi sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem From 53c8acd74cf4b15c12c6d1a630f8ca0fd542d56a Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 24 Jun 2022 23:40:22 -0500 Subject: [PATCH 059/203] reversions from print_x functions and add ts check --- script-cfg/CertificateFunctions.cfg | 6 ++-- script-cfg/ConfigAndServiceFunctions.cfg | 7 ++-- script-cfg/InstallFunctions.cfg | 20 ++++------- script-cfg/MiscFunctions.cfg | 36 +++++++++++++++---- script-cfg/NetworkFunctions.cfg | 4 +-- script-cfg/ParentFunctions.cfg | 45 +++++++++++++----------- script-cfg/SystemInfoFunctions.cfg | 17 +++++---- script-cfg/TroubleshootingFunctions.cfg | 35 +++++++++--------- script-cfg/UserInput.cfg | 44 ++++++++++++----------- 9 files changed, 118 insertions(+), 96 deletions(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index cdb3aff17f..81289aae9b 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -34,8 +34,7 @@ importCerts() # Generate certs generateCerts() { - # MiscFunctions - print_green 'Getting wildcard cert'; + echo -e "${GREEN} Getting wildcard cert${NC}" # Get initial DNS text entry sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email @@ -56,8 +55,7 @@ installCertbot() fi if [ "$1" == "devinstall" ]; then - # MiscFunctions - print_green "Certificates should be in place"; + echo -e "${GREEN} Certificates should be in place${NC}\n" elif [ "$autoinstall" != "1" ]; then dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have wildcard certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 case $? in diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index e74b727391..f8ceb5dbe3 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -115,7 +115,6 @@ configureBackend() clear -x python manage.py createsuperuser --username ${djangousername} --email ${letsemail} python manage.py create_installer_user - RANDBASE=$(python manage.py generate_totp) # Misc functions cls; @@ -250,8 +249,7 @@ enableMeshService() # We will know it's ready once the last line of the systemd service stdout is 'MeshCentral HTTP server running on port.....' while ! [[ $CHECK_MESH_READY ]]; do CHECK_MESH_READY=$(sudo journalctl -u meshcentral.service -b --no-pager | grep "MeshCentral HTTP server running on port") - # Misc functions - print_yellow "Mesh Central not ready yet..."; + echo -e "${YELLOW} Mesh Central not ready yet...${NC}" sleep 3 done } @@ -281,8 +279,7 @@ configMeshUserGroup() while ! [[ $CHECK_MESH_READY2 ]]; do CHECK_MESH_READY2=$(sudo journalctl -u meshcentral.service -b --no-pager | grep "MeshCentral HTTP server running on port") - # Misc functions - print_yellow "Mesh Central not ready yet..."; + echo -e "${YELLOW} Mesh Central not ready yet...${NC}" sleep 3 done diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 1f0753f8fc..784b2747ff 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -58,8 +58,7 @@ installNodeJS() if [ "$1" == "update" ]; then HAS_NODE16=$(node --version | grep v16) if ! [ $HAS_NODE16 ]; then - # Misc functions - print_green "Updating NodeJS to v16"; + echo -e "${GREEN} Updating NodeJS to v16${NC}\n" rm -rf /rmm/web/node_modules sudo systemctl stop meshcentral sudo apt remove -y nodejs @@ -90,14 +89,12 @@ installPython() if [ "$1" == "update" ]; then HAS_PY310=$(python3.10 --version | grep ${PYTHON_VER}) if ! [ $HAS_PY310 ]; then - # Misc functions - print_green "Updating to ${PYTHON_VER}"; + echo -e "${GREEN} Updating to ${PYTHON_VER}${NC}\n" fi fi if [ "$1" == "devinstall" ]; then - # Misc functions - print_green "Python already installed"; + echo -e "${GREEN} Python already installed${NC}\n" else numprocs=$(nproc) cd ~ @@ -135,8 +132,7 @@ installNats() if [ "$1" == "update" ]; then HAS_LATEST_NATS=$(/usr/local/bin/nats-server -version | grep "${NATS_SERVER_VER}") if ! [ $HAS_LATEST_NATS ]; then - # Misc functions - print_green "Updating nats to v${NATS_SERVER_VER}"; + echo -e "${GREEN} Updating nats to v${NATS_SERVER_VER}${NC}\n" fi fi if [ "$1" == "install" ] || [ "$1" == "devinstall" ] || [ "$1" == "restore" ]; then @@ -193,16 +189,14 @@ installNginx() # Check Nginx config if ! sudo nginx -t > /dev/null 2>&1; then sudo nginx -t - # Misc functions - print_red "You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script."; - print_red "Aborting..."; + echo -e "${RED} You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script.${NC}\n" + echo -e "${RED} Aborting...${NC}\n" exit 1 fi elif [ "$1" == "updatepart2" ]; then CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" /etc/nginx/nginx.conf) if ! [ $CHECK_NGINX_WORKER_CONN ]; then - # Misc functions - print_green "Changing nginx worker connections to 2048"; + echo -e "${GREEN} Changing nginx worker connections to 2048${NC}\n" sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf fi sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 92ec9e50e4..2b579e06e7 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -89,7 +89,11 @@ checkScriptVer() if [ "$1" -ne "${NEW_VER}" ]; then wget -q "$2" -O "$3" if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nOld $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3"; + echo -e "${RED} Error:${NC}\n" + echo -e "${RED} Old $3 detected.${NC}\n" + echo -e "${RED} The latest version has been downloaded.${NC}\n" + echo -e "${RED} Please re-run .$3${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 fi @@ -113,7 +117,11 @@ checkCfgVer() if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nOld $2 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3"; + echo -e "${RED} Error:${NC}\n" + echo -e "${RED} Old $2 detected.${NC}\n" + echo -e "${RED} The latest version has been downloaded.${NC}\n" + echo -e "${RED} Please re-run .$3${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 fi @@ -131,7 +139,9 @@ checkRoot() # if user is root, exit if [ $EUID -eq 0 ]; then if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nDo NOT run this script as root.\n\nExiting."; + echo -e "${RED} Error:${NC}\n" + echo -e "${RED} Do NOT run this script as root.${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Do NOT run this script as root. Exiting." 0 0 fi @@ -152,7 +162,10 @@ checkTacticalUser() tacticaluser=$(stat -c '%U' /rmm) if [ "$tacticaluser" != "${USER}" ]; then if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nThis script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting."; + echo -e "${RED} Error:${NC}\n" + echo -e "${RED} This script must be run as the Tactical user.${NC}\n" + echo -e "${RED} Please switch users, and run it again.${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 fi @@ -165,7 +178,10 @@ checkTacticalUser() tacticaluser="$(id -u tactical > /dev/null 2>&1; echo $?)" case $tacticaluser in 0 ) if [ "$autoinstall" == "1" ]; then - print_red "Error.\n\nThis script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." + echo -e "${RED} Error:${NC}\n" + echo -e "${RED} This script must be run as the Tactical user.${NC}\n" + echo -e "${RED} Please switch users, and run it again.${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 fi @@ -177,7 +193,11 @@ checkTacticalUser() tacpass="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)" echo "tactical:$tacpass"| sudo chpasswd if [ "$autoinstall" == "1" ]; then - print_red "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting."; + echo -e "${RED} The Tactical user has been created.${NC}\n" + echo -e "${RED} Username: tactical${NC}" + echo -e "${RED} Password: $tacpass${NC}\n" + echo -e "${RED} Please switch users, re-download the script, and run it again.${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Created" --msgbox "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting." 0 0 fi @@ -194,7 +214,9 @@ checkTacticalUser() 1 ) print_green 'Adding Tactical user to sudo group.' sudo usermod -a -G sudo tactical if [ "$autoinstall" == "1" ]; then - print_red "The Tactical user has been added to the sudo group.\nPlease log out of the tactical user, log back in, and try again.\n\nExiting." + echo -e "${RED} The Tactical user has been added to the sudo group.${NC}\n" + echo -e "${RED} Please log out of the tactical user, log back in, and try again.${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Sudo Privileges Added" --msgbox "The Tactical user has been added to the sudo group.\nPlease log out of the tactical user, log back in, and try again.\n\nExiting." 0 0 fi diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index 618323bde8..fc99b3a012 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -46,13 +46,13 @@ configHosts() # this also allows the install script to properly finish even if DNS has not fully propagated CHECK_LOCALHOST=$(grep "127.0.0.1 localhost" /etc/hosts) if ! [ $CHECK_LOCALHOST ]; then - print_green 'Adding localhost to hosts file'; # Misc functions + echo -e "${GREEN}Adding localhost to hosts file${NC}" sudo sed -i '1i 127.0.0.1 localhost' /etc/hosts fi CHECK_HOSTS=$(grep "127.0.1.1 $rmmdomain $frontenddomain $meshdomain" /etc/hosts) if [[ $CHECK_HOSTS ]]; then - print_green 'Correcting subdomains entries'; # Misc functions + echo -e "${GREEN}Correcting subdomains entries${NC}" sudo sed -i "/127.0.1.1 $rmmdomain $frontenddomain $meshdomain/d" /etc/hosts setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 9ff453145a..7f68364324 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -291,17 +291,16 @@ mainInstall() # Yay, we're done! # Misc functions print_yellow "Installation complete!"; - printf >&2 "${YELLOW}Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n\n" - printf >&2 "${YELLOW}Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n\n" - printf >&2 "${YELLOW}MeshCentral username: ${GREEN}${meshusername}${NC}\n" - printf >&2 "${YELLOW}MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n\n" + echo -e "${YELLOW}Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n" + echo -e "${YELLOW}Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n" + echo -e "${YELLOW}MeshCentral username: ${GREEN}${meshusername}${NC}" + echo -e "${YELLOW}MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n" if [ "$BEHIND_NAT" = true ]; then - # Misc functions - print_yellow "Read below if your router does NOT support Hairpin NAT:"; - print_green "If you will be accessing the web interface of the RMM from the same LAN as this server,\nyou'll need to make sure your 3 subdomains resolve to ${IPV4}"; - print_green "This also applies to any agents that will be on the same local network as the rmm."; - print_green "You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp."; + echo -e "${YELLOW}Read below if your router does NOT support Hairpin NAT:${NC}\n" + echo -e "${GREEN}If you will be accessing the web interface of the RMM from the same LAN as this server,\nyou'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" + echo -e "${GREEN}This also applies to any agents that will be on the same local network as the rmm.${NC}\n" + echo -e "${GREEN}You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp.${NC}\n" fi # Misc functions print_yellow "Please refer to the github README for next steps."; @@ -339,8 +338,7 @@ updateTRMM() # Stop services for i in nginx nats-api nats rmm daphne celery celerybeat do - # Misc functions - print_green "Stopping ${i} service..."; + echo -e "${GREEN}Stopping ${i} service...${NC}"; sudo systemctl stop "${i}" done @@ -433,8 +431,7 @@ updateTRMM() # Start services for i in nats nats-api rmm daphne celery celerybeat nginx do - # Misc functions - print_green "Starting ${i} service"; + echo -e "${GREEN}Starting ${i} service${NC}"; sudo systemctl start "${i}" done sleep 1 @@ -757,8 +754,13 @@ troubleShoot() locdns=$(resolvectl | grep 'Current DNS Server:' | cut -d: -f2 | awk '{ print $1}') # Get existing domain info - # Misc functions - getExistingDomainInfo; + if [ -f /etc/nginx/sites-available/rmm.conf ] && [ -f /etc/nginx/sites-available/rmm.conf ] && [ -f /etc/nginx/sites-available/rmm.conf ]; then + # Misc functions + getExistingDomainInfo; + else + # User Input + getHostAndDomainInfo "TS"; + fi # Verify domains are live # Troubleshooting functions @@ -768,7 +770,7 @@ troubleShoot() # Verify IPs echo -e "${GREEN} Checking IPs${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "\n" # Troubleshooting functions checkIPisLive "$rmmdomain"; remapiip="${reminputip}" @@ -776,10 +778,11 @@ troubleShoot() checkIPisLive "$meshdomain"; # Get services status + # Troubleshooting functions readServicesStatus; # Verify services active - # Troubleshooting functions - ALL + # Troubleshooting functions checkIfServiceActive "$rmmstatus" "RMM Service"; checkIfServiceActive "$daphnestatus" "Daphne Service"; checkIfServiceActive "$celerystatus" "Celery Service"; @@ -795,7 +798,7 @@ troubleShoot() # Get WAN IP wanip=$(dig @resolver4.opendns.com myip.opendns.com +short) echo -e "${GREEN} WAN IP is $wanip.${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "\n" # Check if ports are open # Troubleshooting functions @@ -813,12 +816,12 @@ troubleShoot() # Generate log summary echo -e "${GREEN} Getting summary output of logs.${NC}" | tee -a checklog.log - printf >&2 "\n\n" + echo -e "\n" tail /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | tee -a checklog.log - printf >&2 "\n\n" + echo -e "\n" tail /rmm/api/tacticalrmm/tacticalrmm/private/log/error.log | tee -a checklog.log - printf >&2 "\n\n" + echo -e "\n" # Misc functions print_yellow "You will have a log file called checklog.log in the directory you ran this script from."; diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index b9fbb28636..2248ba1080 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -33,12 +33,13 @@ wutOSThis() verifySupportedOS() { if ([ "$osname" == "ubuntu" ] && ([ "$fullrelno" == "20.04" ] || [ "$fullrelno" == "22.04" ])) || ([ "$osname" == "debian" ] && [ $relno -ge 10 ]); then - # MiscFunctions - print_green "$fullrel"; + echo -e "${GREEN} $fullrel${NC}" else if [ "$autoinstall" == "1" ]; then - # MiscFunctions - print_red "Error.\n\nSupported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting."; + echo -e "${RED} Error:${NC}\n" + echo -e "${RED} Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11${NC}" + echo -e "${RED} Your system, $fullrel, does not appear to be supported.${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 fi @@ -52,8 +53,12 @@ checkLocale() { if [[ "$LANG" != *".UTF-8" ]]; then if [ "$autoinstall" == "1" ]; then - # MiscFunctions - print_red "Error.\n\nSystem locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting."; + echo -e "${RED} Error:${NC}\n" + echo -e "${RED} System locale must be .UTF-8, not ${LANG}.${NC}\n" + echo -e "${RED} Run the following command and change the default locale to your language of choice:${NC}\n" + echo -e "${RED} sudo dpkg-reconfigure locales${NC}\n" + echo -e "${RED} You will need to log out and back in for changes to take effect, then re-run this script.${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "System locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting." 0 0 fi diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index bd2933a80e..770d88a695 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -14,7 +14,7 @@ pingDomain() { if ( ping -c 1 $1 &> /dev/null ); then echo -e "${GREEN} Verified $1${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$1 doesnt exist please create it or check for a typo.\n\nYou will have a log file called checklog.log in the directory you ran this script from.\n\nExiting." 0 0 clear -x @@ -30,12 +30,12 @@ checkIPisLive() if [ "$locinputip" == "$reminputip" ]; then echo -e "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" else echo -e "${RED} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log - printf >&2 "\n" | tee -a checklog.log + echo -e "\n" | tee -a checklog.log echo -e "${RED} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" fi } @@ -60,10 +60,10 @@ checkIfServiceActive() { if [ $1 = active ]; then echo -e "${GREEN} Success $2 is Running.${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" else echo -e "${RED} $2 is not running. \(Tactical will not work without this\)${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" fi } @@ -72,10 +72,10 @@ isPortOpen() { if ( nc -zv $wanip $1 2>&1 >/dev/null ); then echo -e "${GREEN} $2 Port is open.${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" else echo -e "${RED} $2 port is closed. \(you may want this if running locally only\)${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" fi } @@ -83,9 +83,8 @@ isPortOpen() checkProxy() { echo -e "${YELLOW} Checking For Proxy.${NC}" | tee -a checklog.log - printf >&2 "\n" - # Misc functions - print_yellow "......this might take a while!!" + echo -e "\n" + echo -e "${YELLOW} ......this might take a while!!${NC}" # Detect Proxy via cert proxyext="$(openssl s_client -showcerts -servername $remapiip -connect $remapiip:443 2>/dev/null | openssl x509 -inform pem -noout -text)" @@ -93,19 +92,19 @@ checkProxy() if [[ "$proxyext" == "$proxyint" ]]; then echo -e "${GREEN} No Proxy detected using Certificate.${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" else echo -e "${YELLOW} Proxy detected using Certificate.${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" fi # Detect Proxy via IP if [ "$wanip" != "$remrmmip" ]; then echo -e "${YELLOW} Proxy detected using IP.${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" else echo -e "${GREEN} No Proxy detected using IP.${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" fi } @@ -113,16 +112,16 @@ checkProxy() checkIfCertIsValid() { echo -e "${YELLOW} Checking if SSL Certificate is up to date.${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" # SSL Certificate check cert="$(openssl verify -CAfile /etc/letsencrypt/live/$rootdomain/chain.pem /etc/letsencrypt/live/$rootdomain/cert.pem)" if [[ "$cert" == *"OK"* ]]; then echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" else echo -e "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a checklog.log - printf >&2 "\n" + echo -e "\n" fi } \ No newline at end of file diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index ec16bafaba..58388b5d53 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -149,29 +149,33 @@ getHostAndDomainInfo() meshhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter MeshCentral Hostname" --inputbox "Enter the hostname for MeshCentral (e.g. mesh):" 10 90 3>&1 1>&2 2>&3) meshhost="$(translateToLowerCase $meshhost)" - # Get Admin email - while [[ $letsemail != *[@]*[.]* ]]; do - letsemail=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Admin E-Mail Address" --inputbox "Enter a valid e-mail address for Django, MeshCentral, and LetsEncrypt:" 10 90 3>&1 1>&2 2>&3) - letsemail="$(translateToLowerCase $letsemail)" - if [[ $letsemail != *[@]*[.]* ]]; then - derpDerp; - fi - done + if [ "$1" != "TS" ]; then + # Get Admin email + while [[ $letsemail != *[@]*[.]* ]]; do + letsemail=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Admin E-Mail Address" --inputbox "Enter a valid e-mail address for Django, MeshCentral, and LetsEncrypt:" 10 90 3>&1 1>&2 2>&3) + letsemail="$(translateToLowerCase $letsemail)" + if [[ $letsemail != *[@]*[.]* ]]; then + derpDerp; + fi + done - # Verify input - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Confirm Input" --yesno "Is this correct?\n\nroot domain: $rootdomain\nbackend: $rmmhost.$rootdomain\nfrontend: $frontendhost.$rootdomain\nmeshcentral: $meshhost.$rootdomain\ne-mail address: $letsemail" 0 0 - case $? in - 0 ) userconfirm="y";; + # Verify input + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Confirm Input" --yesno "Is this correct?\n\nroot domain: $rootdomain\nbackend: $rmmhost.$rootdomain\nfrontend: $frontendhost.$rootdomain\nmeshcentral: $meshhost.$rootdomain\ne-mail address: $letsemail" 0 0 + case $? in + 0 ) userconfirm="y";; - 1 ) userconfirm="n" - derpDerp;; - esac + 1 ) userconfirm="n" + derpDerp;; + esac + fi done clear -x fi - - # Combine host/domain entries for later use while keeping seperate entries as well - rmmdomain="$rmmhost.$rootdomain" - meshdomain="$meshhost.$rootdomain" - frontenddomain="$frontendhost.$rootdomain" + + if [ "$1" != "TS" ]; then + # Combine host/domain entries for later use while keeping seperate entries as well + rmmdomain="$rmmhost.$rootdomain" + meshdomain="$meshhost.$rootdomain" + frontenddomain="$frontendhost.$rootdomain" + fi } \ No newline at end of file From a7da9e49d75720469d33a25f84d4357025bf2461 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 25 Jun 2022 08:55:22 -0500 Subject: [PATCH 060/203] Updated to match new uwsgi config --- default-configs/uwsgi/app.ini | 12 +++++- installer-util.sh | 14 +++--- script-cfg/ConfigAndServiceFunctions.cfg | 54 ------------------------ script-cfg/ParentFunctions.cfg | 20 ++------- 4 files changed, 20 insertions(+), 80 deletions(-) diff --git a/default-configs/uwsgi/app.ini b/default-configs/uwsgi/app.ini index dd57eb10c8..eb691cbc52 100644 --- a/default-configs/uwsgi/app.ini +++ b/default-configs/uwsgi/app.ini @@ -3,8 +3,6 @@ chdir = /rmm/api/tacticalrmm module = tacticalrmm.wsgi home = /rmm/api/env master = true -processes = uwsgiprocs -threads = uwsgithreads enable-threads = true socket = /rmm/api/tacticalrmm/tacticalrmm.sock harakiri = 300 @@ -14,3 +12,13 @@ vacuum = true die-on-term = true max-requests = 500 disable-logging = true +cheaper-algo = busyness +cheaper = 4 +cheaper-initial = 4 +workers = 20 +cheaper-step = 2 +cheaper-overload = 3 +cheaper-busyness-min = 5 +cheaper-busyness-max = 10 +# stats = /tmp/stats.socket # uncomment when debugging +# cheaper-busyness-verbose = true # uncomment when debugging \ No newline at end of file diff --git a/installer-util.sh b/installer-util.sh index 7b62baaa17..83a3067d98 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -8,7 +8,7 @@ menuselection="" declare -a mainmenuoptions=('Installation' 'Update' 'Utilities' 'Exit') declare -a installmenuoptions=('Standard Install' 'Dev Test Prereqs' 'Dev Test Install' 'Return' 'Exit') declare -a updatemenuoptions=('Standard Update' 'Backup and Update' 'Force Update' 'Return' 'Exit') -declare -a utilitymenuoptions=('Backup' 'Restore' 'Renew Certs' 'Import Certs' 'Edit UWSGI config' 'Add Fail2ban - Use at your own risk' 'Run Server Troubleshooter' 'Return' 'Exit') +declare -a utilitymenuoptions=('Backup' 'Restore' 'Renew Certs' 'Import Certs' 'Add Fail2ban - Use at your own risk' 'Run Server Troubleshooter' 'Return' 'Exit') declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunctions.cfg' 'UserInput.cfg' 'NetworkFunctions.cfg' 'InstallFunctions.cfg' 'DatabaseFunctions.cfg' 'CertificateFunctions.cfg' 'ConfigAndServiceFunctions.cfg' 'UpdateRestoreFunctions.cfg' 'TroubleshootingFunctions.cfg' 'ParentFunctions.cfg') # Script Info variables @@ -266,8 +266,7 @@ utilityMenu() 5 "${utilitymenuoptions[4]}" \ 6 "${utilitymenuoptions[5]}" \ 7 "${utilitymenuoptions[6]}" \ - 8 "${utilitymenuoptions[7]}" \ - 9 "${utilitymenuoptions[8]}" 2>"${INPUT}" + 8 "${utilitymenuoptions[7]}" 2>"${INPUT}" menuselection=$(<"${INPUT}") @@ -277,11 +276,10 @@ utilityMenu() restoreTRMM;; 3 ) renewCerts;; 4 ) importCerts;; - 5 ) changeUWSGIProcs;; - 6 ) installFail2ban;; - 7 ) troubleShoot;; - 8 ) return;; - 9 ) [ -f $INPUT ] && rm $INPUT + 5 ) installFail2ban;; + 6 ) troubleShoot;; + 7 ) return;; + 8 ) [ -f $INPUT ] && rm $INPUT clear -x exit;; * ) derpDerp;; diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index f8ceb5dbe3..e0796204b7 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -125,27 +125,10 @@ configureBackend() fi } -# Set uwsgi procs -setUwsgiProcs() -{ - uwsgiprocs=4 - uwsgithreads=4 - if [[ "$numprocs" == "1" ]]; then - uwsgiprocs=2 - uwsgithreads=2 - else - uwsgiprocs=$numprocs - uwsgithreads=$numprocs - fi -} - # Create UWSGI config createUwsgiConf() { sudo cp /rmm/default-configs/uwsgi/app.ini /rmm/api/tacticalrmm/app.ini - - sudo sed -i "s/uwsgiprocs/$uwsgiprocs/" /rmm/api/tacticalrmm/app.ini - sudo sed -i "s/uwsgithreads/$uwsgithreads/" /rmm/api/tacticalrmm/app.ini } # Create UWSGI service @@ -301,41 +284,4 @@ enableNatsService() sleep 1 sudo systemctl enable nats-api.service sudo systemctl start nats-api.service -} - -# Change UWSGI settings -changeUWSGIProcs() -{ - local countconfirm="n" - - # Get UWSGI Processes value - until [ $countconfirm == "y" ]; do - uwsgiprocs=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Process Count" --inputbox "Enter the desired UWSGI Process Count, usually the same as CPU core count:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Process Count" --yesno "Is this correct?\n$uwsgiprocs" 0 0 - case $? in - 0 ) countconfirm="y";; - - 1 ) countconfirm="n" - derpDerp;; - esac - done - countconfirm="n" - - # Get UWSGI Threads value - until [ $countconfirm == "y" ]; do - uwsgithreads=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Thread Count" --inputbox "Enter the desired UWSGI Process Count, usually the same as CPU core count:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Change UWSGI Thread Count" --yesno "Is this correct?\n$uwsgithreads" 0 0 - case $? in - 0 ) countconfirm="y";; - - 1 ) countconfirm="n" - derpDerp;; - esac - done - countconfirm="n" - - # Stop rmm service, copy default file, edit processes/threads, start service - sudo systemctl stop rmm - createUwsgiConf; - sudo systemctl start rmm } \ No newline at end of file diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 7f68364324..bae31d344a 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -129,12 +129,6 @@ mainInstall() print_green 'Installing the backend'; # Config and Service functions configureBackend; - - # Determine Proc setting for UWSGI - # Misc functions - print_green 'Optimizing UWSGI for number of processors'; - # Config and Service functions - setUwsgiProcs; # Create UWSGI config # Misc functions @@ -338,16 +332,14 @@ updateTRMM() # Stop services for i in nginx nats-api nats rmm daphne celery celerybeat do - echo -e "${GREEN}Stopping ${i} service...${NC}"; + echo -e "${GREEN}Stopping ${i} service...${NC}" sudo systemctl stop "${i}" done # Rebuild uwsgi config rm -f /rmm/api/tacticalrmm/app.ini # Config and Service functions - setUwsgiProcs; - # Config and Service functions - createUwsgiConf; # Config and Service functions + createUwsgiConf; # Check if Python is up to date, if not, update # InstallFunctions @@ -431,7 +423,7 @@ updateTRMM() # Start services for i in nats nats-api rmm daphne celery celerybeat nginx do - echo -e "${GREEN}Starting ${i} service${NC}"; + echo -e "${GREEN}Starting ${i} service${NC}" sudo systemctl start "${i}" done sleep 1 @@ -659,11 +651,7 @@ restoreTRMM() # Restore UWSGI # Misc functions - print_green 'Optimizing UWSGI for number of processors'; - # Config and Service functions - setUwsgiProcs; - # Misc functions - print_green 'Creating UWSGI configuration'; + print_green 'Restoring UWSGI configuration'; # Config and Service functions createUwsgiConf; From 56a77d3217d50f65d929e63c81a5641851de36e8 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 25 Jun 2022 10:27:26 -0500 Subject: [PATCH 061/203] Reversions to not use print_x --- script-cfg/NetworkFunctions.cfg | 4 ++-- script-cfg/ParentFunctions.cfg | 20 ++++++++++---------- script-cfg/TroubleshootingFunctions.cfg | 4 ++-- script-cfg/UpdateRestoreFunctions.cfg | 6 ++---- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index fc99b3a012..60e9f3a9df 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -46,13 +46,13 @@ configHosts() # this also allows the install script to properly finish even if DNS has not fully propagated CHECK_LOCALHOST=$(grep "127.0.0.1 localhost" /etc/hosts) if ! [ $CHECK_LOCALHOST ]; then - echo -e "${GREEN}Adding localhost to hosts file${NC}" + echo -e "${GREEN} Adding localhost to hosts file${NC}\n" sudo sed -i '1i 127.0.0.1 localhost' /etc/hosts fi CHECK_HOSTS=$(grep "127.0.1.1 $rmmdomain $frontenddomain $meshdomain" /etc/hosts) if [[ $CHECK_HOSTS ]]; then - echo -e "${GREEN}Correcting subdomains entries${NC}" + echo -e "${GREEN} Correcting subdomains entries${NC}\n" sudo sed -i "/127.0.1.1 $rmmdomain $frontenddomain $meshdomain/d" /etc/hosts setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index bae31d344a..a203004efc 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -285,16 +285,16 @@ mainInstall() # Yay, we're done! # Misc functions print_yellow "Installation complete!"; - echo -e "${YELLOW}Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n" - echo -e "${YELLOW}Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n" - echo -e "${YELLOW}MeshCentral username: ${GREEN}${meshusername}${NC}" - echo -e "${YELLOW}MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n" + echo -e "${YELLOW} Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n" + echo -e "${YELLOW} Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n" + echo -e "${YELLOW} MeshCentral username: ${GREEN}${meshusername}${NC}" + echo -e "${YELLOW} MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n" if [ "$BEHIND_NAT" = true ]; then - echo -e "${YELLOW}Read below if your router does NOT support Hairpin NAT:${NC}\n" - echo -e "${GREEN}If you will be accessing the web interface of the RMM from the same LAN as this server,\nyou'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" - echo -e "${GREEN}This also applies to any agents that will be on the same local network as the rmm.${NC}\n" - echo -e "${GREEN}You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp.${NC}\n" + echo -e "${YELLOW} Read below if your router does NOT support Hairpin NAT:${NC}\n" + echo -e "${GREEN} If you will be accessing the web interface of the RMM from the same LAN as this server,\nyou'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" + echo -e "${GREEN} This also applies to any agents that will be on the same local network as the rmm.${NC}\n" + echo -e "${GREEN} You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp.${NC}\n" fi # Misc functions print_yellow "Please refer to the github README for next steps."; @@ -332,7 +332,7 @@ updateTRMM() # Stop services for i in nginx nats-api nats rmm daphne celery celerybeat do - echo -e "${GREEN}Stopping ${i} service...${NC}" + echo -e "${GREEN} Stopping ${i} service...${NC}" sudo systemctl stop "${i}" done @@ -423,7 +423,7 @@ updateTRMM() # Start services for i in nats nats-api rmm daphne celery celerybeat nginx do - echo -e "${GREEN}Starting ${i} service${NC}" + echo -e "${GREEN} Starting ${i} service${NC}" sudo systemctl start "${i}" done sleep 1 diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index 770d88a695..bd57f24fe7 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -32,9 +32,9 @@ checkIPisLive() echo -e "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log echo -e "\n" else - echo -e "${RED} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log + echo -e "${YELLOW} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log echo -e "\n" | tee -a checklog.log - echo -e "${RED} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}" | tee -a checklog.log + echo -e "${YELLOW} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}" | tee -a checklog.log echo -e "\n" fi } diff --git a/script-cfg/UpdateRestoreFunctions.cfg b/script-cfg/UpdateRestoreFunctions.cfg index cf4a22c1c1..7c9b25a6da 100644 --- a/script-cfg/UpdateRestoreFunctions.cfg +++ b/script-cfg/UpdateRestoreFunctions.cfg @@ -70,8 +70,7 @@ checkNatsLimitNoFile() # Disable Redis append only turnOffRedisAppendOnly() { - # MiscFunctions - print_green "Turning off redis aof\n"; + echo -e "${GREEN} Turning off redis aof${NC}\n" sudo redis-cli config set appendonly no sudo redis-cli config rewrite sudo rm -f /var/lib/redis/appendonly.aof @@ -82,8 +81,7 @@ updateMeshCentral() { 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 - # MiscFunctions - print_green "Updating meshcentral from ${CURRENT_MESH_VER} to ${LATEST_MESH_VER}\n"; + echo -e "${GREEN} Updating meshcentral from ${CURRENT_MESH_VER} to ${LATEST_MESH_VER}${NC}\n" sudo systemctl stop meshcentral sudo chown "${USER}:${USER}" -R /meshcentral cd /meshcentral From f07e18a95014c2a45a21c5451207fe8e8df3107a Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 12:22:35 -0500 Subject: [PATCH 062/203] fix variable name for dns info gathering --- script-cfg/UserInput.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index 58388b5d53..9deeb90ae0 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -162,9 +162,9 @@ getHostAndDomainInfo() # Verify input dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Confirm Input" --yesno "Is this correct?\n\nroot domain: $rootdomain\nbackend: $rmmhost.$rootdomain\nfrontend: $frontendhost.$rootdomain\nmeshcentral: $meshhost.$rootdomain\ne-mail address: $letsemail" 0 0 case $? in - 0 ) userconfirm="y";; + 0 ) hostsconfirm="y";; - 1 ) userconfirm="n" + 1 ) hostsconfirm="n" derpDerp;; esac fi From 2a9b8db2f402b1593bcd042470f924ae742f88ca Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 12:47:56 -0500 Subject: [PATCH 063/203] Corrections to localhost test and resolution --- script-cfg/InstallFunctions.cfg | 2 +- script-cfg/NetworkFunctions.cfg | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 784b2747ff..2dda685fbd 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -12,7 +12,7 @@ CFG_VERSION="8" # Install script prereqs installPreReqs() { - sudo apt update && sudo apt install -y curl wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev + sudo apt update && sudo apt install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev } # Install remaining prereqs diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index 60e9f3a9df..2150dadeeb 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -13,7 +13,7 @@ CFG_VERSION="8" setSiteHostname() { local textcomp="0" - local runtimes=0 + local runtimes="0" local line1="" local line2="" until [ "$textcomp" == "" ]; do @@ -44,10 +44,10 @@ configHosts() # 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 - CHECK_LOCALHOST=$(grep "127.0.0.1 localhost" /etc/hosts) - if ! [ $CHECK_LOCALHOST ]; then + CHECK_LOCALHOST=$(sed -n "/127.0.0.1/=" /etc/hosts) + if [ $CHECK_LOCALHOST != 1 ]; then echo -e "${GREEN} Adding localhost to hosts file${NC}\n" - sudo sed -i '1i 127.0.0.1 localhost' /etc/hosts + sudo sed -i "1i 127.0.0.1\tlocalhost" /etc/hosts fi CHECK_HOSTS=$(grep "127.0.1.1 $rmmdomain $frontenddomain $meshdomain" /etc/hosts) From 1d39c4a5534525bcd490678201c555a8a7838c7f Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 13:05:26 -0500 Subject: [PATCH 064/203] Correction to vim instructions --- script-cfg/CertificateFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 81289aae9b..97a936c1c2 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -26,7 +26,7 @@ renewCerts() # Import certs importCerts() { - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate and your private key, in that order.\n\nTo paste the contents, type i , then right click in the window.\n\nAfter pasting the contents, type esc , then shift-: , then x , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate and your private key, in that order.\n\nTo paste the contents, type i , then shift+insert.\n\nAfter pasting the contents, type esc , then shift-: , then x , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 sudo vim /etc/ssl/certs/fullchain.pem sudo vim /etc/ssl/private/privkey.pem } From 0d3dc77c0f87024da8cd25d55494e55ce48f2d11 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 13:14:16 -0500 Subject: [PATCH 065/203] Attempt to fix commandline args --- installer-util.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 83a3067d98..e9a0aa8cf0 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -77,9 +77,10 @@ done . $PWD/script-cfg/ParentFunctions.cfg # Get commandline input function -getCommandLineArgs() -{ - while getopts "auto:api:branch:ca:cert:domain:email:h:key:mesh:pass:repo:rmm:username:" option; do +#getCommandLineArgs() +##{ + while getopts auto:api:branch:ca:cert:domain:email:h:key:mesh:pass:repo:rmm:username: option + do case $option in auto ) autoinstall="1" INSTALL_TYPE="$(translateToLowerCase ${OPTARG})";; @@ -163,10 +164,10 @@ getCommandLineArgs() checkCertExists "$sslcert" "Fullchain Cert"; checkCertExists "$sslkey" "Private Key"; fi -} +#} # Get commandline input -getCommandLineArgs; +#getCommandLineArgs; # Set colors # MiscFunctions From f24e47e8688373c7db6478a6792dff6f40f2b085 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 13:26:21 -0500 Subject: [PATCH 066/203] Changed dh to 2048 --- script-cfg/CertificateFunctions.cfg | 2 +- script-cfg/MiscFunctions.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 97a936c1c2..e2cb26d6ea 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -79,7 +79,7 @@ installCertbot() # Generate DH if it doesn't exist if [ ! -f /etc/ssl/certs/dhparam.pem ]; then - sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096 + sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 else return fi diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 2b579e06e7..ad11ec89b1 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -57,7 +57,7 @@ print_yellow() # Command-line help function helpText() { - echo -e 'Syntax: ./installer-util.sh [ -auto|api|branch|ca|cert|domain|email|help|key|mesh|pass|repo|rmm|username]' + echo -e 'Syntax: ./installer-util.sh [-auto|api|branch|ca|cert|domain|email|help|key|mesh|pass|repo|rmm|username]' echo -e "" echo -e "Options:" echo -e "" From 00e02908870f7e637b6783b08464dafecb57594b Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 13:54:12 -0500 Subject: [PATCH 067/203] Attempt to correct various issues --- installer-util.sh | 1 - script-cfg/InstallFunctions.cfg | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index e9a0aa8cf0..f96aa446f5 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -19,7 +19,6 @@ CFG_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/installer-util.sh" REPO_URL="https://github.com/${REPO_OWNER}/tacticalrmm.git" SCRIPTS_REPO_URL="https://github.com/amidaware/community-scripts.git" -FRONTEND_URL="https://github.com/amidaware/tacticalrmm-web/releases/download/v${WEB_VERSION}/${webtar}" THIS_SCRIPT=$(readlink -f "$0") # Misc info variables diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 2dda685fbd..fc02c5ed1a 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -164,7 +164,7 @@ installFrontEnd() fi webtar="trmm-web-v${WEB_VERSION}.tar.gz" - wget -q "$2" -O /tmp/${webtar} + wget -q https://github.com/amidaware/tacticalrmm-web/releases/download/v${WEB_VERSION}/${webtar} -O /tmp/${webtar} if [ "$1" == "update" ]; then sudo rm -rf /var/www/rmm/dist From 2bef31642b3a473df228d736a2d3f3c4448efbcb Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 14:05:43 -0500 Subject: [PATCH 068/203] Corrected vim instructions, again --- script-cfg/CertificateFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index e2cb26d6ea..b350567fc0 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -26,7 +26,7 @@ renewCerts() # Import certs importCerts() { - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate and your private key, in that order.\n\nTo paste the contents, type i , then shift+insert.\n\nAfter pasting the contents, type esc , then shift-: , then x , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate and your private key, in that order.\n\nTo paste the contents, type i , then shift+insert.\n\nAfter pasting the contents, type esc , then shift-: , then wq , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 sudo vim /etc/ssl/certs/fullchain.pem sudo vim /etc/ssl/private/privkey.pem } From 5a14e0db16efca8b6360d1915bf6b201d47aaa06 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 14:59:04 -0500 Subject: [PATCH 069/203] Temp fix for backend build --- script-cfg/ConfigAndServiceFunctions.cfg | 97 +++++++++++++----------- 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index e0796204b7..d3201155d1 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -39,57 +39,64 @@ configureBackend() WHEEL_VER=$(grep "^WHEEL_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') userconfirm="n" - if [ "$1" == "update" ]; then - CHECK_ADMIN_ENABLED=$(grep ADMIN_ENABLED /rmm/api/tacticalrmm/tacticalrmm/local_settings.py) - if ! [ $CHECK_ADMIN_ENABLED ]; then - sudo sed -i '$ a ADMIN_ENABLED = False' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - 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 [ "${CURRENT_PIP_VER}" != "${LATEST_PIP_VER}" ] || [ "$UPDATE_TYPE" == "forced" ]; then - rm -rf /rmm/api/env - fi - fi - - if [ "${CURRENT_PIP_VER}" == "${LATEST_PIP_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then - source /rmm/api/env/bin/activate - cd /rmm/api/tacticalrmm - pip install -r /rmm/api/tacticalrmm/requirements.txt - else - cd /rmm/api + #if [ "$1" == "update" ]; then + # CHECK_ADMIN_ENABLED=$(grep ADMIN_ENABLED /rmm/api/tacticalrmm/tacticalrmm/local_settings.py) + # if ! [ $CHECK_ADMIN_ENABLED ]; then + # sudo sed -i '$ a ADMIN_ENABLED = False' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + # 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 [ "${CURRENT_PIP_VER}" != "${LATEST_PIP_VER}" ] || [ "$UPDATE_TYPE" == "forced" ]; then + # rm -rf /rmm/api/env + # fi + #fi + + #if [ "${CURRENT_PIP_VER}" == "${LATEST_PIP_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then + # source /rmm/api/env/bin/activate + # cd /rmm/api/tacticalrmm + # pip install -r /rmm/api/tacticalrmm/requirements.txt + #else + # cd /rmm/api + # 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 + #fi + + #if [ "$1" == "update" ]; then + # python manage.py pre_update_tasks + # celery -A tacticalrmm purge -f + # python manage.py migrate + # python manage.py delete_tokens + # python manage.py collectstatic --no-input + # python manage.py reload_nats + # python manage.py load_chocos + # python manage.py create_installer_user + # python manage.py create_natsapi_conf + # python manage.py post_update_tasks + # rmmdomain=$(python manage.py get_config api) + # WEB_VERSION=$(python manage.py get_config webversion) + # deactivate + #elif [ "$1" == "restore" ]; then + # python manage.py migrate + # python manage.py collectstatic --no-input + # python manage.py create_natsapi_conf + # python manage.py reload_nats + # python manage.py post_update_tasks + # rmmdomain=$(python manage.py get_config api) + # WEB_VERSION=$(python manage.py get_config webversion) + # deactivate + #else + cd /rmm/api 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 - fi - - if [ "$1" == "update" ]; then - python manage.py pre_update_tasks - celery -A tacticalrmm purge -f - python manage.py migrate - python manage.py delete_tokens - python manage.py collectstatic --no-input - python manage.py reload_nats - python manage.py load_chocos - python manage.py create_installer_user - python manage.py create_natsapi_conf - python manage.py post_update_tasks - rmmdomain=$(python manage.py get_config api) - WEB_VERSION=$(python manage.py get_config webversion) - deactivate - elif [ "$1" == "restore" ]; then - python manage.py migrate - python manage.py collectstatic --no-input - python manage.py create_natsapi_conf - python manage.py reload_nats - python manage.py post_update_tasks - rmmdomain=$(python manage.py get_config api) - WEB_VERSION=$(python manage.py get_config webversion) - deactivate - else python manage.py migrate python manage.py collectstatic --no-input python manage.py create_natsapi_conf From df8c40292f8d24ed725dcd7d6581e00dff7c1242 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 15:27:55 -0500 Subject: [PATCH 070/203] Removed unnecessary \ from conf and services --- default-configs/nginx/frontend.conf | 6 +++--- default-configs/nginx/meshcentral.conf | 12 ++++++------ default-configs/nginx/rmm.conf | 14 +++++++------- script-cfg/CertificateFunctions.cfg | 8 ++++++-- script-cfg/ConfigAndServiceFunctions.cfg | 2 +- service-definitions/celery.service | 6 +++--- service-definitions/celerybeat.service | 2 +- service-definitions/nats.service | 4 ++-- 8 files changed, 29 insertions(+), 25 deletions(-) diff --git a/default-configs/nginx/frontend.conf b/default-configs/nginx/frontend.conf index e78019c660..57fc931e36 100644 --- a/default-configs/nginx/frontend.conf +++ b/default-configs/nginx/frontend.conf @@ -3,7 +3,7 @@ server { charset utf-8; location / { root /var/www/rmm/dist; - try_files \$uri \$uri/ /index.html; + try_files $uri $uri/ /index.html; add_header Cache-Control "no-store, no-cache, must-revalidate"; add_header Pragma "no-cache"; } @@ -27,8 +27,8 @@ server { } server { - if (\$host = rmm.example.com) { - return 301 https://\$host\$request_uri; + if ($host = rmm.example.com) { + return 301 https://$host$request_uri; } listen 80; diff --git a/default-configs/nginx/meshcentral.conf b/default-configs/nginx/meshcentral.conf index ecab990a40..5c4975550d 100644 --- a/default-configs/nginx/meshcentral.conf +++ b/default-configs/nginx/meshcentral.conf @@ -2,7 +2,7 @@ server { listen 80; listen [::]:80; server_name mesh.example.com; - return 301 https://\$server_name\$request_uri; + return 301 https://$server_name$request_uri; } server { @@ -31,11 +31,11 @@ server { proxy_pass http://127.0.0.1:4443/; proxy_http_version 1.1; - proxy_set_header Host \$host; - proxy_set_header Upgrade \$http_upgrade; + 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; + 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; } } diff --git a/default-configs/nginx/rmm.conf b/default-configs/nginx/rmm.conf index 4ed94f8f1b..475f0f176a 100644 --- a/default-configs/nginx/rmm.conf +++ b/default-configs/nginx/rmm.conf @@ -4,7 +4,7 @@ upstream tacticalrmm { server unix:////rmm/api/tacticalrmm/tacticalrmm.sock; } -map \$http_user_agent \$ignore_ua { +map $http_user_agent $ignore_ua { "~python-requests.*" 0; "~go-resty.*" 0; default 1; @@ -14,7 +14,7 @@ server { listen 80; listen [::]:80; server_name api.example.com; - return 301 https://\$server_name\$request_uri; + return 301 https://$server_name$request_uri; } server { @@ -51,14 +51,14 @@ server { proxy_pass http://unix:/rmm/daphne.sock; proxy_http_version 1.1; - proxy_set_header Upgrade \$http_upgrade; + 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; + 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 / { diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index b350567fc0..d71d0ddc7e 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -74,8 +74,12 @@ installCertbot() fi # Set symlinks to avoid security concerns and simplify Nginx config - sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem - sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem + if [ ! -f /etc/ssl/certs/fullchain.pem ]; then + sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem + fi + if [ ! -f /etc/ssl/certs/privkey.pem ]; then + sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem + fi # Generate DH if it doesn't exist if [ ! -f /etc/ssl/certs/dhparam.pem ]; then diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index d3201155d1..9b6cda381d 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -129,7 +129,7 @@ configureBackend() deactivate read -n 1 -s -r -p "Press any key to continue..." fi - fi + #fi } # Create UWSGI config diff --git a/service-definitions/celery.service b/service-definitions/celery.service index 6bd94eacf2..1a895ea010 100644 --- a/service-definitions/celery.service +++ b/service-definitions/celery.service @@ -8,9 +8,9 @@ User=REPLACEME Group=REPLACEME 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' +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 diff --git a/service-definitions/celerybeat.service b/service-definitions/celerybeat.service index d6cefee030..5582be73fb 100644 --- a/service-definitions/celerybeat.service +++ b/service-definitions/celerybeat.service @@ -8,7 +8,7 @@ User=REPLACEME Group=REPLACEME 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}' +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 diff --git a/service-definitions/nats.service b/service-definitions/nats.service index bb85259f44..7d69c0e108 100644 --- a/service-definitions/nats.service +++ b/service-definitions/nats.service @@ -6,8 +6,8 @@ After=network.target 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 +ExecReload=/usr/bin/kill -s HUP $MAINPID +ExecStop=/usr/bin/kill -s SIGINT $MAINPID User=REPLACEME Group=www-data Restart=always From 935739766fb8d5a456661348fb06879d89ce20a6 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 16:02:57 -0500 Subject: [PATCH 071/203] Fingers crossed backend fix is correct --- script-cfg/CertificateFunctions.cfg | 5 +- script-cfg/ConfigAndServiceFunctions.cfg | 108 ++++++++++++----------- script-cfg/ParentFunctions.cfg | 2 +- script-cfg/TroubleshootingFunctions.cfg | 2 +- 4 files changed, 61 insertions(+), 56 deletions(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index d71d0ddc7e..4686770a1c 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -77,9 +77,12 @@ installCertbot() if [ ! -f /etc/ssl/certs/fullchain.pem ]; then sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem fi - if [ ! -f /etc/ssl/certs/privkey.pem ]; then + if [ ! -f /etc/ssl/private/privkey.pem ]; then sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem fi + if [ ! -f /etc/ssl/certs/chain.pem ]; then + sudo ln -s /etc/letsencrypt/live/$rootdomain/chain.pem /etc/ssl/certs/chain.pem + fi # Generate DH if it doesn't exist if [ ! -f /etc/ssl/certs/dhparam.pem ]; then diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 9b6cda381d..ac727e842f 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -39,58 +39,60 @@ configureBackend() WHEEL_VER=$(grep "^WHEEL_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') userconfirm="n" - #if [ "$1" == "update" ]; then - # CHECK_ADMIN_ENABLED=$(grep ADMIN_ENABLED /rmm/api/tacticalrmm/tacticalrmm/local_settings.py) - # if ! [ $CHECK_ADMIN_ENABLED ]; then - # sudo sed -i '$ a ADMIN_ENABLED = False' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - # 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 [ "${CURRENT_PIP_VER}" != "${LATEST_PIP_VER}" ] || [ "$UPDATE_TYPE" == "forced" ]; then - # rm -rf /rmm/api/env - # fi - #fi - - #if [ "${CURRENT_PIP_VER}" == "${LATEST_PIP_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then - # source /rmm/api/env/bin/activate - # cd /rmm/api/tacticalrmm - # pip install -r /rmm/api/tacticalrmm/requirements.txt - #else - # cd /rmm/api - # 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 - #fi - - #if [ "$1" == "update" ]; then - # python manage.py pre_update_tasks - # celery -A tacticalrmm purge -f - # python manage.py migrate - # python manage.py delete_tokens - # python manage.py collectstatic --no-input - # python manage.py reload_nats - # python manage.py load_chocos - # python manage.py create_installer_user - # python manage.py create_natsapi_conf - # python manage.py post_update_tasks - # rmmdomain=$(python manage.py get_config api) - # WEB_VERSION=$(python manage.py get_config webversion) - # deactivate - #elif [ "$1" == "restore" ]; then - # python manage.py migrate - # python manage.py collectstatic --no-input - # python manage.py create_natsapi_conf - # python manage.py reload_nats - # python manage.py post_update_tasks - # rmmdomain=$(python manage.py get_config api) - # WEB_VERSION=$(python manage.py get_config webversion) - # deactivate - #else - cd /rmm/api + if [ "$1" == "update" ]; then + CHECK_ADMIN_ENABLED=$(grep ADMIN_ENABLED /rmm/api/tacticalrmm/tacticalrmm/local_settings.py) + if ! [ $CHECK_ADMIN_ENABLED ]; then + sudo sed -i '$ a ADMIN_ENABLED = False' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + 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 [ "${CURRENT_PIP_VER}" != "${LATEST_PIP_VER}" ] || [ "$UPDATE_TYPE" == "forced" ]; then + rm -rf /rmm/api/env + fi + fi + + if [ "${CURRENT_PIP_VER}" == "${LATEST_PIP_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then + source /rmm/api/env/bin/activate + cd /rmm/api/tacticalrmm + pip install -r /rmm/api/tacticalrmm/requirements.txt + fi + + if [ "$1" == "install" ] || [ "$1" == "restore" ]; then + cd /rmm/api + 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 + fi + + if [ "$1" == "update" ]; then + python manage.py pre_update_tasks + celery -A tacticalrmm purge -f + python manage.py migrate + python manage.py delete_tokens + python manage.py collectstatic --no-input + python manage.py reload_nats + python manage.py load_chocos + python manage.py create_installer_user + python manage.py create_natsapi_conf + python manage.py post_update_tasks + rmmdomain=$(python manage.py get_config api) + WEB_VERSION=$(python manage.py get_config webversion) + deactivate + elif [ "$1" == "restore" ]; then + python manage.py migrate + python manage.py collectstatic --no-input + python manage.py create_natsapi_conf + python manage.py reload_nats + python manage.py post_update_tasks + rmmdomain=$(python manage.py get_config api) + WEB_VERSION=$(python manage.py get_config webversion) + deactivate + elif [ "$1" == "install" ]; then + cd /rmm/api python3.10 -m venv env source /rmm/api/env/bin/activate cd /rmm/api/tacticalrmm @@ -129,7 +131,7 @@ configureBackend() deactivate read -n 1 -s -r -p "Press any key to continue..." fi - #fi + fi } # Create UWSGI config diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index a203004efc..4a31a4a5a4 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -128,7 +128,7 @@ mainInstall() # Misc functions print_green 'Installing the backend'; # Config and Service functions - configureBackend; + configureBackend "$INSTALL_TYPE"; # Create UWSGI config # Misc functions diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index bd57f24fe7..a39487bbea 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -115,7 +115,7 @@ checkIfCertIsValid() echo -e "\n" # SSL Certificate check - cert="$(openssl verify -CAfile /etc/letsencrypt/live/$rootdomain/chain.pem /etc/letsencrypt/live/$rootdomain/cert.pem)" + cert="$(openssl verify -CAfile /etc/ssl/certs/chain.pem /etc/ssl/certs/fullchain.pem)" if [[ "$cert" == *"OK"* ]]; then echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log From d34273bf27af74688a6a1b6d3d95c55d042a84e1 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 16:05:20 -0500 Subject: [PATCH 072/203] added import for ca chain to allow troubleshoot --- script-cfg/CertificateFunctions.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 4686770a1c..2a1858aab9 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -26,9 +26,10 @@ renewCerts() # Import certs importCerts() { - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate and your private key, in that order.\n\nTo paste the contents, type i , then shift+insert.\n\nAfter pasting the contents, type esc , then shift-: , then wq , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate, private key, and CA Chain file, in that order.\n\nTo paste the contents, type i , then shift+insert.\n\nAfter pasting the contents, type esc , then shift-: , then wq , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 sudo vim /etc/ssl/certs/fullchain.pem sudo vim /etc/ssl/private/privkey.pem + sudo vim /etc/ssl/certs/chain.pem } # Generate certs From 4a4b7a129dead25ebc1d9589616c963bcfdcc229 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 16:10:22 -0500 Subject: [PATCH 073/203] Update to cert symlinks --- script-cfg/CertificateFunctions.cfg | 2 +- script-cfg/ParentFunctions.cfg | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 2a1858aab9..63b2649350 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -82,7 +82,7 @@ installCertbot() sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem fi if [ ! -f /etc/ssl/certs/chain.pem ]; then - sudo ln -s /etc/letsencrypt/live/$rootdomain/chain.pem /etc/ssl/certs/chain.pem + sudo ln -s /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/ssl/certs/chain.pem fi # Generate DH if it doesn't exist diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 4a31a4a5a4..fd497905c2 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -375,6 +375,7 @@ updateTRMM() # Set symlinks to avoid security concerns and simplify Nginx config sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem + sudo ln -s /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/ssl/certs/chain.pem # Update from main repo # Misc functions @@ -572,6 +573,7 @@ restoreTRMM() # Set symlinks to avoid security concerns and simplify Nginx config sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem + sudo ln -s /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/ssl/certs/chain.pem # Recreate Nginx conf files # Config and Service functions From 5bf187e4c7343d5bc9d441206d25ede030862ab1 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 16:38:36 -0500 Subject: [PATCH 074/203] edit to make text prettier --- script-cfg/ConfigAndServiceFunctions.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index ac727e842f..4569f37227 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -57,7 +57,7 @@ configureBackend() cd /rmm/api/tacticalrmm pip install -r /rmm/api/tacticalrmm/requirements.txt fi - + if [ "$1" == "install" ] || [ "$1" == "restore" ]; then cd /rmm/api python3.10 -m venv env @@ -130,6 +130,7 @@ configureBackend() python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} deactivate read -n 1 -s -r -p "Press any key to continue..." + echo -e "\n" fi fi } From 1e128edd236d597501966c95fa584957353f3343 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 16:46:54 -0500 Subject: [PATCH 075/203] Backend function cleanup --- script-cfg/ConfigAndServiceFunctions.cfg | 37 ++++++++++++------------ 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 4569f37227..b10e018870 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -49,26 +49,18 @@ configureBackend() sudo chmod +x /usr/local/bin/nats-api if [ "${CURRENT_PIP_VER}" != "${LATEST_PIP_VER}" ] || [ "$UPDATE_TYPE" == "forced" ]; then rm -rf /rmm/api/env + cd /rmm/api + 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 requirements.txt + else + source /rmm/api/env/bin/activate + cd /rmm/api/tacticalrmm + pip install -r /rmm/api/tacticalrmm/requirements.txt fi - fi - - if [ "${CURRENT_PIP_VER}" == "${LATEST_PIP_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then - source /rmm/api/env/bin/activate - cd /rmm/api/tacticalrmm - pip install -r /rmm/api/tacticalrmm/requirements.txt - fi - - if [ "$1" == "install" ] || [ "$1" == "restore" ]; then - cd /rmm/api - 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 - fi - - if [ "$1" == "update" ]; then python manage.py pre_update_tasks celery -A tacticalrmm purge -f python manage.py migrate @@ -83,6 +75,13 @@ configureBackend() WEB_VERSION=$(python manage.py get_config webversion) deactivate elif [ "$1" == "restore" ]; then + cd /rmm/api + 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 From 1aceee871f3c12eead05a2c5e089802d1b70ccc6 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 17:24:02 -0500 Subject: [PATCH 076/203] Updated completion text for nats websockets --- script-cfg/ParentFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index fd497905c2..e984a8d9a7 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -294,7 +294,7 @@ mainInstall() echo -e "${YELLOW} Read below if your router does NOT support Hairpin NAT:${NC}\n" echo -e "${GREEN} If you will be accessing the web interface of the RMM from the same LAN as this server,\nyou'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" echo -e "${GREEN} This also applies to any agents that will be on the same local network as the rmm.${NC}\n" - echo -e "${GREEN} You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp.${NC}\n" + echo -e "${GREEN} You'll also need to setup port forwarding in your router on port 443.${NC}\n" fi # Misc functions print_yellow "Please refer to the github README for next steps."; From a8556a3ec4cd57abbf24afdc16475093b92e15a4 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 17:50:23 -0500 Subject: [PATCH 077/203] reverted completion text --- script-cfg/ParentFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index e984a8d9a7..3047160549 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -294,7 +294,7 @@ mainInstall() echo -e "${YELLOW} Read below if your router does NOT support Hairpin NAT:${NC}\n" echo -e "${GREEN} If you will be accessing the web interface of the RMM from the same LAN as this server,\nyou'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" echo -e "${GREEN} This also applies to any agents that will be on the same local network as the rmm.${NC}\n" - echo -e "${GREEN} You'll also need to setup port forwarding in your router on port 443.${NC}\n" + echo -e "${GREEN} You'll also need to setup port forwarding in your router on ports 443 and 4222.${NC}\n" fi # Misc functions print_yellow "Please refer to the github README for next steps."; From 44c29cce42b9f38faf38ce3f8e54324e5fe89ae9 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 26 Jun 2022 17:55:11 -0500 Subject: [PATCH 078/203] added nginx conf for nats websockets --- default-configs/nginx/rmm.conf | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/default-configs/nginx/rmm.conf b/default-configs/nginx/rmm.conf index 475f0f176a..8a4b832645 100644 --- a/default-configs/nginx/rmm.conf +++ b/default-configs/nginx/rmm.conf @@ -61,6 +61,17 @@ server { proxy_set_header X-Forwarded-Host $server_name; } + location ~ ^/natsws { + proxy_pass http://127.0.0.1:9235; + 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; + } + location / { uwsgi_pass tacticalrmm; include /etc/nginx/uwsgi_params; From dac0d96e873987dc0c6f157035ef2c9889fce49f Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 07:56:31 -0500 Subject: [PATCH 079/203] reverted use of symlinks for certs, causing issues --- api/tacticalrmm/tacticalrmm/helpers.py | 4 ++-- default-configs/mesh/config.json | 2 +- default-configs/nginx/frontend.conf | 4 ++-- default-configs/nginx/meshcentral.conf | 4 ++-- default-configs/nginx/rmm.conf | 8 ++++---- script-cfg/CertificateFunctions.cfg | 24 ++++++++++-------------- script-cfg/ParentFunctions.cfg | 10 ---------- script-cfg/TroubleshootingFunctions.cfg | 2 +- 8 files changed, 22 insertions(+), 36 deletions(-) diff --git a/api/tacticalrmm/tacticalrmm/helpers.py b/api/tacticalrmm/tacticalrmm/helpers.py index 8d12a53c94..9a27ed1f84 100644 --- a/api/tacticalrmm/tacticalrmm/helpers.py +++ b/api/tacticalrmm/tacticalrmm/helpers.py @@ -5,8 +5,8 @@ def get_certs() -> tuple[str, str]: domain = settings.ALLOWED_HOSTS[0].split(".", 1)[1] - cert_file = f"/etc/letsencrypt/live/{domain}/fullchain.pem" - key_file = f"/etc/letsencrypt/live/{domain}/privkey.pem" + cert_file = f"/etc/letsencrypt/live/${rootdomain}/fullchain.pem" + key_file = f"/etc/letsencrypt/live/${rootdomain}/privkey.pem" if hasattr(settings, "CERT_FILE") and hasattr(settings, "KEY_FILE"): cert_file = settings.CERT_FILE diff --git a/default-configs/mesh/config.json b/default-configs/mesh/config.json index 52ae3097f2..a288815e08 100644 --- a/default-configs/mesh/config.json +++ b/default-configs/mesh/config.json @@ -25,7 +25,7 @@ "Title": "Tactical RMM", "Title2": "Tactical RMM", "NewAccounts": false, - "CertUrl": "https://mesh.example.com/", + "CertUrl": "https://mesh.example.com:443/", "GeoLocation": true, "CookieIpCheck": false, "mstsc": true diff --git a/default-configs/nginx/frontend.conf b/default-configs/nginx/frontend.conf index 57fc931e36..48a9ddbb9e 100644 --- a/default-configs/nginx/frontend.conf +++ b/default-configs/nginx/frontend.conf @@ -12,8 +12,8 @@ server { listen 443 ssl; listen [::]:443 ssl; - ssl_certificate /etc/ssl/certs/fullchain.pem; - ssl_certificate_key /etc/ssl/private/privkey.pem; + ssl_certificate /etc/letsencrypt/live/rootdomain/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/rootdomain/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; diff --git a/default-configs/nginx/meshcentral.conf b/default-configs/nginx/meshcentral.conf index 5c4975550d..35372429b1 100644 --- a/default-configs/nginx/meshcentral.conf +++ b/default-configs/nginx/meshcentral.conf @@ -12,8 +12,8 @@ server { proxy_send_timeout 330s; proxy_read_timeout 330s; server_name mesh.example.com; - ssl_certificate /etc/ssl/certs/fullchain.pem; - ssl_certificate_key /etc/ssl/private/privkey.pem; + ssl_certificate /etc/letsencrypt/live/rootdomain/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/rootdomain/privkey.pem; ssl_session_cache shared:WEBSSL:10m; diff --git a/default-configs/nginx/rmm.conf b/default-configs/nginx/rmm.conf index 8a4b832645..81307a1226 100644 --- a/default-configs/nginx/rmm.conf +++ b/default-configs/nginx/rmm.conf @@ -22,10 +22,10 @@ server { listen [::]:443 ssl; server_name api.example.com; client_max_body_size 300M; - access_log /rmm/api/tacticalrmm/tacticalrmm/private/log/access.log combined if=\$ignore_ua; + 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/fullchain.pem; - ssl_certificate_key /etc/ssl/private/privkey.pem; + ssl_certificate /etc/letsencrypt/live/rootdomain/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/rootdomain/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; @@ -61,7 +61,7 @@ server { proxy_set_header X-Forwarded-Host $server_name; } - location ~ ^/natsws { + location ~ ^/natsws/ { proxy_pass http://127.0.0.1:9235; proxy_http_version 1.1; proxy_set_header Host $host; diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 63b2649350..1d1b044f60 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -27,9 +27,14 @@ renewCerts() importCerts() { dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate, private key, and CA Chain file, in that order.\n\nTo paste the contents, type i , then shift+insert.\n\nAfter pasting the contents, type esc , then shift-: , then wq , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 - sudo vim /etc/ssl/certs/fullchain.pem - sudo vim /etc/ssl/private/privkey.pem - sudo vim /etc/ssl/certs/chain.pem + if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then + sudo mkdir -p /etc/letsencrypt/live/${rootdomain} + fi + sudo vim /etc/letsencrypt/live/${rootdomain}/fullchain.pem + sudo vim /etc/letsencrypt/live/${rootdomain}/privkey.pem + sudo vim /etc/letsencrypt/live/${rootdomain}/chain.pem + sudo chown ${USER}:${USER} -R /etc/letsencrypt + sudo chmod 775 -R /etc/letsencrypt } # Generate certs @@ -72,17 +77,8 @@ installCertbot() sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem - fi - - # Set symlinks to avoid security concerns and simplify Nginx config - if [ ! -f /etc/ssl/certs/fullchain.pem ]; then - sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem - fi - if [ ! -f /etc/ssl/private/privkey.pem ]; then - sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem - fi - if [ ! -f /etc/ssl/certs/chain.pem ]; then - sudo ln -s /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/ssl/certs/chain.pem + sudo chown ${USER}:${USER} -R /etc/letsencrypt + sudo chmod 775 -R /etc/letsencrypt fi # Generate DH if it doesn't exist diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index e984a8d9a7..1ab8e278e4 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -372,11 +372,6 @@ updateTRMM() # Misc functions getExistingDomainInfo; - # Set symlinks to avoid security concerns and simplify Nginx config - sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem - sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem - sudo ln -s /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/ssl/certs/chain.pem - # Update from main repo # Misc functions print_green 'Cloning primary repo'; @@ -569,11 +564,6 @@ restoreTRMM() sudo rm -rf /etc/letsencrypt sudo mkdir /etc/letsencrypt sudo tar -xzf $tmp_dir/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt - - # Set symlinks to avoid security concerns and simplify Nginx config - sudo ln -s /etc/letsencrypt/live/${rootdomain}/fullchain.pem /etc/ssl/certs/fullchain.pem - sudo ln -s /etc/letsencrypt/live/${rootdomain}/privkey.pem /etc/ssl/private/privkey.pem - sudo ln -s /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/ssl/certs/chain.pem # Recreate Nginx conf files # Config and Service functions diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index a39487bbea..9c9162943f 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -115,7 +115,7 @@ checkIfCertIsValid() echo -e "\n" # SSL Certificate check - cert="$(openssl verify -CAfile /etc/ssl/certs/chain.pem /etc/ssl/certs/fullchain.pem)" + cert="$(openssl verify -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/cert.pem)" if [[ "$cert" == *"OK"* ]]; then echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log From 861e279e0b96c31b9f93088627fbd7f5e0396381 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 08:16:48 -0500 Subject: [PATCH 080/203] edited nginx conf config functions for reversion --- script-cfg/ConfigAndServiceFunctions.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index b10e018870..2a706cbea9 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -179,6 +179,7 @@ createBackendNginxConf() sudo sed -i "s/api.example.com/$rmmdomain/" /etc/nginx/sites-available/rmm.conf sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/rmm.conf } # Create Mesh nginx conf @@ -187,6 +188,7 @@ createMeshNginxConf() sudo cp /rmm/default-configs/nginx/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf sudo sed -i "s/mesh.example.com/$meshdomain/" /etc/nginx/sites-available/meshcentral.conf + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/rmm.conf } # Create Celery service @@ -225,6 +227,7 @@ createFrontendNginxConf() sudo cp /rmm/default-configs/nginx/frontend.conf /etc/nginx/sites-available/frontend.conf sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/frontend.conf + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/rmm.conf } # Enable MeshCentral service From 1533be8ea3d14fb3c569b49b72a381a672470e23 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 08:28:58 -0500 Subject: [PATCH 081/203] updated to use new branch, derp --- installer-util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer-util.sh b/installer-util.sh index f96aa446f5..b3b5cfbb4b 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -13,7 +13,7 @@ declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunction # Script Info variables REPO_OWNER="ninjamonkey198206" -BRANCH="develop-installer-update" +BRANCH="develop-installer-update-ws" SCRIPT_VERSION="69" CFG_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/installer-util.sh" From 85e77287553d15d22101b82c0d73e4a5809f0f20 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 08:56:14 -0500 Subject: [PATCH 082/203] Fixed helpers.py --- api/tacticalrmm/tacticalrmm/helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/tacticalrmm/tacticalrmm/helpers.py b/api/tacticalrmm/tacticalrmm/helpers.py index 9a27ed1f84..8d12a53c94 100644 --- a/api/tacticalrmm/tacticalrmm/helpers.py +++ b/api/tacticalrmm/tacticalrmm/helpers.py @@ -5,8 +5,8 @@ def get_certs() -> tuple[str, str]: domain = settings.ALLOWED_HOSTS[0].split(".", 1)[1] - cert_file = f"/etc/letsencrypt/live/${rootdomain}/fullchain.pem" - key_file = f"/etc/letsencrypt/live/${rootdomain}/privkey.pem" + cert_file = f"/etc/letsencrypt/live/{domain}/fullchain.pem" + key_file = f"/etc/letsencrypt/live/{domain}/privkey.pem" if hasattr(settings, "CERT_FILE") and hasattr(settings, "KEY_FILE"): cert_file = settings.CERT_FILE From c788f5213867ea2d870ec1fb8f74eac3b9bb43b0 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 08:59:31 -0500 Subject: [PATCH 083/203] fixed nginx confs --- script-cfg/ConfigAndServiceFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 2a706cbea9..5335194e23 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -188,7 +188,7 @@ createMeshNginxConf() sudo cp /rmm/default-configs/nginx/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf sudo sed -i "s/mesh.example.com/$meshdomain/" /etc/nginx/sites-available/meshcentral.conf - sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/meshcentral.conf } # Create Celery service @@ -227,7 +227,7 @@ createFrontendNginxConf() sudo cp /rmm/default-configs/nginx/frontend.conf /etc/nginx/sites-available/frontend.conf sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/frontend.conf - sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/frontend.conf } # Enable MeshCentral service From d854fee2b95b8a899b73af430eb9c7de25321215 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 09:33:57 -0500 Subject: [PATCH 084/203] Updated installer and restore to bring in line --- installer-util.sh | 172 +++++++++++++++----------------- script-cfg/InstallFunctions.cfg | 4 +- script-cfg/ParentFunctions.cfg | 6 +- 3 files changed, 88 insertions(+), 94 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index b3b5cfbb4b..02e0d27f18 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -75,98 +75,92 @@ done . $PWD/script-cfg/TroubleshootingFunctions.cfg . $PWD/script-cfg/ParentFunctions.cfg -# Get commandline input function -#getCommandLineArgs() -##{ - while getopts auto:api:branch:ca:cert:domain:email:h:key:mesh:pass:repo:rmm:username: option - do - case $option in - auto ) autoinstall="1" - INSTALL_TYPE="$(translateToLowerCase ${OPTARG})";; - api ) rmmhost="$(translateToLowerCase ${OPTARG})";; - branch ) BRANCH="$(translateToLowerCase ${OPTARG})";; - ca ) sslcacert="${OPTARG}";; - cert ) sslcert="${OPTARG}";; - domain ) rootdomain="$(translateToLowerCase ${OPTARG})";; - email ) letsemail="$(translateToLowerCase ${OPTARG})";; - h ) helpText - exit;; - key ) sslkey="${OPTARG}";; - mesh ) meshhost="$(translateToLowerCase ${OPTARG})";; - pass ) trmmpass="${OPTARG}";; - repo ) REPO_OWNER="$(translateToLowerCase ${OPTARG})";; - rmm ) frontendhost="$(translateToLowerCase ${OPTARG})";; - username ) trmmuser="${OPTARG}";; - \?) echo -e "Error: Invalid option" - clear -x - exit 1;; - esac - done - - if [ "$autoinstall" == "1" ]; then - # Check all required input is available - if [ -z "$INSTALL_TYPE" ] || [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]; then - echo -e "Error: To perform an automated installation, you must provide all required information." - echo -e "\n" - echo -e "install type, api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for further details." - clear -x - exit 1 - fi - - # Check that install type is valid - if [ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ]; then - echo -e "Error: You've selected an invalid installation type." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for details on the available options." - clear -x - exit 1 - fi - - # Check that repo and branch match install type - if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]) && [ "$BRANCH" == "master" ]; then - echo -e "Error: You've selected a developer installation type, but not changed the repo, branch, or both." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for details on how to select them." - clear -x - exit 1 - fi - - # Check root domain is valid format - if [[ $rootdomain != *[.]* ]]; then - echo -e "Error: You've entered an invalid root domain." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for details on the correct format." - clear -x - exit 1 - fi - - # Check that email address format is valid - if [[ $letsemail != *[@]*[.]* ]]; then - echo -e "Error: You've entered an invalid email address." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for details on the correct format." +# Get commandline input +while getopts auto:api:branch:ca:cert:domain:email:h:key:mesh:pass:repo:rmm:username: option +do + case $option in + auto ) autoinstall="1" + INSTALL_TYPE="$(translateToLowerCase ${OPTARG})";; + api ) rmmhost="$(translateToLowerCase ${OPTARG})";; + branch ) BRANCH="$(translateToLowerCase ${OPTARG})";; + ca ) sslcacert="${OPTARG}";; + cert ) sslcert="${OPTARG}";; + domain ) rootdomain="$(translateToLowerCase ${OPTARG})";; + email ) letsemail="$(translateToLowerCase ${OPTARG})";; + h ) helpText + exit 1;; + key ) sslkey="${OPTARG}";; + mesh ) meshhost="$(translateToLowerCase ${OPTARG})";; + pass ) trmmpass="${OPTARG}";; + repo ) REPO_OWNER="$(translateToLowerCase ${OPTARG})";; + rmm ) frontendhost="$(translateToLowerCase ${OPTARG})";; + username ) trmmuser="${OPTARG}";; + \?) echo -e "Error: Invalid option" clear -x - exit 1 - fi - - # Check subdomains are valid format - # User Input - subdomainCheck "$rmmhost" "api"; - subdomainCheck "$meshhost" "mesh"; - subdomainCheck "$frontendhost" "rmm"; - - # Check that cert file exists - # User Input - checkCertExists "$sslcacert" "CA Chain"; - checkCertExists "$sslcert" "Fullchain Cert"; - checkCertExists "$sslkey" "Private Key"; + exit 1;; + esac +done + +if [ "$autoinstall" == "1" ]; then + # Check all required input is available + if [ -z "$INSTALL_TYPE" ] || [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]; then + echo -e "Error: To perform an automated installation, you must provide all required information." + echo -e "\n" + echo -e "install type, api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required." + echo -e "\n" + echo -e "Run .$THIS_SCRIPT -h for further details." + clear -x + exit 1 fi -#} -# Get commandline input -#getCommandLineArgs; + # Check that install type is valid + if [ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ]; then + echo -e "Error: You've selected an invalid installation type." + echo -e "\n" + echo -e "Run .$THIS_SCRIPT -h for details on the available options." + clear -x + exit 1 + fi + + # Check that repo and branch match install type + if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]) && [ "$BRANCH" == "master" ]; then + echo -e "Error: You've selected a developer installation type, but not changed the repo, branch, or both." + echo -e "\n" + echo -e "Run .$THIS_SCRIPT -h for details on how to select them." + clear -x + exit 1 + fi + + # Check root domain is valid format + if [[ $rootdomain != *[.]* ]]; then + echo -e "Error: You've entered an invalid root domain." + echo -e "\n" + echo -e "Run .$THIS_SCRIPT -h for details on the correct format." + clear -x + exit 1 + fi + + # Check that email address format is valid + if [[ $letsemail != *[@]*[.]* ]]; then + echo -e "Error: You've entered an invalid email address." + echo -e "\n" + echo -e "Run .$THIS_SCRIPT -h for details on the correct format." + clear -x + exit 1 + fi + + # Check subdomains are valid format + # User Input + subdomainCheck "$rmmhost" "api"; + subdomainCheck "$meshhost" "mesh"; + subdomainCheck "$frontendhost" "rmm"; + + # Check that cert file exists + # User Input + checkCertExists "$sslcacert" "CA Chain"; + checkCertExists "$sslcert" "Fullchain Cert"; + checkCertExists "$sslkey" "Private Key"; +fi # Set colors # MiscFunctions diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index fc02c5ed1a..407ceed795 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -155,7 +155,7 @@ installFrontEnd() { if [ "$1" == "update" ]; then if [ -d /rmm/web ]; then - rm -rf /rmm/web + sudo rm -rf /rmm/web fi if [ ! -d /var/www/rmm ]; then @@ -168,7 +168,7 @@ installFrontEnd() if [ "$1" == "update" ]; then sudo rm -rf /var/www/rmm/dist - else + elif [ "$1" == "restore" ]; then sudo mkdir -p /var/www/rmm fi sudo tar -xzf /tmp/${webtar} -C /var/www/rmm diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 1ab8e278e4..9894ec44cc 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -222,7 +222,7 @@ mainInstall() # Misc functions print_green 'Installing the frontend'; # InstallFunctions - installFrontEnd "$INSTALL_TYPE" "$FRONTEND_URL"; + installFrontEnd "$INSTALL_TYPE"; # Set front end Nginx config and enable # Misc functions @@ -414,7 +414,7 @@ updateTRMM() # Update Frontend # InstallFunctions - installFrontEnd "$INSTALL_TYPE" "$FRONTEND_URL"; + installFrontEnd "$INSTALL_TYPE"; # Start services for i in nats nats-api rmm daphne celery celerybeat nginx @@ -689,7 +689,7 @@ restoreTRMM() # Misc functions print_green 'Installing the frontend'; # InstallFunctions - installFrontEnd; + installFrontEnd "$INSTALL_TYPE"; # reset perms sudo chown "${USER}:${USER}" -R /rmm From 1699112b8e0c5d26cd32c4fd81c555b26717c2c8 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 09:35:38 -0500 Subject: [PATCH 085/203] Updated frontend install to match changes --- script-cfg/InstallFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 407ceed795..dc631d9022 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -168,7 +168,7 @@ installFrontEnd() if [ "$1" == "update" ]; then sudo rm -rf /var/www/rmm/dist - elif [ "$1" == "restore" ]; then + elif [ "$1" == "restore" ] || [ "$1" == "install" ]; then sudo mkdir -p /var/www/rmm fi sudo tar -xzf /tmp/${webtar} -C /var/www/rmm From 38e788ff8adeaa02f59675b42aa87060642c489d Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 10:27:51 -0500 Subject: [PATCH 086/203] Update installer-util.sh --- installer-util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer-util.sh b/installer-util.sh index 02e0d27f18..1466c5d296 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -13,7 +13,7 @@ declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunction # Script Info variables REPO_OWNER="ninjamonkey198206" -BRANCH="develop-installer-update-ws" +BRANCH="develop-installer-update" SCRIPT_VERSION="69" CFG_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/installer-util.sh" From 642202a7d63effae8f0310f545f095348f9c58f8 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 10:30:44 -0500 Subject: [PATCH 087/203] Updated troubleshooting to use fullchain.pem --- script-cfg/TroubleshootingFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index 9c9162943f..ce97fda862 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -115,7 +115,7 @@ checkIfCertIsValid() echo -e "\n" # SSL Certificate check - cert="$(openssl verify -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/cert.pem)" + cert="$(openssl verify -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem)" if [[ "$cert" == *"OK"* ]]; then echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log @@ -124,4 +124,4 @@ checkIfCertIsValid() echo -e "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a checklog.log echo -e "\n" fi -} \ No newline at end of file +} From 1dc933504e28b57fec59def890fd51fd20759754 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 10:31:24 -0500 Subject: [PATCH 088/203] Updated troubleshooting to use fullchain.pem --- script-cfg/TroubleshootingFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index 9c9162943f..ce97fda862 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -115,7 +115,7 @@ checkIfCertIsValid() echo -e "\n" # SSL Certificate check - cert="$(openssl verify -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/cert.pem)" + cert="$(openssl verify -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem)" if [[ "$cert" == *"OK"* ]]; then echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log @@ -124,4 +124,4 @@ checkIfCertIsValid() echo -e "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a checklog.log echo -e "\n" fi -} \ No newline at end of file +} From 900559c6626f4e01f0d1d6775ea5350d476b7b38 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 11:46:37 -0500 Subject: [PATCH 089/203] removed accidental added / from rmm nginx config --- default-configs/nginx/rmm.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default-configs/nginx/rmm.conf b/default-configs/nginx/rmm.conf index 81307a1226..46afc19bc2 100644 --- a/default-configs/nginx/rmm.conf +++ b/default-configs/nginx/rmm.conf @@ -61,7 +61,7 @@ server { proxy_set_header X-Forwarded-Host $server_name; } - location ~ ^/natsws/ { + location ~ ^/natsws { proxy_pass http://127.0.0.1:9235; proxy_http_version 1.1; proxy_set_header Host $host; From abe561f525adf133399aa285000fb0d0dbdc1568 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 11:47:40 -0500 Subject: [PATCH 090/203] removed accidental added / from rmm nginx conf --- default-configs/nginx/rmm.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default-configs/nginx/rmm.conf b/default-configs/nginx/rmm.conf index 81307a1226..46afc19bc2 100644 --- a/default-configs/nginx/rmm.conf +++ b/default-configs/nginx/rmm.conf @@ -61,7 +61,7 @@ server { proxy_set_header X-Forwarded-Host $server_name; } - location ~ ^/natsws/ { + location ~ ^/natsws { proxy_pass http://127.0.0.1:9235; proxy_http_version 1.1; proxy_set_header Host $host; From 4e2ce32cec726f84b2b1c5c29050b3bbabf5b6a4 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 13:44:28 -0500 Subject: [PATCH 091/203] Added options to import/renew certs using LE dirs --- installer-util.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 1466c5d296..6000a5d8de 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -268,8 +268,18 @@ utilityMenu() 1 ) backupTRMM;; 2 ) INSTALL_TYPE="restore" restoreTRMM;; - 3 ) renewCerts;; - 4 ) importCerts;; + 3 ) if [ ! -f /etc/nginx/sites-available/rmm.conf ]; then + getHostAndDomainInfo + else + getExistingDomainInfo + fi + renewCerts;; + 4 ) if [ ! -f /etc/nginx/sites-available/rmm.conf ]; then + getHostAndDomainInfo "TS" + else + getExistingDomainInfo + fi + importCerts;; 5 ) installFail2ban;; 6 ) troubleShoot;; 7 ) return;; From 3fd5b60dd3d37a7832aa6456ccc2abf96c631cee Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 14:59:27 -0500 Subject: [PATCH 092/203] Various updates and fixes for troubleshooting --- installer-util.sh | 6 +----- script-cfg/CertificateFunctions.cfg | 6 ------ script-cfg/InstallFunctions.cfg | 2 +- script-cfg/MiscFunctions.cfg | 7 +------ script-cfg/ParentFunctions.cfg | 3 --- script-cfg/TroubleshootingFunctions.cfg | 3 +++ 6 files changed, 6 insertions(+), 21 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 6000a5d8de..cf8c82468c 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -268,11 +268,7 @@ utilityMenu() 1 ) backupTRMM;; 2 ) INSTALL_TYPE="restore" restoreTRMM;; - 3 ) if [ ! -f /etc/nginx/sites-available/rmm.conf ]; then - getHostAndDomainInfo - else - getExistingDomainInfo - fi + 3 ) getHostAndDomainInfo renewCerts;; 4 ) if [ ! -f /etc/nginx/sites-available/rmm.conf ]; then getHostAndDomainInfo "TS" diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 1d1b044f60..d07907d589 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -12,12 +12,6 @@ CFG_VERSION="8" # Renew Certs renewCerts() { - # Pull domain info - rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - local temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" - local tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" - rootdomain="$temprootdomain.$tempdotsomething" - # generate certs and restart services generateCerts; sudo systemctl restart nginx.service rmm.service celery celerybeat.service nats-api.service nats.service meshcentral.service diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index dc631d9022..d21e1e50d7 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -18,7 +18,7 @@ installPreReqs() # Install remaining prereqs installAdditionalPreReqs() { - sudo apt install -y software-properties-common openssl ca-certificates apt-transport-https gcc g++ make build-essential zlib1g-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev git + sudo apt install -y software-properties-common dnsutils openssl ca-certificates apt-transport-https gcc g++ make build-essential zlib1g-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev git } # Configure repos for stuff diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index ad11ec89b1..47ce0299c7 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -332,13 +332,8 @@ decideMainRepos() # Pull domain info from existing installation getExistingDomainInfo() { - local temprootdomain="" - local tempdotsomething="" - rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') - temprootdomain="$(echo $rmmdomain | awk -F. '{print $2}')" - tempdotsomething="$(echo $rmmdomain | awk -F. '{print $3}')" - rootdomain="$temprootdomain.$tempdotsomething" + rootdomain=$(echo "$rmmdomain" | cut -d '.' -f2-) } \ No newline at end of file diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 2b6fe2bf1a..89924678fd 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -730,9 +730,6 @@ restoreTRMM() # Troubleshooting utility troubleShoot() { - # Resolve Locally used DNS server - locdns=$(resolvectl | grep 'Current DNS Server:' | cut -d: -f2 | awk '{ print $1}') - # Get existing domain info if [ -f /etc/nginx/sites-available/rmm.conf ] && [ -f /etc/nginx/sites-available/rmm.conf ] && [ -f /etc/nginx/sites-available/rmm.conf ]; then # Misc functions diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index ce97fda862..67dcdb98eb 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -25,6 +25,9 @@ pingDomain() # Check IPs checkIPisLive() { + # Resolve Locally used DNS server + locdns=$(grep "nameserver" /etc/resolv.conf | awk '{ print $2 }' + locinputip=`dig @"$locdns" +short $1` reminputip=`dig @8.8.8.8 +short $1` From 8210a1c1a15043d3412780449000a419bcd78164 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 15:01:07 -0500 Subject: [PATCH 093/203] fix missing ) --- script-cfg/TroubleshootingFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index 67dcdb98eb..c756383f83 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -26,7 +26,7 @@ pingDomain() checkIPisLive() { # Resolve Locally used DNS server - locdns=$(grep "nameserver" /etc/resolv.conf | awk '{ print $2 }' + locdns=$(grep "nameserver" /etc/resolv.conf | awk '{ print $2 }') locinputip=`dig @"$locdns" +short $1` reminputip=`dig @8.8.8.8 +short $1` From d6196190d1de7deb48535365528a34946e63ddc6 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 15:20:55 -0500 Subject: [PATCH 094/203] Updated cert import function to allow existing --- script-cfg/CertificateFunctions.cfg | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index d07907d589..b31a0154a0 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -24,9 +24,22 @@ importCerts() if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then sudo mkdir -p /etc/letsencrypt/live/${rootdomain} fi + + if [ -f /etc/letsencrypt/live/${rootdomain}/fullchain.pem ]; then + sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/fullchain.pem + fi sudo vim /etc/letsencrypt/live/${rootdomain}/fullchain.pem + + if [ -f /etc/letsencrypt/live/${rootdomain}/privkey.pem ]; then + sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/privkey.pem + fi sudo vim /etc/letsencrypt/live/${rootdomain}/privkey.pem + + if [ -f /etc/letsencrypt/live/${rootdomain}/chain.pem ]; then + sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/chain.pem + fi sudo vim /etc/letsencrypt/live/${rootdomain}/chain.pem + sudo chown ${USER}:${USER} -R /etc/letsencrypt sudo chmod 775 -R /etc/letsencrypt } From 20499f0a86651dbaf873abebd6e90532e432317b Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 16:58:54 -0500 Subject: [PATCH 095/203] Attempt to fix localhost entry --- script-cfg/NetworkFunctions.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index 2150dadeeb..ad80fa90e0 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="8" +CFG_VERSION="9" ####################### @@ -44,8 +44,8 @@ configHosts() # 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 - CHECK_LOCALHOST=$(sed -n "/127.0.0.1/=" /etc/hosts) - if [ $CHECK_LOCALHOST != 1 ]; then + CHECK_LOCALHOST=$(grep "127.0.0.1" /etc/hosts) + if ! [[ $CHECK_LOCALHOST ]]; then echo -e "${GREEN} Adding localhost to hosts file${NC}\n" sudo sed -i "1i 127.0.0.1\tlocalhost" /etc/hosts fi From 9a65f6078f9d2279307873bb79b7b64ecf0b87d0 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 22:19:54 -0500 Subject: [PATCH 096/203] Updated branch after merge --- installer-util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer-util.sh b/installer-util.sh index cf8c82468c..3584281d40 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -13,7 +13,7 @@ declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunction # Script Info variables REPO_OWNER="ninjamonkey198206" -BRANCH="develop-installer-update" +BRANCH="develop-installer-update-ws" SCRIPT_VERSION="69" CFG_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/installer-util.sh" From 035af070a2d6b69b06fbfad3b86cebeb44851f78 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 22:31:53 -0500 Subject: [PATCH 097/203] Testing cfg pull issue --- script-cfg/MiscFunctions.cfg | 2 +- script-cfg/NetworkFunctions.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 47ce0299c7..f1c0e061c3 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -123,7 +123,7 @@ checkCfgVer() echo -e "${RED} Please re-run .$3${NC}\n" echo -e "${RED} Exiting.${NC}\n" else - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 fi rm -f $TMP_FILE clear -x diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index ad80fa90e0..b66ac2ee46 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="9" +CFG_VERSION="8" ####################### From d2bf44ef2a764a2192c5a8387ffa3434e0a6fba4 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 22:37:53 -0500 Subject: [PATCH 098/203] Testing cfg ver check fix --- script-cfg/MiscFunctions.cfg | 4 +++- script-cfg/NetworkFunctions.cfg | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index f1c0e061c3..b1664cd618 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -108,13 +108,15 @@ checkScriptVer() # Check for functions updates checkCfgVer() { + local currentcfgver=$(grep "^CFG_VERSION" "$PWD/script-cfg/$2" | awk -F'[="]' '{print $3}') + # create temp file and download current file to use for comparison TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") curl -s -L "$1/script-cfg/$2" > ${TMP_FILE} NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') # download new file if available - if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then + if [ "${currentcfgver}" -ne "${NEW_VER}" ]; then wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error:${NC}\n" diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index b66ac2ee46..ad80fa90e0 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="8" +CFG_VERSION="9" ####################### From c99ad2e6dd4a870d1d58779738c230b03dc5653e Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 22:39:33 -0500 Subject: [PATCH 099/203] Another test of cfg check --- script-cfg/NetworkFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index ad80fa90e0..4f5a20d201 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="9" +CFG_VERSION="10" ####################### From 49116c2f4c79a04f0707e4fa1e106b43e2e1e2cd Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 22:47:00 -0500 Subject: [PATCH 100/203] Corrected cfg check after test --- script-cfg/MiscFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index b1664cd618..fb694814bb 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -116,7 +116,7 @@ checkCfgVer() NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') # download new file if available - if [ "${currentcfgver}" -ne "${NEW_VER}" ]; then + if [ "$currentcfgver" -ne "${NEW_VER}" ]; then wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error:${NC}\n" From f9a1343f2707112b7f8dcd5fc64b2574c81235fe Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 22:50:57 -0500 Subject: [PATCH 101/203] Corrected cfg check after test --- script-cfg/MiscFunctions.cfg | 12 +++++++----- script-cfg/NetworkFunctions.cfg | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 47ce0299c7..aecc682b29 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -92,10 +92,10 @@ checkScriptVer() echo -e "${RED} Error:${NC}\n" echo -e "${RED} Old $3 detected.${NC}\n" echo -e "${RED} The latest version has been downloaded.${NC}\n" - echo -e "${RED} Please re-run .$3${NC}\n" + echo -e "${RED} Please re-run $3${NC}\n" echo -e "${RED} Exiting.${NC}\n" else - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 fi rm -f $TMP_FILE clear -x @@ -108,22 +108,24 @@ checkScriptVer() # Check for functions updates checkCfgVer() { + local currentcfgver=$(grep "^CFG_VERSION" "$PWD/script-cfg/$2" | awk -F'[="]' '{print $3}') + # create temp file and download current file to use for comparison TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") curl -s -L "$1/script-cfg/$2" > ${TMP_FILE} NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') # download new file if available - if [ "$CFG_VERSION" -ne "${NEW_VER}" ]; then + if [ "$currentcfgver" -ne "${NEW_VER}" ]; then wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error:${NC}\n" echo -e "${RED} Old $2 detected.${NC}\n" echo -e "${RED} The latest version has been downloaded.${NC}\n" - echo -e "${RED} Please re-run .$3${NC}\n" + echo -e "${RED} Please re-run $3${NC}\n" echo -e "${RED} Exiting.${NC}\n" else - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run .$3" 10 40 + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 fi rm -f $TMP_FILE clear -x diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index ad80fa90e0..4f5a20d201 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="9" +CFG_VERSION="10" ####################### From 3c202717a87c79a13cb7f9b00d5953cad3189c08 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 23:22:27 -0500 Subject: [PATCH 102/203] Further update for localhost detection --- script-cfg/NetworkFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index 4f5a20d201..cac3db4436 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -44,7 +44,7 @@ configHosts() # 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 - CHECK_LOCALHOST=$(grep "127.0.0.1" /etc/hosts) + CHECK_LOCALHOST=$(grep "127.0.0.1" /etc/hosts | grep "localhost") if ! [[ $CHECK_LOCALHOST ]]; then echo -e "${GREEN} Adding localhost to hosts file${NC}\n" sudo sed -i "1i 127.0.0.1\tlocalhost" /etc/hosts From 9c25e09c1df52747a15a203ccc99122d566bfc20 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 27 Jun 2022 23:23:22 -0500 Subject: [PATCH 103/203] Further update for localhost detection --- script-cfg/NetworkFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index 4f5a20d201..cac3db4436 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -44,7 +44,7 @@ configHosts() # 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 - CHECK_LOCALHOST=$(grep "127.0.0.1" /etc/hosts) + CHECK_LOCALHOST=$(grep "127.0.0.1" /etc/hosts | grep "localhost") if ! [[ $CHECK_LOCALHOST ]]; then echo -e "${GREEN} Adding localhost to hosts file${NC}\n" sudo sed -i "1i 127.0.0.1\tlocalhost" /etc/hosts From 4abaef76c9ec85db7cfbe5153b044b563c94b351 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 28 Jun 2022 11:07:36 -0500 Subject: [PATCH 104/203] Fix to prevent config hosts running twice --- script-cfg/NetworkFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index cac3db4436..aff2720879 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -57,7 +57,7 @@ configHosts() setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; setSiteHostname "$meshhost" "$rootdomain"; - else + elif [ "$1" != "devinstall" ]; then setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; setSiteHostname "$meshhost" "$rootdomain"; From d8d6a92695d7fab7603cb0020737b9944803aa65 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 28 Jun 2022 11:11:03 -0500 Subject: [PATCH 105/203] Test fix for frontend devinstall --- script-cfg/InstallFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index d21e1e50d7..3e02d56f31 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -168,7 +168,7 @@ installFrontEnd() if [ "$1" == "update" ]; then sudo rm -rf /var/www/rmm/dist - elif [ "$1" == "restore" ] || [ "$1" == "install" ]; then + elif [ "$1" == "restore" ] || [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then sudo mkdir -p /var/www/rmm fi sudo tar -xzf /tmp/${webtar} -C /var/www/rmm From a4c79cc4afdec96edb43edf81fbd85887e048e47 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 28 Jun 2022 11:49:30 -0500 Subject: [PATCH 106/203] Updates to resolve devinstall issues --- script-cfg/ConfigAndServiceFunctions.cfg | 2 +- script-cfg/InstallFunctions.cfg | 52 +++++++++++++----------- script-cfg/ParentFunctions.cfg | 4 +- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 5335194e23..0fa9a7e2b7 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -90,7 +90,7 @@ configureBackend() rmmdomain=$(python manage.py get_config api) WEB_VERSION=$(python manage.py get_config webversion) deactivate - elif [ "$1" == "install" ]; then + elif [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then cd /rmm/api python3.10 -m venv env source /rmm/api/env/bin/activate diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 3e02d56f31..4f1d06181d 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -44,36 +44,40 @@ setInstallRepos() # Install MongoDB installMongo() { - wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/mongo.gpg > /dev/null - 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 - sleep 5 + if [ "$1" != "devinstall" ]; then + wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/mongo.gpg > /dev/null + 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 + sleep 5 + fi } # Install NodeJS installNodeJS() { - if [ "$1" == "update" ]; then - HAS_NODE16=$(node --version | grep v16) - if ! [ $HAS_NODE16 ]; then - echo -e "${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 + if [ "$1" != "devinstall" ]; then + if [ "$1" == "update" ]; then + HAS_NODE16=$(node --version | grep v16) + if ! [ $HAS_NODE16 ]; then + echo -e "${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 + fi + fi + 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 + if [ "$1" == "update" ]; then + sudo chown "${USER}:${USER}" -R /meshcentral + cd /meshcentral + rm -rf node_modules/ + npm install meshcentral@"${LATEST_MESH_VER}" + sudo systemctl start meshcentral fi - fi - 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 - if [ "$1" == "update" ]; then - sudo chown "${USER}:${USER}" -R /meshcentral - cd /meshcentral - rm -rf node_modules/ - npm install meshcentral@"${LATEST_MESH_VER}" - sudo systemctl start meshcentral fi } diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 89924678fd..219a7c1353 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -50,13 +50,13 @@ mainInstall() # Misc functions print_green 'Installing NodeJS'; # InstallFunctions - installNodeJS; + installNodeJS "$INSTALL_TYPE"; # Install and enable MongoDB # Misc functions print_green 'Installing MongoDB'; # InstallFunctions - installMongo; + installMongo "$INSTALL_TYPE"; # Install Python # Misc functions From 0987cdf69eff5be863973493d32e48239d63ab93 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 29 Jun 2022 16:42:26 -0500 Subject: [PATCH 107/203] added checks for dns entry verification --- installer-util.sh | 15 ++++-- script-cfg/CertificateFunctions.cfg | 23 ++++++++ script-cfg/UserInput.cfg | 83 +++++++++++++++++++++-------- 3 files changed, 96 insertions(+), 25 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 3584281d40..11a1543c56 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -151,9 +151,18 @@ if [ "$autoinstall" == "1" ]; then # Check subdomains are valid format # User Input - subdomainCheck "$rmmhost" "api"; - subdomainCheck "$meshhost" "mesh"; - subdomainCheck "$frontendhost" "rmm"; + subdomainFormatCheck "$rmmhost" "api"; + subdomainFormatCheck "$meshhost" "mesh"; + subdomainFormatCheck "$frontendhost" "rmm"; + + # Check that entries resolve via dns + # User Input + rmmdomain="$rmmhost.$rootdomain" + frontenddomain="$frontendhost.$rootdomain" + meshdomain="$meshhost.$rootdomain" + checkDNSEntriesExist "$rmmdomain"; + checkDNSEntriesExist "$frontenddomain"; + checkDNSEntriesExist "$meshdomain"; # Check that cert file exists # User Input diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index b31a0154a0..83c712ad85 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -9,6 +9,26 @@ CFG_VERSION="8" # Certificate Functions # ########################### + +# Check that acme challenge dns entry exists +acmeChallengeCheck() +{ + local acmegood="n" + + until [ "$acmegood" == "y" ]; do + if [[ $(dig +noall +answer -t TXT _acme-challenge.$1) ]] 2>/dev/null; then + acmegood="y" + echo -e "${GREEN} Acme Challenge TXT record available.${NC}\n" + echo -e "${GREEN} Continuing...${NC}" + else + echo -e "${YELLOW} Acme Challenge TXT record not available yet.${NC}\n" + echo -e "${YELLOW} Trying again in 30 sec...${NC}\n" + acmegood="n" + sleep 30 + fi + done +} + # Renew Certs renewCerts() { @@ -52,6 +72,9 @@ generateCerts() # Get initial DNS text entry sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email + # Ensure TXT record has populated + acmeChallengeCheck "$rootdomain"; + # Keep going until successful cert issue after adding DNS txt entry while [[ $? -ne 0 ]]; do sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index 9deeb90ae0..4cb324ccf4 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -93,14 +93,27 @@ generateUsersAndPass() } # Check subdomain provided is valid format -subdomainCheck() +subdomainFormatCheck() { if [[ $1 = *[.]*[.]* ]] || [[ $1 = *[.]* ]]; then - echo -e "Error: The $2 hostname/subdomain you provided is in the incorrect format." - echo -e "\n" - echo -e "Do not include the root domain." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for further details." + echo -e "Error: The $2 hostname/subdomain you provided is in the incorrect format.\n" + echo -e "Do not include the root domain.\n" + echo -e "Run $THIS_SCRIPT -h help for further details.\n" + echo -e "Exiting...\n" + clear -x + exit 1 + fi +} + +# Check host/domain entries exist in DNS +checkDNSEntriesExist() +{ + if [[ $(dig +noall +answer $1) ]] 2>/dev/null; then + echo -e "DNS record for $1 exists.\n" + else + echo -e "Error: $1 does not resolve via DNS.\n" + echo -e "Please correct the issue and run $THIS_SCRIPT again.\n" + echo -e "Exiting...\n" clear -x exit 1 fi @@ -110,9 +123,9 @@ subdomainCheck() checkCertExists() { if [ ! -f "$1" ]; then - echo -e "Error: The $2 path and/or filename you provided is invalid." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for further details." + echo -e "Error: The $2 path and/or filename you provided is invalid.\n" + echo -e "Run $THIS_SCRIPT -h help for further details.\n" + echo -e "Exiting...\n" clear -x exit 1 fi @@ -127,6 +140,7 @@ getHostAndDomainInfo() until [ $hostsconfirm == "y" ]; do rootdomain="none" letsemail="none" + local dnsgood="n" # Get root domain while [[ $rootdomain != *[.]* ]]; do @@ -138,16 +152,48 @@ getHostAndDomainInfo() done # Get backend hostname - rmmhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Backend Hostname" --inputbox "Enter the hostname for the backend (e.g. api):" 10 90 3>&1 1>&2 2>&3) - rmmhost="$(translateToLowerCase $rmmhost)" + until [ $dnsgood == "y" ]; do + rmmhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Backend Hostname" --inputbox "Enter the hostname for the backend (e.g. api):" 10 90 3>&1 1>&2 2>&3) + rmmhost="$(translateToLowerCase $rmmhost)" + rmmdomain="$rmmhost.$rootdomain" + if [[ $(dig +noall +answer $rmmdomain) ]] 2>/dev/null; then + dnsgood="y" + else + derpDerp; + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$rmmdomain does not resolve via DNS.\n\nPlease correct the issue before trying again." 0 0 + dnsgood="n" + fi + done + dnsgood="n" # Get frontend hostname - frontendhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Frontend Hostname" --inputbox "Enter the hostname for the frontend (e.g. rmm):" 10 90 3>&1 1>&2 2>&3) - frontendhost="$(translateToLowerCase $frontendhost)" + until [ $dnsgood == "y" ]; do + frontendhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Frontend Hostname" --inputbox "Enter the hostname for the frontend (e.g. rmm):" 10 90 3>&1 1>&2 2>&3) + frontendhost="$(translateToLowerCase $frontendhost)" + frontenddomain="$frontendhost.$rootdomain" + if [[ $(dig +noall +answer $frontenddomain) ]] 2>/dev/null; then + dnsgood="y" + else + derpDerp; + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$frontenddomain does not resolve via DNS.\n\nPlease correct the issue before trying again." 0 0 + dnsgood="n" + fi + done + dnsgood="n" # Get MeshCentral hostname - meshhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter MeshCentral Hostname" --inputbox "Enter the hostname for MeshCentral (e.g. mesh):" 10 90 3>&1 1>&2 2>&3) - meshhost="$(translateToLowerCase $meshhost)" + until [ $dnsgood == "y" ]; do + meshhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter MeshCentral Hostname" --inputbox "Enter the hostname for MeshCentral (e.g. mesh):" 10 90 3>&1 1>&2 2>&3) + meshhost="$(translateToLowerCase $meshhost)" + meshdomain="$meshhost.$rootdomain" + if [[ $(dig +noall +answer $meshdomain) ]] 2>/dev/null; then + dnsgood="y" + else + derpDerp; + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$meshdomain does not resolve via DNS.\n\nPlease correct the issue before trying again." 0 0 + dnsgood="n" + fi + done if [ "$1" != "TS" ]; then # Get Admin email @@ -171,11 +217,4 @@ getHostAndDomainInfo() done clear -x fi - - if [ "$1" != "TS" ]; then - # Combine host/domain entries for later use while keeping seperate entries as well - rmmdomain="$rmmhost.$rootdomain" - meshdomain="$meshhost.$rootdomain" - frontenddomain="$frontendhost.$rootdomain" - fi } \ No newline at end of file From d4beb888aa1cc21bc50bc0a88733928d43c5d051 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 29 Jun 2022 17:12:56 -0500 Subject: [PATCH 108/203] Added additional dns checks --- installer-util.sh | 13 +++---- script-cfg/UserInput.cfg | 73 ++++++++++++++++++++++++++++++---------- 2 files changed, 59 insertions(+), 27 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 11a1543c56..b8028483fe 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -131,15 +131,6 @@ if [ "$autoinstall" == "1" ]; then exit 1 fi - # Check root domain is valid format - if [[ $rootdomain != *[.]* ]]; then - echo -e "Error: You've entered an invalid root domain." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for details on the correct format." - clear -x - exit 1 - fi - # Check that email address format is valid if [[ $letsemail != *[@]*[.]* ]]; then echo -e "Error: You've entered an invalid email address." @@ -155,6 +146,10 @@ if [ "$autoinstall" == "1" ]; then subdomainFormatCheck "$meshhost" "mesh"; subdomainFormatCheck "$frontendhost" "rmm"; + # Check root domain format is valid + # User Input + rootDomainFormatCheck "$rootdomain"; + # Check that entries resolve via dns # User Input rmmdomain="$rmmhost.$rootdomain" diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index 4cb324ccf4..fb92c7dc1d 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -95,7 +95,7 @@ generateUsersAndPass() # Check subdomain provided is valid format subdomainFormatCheck() { - if [[ $1 = *[.]*[.]* ]] || [[ $1 = *[.]* ]]; then + if [[ $(grep "\." <<< "$1") ]] 2>/dev/null; then echo -e "Error: The $2 hostname/subdomain you provided is in the incorrect format.\n" echo -e "Do not include the root domain.\n" echo -e "Run $THIS_SCRIPT -h help for further details.\n" @@ -105,6 +105,20 @@ subdomainFormatCheck() fi } +# Check root domain format +rootDomainFormatCheck() +{ + if [[ $(grep "\." <<< "$1") ]] 2>/dev/null; then + echo -e "Root domain format ok" + else + echo -e "Error: The root domain you provided is in the incorrect format.\n" + echo -e "Run $THIS_SCRIPT -h help for further details.\n" + echo -e "Exiting...\n" + clear -x + exit 1 + fi +} + # Check host/domain entries exist in DNS checkDNSEntriesExist() { @@ -143,11 +157,15 @@ getHostAndDomainInfo() local dnsgood="n" # Get root domain - while [[ $rootdomain != *[.]* ]]; do + while [[ "$rootdomain" == "none" ]]; do rootdomain=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Root Domain" --inputbox "Enter the root domain (eg example.com or example.co.uk):" 10 90 3>&1 1>&2 2>&3) rootdomain="$(translateToLowerCase $rootdomain)" - if [[ $rootdomain != *[.]* ]]; then + if [[ $(grep "\." <<< "$rootdomain") ]] 2>/dev/null; then + echo -e "" + else + rootdomain="none" derpDerp; + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "The root domain you provided is in the incorrect format\n\nPlease try again." 0 0 fi done @@ -155,13 +173,19 @@ getHostAndDomainInfo() until [ $dnsgood == "y" ]; do rmmhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Backend Hostname" --inputbox "Enter the hostname for the backend (e.g. api):" 10 90 3>&1 1>&2 2>&3) rmmhost="$(translateToLowerCase $rmmhost)" - rmmdomain="$rmmhost.$rootdomain" - if [[ $(dig +noall +answer $rmmdomain) ]] 2>/dev/null; then - dnsgood="y" - else + if [[ $(grep "\." <<< "$rmmhost") ]] 2>/dev/null; then derpDerp; - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$rmmdomain does not resolve via DNS.\n\nPlease correct the issue before trying again." 0 0 + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "The backend hostname/subdomain you provided is in the incorrect format.\n\nDo not include the root domain.\n\nPlease try again." 0 0 dnsgood="n" + else + rmmdomain="$rmmhost.$rootdomain" + if [[ $(dig +noall +answer $rmmdomain) ]] 2>/dev/null; then + dnsgood="y" + else + derpDerp; + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$rmmdomain does not resolve via DNS.\n\nPlease correct the issue before trying again." 0 0 + dnsgood="n" + fi fi done dnsgood="n" @@ -170,13 +194,19 @@ getHostAndDomainInfo() until [ $dnsgood == "y" ]; do frontendhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Frontend Hostname" --inputbox "Enter the hostname for the frontend (e.g. rmm):" 10 90 3>&1 1>&2 2>&3) frontendhost="$(translateToLowerCase $frontendhost)" - frontenddomain="$frontendhost.$rootdomain" - if [[ $(dig +noall +answer $frontenddomain) ]] 2>/dev/null; then - dnsgood="y" - else + if [[ $(grep "\." <<< "$frontendhost") ]] 2>/dev/null; then derpDerp; - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$frontenddomain does not resolve via DNS.\n\nPlease correct the issue before trying again." 0 0 + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "The frontend hostname/subdomain you provided is in the incorrect format.\n\nDo not include the root domain.\n\nPlease try again." 0 0 dnsgood="n" + else + frontenddomain="$frontendhost.$rootdomain" + if [[ $(dig +noall +answer $frontenddomain) ]] 2>/dev/null; then + dnsgood="y" + else + derpDerp; + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$frontenddomain does not resolve via DNS.\n\nPlease correct the issue before trying again." 0 0 + dnsgood="n" + fi fi done dnsgood="n" @@ -185,13 +215,19 @@ getHostAndDomainInfo() until [ $dnsgood == "y" ]; do meshhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter MeshCentral Hostname" --inputbox "Enter the hostname for MeshCentral (e.g. mesh):" 10 90 3>&1 1>&2 2>&3) meshhost="$(translateToLowerCase $meshhost)" - meshdomain="$meshhost.$rootdomain" - if [[ $(dig +noall +answer $meshdomain) ]] 2>/dev/null; then - dnsgood="y" - else + if [[ $(grep "\." <<< "$meshhost") ]] 2>/dev/null; then derpDerp; - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$meshdomain does not resolve via DNS.\n\nPlease correct the issue before trying again." 0 0 + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "The meshcentral hostname/subdomain you provided is in the incorrect format.\n\nDo not include the root domain.\n\nPlease try again." 0 0 dnsgood="n" + else + meshdomain="$meshhost.$rootdomain" + if [[ $(dig +noall +answer $meshdomain) ]] 2>/dev/null; then + dnsgood="y" + else + derpDerp; + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$meshdomain does not resolve via DNS.\n\nPlease correct the issue before trying again." 0 0 + dnsgood="n" + fi fi done @@ -202,6 +238,7 @@ getHostAndDomainInfo() letsemail="$(translateToLowerCase $letsemail)" if [[ $letsemail != *[@]*[.]* ]]; then derpDerp; + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "The e-mail address you entered is not correctly formatted.\n\nPlease try again." 0 0 fi done From 1498514b6814bb53d967e521f7e74a2cbf5d6d0d Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 29 Jun 2022 18:19:07 -0500 Subject: [PATCH 109/203] Added url verification for selected repo --- installer-util.sh | 4 ++ script-cfg/MiscFunctions.cfg | 84 ++++++++++++++++++++++++------------ 2 files changed, 60 insertions(+), 28 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index b8028483fe..2f901068f8 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -164,6 +164,10 @@ if [ "$autoinstall" == "1" ]; then checkCertExists "$sslcacert" "CA Chain"; checkCertExists "$sslcert" "Fullchain Cert"; checkCertExists "$sslkey" "Private Key"; + + # Verify repo exists + # MiscFunctions + verifyRepoExists "$SCRIPT_URL"; fi # Set colors diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index aecc682b29..f9b99a6a72 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -285,42 +285,70 @@ cloneScriptsRepo() fi } +# Verify repo exists +verifyRepoExists() +{ + local repostatus=$(curl --output /dev/null --silent --write-out "%{http_code}" "$1") + if [ "$repostatus" == "200" ]; then + echo -e "Repo exists" + else + echo -e "The Tactical RMM repository you entered does not exist.\n" + echo -e "Please try again.\n" + echo -e "Exiting...\n" + clear -x + exit 1 + fi +} + # Set primary repos to use decideMainRepos() { userconfirm="n" local own="" local bran="" + local repostatus="" + local goodrepo="n" + + until [ "$goodrepo" == "y" ]; do + # prompt for repo owner info and verify before proceeding + until [ "$userconfirm" == "y" ]; do + own=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository" --inputbox "Enter the dev repo owner name.\nThis is right after github.com in the URL:" 10 90 3>&1 1>&2 2>&3) + own="$(translateToLowerCase $own)" + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository" --yesno "Is this correct?\n$own" 0 0 + case $? in + 0 ) userconfirm="y" + clear -x;; + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + REPO_OWNER="$own" + + # prompt for branch info and verify before proceeding + until [ "$userconfirm" == "y" ]; do + bran=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository Branch" --inputbox "Enter the dev repo branch name.\nThis is right after tacticalrmm in the URL:" 10 90 3>&1 1>&2 2>&3) + bran="$(translateToLowerCase $bran)" + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository Branch" --yesno "Is this correct?\n$bran" 0 0 + case $? in + 0 ) userconfirm="y" + clear -x;; + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + BRANCH="$bran" - # prompt for repo owner info and verify before proceeding - until [ "$userconfirm" == "y" ]; do - own=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository" --inputbox "Enter the dev repo owner name.\nThis is right after github.com in the URL:" 10 90 3>&1 1>&2 2>&3) - own="$(translateToLowerCase $own)" - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository" --yesno "Is this correct?\n$own" 0 0 - case $? in - 0 ) userconfirm="y" - clear -x;; - 1 ) userconfirm="n" - derpDerp;; - esac - done - userconfirm="n" - REPO_OWNER="$own" - - # prompt for branch info and verify before proceeding - until [ "$userconfirm" == "y" ]; do - bran=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository Branch" --inputbox "Enter the dev repo branch name.\nThis is right after tacticalrmm in the URL:" 10 90 3>&1 1>&2 2>&3) - bran="$(translateToLowerCase $bran)" - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Select Repository Branch" --yesno "Is this correct?\n$bran" 0 0 - case $? in - 0 ) userconfirm="y" - clear -x;; - 1 ) userconfirm="n" - derpDerp;; - esac + repostatus=$(curl --output /dev/null --silent --write-out "%{http_code}" "$SCRIPT_URL") + if [ "$repostatus" == "200" ]; then + goodrepo="y" + else + goodrepo="n" + derpDerp; + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "The Tactical RMM repository you entered does not exist.\n\nPlease try again." 0 0 + fi done - userconfirm="n" - BRANCH="$bran" # Check for new functions versions, include url, filename, and script name as variables for i in "${cfgfiles[@]}" From f9e283761ffe5f36a34f9f03c36279b0ee3b0d9e Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 30 Jun 2022 19:00:13 -0500 Subject: [PATCH 110/203] Added functions to verify minimum specs --- installer-util.sh | 28 ++++++++-------- script-cfg/MiscFunctions.cfg | 8 ++--- script-cfg/SystemInfoFunctions.cfg | 52 ++++++++++++++++++++++++++++++ script-cfg/UserInput.cfg | 2 +- 4 files changed, 71 insertions(+), 19 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 2f901068f8..77053b3cd5 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -104,38 +104,33 @@ done if [ "$autoinstall" == "1" ]; then # Check all required input is available if [ -z "$INSTALL_TYPE" ] || [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]; then - echo -e "Error: To perform an automated installation, you must provide all required information." - echo -e "\n" - echo -e "install type, api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for further details." + echo -e "${RED} Error: To perform an automated installation, you must provide all required information.${NC}\n" + echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required.${NC}\n" + echo -e "${RED} Run .$THIS_SCRIPT -h help for further details.${NC}" clear -x exit 1 fi # Check that install type is valid if [ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ]; then - echo -e "Error: You've selected an invalid installation type." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for details on the available options." + echo -e "${RED} Error: You've selected an invalid installation type.${NC}\n" + echo -e "${RED} Run .$THIS_SCRIPT -h help for details on the available options.${NC}" clear -x exit 1 fi # Check that repo and branch match install type if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]) && [ "$BRANCH" == "master" ]; then - echo -e "Error: You've selected a developer installation type, but not changed the repo, branch, or both." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for details on how to select them." + echo -e "${RED} Error: You've selected a developer installation type, but not changed the repo, branch, or both.${NC}\n" + echo -e "${RED} Run .$THIS_SCRIPT -h help for details on how to select them.${NC}" clear -x exit 1 fi # Check that email address format is valid if [[ $letsemail != *[@]*[.]* ]]; then - echo -e "Error: You've entered an invalid email address." - echo -e "\n" - echo -e "Run .$THIS_SCRIPT -h for details on the correct format." + echo -e "${RED} Error: You've entered an invalid email address.${NC}\n" + echo -e "${RED} Run .$THIS_SCRIPT -h help for details on the correct format.${NC}" clear -x exit 1 fi @@ -205,6 +200,11 @@ wutOSThis; # SystemInfoFunctions verifySupportedOS; +# Verify system meets minimum recommended specs +# SystemInfoFunctions +getTotalSystemMemory; +GetCPUAndThreadCount; + # Check if root # MiscFunctions checkRoot; diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index f9b99a6a72..8a74338265 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -290,11 +290,11 @@ verifyRepoExists() { local repostatus=$(curl --output /dev/null --silent --write-out "%{http_code}" "$1") if [ "$repostatus" == "200" ]; then - echo -e "Repo exists" + echo -e "${GREEN} Repo exists.${NC}\n" else - echo -e "The Tactical RMM repository you entered does not exist.\n" - echo -e "Please try again.\n" - echo -e "Exiting...\n" + echo -e "${RED} The Tactical RMM repository you entered does not exist.${NC}\n" + echo -e "${RED} Please try again.${NC}\n" + echo -e "${RED} Exiting...${NC}\n" clear -x exit 1 fi diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 2248ba1080..2ff171ae0d 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -65,4 +65,56 @@ checkLocale() clear -x exit 1 fi +} + +getTotalSystemMemory() +{ + local totsysmemory=$(grep MemTotal /proc/meminfo | awk '{print $2 / 1024 / 1000}' | cut -d '.' -f1) + + if [ $totsysmemory -ge 2 ]; then + return + else + if [ "$autoinstall" == "1" ]; then + echo -e "${RED} Error: System does not meet the minimum recommended RAM amount of 2GB.${NC}\n" + echo -e "${RED} Please add RAM to the system to prevent potential issues during install.${NC}\n" + echo -e "${RED} Re-run $THIS_SCRIPT after resolving the issue.${NC}\n" + echo -e "${RED} Exiting...${NC}\n" + clear -x + exit 1 + elif [ "$autoinstall" != "1" ]; then + dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended RAM amount of 2GB.\n\nYou may experience issues during install.\n\nIt's recommended to exit and add RAM to the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 + case $? in + 0 ) return;; + + 1 ) clear -x + exit 1;; + esac + fi + fi +} + +GetCPUAndThreadCount() +{ + local threadcount=$(nproc) + + if [ $threadcount -ge 2 ]; then + return + else + if [ "$autoinstall" == "1" ]; then + echo -e "${RED} Error: System does not meet the minimum recommended CPU core or thread count of 2.${NC}\n" + echo -e "${RED} Please upgrade the system to prevent potential issues with performance during install and use.${NC}\n" + echo -e "${RED} Re-run $THIS_SCRIPT after resolving the issue.${NC}\n" + echo -e "${RED} Exiting...${NC}\n" + clear -x + exit 1 + elif [ "$autoinstall" != "1" ]; then + dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended CPU core or thread count of 2.\n\nYou may experience issues during install and use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 + case $? in + 0 ) return;; + + 1 ) clear -x + exit 1;; + esac + fi + fi } \ No newline at end of file diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index fb92c7dc1d..4692cde774 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -23,7 +23,7 @@ generateUsersAndPass() 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) else - dialog --cr-wrap --clear --yes-label "Automatic" --no-label "Manual" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "User and Password Generation" --yesno "Would you like to have usernames and passwords automatically randomly generated, or enter your own manually?" 0 0 + dialog --cr-wrap --clear --yes-label "Automatic" --no-label "Manual" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "User and Password Generation" --yesno "Would you like to have Postgresql and MeshCentral usernames and passwords automatically randomly generated, or enter your own manually?" 0 0 case $? in # auto gen info for user 0 ) MESHPASSWD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 25 | head -n 1) From cd882346fc5fa0949c406e36a41ba7cd7f6a08cf Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 30 Jun 2022 19:03:08 -0500 Subject: [PATCH 111/203] Fixed sysinfo function names --- installer-util.sh | 3 ++- script-cfg/SystemInfoFunctions.cfg | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 77053b3cd5..a562f67d0f 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -203,7 +203,8 @@ verifySupportedOS; # Verify system meets minimum recommended specs # SystemInfoFunctions getTotalSystemMemory; -GetCPUAndThreadCount; +getCPUAndThreadCount; + # Check if root # MiscFunctions diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 2ff171ae0d..d9c0fcc712 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -93,7 +93,7 @@ getTotalSystemMemory() fi } -GetCPUAndThreadCount() +getCPUAndThreadCount() { local threadcount=$(nproc) From 280195d5d1137fe6b1fe286cb075021f4fb326d2 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 30 Jun 2022 19:36:57 -0500 Subject: [PATCH 112/203] Added check for storage capacity --- installer-util.sh | 6 ++--- script-cfg/SystemInfoFunctions.cfg | 35 +++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index a562f67d0f..b2a6075032 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -202,9 +202,9 @@ verifySupportedOS; # Verify system meets minimum recommended specs # SystemInfoFunctions -getTotalSystemMemory; -getCPUAndThreadCount; - +checkTotalSystemMemory; +checkCPUAndThreadCount; +checkStorageCapacity; # Check if root # MiscFunctions diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index d9c0fcc712..dfbef7daa8 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -67,7 +67,8 @@ checkLocale() fi } -getTotalSystemMemory() +# Check total system memory +checkTotalSystemMemory() { local totsysmemory=$(grep MemTotal /proc/meminfo | awk '{print $2 / 1024 / 1000}' | cut -d '.' -f1) @@ -93,7 +94,8 @@ getTotalSystemMemory() fi } -getCPUAndThreadCount() +# Check cpu core/thread count +checkCPUAndThreadCount() { local threadcount=$(nproc) @@ -117,4 +119,31 @@ getCPUAndThreadCount() esac fi fi -} \ No newline at end of file +} + +# Check storage capacity available +checkStorageCapacity() +{ + local totalstorage=$(df -h / | grep 'dev' | cut -d " " -f3 | tr -dc '[0-9]') + + if [ $totalstorage -ge 20 ]; then + return + else + if [ "$autoinstall" == "1" ]; then + echo -e "${RED} Error: System does not meet the minimum recommended storage capacity of 20GB.${NC}\n" + echo -e "${RED} Please upgrade the system to prevent potential issues during use.${NC}\n" + echo -e "${RED} Re-run $THIS_SCRIPT after resolving the issue.${NC}\n" + echo -e "${RED} Exiting...${NC}\n" + clear -x + exit 1 + elif [ "$autoinstall" != "1" ]; then + dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended storage capacity of 20GB.\n\nYou may experience issues during use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 + case $? in + 0 ) return;; + + 1 ) clear -x + exit 1;; + esac + fi + fi +} From 38aeaed775a16f81713511e9a146f95a27de3dcf Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 1 Jul 2022 15:45:47 -0500 Subject: [PATCH 113/203] Added further edits for automated runs --- installer-util.sh | 86 +++++++---- script-cfg/CertificateFunctions.cfg | 6 +- script-cfg/InstallFunctions.cfg | 58 +++---- script-cfg/MiscFunctions.cfg | 48 +++--- script-cfg/NetworkFunctions.cfg | 3 +- script-cfg/ParentFunctions.cfg | 8 +- script-cfg/SystemInfoFunctions.cfg | 46 ++---- script-cfg/TroubleshootingFunctions.cfg | 13 +- script-cfg/UpdateRestoreFunctions.cfg | 78 ++++++---- script-cfg/UserInput.cfg | 192 ++++++++++++------------ 10 files changed, 284 insertions(+), 254 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index b2a6075032..0372c0448f 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -41,6 +41,13 @@ sslkey="" sslcert="" trmmuser="" trmmpass="" +backupfile="" +troubleshoot="" + +# Check if directory exists, if not, create +if [ ! -d $PWD/script-cfg ]; then + mkdir $PWD/script-cfg +fi # Get cfg files function getCfgFiles() @@ -50,11 +57,6 @@ getCfgFiles() fi } -# Check if directory exists, if not, create -if [ ! -d $PWD/script-cfg ]; then - mkdir $PWD/script-cfg -fi - # Get cfg files for i in "${cfgfiles[@]}" do @@ -75,8 +77,12 @@ done . $PWD/script-cfg/TroubleshootingFunctions.cfg . $PWD/script-cfg/ParentFunctions.cfg +# Set colors +# MiscFunctions +setColors; + # Get commandline input -while getopts auto:api:branch:ca:cert:domain:email:h:key:mesh:pass:repo:rmm:username: option +while getopts auto:api:branch:ca:cert:domain:email:file:h:key:mesh:pass:repo:rmm:ts:update:username: option do case $option in auto ) autoinstall="1" @@ -87,6 +93,7 @@ do cert ) sslcert="${OPTARG}";; domain ) rootdomain="$(translateToLowerCase ${OPTARG})";; email ) letsemail="$(translateToLowerCase ${OPTARG})";; + file ) backupfile="${OPTARG}";; h ) helpText exit 1;; key ) sslkey="${OPTARG}";; @@ -94,44 +101,59 @@ do pass ) trmmpass="${OPTARG}";; repo ) REPO_OWNER="$(translateToLowerCase ${OPTARG})";; rmm ) frontendhost="$(translateToLowerCase ${OPTARG})";; + ts ) troubleshoot="1" + troubleShoot;; + update ) UPDATE_TYPE="$(translateToLowerCase ${OPTARG})";; username ) trmmuser="${OPTARG}";; \?) echo -e "Error: Invalid option" - clear -x + helpText exit 1;; esac done if [ "$autoinstall" == "1" ]; then - # Check all required input is available - if [ -z "$INSTALL_TYPE" ] || [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]; then - echo -e "${RED} Error: To perform an automated installation, you must provide all required information.${NC}\n" - echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required.${NC}\n" - echo -e "${RED} Run .$THIS_SCRIPT -h help for further details.${NC}" - clear -x + + # Check that update type is valid + if [ "$INSTALL_TYPE" == "update" ] && ([ "$UPDATE_TYPE" != "standard" ] && [ "$UPDATE_TYPE" != "forced" ]); then + echo -e "${RED} Error: You've selected update, but not selected an appropriate type.${NC}\n" + echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to select them.${NC}" + exit 1 + fi + + # Check that backup file exists + if [ "$INSTALL_TYPE" == "restore" ] && ([ -z "$backupfile" ] || [ ! -f "$backupfile" ]); then + echo -e "${RED} Error: You've selected restore, but not provided a valid backup file.${NC}\n" + echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to enter this.${NC}" exit 1 fi # Check that install type is valid - if [ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ]; then + if [ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ] && [ "$INSTALL_TYPE" != "update" ] && [ "$INSTALL_TYPE" != "restore" ]; then echo -e "${RED} Error: You've selected an invalid installation type.${NC}\n" - echo -e "${RED} Run .$THIS_SCRIPT -h help for details on the available options.${NC}" - clear -x + echo -e "${RED} Run $THIS_SCRIPT -h help for details on the available options.${NC}" + exit 1 + fi + + # Check all required input is available for install + if [ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" || "install" ]; then + if [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]; then + echo -e "${RED} Error: To perform an automated installation, you must provide all required information.${NC}\n" + echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required.${NC}\n" + echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}" exit 1 fi # Check that repo and branch match install type if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]) && [ "$BRANCH" == "master" ]; then echo -e "${RED} Error: You've selected a developer installation type, but not changed the repo, branch, or both.${NC}\n" - echo -e "${RED} Run .$THIS_SCRIPT -h help for details on how to select them.${NC}" - clear -x + echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to select them.${NC}" exit 1 fi # Check that email address format is valid if [[ $letsemail != *[@]*[.]* ]]; then echo -e "${RED} Error: You've entered an invalid email address.${NC}\n" - echo -e "${RED} Run .$THIS_SCRIPT -h help for details on the correct format.${NC}" - clear -x + echo -e "${RED} Run $THIS_SCRIPT -h help for details on the correct format.${NC}" exit 1 fi @@ -165,10 +187,6 @@ if [ "$autoinstall" == "1" ]; then verifyRepoExists "$SCRIPT_URL"; fi -# Set colors -# MiscFunctions -setColors; - # Gather OS info # SystemInfoFunctions getOSInfo; @@ -250,7 +268,7 @@ installMenu() 5 ) [ -f $INPUT ] && rm $INPUT clear -x exit;; - * ) derpDerp;; + \?) derpDerp;; esac done @@ -280,7 +298,8 @@ utilityMenu() 3 ) getHostAndDomainInfo renewCerts;; 4 ) if [ ! -f /etc/nginx/sites-available/rmm.conf ]; then - getHostAndDomainInfo "TS" + troubleshoot="1" + getHostAndDomainInfo else getExistingDomainInfo fi @@ -291,7 +310,7 @@ utilityMenu() 8 ) [ -f $INPUT ] && rm $INPUT clear -x exit;; - * ) derpDerp;; + \?) derpDerp;; esac done @@ -326,7 +345,7 @@ updateMenu() 5 ) [ -f $INPUT ] && rm $INPUT clear -x exit;; - * ) derpDerp;; + \?) derpDerp;; esac done @@ -336,8 +355,15 @@ updateMenu() # Main menu mainMenu() { - if [ "$autoinstall" == "1" ]; then + # Automated install types install, devprep, or devinstall + if [ "$autoinstall" == "1" ] && ([ "$INSTALL_TYPE" == "install" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "devprep" ]); then mainInstall; + # Automated update + elif [ "$autoinstall" == "1" ] && [ "$INSTALL_TYPE" == "update" ]; then + updateTRMM; + # Automated restore + elif [ "$autoinstall" == "1" ] && [ "$INSTALL_TYPE" == "restore" ]; then + restoreTRMM; else until [ "$menuselection" = "0" ]; do dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Main Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections." 0 0 0 \ @@ -355,7 +381,7 @@ mainMenu() 4 ) [ -f $INPUT ] && rm $INPUT clear -x exit;; - * ) derpDerp;; + \?) derpDerp;; esac done fi diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 83c712ad85..5ff4f93063 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -87,6 +87,10 @@ installCertbot() # Install Certbot sudo apt install -y certbot if [ "$1" == "restore" ]; then + # Generate DH if it doesn't exist + if [ ! -f /etc/ssl/certs/dhparam.pem ]; then + sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 + fi return fi @@ -114,7 +118,5 @@ installCertbot() # Generate DH if it doesn't exist if [ ! -f /etc/ssl/certs/dhparam.pem ]; then sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 - else - return fi } \ No newline at end of file diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 4f1d06181d..b73b0e8aba 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -184,36 +184,38 @@ installFrontEnd() # Install Nginx installNginx() { - if [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then - sudo apt install -y nginx - sudo systemctl stop nginx - sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf - sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf - elif [ "$1" == "updatepart1" ]; then - # Check Nginx config - if ! sudo nginx -t > /dev/null 2>&1; then - sudo nginx -t - echo -e "${RED} You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script.${NC}\n" - echo -e "${RED} Aborting...${NC}\n" - exit 1 - fi - elif [ "$1" == "updatepart2" ]; then - CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" /etc/nginx/nginx.conf) - if ! [ $CHECK_NGINX_WORKER_CONN ]; then - echo -e "${GREEN} Changing nginx worker connections to 2048${NC}\n" + if [ "$1" != "devinstall" ]; then + if [ "$1" == "install" ] || [ "$1" == "devprep" ]; then + sudo apt install -y nginx + sudo systemctl stop nginx + sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf + sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf + elif [ "$1" == "updatepart1" ]; then + # Check Nginx config + if ! sudo nginx -t > /dev/null 2>&1; then + sudo nginx -t + echo -e "${RED} You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script.${NC}\n" + echo -e "${RED} Aborting...${NC}\n" + exit 1 + fi + elif [ "$1" == "updatepart2" ]; then + CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" /etc/nginx/nginx.conf) + if ! [ $CHECK_NGINX_WORKER_CONN ]; then + echo -e "${GREEN} Changing nginx worker connections to 2048${NC}\n" + sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf + fi + sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf + elif [ "$1" == "restore" ]; then + sudo apt install -y nginx + sudo systemctl stop nginx + sudo rm -rf /etc/nginx + sudo mkdir /etc/nginx + sudo tar -xzf $tmp_dir/nginx/etc-nginx.tar.gz -C /etc/nginx sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf + sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf + # Misc functions + getExistingDomainInfo; fi - sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf - elif [ "$1" == "restore" ]; then - sudo apt install -y nginx - sudo systemctl stop nginx - sudo rm -rf /etc/nginx - sudo mkdir /etc/nginx - sudo tar -xzf $tmp_dir/nginx/etc-nginx.tar.gz -C /etc/nginx - sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf - sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf - # Misc functions - getExistingDomainInfo; fi } diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 8a74338265..a4ae8cb22e 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -57,24 +57,27 @@ print_yellow() # Command-line help function helpText() { - echo -e 'Syntax: ./installer-util.sh [-auto|api|branch|ca|cert|domain|email|help|key|mesh|pass|repo|rmm|username]' + echo -e 'Syntax: ./installer-util.sh [-auto|api|branch|ca|cert|domain|email|file|h|key|mesh|pass|repo|rmm|ts|update|username]' echo -e "" echo -e "Options:" echo -e "" - echo -e "auto Select type of automated installation. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC}, or${YELLOW} devinstall${NC}" - echo -e "api Provide the api hostname/subdomain, eg ${YELLOW}api${NC}.example.com" - echo -e "branch If performing a dev install, this will select the branch. eg, https://github.com/amidaware/tacticalrmm/${YELLOW}branch${NC}/.git" - echo -e "ca Full path to SSL CA Chain certificate for import. Must be in .pem format. Include the filename." - echo -e "cert Full path to SSL certificate for import. Must be in .pem format. Include the filename." - echo -e "domain Provide the root domain, eg rmm.${YELLOW}example.com${NC}" - echo -e "email Provide a valid email address for LetsEncrypt cert generation and primary T-RMM user" - echo -e "h Show this help text" - echo -e "key Full path to SSL private key for import. Must be in .pem format. Include the filename." - echo -e "mesh Provide the mesh hostname/subdomain, eg ${YELLOW}mesh${NC}.example.com" - echo -e "pass Provide the password for the initial T-RMM user" - echo -e "repo If performing a dev install, this will select the repo owner. eg, https://github.com/${YELLOW}repo-owner${NC}/tacticalrmm/master/.git" - echo -e "rmm Provide the rmm hostname/subdomain, eg ${YELLOW}rmm${NC}.example.com" - echo -e "username Provide the username for the initial T-RMM user" + echo -e "auto Select type of automated installation. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC}, or${YELLOW} devinstall${NC}." + echo -e "api Provide the api hostname/subdomain, eg ${YELLOW}api${NC}.example.com" + echo -e "branch If performing a dev install, this will select the branch. eg, https://github.com/amidaware/tacticalrmm/${YELLOW}branch${NC}/.git" + echo -e "ca Full path to SSL CA Chain certificate for import. Must be in .pem format. Include the filename." + echo -e "cert Full path to SSL certificate for import. Must be in .pem format. Include the filename." + echo -e "domain Provide the root domain, eg rmm.${YELLOW}example.com${NC}" + echo -e "email Provide a valid email address for LetsEncrypt cert generation and primary T-RMM user." + echo -e "file Provide the full path to the backup file, including file name." + echo -e "h Type help to show this help text." + echo -e "key Full path to SSL private key for import. Must be in .pem format. Include the filename." + echo -e "mesh Provide the mesh hostname/subdomain, eg ${YELLOW}mesh${NC}.example.com" + echo -e "pass Provide the password for the initial T-RMM user." + echo -e "repo If performing a dev install, this will select the repo owner. eg, https://github.com/${YELLOW}repo-owner${NC}/tacticalrmm/master/.git" + echo -e "rmm Provide the rmm hostname/subdomain, eg ${YELLOW}rmm${NC}.example.com" + echo -e "ts Enter ${YELLOW}trouble${NC} to perform troubleshooting functions." + echo -e "update Select update type. Options are ${YELLOW}standard${NC} or ${YELLOW} forced${NC}." + echo -e "username Provide the username for the initial T-RMM user." } # Check for new script version @@ -96,9 +99,9 @@ checkScriptVer() echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 + clear -x fi rm -f $TMP_FILE - clear -x exit 1 fi @@ -126,9 +129,9 @@ checkCfgVer() echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 + clear -x fi rm -f $TMP_FILE - clear -x exit 1 fi @@ -146,8 +149,8 @@ checkRoot() echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Do NOT run this script as root. Exiting." 0 0 + clear -x fi - clear -x exit 1 fi } @@ -170,8 +173,8 @@ checkTacticalUser() echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 + clear -x fi - clear -x exit 1 fi @@ -186,8 +189,8 @@ checkTacticalUser() echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 + clear -x fi - clear -x exit 1;; 1 ) print_yellow 'Tactical user does not exist. Creating now.' @@ -202,8 +205,8 @@ checkTacticalUser() echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Created" --msgbox "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting." 0 0 + clear -x fi - clear -x exit 1;; esac @@ -221,8 +224,8 @@ checkTacticalUser() echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Sudo Privileges Added" --msgbox "The Tactical user has been added to the sudo group.\nPlease log out of the tactical user, log back in, and try again.\n\nExiting." 0 0 + clear -x fi - clear -x exit 1;; esac fi @@ -295,7 +298,6 @@ verifyRepoExists() echo -e "${RED} The Tactical RMM repository you entered does not exist.${NC}\n" echo -e "${RED} Please try again.${NC}\n" echo -e "${RED} Exiting...${NC}\n" - clear -x exit 1 fi } diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index aff2720879..f4e786feb1 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -52,12 +52,13 @@ configHosts() CHECK_HOSTS=$(grep "127.0.1.1 $rmmdomain $frontenddomain $meshdomain" /etc/hosts) if [[ $CHECK_HOSTS ]]; then - echo -e "${GREEN} Correcting subdomains entries${NC}\n" + echo -e "${GREEN} Correcting subdomain entries${NC}\n" sudo sed -i "/127.0.1.1 $rmmdomain $frontenddomain $meshdomain/d" /etc/hosts setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; setSiteHostname "$meshhost" "$rootdomain"; elif [ "$1" != "devinstall" ]; then + echo -e "${GREEN} Adding subdomain entries${NC}\n" setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; setSiteHostname "$meshhost" "$rootdomain"; diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 219a7c1353..3682912aef 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -18,7 +18,7 @@ mainInstall() # Create usernames and passwords # User Input - generateUsersAndPass; + generateUsersAndPass "$INSTALL_TYPE"; # This does... something # Misc functions @@ -32,7 +32,7 @@ mainInstall() # Misc functions print_green 'Configuring Hosts file'; # Network functions - configHosts; + configHosts "$INSTALL_TYPE"; # Certificate generation # Misc functions @@ -529,7 +529,7 @@ restoreTRMM() # Extract backup # UpdateRestoreFunctions - extractBackup "$backuppath"; + extractBackup "$backupfile"; # Check if original user # UpdateRestoreFunctions @@ -736,7 +736,7 @@ troubleShoot() getExistingDomainInfo; else # User Input - getHostAndDomainInfo "TS"; + getHostAndDomainInfo; fi # Verify domains are live diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index dfbef7daa8..6df62c9016 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -99,25 +99,16 @@ checkCPUAndThreadCount() { local threadcount=$(nproc) - if [ $threadcount -ge 2 ]; then + if [ $threadcount -ge 2 ] || [ "$autoinstall" == "1" ]; then return else - if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error: System does not meet the minimum recommended CPU core or thread count of 2.${NC}\n" - echo -e "${RED} Please upgrade the system to prevent potential issues with performance during install and use.${NC}\n" - echo -e "${RED} Re-run $THIS_SCRIPT after resolving the issue.${NC}\n" - echo -e "${RED} Exiting...${NC}\n" - clear -x - exit 1 - elif [ "$autoinstall" != "1" ]; then - dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended CPU core or thread count of 2.\n\nYou may experience issues during install and use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 - case $? in - 0 ) return;; + dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended CPU core or thread count of 2.\n\nYou may experience issues during install and use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 + case $? in + 0 ) return;; - 1 ) clear -x - exit 1;; - esac - fi + 1 ) clear -x + exit 1;; + esac fi } @@ -126,24 +117,15 @@ checkStorageCapacity() { local totalstorage=$(df -h / | grep 'dev' | cut -d " " -f3 | tr -dc '[0-9]') - if [ $totalstorage -ge 20 ]; then + if [ $totalstorage -ge 20 ] || [ "$autoinstall" == "1" ]; then return else - if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error: System does not meet the minimum recommended storage capacity of 20GB.${NC}\n" - echo -e "${RED} Please upgrade the system to prevent potential issues during use.${NC}\n" - echo -e "${RED} Re-run $THIS_SCRIPT after resolving the issue.${NC}\n" - echo -e "${RED} Exiting...${NC}\n" - clear -x - exit 1 - elif [ "$autoinstall" != "1" ]; then - dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended storage capacity of 20GB.\n\nYou may experience issues during use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 - case $? in - 0 ) return;; + dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended storage capacity of 20GB.\n\nYou may experience issues during use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 + case $? in + 0 ) return;; - 1 ) clear -x - exit 1;; - esac - fi + 1 ) clear -x + exit 1;; + esac fi } diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index c756383f83..934f825e15 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -13,12 +13,11 @@ CFG_VERSION="8" pingDomain() { if ( ping -c 1 $1 &> /dev/null ); then - echo -e "${GREEN} Verified $1${NC}" | tee -a checklog.log + echo -e "${GREEN} Verified $1 by ping.${NC}" | tee -a checklog.log echo -e "\n" else - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "$1 doesnt exist please create it or check for a typo.\n\nYou will have a log file called checklog.log in the directory you ran this script from.\n\nExiting." 0 0 - clear -x - exit + echo -e "${RED} $1 cannot be verified by ping.${NC}" | tee -a checklog.log + echo -e "\n" fi } @@ -33,7 +32,7 @@ checkIPisLive() if [ "$locinputip" == "$reminputip" ]; then echo -e "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log - echo -e "\n" + echo -e "\n" else echo -e "${YELLOW} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log echo -e "\n" | tee -a checklog.log @@ -77,7 +76,7 @@ isPortOpen() echo -e "${GREEN} $2 Port is open.${NC}" | tee -a checklog.log echo -e "\n" else - echo -e "${RED} $2 port is closed. \(you may want this if running locally only\)${NC}" | tee -a checklog.log + echo -e "${YELLOW} $2 port is closed. \(you may want this if running locally only\)${NC}" | tee -a checklog.log echo -e "\n" fi } @@ -85,7 +84,7 @@ isPortOpen() # Check proxy checkProxy() { - echo -e "${YELLOW} Checking For Proxy.${NC}" | tee -a checklog.log + echo -e "${GREEN} Checking For Proxy.${NC}" | tee -a checklog.log echo -e "\n" echo -e "${YELLOW} ......this might take a while!!${NC}" diff --git a/script-cfg/UpdateRestoreFunctions.cfg b/script-cfg/UpdateRestoreFunctions.cfg index 7c9b25a6da..cc92e56c2c 100644 --- a/script-cfg/UpdateRestoreFunctions.cfg +++ b/script-cfg/UpdateRestoreFunctions.cfg @@ -19,12 +19,21 @@ checkSameUser() ORIGUSER=$(grep ${strip} $tmp_dir/systemd/rmm.service | sed -e "s/^${strip}//") fi if [ "$ORIGUSER" != "$USER" ]; then - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "You must run this update script from the same user account used during install: ${ORIGUSER}\n\nExiting." 0 0 - if [ "$1" == "restore" ]; then - rm -rf $tmp_dir + if [ "$autoinstall" == "1" ]; then + echo -e "${RED} You must run this update script from the same user account used during install: ${ORIGUSER}${NC}\n" + echo -e "${RED} Exiting...${NC}\n" + if [ "$1" == "restore" ]; then + rm -rf $tmp_dir + fi + exit 1 + elif [ "$autoinstall" != "1" ]; then + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "You must run this update script from the same user account used during install: ${ORIGUSER}\n\nExiting." 0 0 + if [ "$1" == "restore" ]; then + rm -rf $tmp_dir + fi + clear -x + exit 1 fi - clear -x - exit 1 fi } @@ -38,10 +47,16 @@ checkIfUpdate() CURRENT_TRMM_VER=$(grep "^TRMM_VERSION" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') if [ "${CURRENT_TRMM_VER}" == "${LATEST_TRMM_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then - # MiscFunctions - print_green "Already on latest version. Current version: ${CURRENT_TRMM_VER} Latest version: ${LATEST_TRMM_VER}\n"; - rm -f $TMP_SETTINGS - exit 0 + if [ "$autoinstall" == "1" ]; then + echo -e "${GREEN} Already on latest version. Current version:${NC} ${YELLOW}${CURRENT_TRMM_VER}${NC} ${GREEN}Latest version:${NC} ${YELLOW}${LATEST_TRMM_VER}${NC}\n" + rm -f $TMP_SETTINGS + exit 0 + elif [ "$autoinstall" != "1" ]; then + # MiscFunctions + print_green "Already on latest version. Current version: ${CURRENT_TRMM_VER} Latest version: ${LATEST_TRMM_VER}\n"; + rm -f $TMP_SETTINGS + exit 0 + fi fi } @@ -80,7 +95,7 @@ turnOffRedisAppendOnly() updateMeshCentral() { 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 + if [ "${CURRENT_MESH_VER}" != "${LATEST_MESH_VER}" ] || [ "$UPDATE_TYPE" = "forced" ]; then echo -e "${GREEN} Updating meshcentral from ${CURRENT_MESH_VER} to ${LATEST_MESH_VER}${NC}\n" sudo systemctl stop meshcentral sudo chown "${USER}:${USER}" -R /meshcentral @@ -94,26 +109,29 @@ updateMeshCentral() # Get backup location getBackupFileLocation() { - backuppath="" - userconfirm="n" - - until [ "$userconfirm" == "y" ]; do - backuppath=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Path to Backup File" --inputbox "Enter the full path to the backup file, including filename:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Backup File Path" --yesno "Is this correct?\n$backuppath" 0 0 - case $? in - 0 ) userconfirm="y";; - - 1 ) userconfirm="n" - derpDerp;; - esac - if [ ! -f "$backuppath" ]; then - userconfirm="n" - derpDerp; - else - userconfirm="y" - fi - done - userconfirm="n" + if [ "$autoinstall" == "1" ]; then + return + elif [ "$autoinstall" != "1" ]; then + userconfirm="n" + + until [ "$userconfirm" == "y" ]; do + backupfile=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Path to Backup File" --inputbox "Enter the full path to the backup file, including filename:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Backup File Path" --yesno "Is this correct?\n$backupfile" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + if [ ! -f "$backupfile" ]; then + userconfirm="n" + derpDerp; + else + userconfirm="y" + fi + done + userconfirm="n" + fi } # Extract backup diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index 4692cde774..536ad3491d 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -12,83 +12,85 @@ CFG_VERSION="8" # Create usernames and passwords generateUsersAndPass() { - # generate django key and admin url - DJANGO_SEKRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1) - ADMINURL=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 70 | head -n 1) - - # prompt to see if user wants to manually enter info or have it generated - if [ "$autoinstall" == "1" ]; then - 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) - else - dialog --cr-wrap --clear --yes-label "Automatic" --no-label "Manual" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "User and Password Generation" --yesno "Would you like to have Postgresql and MeshCentral usernames and passwords automatically randomly generated, or enter your own manually?" 0 0 - case $? in - # auto gen info for user - 0 ) 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) - clear -x;; - - 1 ) userconfirm="n" - - # Get MeshCentral admin username - until [ "$userconfirm" == "y" ]; do - meshusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --inputbox "Enter the MeshCentral Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --yesno "Is this correct?\n$meshusername" 0 0 - case $? in - 0 ) userconfirm="y";; - - 1 ) userconfirm="n" - derpDerp;; - esac - done - userconfirm="n" - - # Get MeshCentral admin password - MESHPASSWD="dont" - passinput="match" - until [ "$passinput" == "$MESHPASSWD" ]; do - MESHPASSWD=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Re-enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - if [ "$passinput" != "$MESHPASSWD" ]; then - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 - derpDerp; - else - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 - fi - done - - # Get Postgresql admin username - until [ "$userconfirm" == "y" ]; do - pgusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --inputbox "Enter the Postgresql Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) - dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --yesno "Is this correct?\n$pgusername" 0 0 - case $? in - 0 ) userconfirm="y";; - - 1 ) userconfirm="n" - derpDerp;; - esac - done - userconfirm="n" - - # Get Postgresql admin password - pgpw="dont" - passinput="match" - until [ "$passinput" == "$pgpw" ]; do - pgpw=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Re-enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - if [ "$passinput" != "$pgpw" ]; then - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 - derpDerp; - else - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 - fi - done - clear -x;; - esac + if [ "$1" != "devprep" ]; then + # generate django key and admin url + DJANGO_SEKRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1) + ADMINURL=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 70 | head -n 1) + + # prompt to see if user wants to manually enter info or have it generated + if [ "$autoinstall" == "1" ]; then + 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) + else + dialog --cr-wrap --clear --yes-label "Automatic" --no-label "Manual" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "User and Password Generation" --yesno "Would you like to have Postgresql and MeshCentral usernames and passwords automatically randomly generated, or enter your own manually?" 0 0 + case $? in + # auto gen info for user + 0 ) 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) + clear -x;; + + 1 ) userconfirm="n" + + # Get MeshCentral admin username + until [ "$userconfirm" == "y" ]; do + meshusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --inputbox "Enter the MeshCentral Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin" --yesno "Is this correct?\n$meshusername" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + + # Get MeshCentral admin password + MESHPASSWD="dont" + passinput="match" + until [ "$passinput" == "$MESHPASSWD" ]; do + MESHPASSWD=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Re-enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + if [ "$passinput" != "$MESHPASSWD" ]; then + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 + derpDerp; + else + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 + fi + done + + # Get Postgresql admin username + until [ "$userconfirm" == "y" ]; do + pgusername=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --inputbox "Enter the Postgresql Admin username you wish to use:" 10 90 3>&1 1>&2 2>&3) + dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin" --yesno "Is this correct?\n$pgusername" 0 0 + case $? in + 0 ) userconfirm="y";; + + 1 ) userconfirm="n" + derpDerp;; + esac + done + userconfirm="n" + + # Get Postgresql admin password + pgpw="dont" + passinput="match" + until [ "$passinput" == "$pgpw" ]; do + pgpw=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Postgresql Admin Password" --passwordbox "Re-enter the Postgresql Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + if [ "$passinput" != "$pgpw" ]; then + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 + derpDerp; + else + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "SUCCESS" --msgbox "Passwords match." 0 0 + fi + done + clear -x;; + esac + fi fi } @@ -96,11 +98,10 @@ generateUsersAndPass() subdomainFormatCheck() { if [[ $(grep "\." <<< "$1") ]] 2>/dev/null; then - echo -e "Error: The $2 hostname/subdomain you provided is in the incorrect format.\n" - echo -e "Do not include the root domain.\n" - echo -e "Run $THIS_SCRIPT -h help for further details.\n" - echo -e "Exiting...\n" - clear -x + echo -e "${RED} Error: The $2 hostname/subdomain you provided is in the incorrect format.${NC}\n" + echo -e "${RED} Do not include the root domain.${NC}\n" + echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}\n" + echo -e "${RED} Exiting...${NC}\n" exit 1 fi } @@ -109,12 +110,11 @@ subdomainFormatCheck() rootDomainFormatCheck() { if [[ $(grep "\." <<< "$1") ]] 2>/dev/null; then - echo -e "Root domain format ok" + echo -e "${GREEN} Root domain format ok.${NC}\n" else - echo -e "Error: The root domain you provided is in the incorrect format.\n" - echo -e "Run $THIS_SCRIPT -h help for further details.\n" - echo -e "Exiting...\n" - clear -x + echo -e "${RED} Error: The root domain you provided is in the incorrect format.${NC}\n" + echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}\n" + echo -e "${RED} Exiting...${NC}\n" exit 1 fi } @@ -123,12 +123,11 @@ rootDomainFormatCheck() checkDNSEntriesExist() { if [[ $(dig +noall +answer $1) ]] 2>/dev/null; then - echo -e "DNS record for $1 exists.\n" + echo -e "${GREEN} DNS record for $1 exists.${NC}\n" else - echo -e "Error: $1 does not resolve via DNS.\n" - echo -e "Please correct the issue and run $THIS_SCRIPT again.\n" - echo -e "Exiting...\n" - clear -x + echo -e "${RED} Error: $1 does not resolve via DNS.${NC}\n" + echo -e "${RED} Please correct the issue and run $THIS_SCRIPT again.${NC}\n" + echo -e "${RED} Exiting...${NC}\n" exit 1 fi } @@ -137,10 +136,9 @@ checkDNSEntriesExist() checkCertExists() { if [ ! -f "$1" ]; then - echo -e "Error: The $2 path and/or filename you provided is invalid.\n" - echo -e "Run $THIS_SCRIPT -h help for further details.\n" - echo -e "Exiting...\n" - clear -x + echo -e "${RED} Error: The $2 path and/or filename you provided is invalid.${NC}\n" + echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}\n" + echo -e "${RED} Exiting...${NC}\n" exit 1 fi } @@ -231,7 +229,7 @@ getHostAndDomainInfo() fi done - if [ "$1" != "TS" ]; then + if [ "$troubleshoot" != "1" ]; then # Get Admin email while [[ $letsemail != *[@]*[.]* ]]; do letsemail=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Admin E-Mail Address" --inputbox "Enter a valid e-mail address for Django, MeshCentral, and LetsEncrypt:" 10 90 3>&1 1>&2 2>&3) From 5e78998c70dd8ffaf219958562a9ce0fc7a2f3ea Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 1 Jul 2022 16:08:35 -0500 Subject: [PATCH 114/203] Added backup cli option --- installer-util.sh | 7 +++++-- script-cfg/InstallFunctions.cfg | 14 ++++++-------- script-cfg/MiscFunctions.cfg | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 0372c0448f..f42e6e9f7b 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -128,8 +128,8 @@ if [ "$autoinstall" == "1" ]; then fi # Check that install type is valid - if [ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ] && [ "$INSTALL_TYPE" != "update" ] && [ "$INSTALL_TYPE" != "restore" ]; then - echo -e "${RED} Error: You've selected an invalid installation type.${NC}\n" + if [ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ] && [ "$INSTALL_TYPE" != "update" ] && [ "$INSTALL_TYPE" != "restore" ] && [ "$INSTALL_TYPE" != "backup" ]; then + echo -e "${RED} Error: You've selected an invalid function type.${NC}\n" echo -e "${RED} Run $THIS_SCRIPT -h help for details on the available options.${NC}" exit 1 fi @@ -364,6 +364,9 @@ mainMenu() # Automated restore elif [ "$autoinstall" == "1" ] && [ "$INSTALL_TYPE" == "restore" ]; then restoreTRMM; + # Automated backup + elif [ "$autoinstall" == "1" ] && [ "$INSTALL_TYPE" == "backup" ]; then + backupTRMM; else until [ "$menuselection" = "0" ]; do dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Main Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections." 0 0 0 \ diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index b73b0e8aba..c9ca5b8590 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -161,20 +161,18 @@ installFrontEnd() if [ -d /rmm/web ]; then sudo rm -rf /rmm/web fi - - if [ ! -d /var/www/rmm ]; then - sudo mkdir -p /var/www/rmm + if [ -d /var/www/rmm/dist ]; then + sudo rm -rf /var/www/rmm/dist fi fi - + webtar="trmm-web-v${WEB_VERSION}.tar.gz" wget -q https://github.com/amidaware/tacticalrmm-web/releases/download/v${WEB_VERSION}/${webtar} -O /tmp/${webtar} - - if [ "$1" == "update" ]; then - sudo rm -rf /var/www/rmm/dist - elif [ "$1" == "restore" ] || [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then + + if [ ! -d /var/www/rmm ]; then sudo mkdir -p /var/www/rmm fi + sudo tar -xzf /tmp/${webtar} -C /var/www/rmm echo "window._env_ = {PROD_URL: \"https://${rmmdomain}\"}" | sudo tee /var/www/rmm/dist/env-config.js > /dev/null sudo chown www-data:www-data -R /var/www/rmm/dist diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index a4ae8cb22e..40d29b615d 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -61,7 +61,7 @@ helpText() echo -e "" echo -e "Options:" echo -e "" - echo -e "auto Select type of automated installation. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC}, or${YELLOW} devinstall${NC}." + echo -e "auto Select type of automated function. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC},${YELLOW} devinstall${NC},${YELLOW} backup${NC}, or ${YELLOW}restore${NC}." echo -e "api Provide the api hostname/subdomain, eg ${YELLOW}api${NC}.example.com" echo -e "branch If performing a dev install, this will select the branch. eg, https://github.com/amidaware/tacticalrmm/${YELLOW}branch${NC}/.git" echo -e "ca Full path to SSL CA Chain certificate for import. Must be in .pem format. Include the filename." From 2824c143edd6fd2ef666b9522ecfbeec9e1bffed Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 1 Jul 2022 16:26:22 -0500 Subject: [PATCH 115/203] Fixed cli arg checks for required install info --- installer-util.sh | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index f42e6e9f7b..10b2839912 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -137,10 +137,20 @@ if [ "$autoinstall" == "1" ]; then # Check all required input is available for install if [ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" || "install" ]; then if [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]; then - echo -e "${RED} Error: To perform an automated installation, you must provide all required information.${NC}\n" - echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required.${NC}\n" - echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}" - exit 1 + echo -e "${RED} Error: To perform an automated installation, you must provide all required information.${NC}\n" + echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required.${NC}\n" + echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}" + exit 1 + fi + fi + + # Check that email address format is valid + if [ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" || "install" ]; then + if [[ $letsemail != *[@]*[.]* ]]; then + echo -e "${RED} Error: You've entered an invalid email address.${NC}\n" + echo -e "${RED} Run $THIS_SCRIPT -h help for details on the correct format.${NC}" + exit 1 + fi fi # Check that repo and branch match install type @@ -150,13 +160,6 @@ if [ "$autoinstall" == "1" ]; then exit 1 fi - # Check that email address format is valid - if [[ $letsemail != *[@]*[.]* ]]; then - echo -e "${RED} Error: You've entered an invalid email address.${NC}\n" - echo -e "${RED} Run $THIS_SCRIPT -h help for details on the correct format.${NC}" - exit 1 - fi - # Check subdomains are valid format # User Input subdomainFormatCheck "$rmmhost" "api"; From c4fa0735ab11547c4d6a09b5e5087bb614027e1b Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 1 Jul 2022 16:56:14 -0500 Subject: [PATCH 116/203] Minor changes to formatting and grammar --- script-cfg/CertificateFunctions.cfg | 5 +++-- script-cfg/NetworkFunctions.cfg | 6 +++--- script-cfg/SystemInfoFunctions.cfg | 5 ++--- script-cfg/UserInput.cfg | 4 ++++ 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 5ff4f93063..e908e9dd41 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -67,7 +67,7 @@ importCerts() # Generate certs generateCerts() { - echo -e "${GREEN} Getting wildcard cert${NC}" + echo -e "${GREEN} Getting wildcard cert...${NC}" # Get initial DNS text entry sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email @@ -95,7 +95,7 @@ installCertbot() fi if [ "$1" == "devinstall" ]; then - echo -e "${GREEN} Certificates should be in place${NC}\n" + echo -e "${GREEN} Certificates should be in place.${NC}\n" elif [ "$autoinstall" != "1" ]; then dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have wildcard certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 case $? in @@ -108,6 +108,7 @@ installCertbot() if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then sudo mkdir -p /etc/letsencrypt/live/${rootdomain} fi + echo -e "${GREEN} Importing certificates.${NC}" sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index f4e786feb1..692fd40487 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -46,19 +46,19 @@ configHosts() # this also allows the install script to properly finish even if DNS has not fully propagated CHECK_LOCALHOST=$(grep "127.0.0.1" /etc/hosts | grep "localhost") if ! [[ $CHECK_LOCALHOST ]]; then - echo -e "${GREEN} Adding localhost to hosts file${NC}\n" + echo -e "${GREEN} Adding localhost to hosts file...${NC}\n" sudo sed -i "1i 127.0.0.1\tlocalhost" /etc/hosts fi CHECK_HOSTS=$(grep "127.0.1.1 $rmmdomain $frontenddomain $meshdomain" /etc/hosts) if [[ $CHECK_HOSTS ]]; then - echo -e "${GREEN} Correcting subdomain entries${NC}\n" + echo -e "${GREEN} Correcting subdomain entries...${NC}\n" sudo sed -i "/127.0.1.1 $rmmdomain $frontenddomain $meshdomain/d" /etc/hosts setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; setSiteHostname "$meshhost" "$rootdomain"; elif [ "$1" != "devinstall" ]; then - echo -e "${GREEN} Adding subdomain entries${NC}\n" + echo -e "${GREEN} Adding subdomain entries...${NC}\n" setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; setSiteHostname "$meshhost" "$rootdomain"; diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 6df62c9016..2e74118d0e 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -42,8 +42,8 @@ verifySupportedOS() echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 + clear -x fi - clear -x exit 1 fi } @@ -61,8 +61,8 @@ checkLocale() echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "System locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting." 0 0 + clear -x fi - clear -x exit 1 fi } @@ -80,7 +80,6 @@ checkTotalSystemMemory() echo -e "${RED} Please add RAM to the system to prevent potential issues during install.${NC}\n" echo -e "${RED} Re-run $THIS_SCRIPT after resolving the issue.${NC}\n" echo -e "${RED} Exiting...${NC}\n" - clear -x exit 1 elif [ "$autoinstall" != "1" ]; then dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended RAM amount of 2GB.\n\nYou may experience issues during install.\n\nIt's recommended to exit and add RAM to the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index 536ad3491d..9dd1b18b83 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -103,6 +103,8 @@ subdomainFormatCheck() echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}\n" echo -e "${RED} Exiting...${NC}\n" exit 1 + else + echo -e "${GREEN} $2 hostname format ok.${NC}\n" fi } @@ -140,6 +142,8 @@ checkCertExists() echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}\n" echo -e "${RED} Exiting...${NC}\n" exit 1 + else + echo -e "${GREEN} The $2 path you provided is valid.${NC}\n" fi } From 62f129401c4381077800dd3a273a8d01d93344ba Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 1 Jul 2022 19:28:15 -0500 Subject: [PATCH 117/203] Remove disk space check --- installer-util.sh | 1 - script-cfg/SystemInfoFunctions.cfg | 20 +------------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 10b2839912..e1daf1a10e 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -225,7 +225,6 @@ verifySupportedOS; # SystemInfoFunctions checkTotalSystemMemory; checkCPUAndThreadCount; -checkStorageCapacity; # Check if root # MiscFunctions diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 2e74118d0e..422ead190c 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -109,22 +109,4 @@ checkCPUAndThreadCount() exit 1;; esac fi -} - -# Check storage capacity available -checkStorageCapacity() -{ - local totalstorage=$(df -h / | grep 'dev' | cut -d " " -f3 | tr -dc '[0-9]') - - if [ $totalstorage -ge 20 ] || [ "$autoinstall" == "1" ]; then - return - else - dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended storage capacity of 20GB.\n\nYou may experience issues during use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 - case $? in - 0 ) return;; - - 1 ) clear -x - exit 1;; - esac - fi -} +} \ No newline at end of file From 18dd6688f37b3c28bb1e83d43137b5c5ac5688c9 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 1 Jul 2022 19:54:23 -0500 Subject: [PATCH 118/203] Fixed cli args --- installer-util.sh | 50 ++++++++++++++++++------------------ script-cfg/MiscFunctions.cfg | 34 ++++++++++++------------ 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index e1daf1a10e..bd4f6f621b 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -82,29 +82,29 @@ done setColors; # Get commandline input -while getopts auto:api:branch:ca:cert:domain:email:file:h:key:mesh:pass:repo:rmm:ts:update:username: option +while getopts i:a:b:c:e:d:m:f:h:k:s:p:r:o:t:u:n: option do case $option in - auto ) autoinstall="1" + i) autoinstall="1" INSTALL_TYPE="$(translateToLowerCase ${OPTARG})";; - api ) rmmhost="$(translateToLowerCase ${OPTARG})";; - branch ) BRANCH="$(translateToLowerCase ${OPTARG})";; - ca ) sslcacert="${OPTARG}";; - cert ) sslcert="${OPTARG}";; - domain ) rootdomain="$(translateToLowerCase ${OPTARG})";; - email ) letsemail="$(translateToLowerCase ${OPTARG})";; - file ) backupfile="${OPTARG}";; - h ) helpText + a) rmmhost="$(translateToLowerCase ${OPTARG})";; + b) BRANCH="$(translateToLowerCase ${OPTARG})";; + c) sslcacert="${OPTARG}";; + e) sslcert="${OPTARG}";; + d) rootdomain="$(translateToLowerCase ${OPTARG})";; + m) letsemail="$(translateToLowerCase ${OPTARG})";; + f) backupfile="${OPTARG}";; + h) helpText exit 1;; - key ) sslkey="${OPTARG}";; - mesh ) meshhost="$(translateToLowerCase ${OPTARG})";; - pass ) trmmpass="${OPTARG}";; - repo ) REPO_OWNER="$(translateToLowerCase ${OPTARG})";; - rmm ) frontendhost="$(translateToLowerCase ${OPTARG})";; - ts ) troubleshoot="1" + k) sslkey="${OPTARG}";; + s) meshhost="$(translateToLowerCase ${OPTARG})";; + p) trmmpass="${OPTARG}";; + r) REPO_OWNER="$(translateToLowerCase ${OPTARG})";; + o) frontendhost="$(translateToLowerCase ${OPTARG})";; + t) troubleshoot="1" troubleShoot;; - update ) UPDATE_TYPE="$(translateToLowerCase ${OPTARG})";; - username ) trmmuser="${OPTARG}";; + u) UPDATE_TYPE="$(translateToLowerCase ${OPTARG})";; + n) trmmuser="${OPTARG}";; \?) echo -e "Error: Invalid option" helpText exit 1;; @@ -114,29 +114,29 @@ done if [ "$autoinstall" == "1" ]; then # Check that update type is valid - if [ "$INSTALL_TYPE" == "update" ] && ([ "$UPDATE_TYPE" != "standard" ] && [ "$UPDATE_TYPE" != "forced" ]); then + if ([ "$INSTALL_TYPE" == "update" ] && ([ "$UPDATE_TYPE" != "standard" ] && [ "$UPDATE_TYPE" != "forced" ])); then echo -e "${RED} Error: You've selected update, but not selected an appropriate type.${NC}\n" echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to select them.${NC}" exit 1 fi # Check that backup file exists - if [ "$INSTALL_TYPE" == "restore" ] && ([ -z "$backupfile" ] || [ ! -f "$backupfile" ]); then + if ([ "$INSTALL_TYPE" == "restore" ] && ([ -z "$backupfile" ] || [ ! -f "$backupfile" ])); then echo -e "${RED} Error: You've selected restore, but not provided a valid backup file.${NC}\n" echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to enter this.${NC}" exit 1 fi # Check that install type is valid - if [ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ] && [ "$INSTALL_TYPE" != "update" ] && [ "$INSTALL_TYPE" != "restore" ] && [ "$INSTALL_TYPE" != "backup" ]; then + if ([ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ] && [ "$INSTALL_TYPE" != "update" ] && [ "$INSTALL_TYPE" != "restore" ] && [ "$INSTALL_TYPE" != "backup" ]); then echo -e "${RED} Error: You've selected an invalid function type.${NC}\n" echo -e "${RED} Run $THIS_SCRIPT -h help for details on the available options.${NC}" exit 1 fi # Check all required input is available for install - if [ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" || "install" ]; then - if [ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]; then + if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" || "install" ]); then + if ([ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]); then echo -e "${RED} Error: To perform an automated installation, you must provide all required information.${NC}\n" echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required.${NC}\n" echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}" @@ -145,7 +145,7 @@ if [ "$autoinstall" == "1" ]; then fi # Check that email address format is valid - if [ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" || "install" ]; then + if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" || "install" ]); then if [[ $letsemail != *[@]*[.]* ]]; then echo -e "${RED} Error: You've entered an invalid email address.${NC}\n" echo -e "${RED} Run $THIS_SCRIPT -h help for details on the correct format.${NC}" @@ -154,7 +154,7 @@ if [ "$autoinstall" == "1" ]; then fi # Check that repo and branch match install type - if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]) && [ "$BRANCH" == "master" ]; then + if (([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]) && [ "$BRANCH" == "master" ]); then echo -e "${RED} Error: You've selected a developer installation type, but not changed the repo, branch, or both.${NC}\n" echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to select them.${NC}" exit 1 diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 40d29b615d..fbe108ba44 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -61,23 +61,23 @@ helpText() echo -e "" echo -e "Options:" echo -e "" - echo -e "auto Select type of automated function. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC},${YELLOW} devinstall${NC},${YELLOW} backup${NC}, or ${YELLOW}restore${NC}." - echo -e "api Provide the api hostname/subdomain, eg ${YELLOW}api${NC}.example.com" - echo -e "branch If performing a dev install, this will select the branch. eg, https://github.com/amidaware/tacticalrmm/${YELLOW}branch${NC}/.git" - echo -e "ca Full path to SSL CA Chain certificate for import. Must be in .pem format. Include the filename." - echo -e "cert Full path to SSL certificate for import. Must be in .pem format. Include the filename." - echo -e "domain Provide the root domain, eg rmm.${YELLOW}example.com${NC}" - echo -e "email Provide a valid email address for LetsEncrypt cert generation and primary T-RMM user." - echo -e "file Provide the full path to the backup file, including file name." - echo -e "h Type help to show this help text." - echo -e "key Full path to SSL private key for import. Must be in .pem format. Include the filename." - echo -e "mesh Provide the mesh hostname/subdomain, eg ${YELLOW}mesh${NC}.example.com" - echo -e "pass Provide the password for the initial T-RMM user." - echo -e "repo If performing a dev install, this will select the repo owner. eg, https://github.com/${YELLOW}repo-owner${NC}/tacticalrmm/master/.git" - echo -e "rmm Provide the rmm hostname/subdomain, eg ${YELLOW}rmm${NC}.example.com" - echo -e "ts Enter ${YELLOW}trouble${NC} to perform troubleshooting functions." - echo -e "update Select update type. Options are ${YELLOW}standard${NC} or ${YELLOW} forced${NC}." - echo -e "username Provide the username for the initial T-RMM user." + echo -e "i Select type of automated function. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC},${YELLOW} devinstall${NC},${YELLOW} backup${NC}, or ${YELLOW}restore${NC}." + echo -e "a Provide the api hostname/subdomain, eg ${YELLOW}api${NC}.example.com" + echo -e "b If performing a dev install, this will select the branch. eg, https://github.com/amidaware/tacticalrmm/${YELLOW}branch${NC}/.git" + echo -e "c Full path to SSL CA Chain certificate for import. Must be in .pem format. Include the filename." + echo -e "e Full path to SSL certificate for import. Must be in .pem format. Include the filename." + echo -e "d Provide the root domain, eg rmm.${YELLOW}example.com${NC}" + echo -e "m Provide a valid email address for LetsEncrypt cert generation and primary T-RMM user." + echo -e "f Provide the full path to the backup file, including file name." + echo -e "h Type help to show this help text." + echo -e "k Full path to SSL private key for import. Must be in .pem format. Include the filename." + echo -e "s Provide the mesh hostname/subdomain, eg ${YELLOW}mesh${NC}.example.com" + echo -e "p Provide the password for the initial T-RMM user." + echo -e "r If performing a dev install, this will select the repo owner. eg, https://github.com/${YELLOW}repo-owner${NC}/tacticalrmm/master/.git" + echo -e "o Provide the rmm hostname/subdomain, eg ${YELLOW}rmm${NC}.example.com" + echo -e "t Enter ${YELLOW}trouble${NC} to perform troubleshooting functions." + echo -e "u Select update type. Options are ${YELLOW}standard${NC} or ${YELLOW} forced${NC}." + echo -e "n Provide the username for the initial T-RMM user." } # Check for new script version From b97d59763be8eb4b4511f2e0f6f7dc94770949d5 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 1 Jul 2022 19:56:41 -0500 Subject: [PATCH 119/203] Fixed cli arg mesg to match changes --- script-cfg/MiscFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index fbe108ba44..18978872e1 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -57,7 +57,7 @@ print_yellow() # Command-line help function helpText() { - echo -e 'Syntax: ./installer-util.sh [-auto|api|branch|ca|cert|domain|email|file|h|key|mesh|pass|repo|rmm|ts|update|username]' + echo -e 'Syntax: ./installer-util.sh [-i|a|b|c|e|d|m|f|h|k|s|p|r|o|t|u|n]' echo -e "" echo -e "Options:" echo -e "" From 133a59945797771d845ff3c098233cc420c498fb Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 1 Jul 2022 20:14:22 -0500 Subject: [PATCH 120/203] more cli arg fixes --- installer-util.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index bd4f6f621b..f1a520dd37 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -135,7 +135,7 @@ if [ "$autoinstall" == "1" ]; then fi # Check all required input is available for install - if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" || "install" ]); then + if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]); then if ([ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]); then echo -e "${RED} Error: To perform an automated installation, you must provide all required information.${NC}\n" echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required.${NC}\n" @@ -145,7 +145,7 @@ if [ "$autoinstall" == "1" ]; then fi # Check that email address format is valid - if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" || "install" ]); then + if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]); then if [[ $letsemail != *[@]*[.]* ]]; then echo -e "${RED} Error: You've entered an invalid email address.${NC}\n" echo -e "${RED} Run $THIS_SCRIPT -h help for details on the correct format.${NC}" From 6bc1106ac320a85612e31aadd1f6926451b93dd7 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 2 Jul 2022 09:01:43 -0500 Subject: [PATCH 121/203] Fix for cli troubleshooting launch --- installer-util.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index f1a520dd37..f08c08ad18 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -101,8 +101,7 @@ do p) trmmpass="${OPTARG}";; r) REPO_OWNER="$(translateToLowerCase ${OPTARG})";; o) frontendhost="$(translateToLowerCase ${OPTARG})";; - t) troubleshoot="1" - troubleShoot;; + t) troubleshoot="1";; u) UPDATE_TYPE="$(translateToLowerCase ${OPTARG})";; n) trmmuser="${OPTARG}";; \?) echo -e "Error: Invalid option" @@ -369,6 +368,9 @@ mainMenu() # Automated backup elif [ "$autoinstall" == "1" ] && [ "$INSTALL_TYPE" == "backup" ]; then backupTRMM; + # Automated troubleshoot + elif [ "$autoinstall" != "1" ] && [ "$troubleshoot" == "1" ]; then + troubleShoot; else until [ "$menuselection" = "0" ]; do dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Main Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections." 0 0 0 \ From 7ab6d17c137c47ab2f2d1532051ac76d11533996 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 2 Jul 2022 13:11:33 -0500 Subject: [PATCH 122/203] Fixes for backup and restore cli functions --- installer-util.sh | 54 +++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index f08c08ad18..d1c285b180 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -153,36 +153,40 @@ if [ "$autoinstall" == "1" ]; then fi # Check that repo and branch match install type - if (([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]) && [ "$BRANCH" == "master" ]); then + if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]) && [ "$BRANCH" == "master" ]; then echo -e "${RED} Error: You've selected a developer installation type, but not changed the repo, branch, or both.${NC}\n" echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to select them.${NC}" exit 1 fi - # Check subdomains are valid format - # User Input - subdomainFormatCheck "$rmmhost" "api"; - subdomainFormatCheck "$meshhost" "mesh"; - subdomainFormatCheck "$frontendhost" "rmm"; - - # Check root domain format is valid - # User Input - rootDomainFormatCheck "$rootdomain"; - - # Check that entries resolve via dns - # User Input - rmmdomain="$rmmhost.$rootdomain" - frontenddomain="$frontendhost.$rootdomain" - meshdomain="$meshhost.$rootdomain" - checkDNSEntriesExist "$rmmdomain"; - checkDNSEntriesExist "$frontenddomain"; - checkDNSEntriesExist "$meshdomain"; - - # Check that cert file exists - # User Input - checkCertExists "$sslcacert" "CA Chain"; - checkCertExists "$sslcert" "Fullchain Cert"; - checkCertExists "$sslkey" "Private Key"; + if ([ ! -z "$rmmhost" ] && [ ! -z "$meshhost" ] && [ ! -z "$frontendhost" ] && [ ! -z "$rootdomain" ]); then + # Check subdomains are valid format + # User Input + subdomainFormatCheck "$rmmhost" "api"; + subdomainFormatCheck "$meshhost" "mesh"; + subdomainFormatCheck "$frontendhost" "rmm"; + + # Check root domain format is valid + # User Input + rootDomainFormatCheck "$rootdomain"; + + # Check that entries resolve via dns + # User Input + rmmdomain="$rmmhost.$rootdomain" + frontenddomain="$frontendhost.$rootdomain" + meshdomain="$meshhost.$rootdomain" + checkDNSEntriesExist "$rmmdomain"; + checkDNSEntriesExist "$frontenddomain"; + checkDNSEntriesExist "$meshdomain"; + fi + + if ([ ! -z "$sslcacert" ] && [ ! -z "$sslcert" ] && [ ! -z "$sslkey" ]); then + # Check that cert file exists + # User Input + checkCertExists "$sslcacert" "CA Chain"; + checkCertExists "$sslcert" "Fullchain Cert"; + checkCertExists "$sslkey" "Private Key"; + fi # Verify repo exists # MiscFunctions From ec50500115306a36d2fa175b5b0cb9e50f35bf2d Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 2 Jul 2022 13:13:11 -0500 Subject: [PATCH 123/203] Minor fix for help menu spacing --- script-cfg/MiscFunctions.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 18978872e1..38f3fb49ce 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -57,6 +57,7 @@ print_yellow() # Command-line help function helpText() { + echo -e "\n" echo -e 'Syntax: ./installer-util.sh [-i|a|b|c|e|d|m|f|h|k|s|p|r|o|t|u|n]' echo -e "" echo -e "Options:" From cc5a6012661937ab74bb6bd412773205ca5b32ad Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 2 Jul 2022 13:13:50 -0500 Subject: [PATCH 124/203] same as last --- script-cfg/MiscFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 38f3fb49ce..e5b8899e58 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -57,7 +57,7 @@ print_yellow() # Command-line help function helpText() { - echo -e "\n" + echo -e "\n\n" echo -e 'Syntax: ./installer-util.sh [-i|a|b|c|e|d|m|f|h|k|s|p|r|o|t|u|n]' echo -e "" echo -e "Options:" @@ -78,7 +78,7 @@ helpText() echo -e "o Provide the rmm hostname/subdomain, eg ${YELLOW}rmm${NC}.example.com" echo -e "t Enter ${YELLOW}trouble${NC} to perform troubleshooting functions." echo -e "u Select update type. Options are ${YELLOW}standard${NC} or ${YELLOW} forced${NC}." - echo -e "n Provide the username for the initial T-RMM user." + echo -e "n Provide the username for the initial T-RMM user.\n\n" } # Check for new script version From 2128e1e5311decfc6ba19c3c5f86487862c7c97b Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 2 Jul 2022 13:16:23 -0500 Subject: [PATCH 125/203] last formatting changes for help menu --- script-cfg/MiscFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index e5b8899e58..6de41864c1 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -57,7 +57,7 @@ print_yellow() # Command-line help function helpText() { - echo -e "\n\n" + echo -e "" echo -e 'Syntax: ./installer-util.sh [-i|a|b|c|e|d|m|f|h|k|s|p|r|o|t|u|n]' echo -e "" echo -e "Options:" @@ -78,7 +78,7 @@ helpText() echo -e "o Provide the rmm hostname/subdomain, eg ${YELLOW}rmm${NC}.example.com" echo -e "t Enter ${YELLOW}trouble${NC} to perform troubleshooting functions." echo -e "u Select update type. Options are ${YELLOW}standard${NC} or ${YELLOW} forced${NC}." - echo -e "n Provide the username for the initial T-RMM user.\n\n" + echo -e "n Provide the username for the initial T-RMM user.\n" } # Check for new script version From 94d1f114b7e25caf22a83e2cdfff38b47f9934e7 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 2 Jul 2022 13:18:35 -0500 Subject: [PATCH 126/203] Really, the last help menu fix --- script-cfg/MiscFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 6de41864c1..3ce0e86b5c 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -70,14 +70,14 @@ helpText() echo -e "d Provide the root domain, eg rmm.${YELLOW}example.com${NC}" echo -e "m Provide a valid email address for LetsEncrypt cert generation and primary T-RMM user." echo -e "f Provide the full path to the backup file, including file name." - echo -e "h Type help to show this help text." + echo -e "h Type ${YELLOW}help${NC} to show this help text." echo -e "k Full path to SSL private key for import. Must be in .pem format. Include the filename." echo -e "s Provide the mesh hostname/subdomain, eg ${YELLOW}mesh${NC}.example.com" echo -e "p Provide the password for the initial T-RMM user." echo -e "r If performing a dev install, this will select the repo owner. eg, https://github.com/${YELLOW}repo-owner${NC}/tacticalrmm/master/.git" echo -e "o Provide the rmm hostname/subdomain, eg ${YELLOW}rmm${NC}.example.com" echo -e "t Enter ${YELLOW}trouble${NC} to perform troubleshooting functions." - echo -e "u Select update type. Options are ${YELLOW}standard${NC} or ${YELLOW} forced${NC}." + echo -e "u Select update type. Options are ${YELLOW}standard${NC} or ${YELLOW}forced${NC}." echo -e "n Provide the username for the initial T-RMM user.\n" } From 36d284ecbb7127b42e697c37a69f95158f3fe74e Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 3 Jul 2022 10:11:18 -0500 Subject: [PATCH 127/203] This better be the last update for help text --- script-cfg/MiscFunctions.cfg | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 3ce0e86b5c..93b4a6616b 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -60,24 +60,23 @@ helpText() echo -e "" echo -e 'Syntax: ./installer-util.sh [-i|a|b|c|e|d|m|f|h|k|s|p|r|o|t|u|n]' echo -e "" - echo -e "Options:" - echo -e "" - echo -e "i Select type of automated function. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC},${YELLOW} devinstall${NC},${YELLOW} backup${NC}, or ${YELLOW}restore${NC}." - echo -e "a Provide the api hostname/subdomain, eg ${YELLOW}api${NC}.example.com" - echo -e "b If performing a dev install, this will select the branch. eg, https://github.com/amidaware/tacticalrmm/${YELLOW}branch${NC}/.git" - echo -e "c Full path to SSL CA Chain certificate for import. Must be in .pem format. Include the filename." - echo -e "e Full path to SSL certificate for import. Must be in .pem format. Include the filename." - echo -e "d Provide the root domain, eg rmm.${YELLOW}example.com${NC}" - echo -e "m Provide a valid email address for LetsEncrypt cert generation and primary T-RMM user." - echo -e "f Provide the full path to the backup file, including file name." - echo -e "h Type ${YELLOW}help${NC} to show this help text." - echo -e "k Full path to SSL private key for import. Must be in .pem format. Include the filename." - echo -e "s Provide the mesh hostname/subdomain, eg ${YELLOW}mesh${NC}.example.com" - echo -e "p Provide the password for the initial T-RMM user." - echo -e "r If performing a dev install, this will select the repo owner. eg, https://github.com/${YELLOW}repo-owner${NC}/tacticalrmm/master/.git" - echo -e "o Provide the rmm hostname/subdomain, eg ${YELLOW}rmm${NC}.example.com" - echo -e "t Enter ${YELLOW}trouble${NC} to perform troubleshooting functions." - echo -e "u Select update type. Options are ${YELLOW}standard${NC} or ${YELLOW}forced${NC}." + echo -e "Options:\n" + echo -e "i Select type of automated function. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC},${YELLOW} devinstall${NC},${YELLOW} backup${NC}, or ${YELLOW}restore${NC}.\n" + echo -e "a Provide the api hostname/subdomain, eg ${YELLOW}api${NC}.example.com\n" + echo -e "b If performing a dev install, this will select the branch. eg, https://github.com/amidaware/tacticalrmm/${YELLOW}branch${NC}/.git\n" + echo -e "c Full path to SSL CA Chain certificate for import. Must be in .pem format. Include the filename.\n" + echo -e "e Full path to SSL certificate for import. Must be in .pem format. Include the filename.\n" + echo -e "d Provide the root domain, eg rmm.${YELLOW}example.com${NC}\n" + echo -e "m Provide a valid email address for LetsEncrypt cert generation and primary T-RMM user.\n" + echo -e "f Provide the full path to the backup file, including file name.\n" + echo -e "h Type ${YELLOW}help${NC} to show this help text.\n" + echo -e "k Full path to SSL private key for import. Must be in .pem format. Include the filename.\n" + echo -e "s Provide the mesh hostname/subdomain, eg ${YELLOW}mesh${NC}.example.com\n" + echo -e "p Provide the password for the initial T-RMM user.\n" + echo -e "r If performing a dev install, this will select the repo owner. eg, https://github.com/${YELLOW}repo-owner${NC}/tacticalrmm/master/.git\n" + echo -e "o Provide the rmm hostname/subdomain, eg ${YELLOW}rmm${NC}.example.com\n" + echo -e "t Enter ${YELLOW}trouble${NC} to perform troubleshooting functions.\n" + echo -e "u Select update type. Options are ${YELLOW}standard${NC} or ${YELLOW}forced${NC}.\n" echo -e "n Provide the username for the initial T-RMM user.\n" } From bedf4c54625f0fe161d222b5abb1c8aca33102a3 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 3 Jul 2022 16:42:35 -0500 Subject: [PATCH 128/203] Added fix for derpy lines from ncurses --- installer-util.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/installer-util.sh b/installer-util.sh index d1c285b180..1595027c7b 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -1,5 +1,8 @@ #!/usr/bin/env bash +# Fix for ncurses derpy lines in putty and similar apps +export NCURSES_NO_UTF8_ACS=1 + # Menu option variables INPUT=/tmp/menu.sh.$$ menuselection="" From 9686dbc36f0596a2cac643cf1c99b96fe8bb7b01 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 3 Jul 2022 18:29:32 -0500 Subject: [PATCH 129/203] Fix to python update if statement --- .../core/management/commands/pre_update_tasks.py | 2 +- script-cfg/InstallFunctions.cfg | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/api/tacticalrmm/core/management/commands/pre_update_tasks.py b/api/tacticalrmm/core/management/commands/pre_update_tasks.py index 38de0e13a1..3c29deb617 100644 --- a/api/tacticalrmm/core/management/commands/pre_update_tasks.py +++ b/api/tacticalrmm/core/management/commands/pre_update_tasks.py @@ -7,6 +7,6 @@ class Command(BaseCommand): help = "Collection of tasks to run after updating the rmm, before migrations" def handle(self, *args, **kwargs): - self.stdout.write(self.style.WARNING("Clearning the cache")) + self.stdout.write(self.style.WARNING("Clearing the cache")) clear_entire_cache() self.stdout.write(self.style.SUCCESS("Cache was cleared!")) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index c9ca5b8590..2ce0b8da81 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -91,9 +91,11 @@ installRedis() installPython() { if [ "$1" == "update" ]; then - HAS_PY310=$(python3.10 --version | grep ${PYTHON_VER}) - if ! [ $HAS_PY310 ]; then - echo -e "${GREEN} Updating to ${PYTHON_VER}${NC}\n" + CURRENT_PY=$(python3.10 --version | cut -d " " -f2) + if [ "$CURRENT_PY" != "$PYTHON_VER" ]; then + echo -e "${GREEN} Updating to ${PYTHON_VER}.${NC}\n" + elif [ "$CURRENT_PY" == "$PYTHON_VER" ]; then + echo -e "${GREEN} No update needed.${NC}\n" fi fi From dfd8323f3aff7383f5fbb0b639a211afd19d6309 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 3 Jul 2022 19:15:00 -0500 Subject: [PATCH 130/203] Fixes to update functions --- installer-util.sh | 1 + script-cfg/CertificateFunctions.cfg | 3 +++ script-cfg/InstallFunctions.cfg | 17 ++++++++++++----- script-cfg/ParentFunctions.cfg | 4 +++- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 1595027c7b..d2ab4a1b55 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -29,6 +29,7 @@ INSTALL_TYPE="install" UPDATE_TYPE="standard" SCRIPTS_DIR='/opt/trmm-community-scripts' PYTHON_VER='3.10.4' +NODE_MAJOR_VER='16' SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py' LATEST_SETTINGS_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/api/tacticalrmm/tacticalrmm/settings.py" diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index e908e9dd41..ab61dcbbc4 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -79,6 +79,9 @@ generateCerts() while [[ $? -ne 0 ]]; do sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email done + + sudo chown ${USER}:${USER} -R /etc/letsencrypt + sudo chmod 775 -R /etc/letsencrypt } # Install Certbot and get initial certs diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 2ce0b8da81..a1c74a9ed9 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -59,13 +59,16 @@ installNodeJS() { if [ "$1" != "devinstall" ]; then if [ "$1" == "update" ]; then - HAS_NODE16=$(node --version | grep v16) - if ! [ $HAS_NODE16 ]; then - echo -e "${GREEN} Updating NodeJS to v16${NC}\n" + CURRENT_NODE_VER=$(node --version | cut -d "v" -f2 | cut -d "." -f1) + if [ "$CURRENT_NODE_VER" != "$NODE_MAJOR_VER" ]; then + echo -e "${GREEN} Updating NodeJS to v${NODE_MAJOR_VER}${NC}\n" rm -rf /rmm/web/node_modules sudo systemctl stop meshcentral sudo apt remove -y nodejs sudo rm -rf /usr/lib/node_modules + else + echo -e "${GREEN} NodeJS up to date.${NC}\n" + return fi fi curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - @@ -96,6 +99,7 @@ installPython() echo -e "${GREEN} Updating to ${PYTHON_VER}.${NC}\n" elif [ "$CURRENT_PY" == "$PYTHON_VER" ]; then echo -e "${GREEN} No update needed.${NC}\n" + return fi fi @@ -136,9 +140,12 @@ installPostgresql() installNats() { if [ "$1" == "update" ]; then - HAS_LATEST_NATS=$(/usr/local/bin/nats-server -version | grep "${NATS_SERVER_VER}") - if ! [ $HAS_LATEST_NATS ]; then + HAS_LATEST_NATS=$(/usr/local/bin/nats-server -version | cut -d " " -f2 | cut -d "v" -f2) + if [ "$HAS_LATEST_NATS" != "${NATS_SERVER_VER}" ]; then echo -e "${GREEN} Updating nats to v${NATS_SERVER_VER}${NC}\n" + else + echo -e "${GREEN} Nats is up to date${NC}\n" + return fi fi if [ "$1" == "install" ] || [ "$1" == "devinstall" ] || [ "$1" == "restore" ]; then diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 3682912aef..021c950a9b 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -386,9 +386,11 @@ updateTRMM() # Apply updated Ownership and perms sudo chown "${USER}:${USER}" -R /rmm - sudo chown "${USER}:${USER}" -R ${SCRIPTS_DIR} + 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 chmod 775 -R /etc/letsencrypt # Check additional Nginx settings and update # InstallFunctions From 6e46b86535777a50cea5f05b31edf5d095000a5b Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 3 Jul 2022 19:21:49 -0500 Subject: [PATCH 131/203] syntax fixes for nginx checks --- script-cfg/ConfigAndServiceFunctions.cfg | 2 +- script-cfg/InstallFunctions.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 0fa9a7e2b7..1ac28aa4b7 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -41,7 +41,7 @@ configureBackend() if [ "$1" == "update" ]; then CHECK_ADMIN_ENABLED=$(grep ADMIN_ENABLED /rmm/api/tacticalrmm/tacticalrmm/local_settings.py) - if ! [ $CHECK_ADMIN_ENABLED ]; then + if ! [[ $CHECK_ADMIN_ENABLED ]]; then sudo sed -i '$ a ADMIN_ENABLED = False' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py fi sudo cp /rmm/natsapi/bin/nats-api /usr/local/bin diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index a1c74a9ed9..848a82586c 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -207,7 +207,7 @@ installNginx() fi elif [ "$1" == "updatepart2" ]; then CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" /etc/nginx/nginx.conf) - if ! [ $CHECK_NGINX_WORKER_CONN ]; then + if ! [[ $CHECK_NGINX_WORKER_CONN ]]; then echo -e "${GREEN} Changing nginx worker connections to 2048${NC}\n" sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf fi From b5aca80abf7b8575ed7e578f6ea1a4a6d5666c3e Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 3 Jul 2022 19:28:54 -0500 Subject: [PATCH 132/203] Fixes to various checks for update --- script-cfg/InstallFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 848a82586c..a7d95dacee 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -98,7 +98,7 @@ installPython() if [ "$CURRENT_PY" != "$PYTHON_VER" ]; then echo -e "${GREEN} Updating to ${PYTHON_VER}.${NC}\n" elif [ "$CURRENT_PY" == "$PYTHON_VER" ]; then - echo -e "${GREEN} No update needed.${NC}\n" + echo -e "${GREEN} Python is up to date.${NC}\n" return fi fi From 599f6c5ffb6bef63f3dc539a0e8c6f29efaf9da2 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 4 Jul 2022 07:41:29 -0500 Subject: [PATCH 133/203] Fixes for restore dns host file entries --- script-cfg/MiscFunctions.cfg | 3 +++ script-cfg/ParentFunctions.cfg | 2 +- script-cfg/UpdateRestoreFunctions.cfg | 14 +++----------- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 93b4a6616b..7c92e5cd7d 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -367,5 +367,8 @@ getExistingDomainInfo() rmmdomain=$(grep server_name /etc/nginx/sites-available/rmm.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') frontenddomain=$(grep server_name /etc/nginx/sites-available/frontend.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') meshdomain=$(grep server_name /etc/nginx/sites-available/meshcentral.conf | grep -v 301 | head -1 | tr -d " \t" | sed 's/.*server_name//' | tr -d ';') + rmmhost=$(echo "$rmmdomain" | cut -d '.' -f1) + frontendhost=$(echo "$frontenddomain" | cut -d '.' -f1) + meshhost=$(echo "$meshdomain" | cut -d '.' -f1) rootdomain=$(echo "$rmmdomain" | cut -d '.' -f2-) } \ No newline at end of file diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 021c950a9b..2cc76e4455 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -424,7 +424,7 @@ updateTRMM() echo -e "${GREEN} Starting ${i} service${NC}" sudo systemctl start "${i}" done - sleep 1 + sleep 3 # Push agent updates /rmm/api/env/bin/python /rmm/api/tacticalrmm/manage.py update_agents diff --git a/script-cfg/UpdateRestoreFunctions.cfg b/script-cfg/UpdateRestoreFunctions.cfg index cc92e56c2c..8e406a672d 100644 --- a/script-cfg/UpdateRestoreFunctions.cfg +++ b/script-cfg/UpdateRestoreFunctions.cfg @@ -47,16 +47,9 @@ checkIfUpdate() CURRENT_TRMM_VER=$(grep "^TRMM_VERSION" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') if [ "${CURRENT_TRMM_VER}" == "${LATEST_TRMM_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then - if [ "$autoinstall" == "1" ]; then - echo -e "${GREEN} Already on latest version. Current version:${NC} ${YELLOW}${CURRENT_TRMM_VER}${NC} ${GREEN}Latest version:${NC} ${YELLOW}${LATEST_TRMM_VER}${NC}\n" - rm -f $TMP_SETTINGS - exit 0 - elif [ "$autoinstall" != "1" ]; then - # MiscFunctions - print_green "Already on latest version. Current version: ${CURRENT_TRMM_VER} Latest version: ${LATEST_TRMM_VER}\n"; - rm -f $TMP_SETTINGS - exit 0 - fi + echo -e "${GREEN} Already on latest version. Current version:${NC} ${YELLOW}${CURRENT_TRMM_VER}${NC} ${GREEN}Latest version:${NC} ${YELLOW}${LATEST_TRMM_VER}${NC}\n" + rm -f $TMP_SETTINGS + exit 0 fi } @@ -74,7 +67,6 @@ checkNatsLimitNoFile() { CHECK_NATS_LIMITNOFILE=$(grep LimitNOFILE /etc/systemd/system/nats.service) if ! [ $CHECK_NATS_LIMITNOFILE ]; then - sudo rm -f /etc/systemd/system/nats.service # Config and Service functions createNatsService; From 18ad1290902357bf4a30a6ed486e7ed23e7bae36 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 4 Jul 2022 14:07:25 -0500 Subject: [PATCH 134/203] Minor fixes --- script-cfg/InstallFunctions.cfg | 1 + script-cfg/ParentFunctions.cfg | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index a7d95dacee..9d9cb26eef 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -105,6 +105,7 @@ installPython() if [ "$1" == "devinstall" ]; then echo -e "${GREEN} Python already installed${NC}\n" + return else numprocs=$(nproc) cd ~ diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 2cc76e4455..c8639d1b20 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -291,8 +291,8 @@ mainInstall() echo -e "${YELLOW} MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n" if [ "$BEHIND_NAT" = true ]; then - echo -e "${YELLOW} Read below if your router does NOT support Hairpin NAT:${NC}\n" - echo -e "${GREEN} If you will be accessing the web interface of the RMM from the same LAN as this server,\nyou'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" + echo -e "${YELLOW} Read below if your router does NOT support Hairpin NAT:${NC}\n" + echo -e "${GREEN} If you will be accessing the web interface of the RMM from the same LAN as this server,\n you'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" echo -e "${GREEN} This also applies to any agents that will be on the same local network as the rmm.${NC}\n" echo -e "${GREEN} You'll also need to setup port forwarding in your router on ports 443 and 4222.${NC}\n" fi From b3573cdcf8c3e2315cb0afa6a1f8bcf6ef84a279 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 4 Jul 2022 19:05:56 -0500 Subject: [PATCH 135/203] Enabling webroot cert option during install --- default-configs/nginx/frontend.conf | 13 ++-- default-configs/nginx/meshcentral.conf | 15 ++-- default-configs/nginx/rmm.conf | 9 ++- default-configs/python/local_settings.py | 22 +++--- script-cfg/CertificateFunctions.cfg | 90 +++++++++++++++++++----- script-cfg/ConfigAndServiceFunctions.cfg | 21 +++++- script-cfg/ParentFunctions.cfg | 11 ++- 7 files changed, 136 insertions(+), 45 deletions(-) diff --git a/default-configs/nginx/frontend.conf b/default-configs/nginx/frontend.conf index 48a9ddbb9e..ae10f16a17 100644 --- a/default-configs/nginx/frontend.conf +++ b/default-configs/nginx/frontend.conf @@ -27,12 +27,15 @@ server { } server { - if ($host = rmm.example.com) { - return 301 https://$host$request_uri; - } - listen 80; listen [::]:80; server_name rmm.example.com; - return 404; + + #location /.well-known/acme-challenge/ { + #root /var/www/letsencrypt/; + #} + + location / { + return 301 https://$host$request_uri; + } } diff --git a/default-configs/nginx/meshcentral.conf b/default-configs/nginx/meshcentral.conf index 35372429b1..9761ce631c 100644 --- a/default-configs/nginx/meshcentral.conf +++ b/default-configs/nginx/meshcentral.conf @@ -1,8 +1,15 @@ server { - listen 80; - listen [::]:80; - server_name mesh.example.com; - return 301 https://$server_name$request_uri; + listen 80; + listen [::]:80; + server_name mesh.example.com; + + #location /.well-known/acme-challenge/ { + #root /var/www/letsencrypt/; + #} + + location / { + return 301 https://$host$request_uri; + } } server { diff --git a/default-configs/nginx/rmm.conf b/default-configs/nginx/rmm.conf index 46afc19bc2..611d47346f 100644 --- a/default-configs/nginx/rmm.conf +++ b/default-configs/nginx/rmm.conf @@ -14,7 +14,14 @@ server { listen 80; listen [::]:80; server_name api.example.com; - return 301 https://$server_name$request_uri; + + #location /.well-known/acme-challenge/ { + #root /var/www/letsencrypt/; + #} + + location / { + return 301 https://$host$request_uri; + } } server { diff --git a/default-configs/python/local_settings.py b/default-configs/python/local_settings.py index 954b54a650..3962e0dfba 100644 --- a/default-configs/python/local_settings.py +++ b/default-configs/python/local_settings.py @@ -2,26 +2,24 @@ DEBUG = False -ALLOWED_HOSTS = ['api.example.com'] +ALLOWED_HOSTS = ["api.example.com"] ADMIN_URL = "ADMINURL/" -CORS_ORIGIN_WHITELIST = [ - "https://rmm.example.com" -] +CORS_ORIGIN_WHITELIST = ["https://rmm.example.com"] DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': 'tacticalrmm', - 'USER': 'pgusername', - 'PASSWORD': 'pgpw', - 'HOST': 'localhost', - 'PORT': '5432', + "default": { + "ENGINE": "django.db.backends.postgresql", + "NAME": "tacticalrmm", + "USER": "pgusername", + "PASSWORD": "pgpw", + "HOST": "localhost", + "PORT": "5432", } } MESH_USERNAME = "meshusername" MESH_SITE = "https://mesh.example.com" -REDIS_HOST = "localhost" +REDIS_HOST = "localhost" ADMIN_ENABLED = True diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index ab61dcbbc4..2794d9ef19 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -60,28 +60,75 @@ importCerts() fi sudo vim /etc/letsencrypt/live/${rootdomain}/chain.pem - sudo chown ${USER}:${USER} -R /etc/letsencrypt - sudo chmod 775 -R /etc/letsencrypt + sudo chown root:${USER} -R /etc/letsencrypt + sudo chmod 755 -R /etc/letsencrypt } # Generate certs generateCerts() { - echo -e "${GREEN} Getting wildcard cert...${NC}" + # Manual DNS method + if [ "$certtype" == "dns" ]; then + echo -e "${GREEN} Getting wildcard certificate...${NC}" - # Get initial DNS text entry - sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email + # Get initial DNS text entry + sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email - # Ensure TXT record has populated - acmeChallengeCheck "$rootdomain"; + # Ensure TXT record has populated + acmeChallengeCheck "$rootdomain"; - # Keep going until successful cert issue after adding DNS txt entry - while [[ $? -ne 0 ]]; do - sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email - done + # Keep going until successful cert issue after adding DNS txt entry + while [[ $? -ne 0 ]]; do + sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email + done + # Webroot method + elif [ "$certtype" == "webroot" ]; then + echo -e "${GREEN} Getting webroot certificates...${NC}" + + # Edit nginx conf files + sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/frontend.conf + sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/frontend.conf + sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/frontend.conf + sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/meshcentral.conf + sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/meshcentral.conf + sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/meshcentral.conf + + # Create folder + sudo mkdir -P /var/www/letsencrypt + + # Start nginx + sudo systemctl start nginx + + # Get webroot certs + sudo certbot certonly --webroot --webroot-path /var/www/letsencrypt/ --agree-tos -m ${letsemail} --no-eff-email -d ${rmmdomain} -d ${frontenddomain} -d ${meshdomain} + + # Stop nginx + sudo systemctl stop nginx + + # Switch from snakeoil to webroot + sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/frontend.conf + sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/frontend.conf + sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/meshcentral.conf + sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/meshcentral.conf + + # Create dns type folder if it doesn't exist + if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then + sudo mkdir -p /etc/letsencrypt/live/${rootdomain} + fi + + # Create symlinks so cert paths don't need to be edited + sudo ln -s /etc/letsencrypt/live/${rmmdomain}/fullchain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem + sudo ln -s /etc/letsencrypt/live/${rmmdomain}/privkey.pem /etc/letsencrypt/live/${rootdomain}/privkey.pem + sudo ln -s /etc/letsencrypt/live/${rmmdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/chain.pem + fi - sudo chown ${USER}:${USER} -R /etc/letsencrypt - sudo chmod 775 -R /etc/letsencrypt + sudo chown root:${USER} -R /etc/letsencrypt + sudo chmod 755 -R /etc/letsencrypt } # Install Certbot and get initial certs @@ -100,10 +147,17 @@ installCertbot() if [ "$1" == "devinstall" ]; then echo -e "${GREEN} Certificates should be in place.${NC}\n" elif [ "$autoinstall" != "1" ]; then - dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have wildcard certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 + dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 case $? in - # Get wildcard cert via LetsEncrypt - 0 ) generateCerts;; + # Get LetsEncrypt type + 0 ) dialog --cr-wrap --clear --yes-label "Manual-DNS" --no-label "Webroot" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "LetsEncrypt Manual-DNS method, or Webroot method?\n\nWebroot requires port 80 to be open publicly but allows auto-renewal.\n\nManual-DNS requires manual renewal, but can be used on internal only servers." 0 0 + case $? in + # Manual-DNS certs + 0 ) certtype="dns" + generateCerts;; + # Webroot certs + 1 ) certtype="webroot";; + esac # Import certs using vim 1 ) importCerts;; esac @@ -115,8 +169,8 @@ installCertbot() sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem - sudo chown ${USER}:${USER} -R /etc/letsencrypt - sudo chmod 775 -R /etc/letsencrypt + sudo chown root:${USER} -R /etc/letsencrypt + sudo chmod 755 -R /etc/letsencrypt fi # Generate DH if it doesn't exist diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 1ac28aa4b7..9bae5f119c 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -179,7 +179,12 @@ createBackendNginxConf() sudo sed -i "s/api.example.com/$rmmdomain/" /etc/nginx/sites-available/rmm.conf sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/rmm.conf - sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/rmm.conf + if [ "$certtype" == "dns" ]; then + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/rmm.conf + elif [ "$certtype" == "webroot" ]; then + sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/rmm.conf + fi } # Create Mesh nginx conf @@ -188,7 +193,12 @@ createMeshNginxConf() sudo cp /rmm/default-configs/nginx/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf sudo sed -i "s/mesh.example.com/$meshdomain/" /etc/nginx/sites-available/meshcentral.conf - sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/meshcentral.conf + if [ "$certtype" == "dns" ]; then + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/meshcentral.conf + elif [ "$certtype" == "webroot" ]; then + sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/meshcentral.conf + sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/meshcentral.conf + fi } # Create Celery service @@ -227,7 +237,12 @@ createFrontendNginxConf() sudo cp /rmm/default-configs/nginx/frontend.conf /etc/nginx/sites-available/frontend.conf sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/frontend.conf - sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/frontend.conf + if [ "$certtype" == "dns" ]; then + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/frontend.conf + elif [ "$certtype" == "webroot" ]; then + sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/frontend.conf + sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/frontend.conf + fi } # Enable MeshCentral service diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index c8639d1b20..bd5420d0a8 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -233,6 +233,11 @@ mainInstall() # Enable Frontend site sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf + # Webroot certificate fix + if [ "$certtype" == "webroot" ]; then + generateCerts; + fi + # Enable RMM, Daphne, Celery, and Nginx services # Misc functions print_green 'Enabling Services'; @@ -389,8 +394,8 @@ updateTRMM() 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 chmod 775 -R /etc/letsencrypt + sudo chown "root:${USER}" -R /etc/letsencrypt + sudo chmod 755 -R /etc/letsencrypt # Check additional Nginx settings and update # InstallFunctions @@ -566,6 +571,8 @@ restoreTRMM() sudo rm -rf /etc/letsencrypt sudo mkdir /etc/letsencrypt sudo tar -xzf $tmp_dir/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt + sudo chown root:${USER} -R /etc/letsencrypt + sudo chmod 755 -R /etc/letsencrypt # Recreate Nginx conf files # Config and Service functions From a10c2ca26ee1c273477606b575726667045150fd Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Mon, 4 Jul 2022 23:51:39 -0500 Subject: [PATCH 136/203] moved prompt for webroot to separate function --- script-cfg/CertificateFunctions.cfg | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 2794d9ef19..a5da70b97f 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -131,6 +131,20 @@ generateCerts() sudo chmod 755 -R /etc/letsencrypt } +# Select DNS or Webroot +dnsOrWebroot() +{ + dialog --cr-wrap --clear --yes-label "Manual-DNS" --no-label "Webroot" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "LetsEncrypt Manual-DNS method, or Webroot method?\n\nWebroot requires port 80 to be open publicly but allows auto-renewal.\n\nManual-DNS requires manual renewal, but can be used on internal only servers." 0 0 + case $? in + # Manual-DNS certs + 0 ) certtype="dns" + generateCerts;; + + # Webroot certs + 1 ) certtype="webroot";; + esac +} + # Install Certbot and get initial certs installCertbot() { @@ -150,14 +164,8 @@ installCertbot() dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 case $? in # Get LetsEncrypt type - 0 ) dialog --cr-wrap --clear --yes-label "Manual-DNS" --no-label "Webroot" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "LetsEncrypt Manual-DNS method, or Webroot method?\n\nWebroot requires port 80 to be open publicly but allows auto-renewal.\n\nManual-DNS requires manual renewal, but can be used on internal only servers." 0 0 - case $? in - # Manual-DNS certs - 0 ) certtype="dns" - generateCerts;; - # Webroot certs - 1 ) certtype="webroot";; - esac + 0 ) dnsOrWebroot;; + # Import certs using vim 1 ) importCerts;; esac From 660624b8a1e6f4f9970f0f61e99c5b51e4d70123 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 5 Jul 2022 00:11:11 -0500 Subject: [PATCH 137/203] fix for webroot cert generation --- script-cfg/CertificateFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index a5da70b97f..22bb57264f 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -97,7 +97,7 @@ generateCerts() sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/meshcentral.conf # Create folder - sudo mkdir -P /var/www/letsencrypt + sudo mkdir -p /var/www/letsencrypt # Start nginx sudo systemctl start nginx @@ -165,7 +165,7 @@ installCertbot() case $? in # Get LetsEncrypt type 0 ) dnsOrWebroot;; - + # Import certs using vim 1 ) importCerts;; esac From e08196f71d87f289639c8a0ff68554aaa761452c Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 5 Jul 2022 09:06:48 -0500 Subject: [PATCH 138/203] disable ssl stapling during webroot cert gen --- script-cfg/CertificateFunctions.cfg | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 22bb57264f..10ad342d3f 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -89,12 +89,15 @@ generateCerts() sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/frontend.conf sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/frontend.conf sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/frontend.conf + sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/frontend.conf sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/rmm.conf sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/rmm.conf sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/rmm.conf sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/meshcentral.conf sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/meshcentral.conf sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/meshcentral.conf + sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/meshcentral.conf # Create folder sudo mkdir -p /var/www/letsencrypt @@ -111,10 +114,13 @@ generateCerts() # Switch from snakeoil to webroot sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/rmm.conf sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/rmm.conf sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/frontend.conf sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/frontend.conf + sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/frontend.conf sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/meshcentral.conf sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/meshcentral.conf + sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/meshcentral.conf # Create dns type folder if it doesn't exist if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then @@ -129,6 +135,8 @@ generateCerts() sudo chown root:${USER} -R /etc/letsencrypt sudo chmod 755 -R /etc/letsencrypt + + sudo systemctl start nginx } # Select DNS or Webroot From 6c2a8f59441789ee48b60ccb2230d60bb0927b0c Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 5 Jul 2022 09:53:35 -0500 Subject: [PATCH 139/203] Added service restart post hook for webroot --- script-cfg/CertificateFunctions.cfg | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 10ad342d3f..bc94f9cda9 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -131,6 +131,10 @@ generateCerts() sudo ln -s /etc/letsencrypt/live/${rmmdomain}/fullchain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem sudo ln -s /etc/letsencrypt/live/${rmmdomain}/privkey.pem /etc/letsencrypt/live/${rootdomain}/privkey.pem sudo ln -s /etc/letsencrypt/live/${rmmdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/chain.pem + + sudo echo '#!/usr/bin/env bash' | sudo tee /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh + sudo sed -i "/\#\!\/usr\/bin\/env bash/ a systemctl restart nginx meshcentral rmm celery celerybeat nats" /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh + sudo chmod +x /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh fi sudo chown root:${USER} -R /etc/letsencrypt From 005f195043d3fa2b63448c512262f91d1ccfb1d0 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 5 Jul 2022 11:24:46 -0500 Subject: [PATCH 140/203] Added webroot option to cli args with checks --- installer-util.sh | 23 ++++++++++++++++++++--- script-cfg/CertificateFunctions.cfg | 20 ++++++++++++-------- script-cfg/MiscFunctions.cfg | 3 ++- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index d2ab4a1b55..dfef958355 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -47,6 +47,7 @@ trmmuser="" trmmpass="" backupfile="" troubleshoot="" +certtype="" # Check if directory exists, if not, create if [ ! -d $PWD/script-cfg ]; then @@ -86,7 +87,7 @@ done setColors; # Get commandline input -while getopts i:a:b:c:e:d:m:f:h:k:s:p:r:o:t:u:n: option +while getopts i:a:b:c:e:d:m:f:h:k:s:p:r:o:t:u:n:w: option do case $option in i) autoinstall="1" @@ -108,6 +109,7 @@ do t) troubleshoot="1";; u) UPDATE_TYPE="$(translateToLowerCase ${OPTARG})";; n) trmmuser="${OPTARG}";; + w) certtype="$(translateToLowerCase ${OPTARG})";; \?) echo -e "Error: Invalid option" helpText exit 1;; @@ -139,9 +141,24 @@ if [ "$autoinstall" == "1" ]; then # Check all required input is available for install if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]); then - if ([ -z "$rmmhost" ] || [ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$rootdomain" ] || [ -z "$sslkey" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]); then + if ([ -z "$rmmhost" ] || [ -z "$certtype" ] || [ -z "$rootdomain" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]); then echo -e "${RED} Error: To perform an automated installation, you must provide all required information.${NC}\n" - echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, CA cert path, Cert path, Private key path, and T-RMM username and password are all required.${NC}\n" + echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, and T-RMM username and password are all required.${NC}\n" + echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}" + exit 1 + fi + + # Check that certificate install type is valid + if ([ "$certtype" != "import" ] && [ "$certtype" != "webroot" ]); then + echo -e "${RED} Error: You've selected an invalid certificate installation type.${NC}\n" + echo -e "${RED} Run $THIS_SCRIPT -h help for details on the available options.${NC}" + exit 1 + fi + + # Check for required input if import certificate + if ([ "$certtype" == "import" ] && ([ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$sslkey" ])); then + echo -e "${RED} Error: To perform an automated installation using imported certificates, you must provide all required information.${NC}\n" + echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, CA cert path, Cert path, Private key path, and T-RMM username and password are all required.${NC}\n" echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}" exit 1 fi diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index bc94f9cda9..7623b25bc1 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -182,15 +182,19 @@ installCertbot() 1 ) importCerts;; esac elif [ "$autoinstall" == "1" ]; then - if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then - sudo mkdir -p /etc/letsencrypt/live/${rootdomain} + if [ "$certtype" == "import" ]; then + if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then + sudo mkdir -p /etc/letsencrypt/live/${rootdomain} + fi + echo -e "${GREEN} Importing certificates.${NC}" + sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem + sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem + sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem + sudo chown root:${USER} -R /etc/letsencrypt + sudo chmod 755 -R /etc/letsencrypt + elif [ "$certtype" == "webroot" ]; then + return fi - echo -e "${GREEN} Importing certificates.${NC}" - sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem - sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem - sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem - sudo chown root:${USER} -R /etc/letsencrypt - sudo chmod 755 -R /etc/letsencrypt fi # Generate DH if it doesn't exist diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 7c92e5cd7d..178d1f5279 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -58,7 +58,7 @@ print_yellow() helpText() { echo -e "" - echo -e 'Syntax: ./installer-util.sh [-i|a|b|c|e|d|m|f|h|k|s|p|r|o|t|u|n]' + echo -e 'Syntax: ./installer-util.sh [-i|a|b|c|e|d|m|f|h|k|s|p|r|o|t|u|n|w]' echo -e "" echo -e "Options:\n" echo -e "i Select type of automated function. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC},${YELLOW} devinstall${NC},${YELLOW} backup${NC}, or ${YELLOW}restore${NC}.\n" @@ -78,6 +78,7 @@ helpText() echo -e "t Enter ${YELLOW}trouble${NC} to perform troubleshooting functions.\n" echo -e "u Select update type. Options are ${YELLOW}standard${NC} or ${YELLOW}forced${NC}.\n" echo -e "n Provide the username for the initial T-RMM user.\n" + echo -e "w Select certificate install type. Options are ${YELLOW}import${NC} or ${YELLOW}webroot${NC}.\n"" } # Check for new script version From 6edbaa988ca7142e5e9be10f55062d2739b1b317 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 5 Jul 2022 11:30:07 -0500 Subject: [PATCH 141/203] Updated install complete text to reflect webroot --- script-cfg/ParentFunctions.cfg | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index bd5420d0a8..3d7038204b 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -299,7 +299,11 @@ mainInstall() echo -e "${YELLOW} Read below if your router does NOT support Hairpin NAT:${NC}\n" echo -e "${GREEN} If you will be accessing the web interface of the RMM from the same LAN as this server,\n you'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" echo -e "${GREEN} This also applies to any agents that will be on the same local network as the rmm.${NC}\n" - echo -e "${GREEN} You'll also need to setup port forwarding in your router on ports 443 and 4222.${NC}\n" + if [ "$certtype" == "webroot" ]; then + echo -e "${GREEN} You'll also need to setup port forwarding in your router on ports 80, 443, and 4222, if you have not done so already.${NC}\n" + else + echo -e "${GREEN} You'll also need to setup port forwarding in your router on ports 443 and 4222.${NC}\n" + fi fi # Misc functions print_yellow "Please refer to the github README for next steps."; From 79378e590a236ead96664e37c81c904772dc5e3c Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 5 Jul 2022 14:09:11 -0500 Subject: [PATCH 142/203] Removed extra quote --- script-cfg/MiscFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 178d1f5279..80f8134ea6 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -78,7 +78,7 @@ helpText() echo -e "t Enter ${YELLOW}trouble${NC} to perform troubleshooting functions.\n" echo -e "u Select update type. Options are ${YELLOW}standard${NC} or ${YELLOW}forced${NC}.\n" echo -e "n Provide the username for the initial T-RMM user.\n" - echo -e "w Select certificate install type. Options are ${YELLOW}import${NC} or ${YELLOW}webroot${NC}.\n"" + echo -e "w Select certificate install type. Options are ${YELLOW}import${NC} or ${YELLOW}webroot${NC}.\n" } # Check for new script version @@ -372,4 +372,4 @@ getExistingDomainInfo() frontendhost=$(echo "$frontenddomain" | cut -d '.' -f1) meshhost=$(echo "$meshdomain" | cut -d '.' -f1) rootdomain=$(echo "$rmmdomain" | cut -d '.' -f2-) -} \ No newline at end of file +} From 49d9d17adba788854b02fdc5a9330517b92b17f0 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 6 Jul 2022 08:39:35 -0500 Subject: [PATCH 143/203] Fixes for dns cert renewal --- script-cfg/CertificateFunctions.cfg | 34 +++++++++++++++++++---------- script-cfg/UserInput.cfg | 23 ++++++++++++------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 7623b25bc1..9da30bfcf3 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -29,14 +29,6 @@ acmeChallengeCheck() done } -# Renew Certs -renewCerts() -{ - # generate certs and restart services - generateCerts; - sudo systemctl restart nginx.service rmm.service celery celerybeat.service nats-api.service nats.service meshcentral.service -} - # Import certs importCerts() { @@ -81,6 +73,10 @@ generateCerts() while [[ $? -ne 0 ]]; do sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email done + + sudo chown root:${USER} -R /etc/letsencrypt + sudo chmod 755 -R /etc/letsencrypt + # Webroot method elif [ "$certtype" == "webroot" ]; then echo -e "${GREEN} Getting webroot certificates...${NC}" @@ -135,12 +131,28 @@ generateCerts() sudo echo '#!/usr/bin/env bash' | sudo tee /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh sudo sed -i "/\#\!\/usr\/bin\/env bash/ a systemctl restart nginx meshcentral rmm celery celerybeat nats" /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh sudo chmod +x /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh + + sudo chown root:${USER} -R /etc/letsencrypt + sudo chmod 755 -R /etc/letsencrypt + sudo systemctl start nginx fi +} - sudo chown root:${USER} -R /etc/letsencrypt - sudo chmod 755 -R /etc/letsencrypt +# Renew Certs +renewCerts() +{ + # generate certs and restart services + certtype="dns" - sudo systemctl start nginx + # UserInput + getEmailAddress; + + # MiscFunctions + getExistingDomainInfo; + + generateCerts; + + sudo systemctl restart nginx.service rmm.service celery celerybeat.service nats-api.service nats.service meshcentral.service } # Select DNS or Webroot diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index 9dd1b18b83..30b5243380 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -147,6 +147,20 @@ checkCertExists() fi } +# Get email address +getEmailAddress() +{ + # Get Admin email + while [[ $letsemail != *[@]*[.]* ]]; do + letsemail=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Admin E-Mail Address" --inputbox "Enter a valid e-mail address for Django, MeshCentral, and LetsEncrypt:" 10 90 3>&1 1>&2 2>&3) + letsemail="$(translateToLowerCase $letsemail)" + if [[ $letsemail != *[@]*[.]* ]]; then + derpDerp; + dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "The e-mail address you entered is not correctly formatted.\n\nPlease try again." 0 0 + fi + done +} + # Get host and domain info getHostAndDomainInfo() { @@ -235,14 +249,7 @@ getHostAndDomainInfo() if [ "$troubleshoot" != "1" ]; then # Get Admin email - while [[ $letsemail != *[@]*[.]* ]]; do - letsemail=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Admin E-Mail Address" --inputbox "Enter a valid e-mail address for Django, MeshCentral, and LetsEncrypt:" 10 90 3>&1 1>&2 2>&3) - letsemail="$(translateToLowerCase $letsemail)" - if [[ $letsemail != *[@]*[.]* ]]; then - derpDerp; - dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "The e-mail address you entered is not correctly formatted.\n\nPlease try again." 0 0 - fi - done + getEmailAddress; # Verify input dialog --cr-wrap --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Confirm Input" --yesno "Is this correct?\n\nroot domain: $rootdomain\nbackend: $rmmhost.$rootdomain\nfrontend: $frontendhost.$rootdomain\nmeshcentral: $meshhost.$rootdomain\ne-mail address: $letsemail" 0 0 From 9c2c49691d1cc76b8a3abe8c3370b38269d6c3e5 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 6 Jul 2022 18:29:15 -0500 Subject: [PATCH 144/203] Fix for install repos for 22.04 and 11 --- default-configs/nginx/frontend.conf | 32 +++++++++++++------------- default-configs/nginx/meshcentral.conf | 1 - script-cfg/InstallFunctions.cfg | 5 ++++ 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/default-configs/nginx/frontend.conf b/default-configs/nginx/frontend.conf index ae10f16a17..5250828cbf 100644 --- a/default-configs/nginx/frontend.conf +++ b/default-configs/nginx/frontend.conf @@ -1,4 +1,20 @@ server { + listen 80; + listen [::]:80; + server_name rmm.example.com; + + #location /.well-known/acme-challenge/ { + #root /var/www/letsencrypt/; + #} + + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl; + listen [::]:443 ssl; server_name rmm.example.com; charset utf-8; location / { @@ -10,8 +26,6 @@ server { 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/letsencrypt/live/rootdomain/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/rootdomain/privkey.pem; @@ -25,17 +39,3 @@ server { add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; add_header X-Content-Type-Options nosniff; } - -server { - listen 80; - listen [::]:80; - server_name rmm.example.com; - - #location /.well-known/acme-challenge/ { - #root /var/www/letsencrypt/; - #} - - location / { - return 301 https://$host$request_uri; - } -} diff --git a/default-configs/nginx/meshcentral.conf b/default-configs/nginx/meshcentral.conf index 9761ce631c..b815e5a9f0 100644 --- a/default-configs/nginx/meshcentral.conf +++ b/default-configs/nginx/meshcentral.conf @@ -13,7 +13,6 @@ server { } server { - listen 443 ssl; listen [::]:443 ssl; proxy_send_timeout 330s; diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 9d9cb26eef..0dcfa7710b 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -24,18 +24,23 @@ installAdditionalPreReqs() # Configure repos for stuff setInstallRepos() { + local tempcodename="$codename" + # There is no Jammy repo yet so use Focal for Ubuntu 22.04 if ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "20.04" ]); then mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" elif ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "22.04" ]); then codename="focal" mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" + codename="$tempcodename" # There is no bullseye repo yet for mongo so just use Buster on Debian 11 elif ([ "$osname" == "debian" ] && [ $relno -eq 10 ]); then mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 main" + postgresql_repo="deb [arch=amd64] https://apt.postgresql.org/pub/repos/apt/ $codename-pgdg main" else codename="buster" mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 main" + codename="$tempcodename" fi postgresql_repo="deb [arch=amd64] https://apt.postgresql.org/pub/repos/apt/ $codename-pgdg main" From 813e76d64c1e284539eaf98ae895804b1be469c7 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 6 Jul 2022 23:48:35 -0500 Subject: [PATCH 145/203] Updated troubleshooting functions for webroot --- script-cfg/TroubleshootingFunctions.cfg | 34 +++++++++++++++++++------ 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index 934f825e15..2ac05b1d30 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -117,13 +117,31 @@ checkIfCertIsValid() echo -e "\n" # SSL Certificate check - cert="$(openssl verify -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem)" - - if [[ "$cert" == *"OK"* ]]; then - echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log - echo -e "\n" - else - echo -e "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a checklog.log - echo -e "\n" + # Check DNS-Manual or imported certs + if [ ! -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then + cert="$(openssl verify -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem)" + certexp="$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/${rootdomain}/fullchain.pem | cut -d "=" -f2)" + + if [[ "$cert" == *"OK"* ]]; then + echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log + echo -e "${GREEN} SSL Certificate expires $certexp${NC}" | tee -a checklog.log + echo -e "\n" + else + echo -e "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a checklog.log + echo -e "\n" + fi + # Check Webroot authenticated certs + elif [ -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then + cert="$(openssl verify -no_check_time -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem)" + certexp="$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/${rootdomain}/fullchain.pem | cut -d "=" -f2)" + + if [[ "$cert" == *"OK"* ]]; then + echo -e "${GREEN} SSL Certificate for $rmmdomain , $frontenddomain , and $meshdomain is fine.${NC}" | tee -a checklog.log + echo -e "${GREEN} SSL Certificate expires $certexp${NC}" | tee -a checklog.log + echo -e "\n" + else + echo -e "${RED} SSL Certificate has expired or doesnt exist for $rmmdomain , $frontenddomain , and $meshdomain.${NC}" | tee -a checklog.log + echo -e "\n" + fi fi } From a1dae7f82c0aea508b3459cacd3847a0d86e2278 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 09:12:25 -0500 Subject: [PATCH 146/203] testing logging commands --- installer-util.sh | 36 +++-- script-cfg/CertificateFunctions.cfg | 130 +++++++-------- script-cfg/ParentFunctions.cfg | 205 +++++++++++++----------- script-cfg/TroubleshootingFunctions.cfg | 42 ++--- 4 files changed, 220 insertions(+), 193 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index dfef958355..ac197a31a2 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -14,6 +14,16 @@ declare -a updatemenuoptions=('Standard Update' 'Backup and Update' 'Force Updat declare -a utilitymenuoptions=('Backup' 'Restore' 'Renew Certs' 'Import Certs' 'Add Fail2ban - Use at your own risk' 'Run Server Troubleshooter' 'Return' 'Exit') declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunctions.cfg' 'UserInput.cfg' 'NetworkFunctions.cfg' 'InstallFunctions.cfg' 'DatabaseFunctions.cfg' 'CertificateFunctions.cfg' 'ConfigAndServiceFunctions.cfg' 'UpdateRestoreFunctions.cfg' 'TroubleshootingFunctions.cfg' 'ParentFunctions.cfg') +# Log file variables +rundate="$(date '+%Y_%m_%d__%H_%M_%S')" +installlog="$PWD/trmm-install_$rundate.log" +restorelog="$PWD/trmm-restore_$rundate.log" +updatelog="$PWD/trmm-update_$rundate.log" +backuplog="$PWD/trmm-backup_$rundate.log" +checklog="$PWD/trmm-checklog_$rundate.log" +preinstalllog="$PWD/trmm-preinstalllog_$rundate.log" +currentlog="$preinstalllog" + # Script Info variables REPO_OWNER="ninjamonkey198206" BRANCH="develop-installer-update-ws" @@ -51,14 +61,14 @@ certtype="" # Check if directory exists, if not, create if [ ! -d $PWD/script-cfg ]; then - mkdir $PWD/script-cfg + mkdir $PWD/script-cfg | tee -a "${currentlog}" fi # Get cfg files function getCfgFiles() { if [ ! -f "$PWD/script-cfg/$2" ]; then - wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" + wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" | tee -a "${currentlog}" fi } @@ -120,21 +130,21 @@ if [ "$autoinstall" == "1" ]; then # Check that update type is valid if ([ "$INSTALL_TYPE" == "update" ] && ([ "$UPDATE_TYPE" != "standard" ] && [ "$UPDATE_TYPE" != "forced" ])); then - echo -e "${RED} Error: You've selected update, but not selected an appropriate type.${NC}\n" + echo -e "${RED} Error: You've selected update, but not selected an appropriate type.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to select them.${NC}" exit 1 fi # Check that backup file exists if ([ "$INSTALL_TYPE" == "restore" ] && ([ -z "$backupfile" ] || [ ! -f "$backupfile" ])); then - echo -e "${RED} Error: You've selected restore, but not provided a valid backup file.${NC}\n" + echo -e "${RED} Error: You've selected restore, but not provided a valid backup file.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to enter this.${NC}" exit 1 fi # Check that install type is valid if ([ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ] && [ "$INSTALL_TYPE" != "update" ] && [ "$INSTALL_TYPE" != "restore" ] && [ "$INSTALL_TYPE" != "backup" ]); then - echo -e "${RED} Error: You've selected an invalid function type.${NC}\n" + echo -e "${RED} Error: You've selected an invalid function type.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for details on the available options.${NC}" exit 1 fi @@ -142,23 +152,23 @@ if [ "$autoinstall" == "1" ]; then # Check all required input is available for install if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]); then if ([ -z "$rmmhost" ] || [ -z "$certtype" ] || [ -z "$rootdomain" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]); then - echo -e "${RED} Error: To perform an automated installation, you must provide all required information.${NC}\n" - echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, and T-RMM username and password are all required.${NC}\n" + echo -e "${RED} Error: To perform an automated installation, you must provide all required information.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, and T-RMM username and password are all required.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}" exit 1 fi # Check that certificate install type is valid if ([ "$certtype" != "import" ] && [ "$certtype" != "webroot" ]); then - echo -e "${RED} Error: You've selected an invalid certificate installation type.${NC}\n" + echo -e "${RED} Error: You've selected an invalid certificate installation type.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for details on the available options.${NC}" exit 1 fi # Check for required input if import certificate if ([ "$certtype" == "import" ] && ([ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$sslkey" ])); then - echo -e "${RED} Error: To perform an automated installation using imported certificates, you must provide all required information.${NC}\n" - echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, CA cert path, Cert path, Private key path, and T-RMM username and password are all required.${NC}\n" + echo -e "${RED} Error: To perform an automated installation using imported certificates, you must provide all required information.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, CA cert path, Cert path, Private key path, and T-RMM username and password are all required.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}" exit 1 fi @@ -167,7 +177,7 @@ if [ "$autoinstall" == "1" ]; then # Check that email address format is valid if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]); then if [[ $letsemail != *[@]*[.]* ]]; then - echo -e "${RED} Error: You've entered an invalid email address.${NC}\n" + echo -e "${RED} Error: You've entered an invalid email address.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for details on the correct format.${NC}" exit 1 fi @@ -175,7 +185,7 @@ if [ "$autoinstall" == "1" ]; then # Check that repo and branch match install type if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]) && [ "$BRANCH" == "master" ]; then - echo -e "${RED} Error: You've selected a developer installation type, but not changed the repo, branch, or both.${NC}\n" + echo -e "${RED} Error: You've selected a developer installation type, but not changed the repo, branch, or both.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to select them.${NC}" exit 1 fi @@ -263,7 +273,7 @@ checkTacticalUser; checkLocale; # 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 +sudo systemctl restart systemd-journald.service | tee -a "${currentlog}" #################### # Menu Functions # diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 9da30bfcf3..ffe9f8f469 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -18,11 +18,11 @@ acmeChallengeCheck() until [ "$acmegood" == "y" ]; do if [[ $(dig +noall +answer -t TXT _acme-challenge.$1) ]] 2>/dev/null; then acmegood="y" - echo -e "${GREEN} Acme Challenge TXT record available.${NC}\n" - echo -e "${GREEN} Continuing...${NC}" + echo -e "${GREEN} Acme Challenge TXT record available.${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} Continuing...${NC}" | tee -a "${currentlog}" else - echo -e "${YELLOW} Acme Challenge TXT record not available yet.${NC}\n" - echo -e "${YELLOW} Trying again in 30 sec...${NC}\n" + echo -e "${YELLOW} Acme Challenge TXT record not available yet.${NC}\n" | tee -a "${currentlog}" + echo -e "${YELLOW} Trying again in 30 sec...${NC}\n" | tee -a "${currentlog}" acmegood="n" sleep 30 fi @@ -34,26 +34,26 @@ importCerts() { dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate, private key, and CA Chain file, in that order.\n\nTo paste the contents, type i , then shift+insert.\n\nAfter pasting the contents, type esc , then shift-: , then wq , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then - sudo mkdir -p /etc/letsencrypt/live/${rootdomain} + sudo mkdir -p /etc/letsencrypt/live/${rootdomain} | tee -a "${currentlog}" fi if [ -f /etc/letsencrypt/live/${rootdomain}/fullchain.pem ]; then - sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/fullchain.pem + sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/fullchain.pem | tee -a "${currentlog}" fi - sudo vim /etc/letsencrypt/live/${rootdomain}/fullchain.pem + sudo vim /etc/letsencrypt/live/${rootdomain}/fullchain.pem | tee -a "${currentlog}" if [ -f /etc/letsencrypt/live/${rootdomain}/privkey.pem ]; then - sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/privkey.pem + sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/privkey.pem | tee -a "${currentlog}" fi - sudo vim /etc/letsencrypt/live/${rootdomain}/privkey.pem + sudo vim /etc/letsencrypt/live/${rootdomain}/privkey.pem | tee -a "${currentlog}" if [ -f /etc/letsencrypt/live/${rootdomain}/chain.pem ]; then - sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/chain.pem + sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/chain.pem | tee -a "${currentlog}" fi - sudo vim /etc/letsencrypt/live/${rootdomain}/chain.pem + sudo vim /etc/letsencrypt/live/${rootdomain}/chain.pem | tee -a "${currentlog}" - sudo chown root:${USER} -R /etc/letsencrypt - sudo chmod 755 -R /etc/letsencrypt + sudo chown root:${USER} -R /etc/letsencrypt | tee -a "${currentlog}" + sudo chmod 755 -R /etc/letsencrypt | tee -a "${currentlog}" } # Generate certs @@ -61,80 +61,80 @@ generateCerts() { # Manual DNS method if [ "$certtype" == "dns" ]; then - echo -e "${GREEN} Getting wildcard certificate...${NC}" + echo -e "${GREEN} Getting wildcard certificate...${NC}" | tee -a "${currentlog}" # Get initial DNS text entry - sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email + sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email | tee -a "${currentlog}" # Ensure TXT record has populated acmeChallengeCheck "$rootdomain"; # Keep going until successful cert issue after adding DNS txt entry while [[ $? -ne 0 ]]; do - sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email + sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email | tee -a "${currentlog}" done - sudo chown root:${USER} -R /etc/letsencrypt - sudo chmod 755 -R /etc/letsencrypt + sudo chown root:${USER} -R /etc/letsencrypt | tee -a "${currentlog}" + sudo chmod 755 -R /etc/letsencrypt | tee -a "${currentlog}" # Webroot method elif [ "$certtype" == "webroot" ]; then - echo -e "${GREEN} Getting webroot certificates...${NC}" + echo -e "${GREEN} Getting webroot certificates...${NC}" | tee -a "${currentlog}" # Edit nginx conf files - sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/frontend.conf - sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/frontend.conf - sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/frontend.conf - sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/frontend.conf - sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/rmm.conf - sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/rmm.conf - sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/rmm.conf - sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/rmm.conf - sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/meshcentral.conf - sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/meshcentral.conf - sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/meshcentral.conf - sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/meshcentral.conf + sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" + sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" + sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" + sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" + sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" + sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" + sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" + sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" + sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" + sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" + sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" + sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" # Create folder - sudo mkdir -p /var/www/letsencrypt + sudo mkdir -p /var/www/letsencrypt | tee -a "${currentlog}" # Start nginx - sudo systemctl start nginx + sudo systemctl start nginx | tee -a "${currentlog}" # Get webroot certs - sudo certbot certonly --webroot --webroot-path /var/www/letsencrypt/ --agree-tos -m ${letsemail} --no-eff-email -d ${rmmdomain} -d ${frontenddomain} -d ${meshdomain} + sudo certbot certonly --webroot --webroot-path /var/www/letsencrypt/ --agree-tos -m ${letsemail} --no-eff-email -d ${rmmdomain} -d ${frontenddomain} -d ${meshdomain} | tee -a "${currentlog}" # Stop nginx - sudo systemctl stop nginx + sudo systemctl stop nginx | tee -a "${currentlog}" # Switch from snakeoil to webroot - sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/rmm.conf - sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/rmm.conf - sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/rmm.conf - sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/frontend.conf - sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/frontend.conf - sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/frontend.conf - sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/meshcentral.conf - sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/meshcentral.conf - sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/meshcentral.conf + sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" + sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" + sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" + sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" + sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" + sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" + sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" + sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" + sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" # Create dns type folder if it doesn't exist if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then - sudo mkdir -p /etc/letsencrypt/live/${rootdomain} + sudo mkdir -p /etc/letsencrypt/live/${rootdomain} | tee -a "${currentlog}" fi # Create symlinks so cert paths don't need to be edited - sudo ln -s /etc/letsencrypt/live/${rmmdomain}/fullchain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem - sudo ln -s /etc/letsencrypt/live/${rmmdomain}/privkey.pem /etc/letsencrypt/live/${rootdomain}/privkey.pem - sudo ln -s /etc/letsencrypt/live/${rmmdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/chain.pem + sudo ln -s /etc/letsencrypt/live/${rmmdomain}/fullchain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem | tee -a "${currentlog}" + sudo ln -s /etc/letsencrypt/live/${rmmdomain}/privkey.pem /etc/letsencrypt/live/${rootdomain}/privkey.pem | tee -a "${currentlog}" + sudo ln -s /etc/letsencrypt/live/${rmmdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/chain.pem | tee -a "${currentlog}" sudo echo '#!/usr/bin/env bash' | sudo tee /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh - sudo sed -i "/\#\!\/usr\/bin\/env bash/ a systemctl restart nginx meshcentral rmm celery celerybeat nats" /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh - sudo chmod +x /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh + sudo sed -i "/\#\!\/usr\/bin\/env bash/ a systemctl restart nginx meshcentral rmm celery celerybeat nats" /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh | tee -a "${currentlog}" + sudo chmod +x /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh | tee -a "${currentlog}" - sudo chown root:${USER} -R /etc/letsencrypt - sudo chmod 755 -R /etc/letsencrypt - sudo systemctl start nginx + sudo chown root:${USER} -R /etc/letsencrypt | tee -a "${currentlog}" + sudo chmod 755 -R /etc/letsencrypt | tee -a "${currentlog}" + sudo systemctl start nginx | tee -a "${currentlog}" fi } @@ -152,7 +152,7 @@ renewCerts() generateCerts; - sudo systemctl restart nginx.service rmm.service celery celerybeat.service nats-api.service nats.service meshcentral.service + sudo systemctl restart nginx.service rmm.service celery celerybeat.service nats-api.service nats.service meshcentral.service | tee -a "${currentlog}" } # Select DNS or Webroot @@ -173,17 +173,17 @@ dnsOrWebroot() installCertbot() { # Install Certbot - sudo apt install -y certbot + sudo apt install -y certbot | tee -a "${currentlog}" if [ "$1" == "restore" ]; then # Generate DH if it doesn't exist if [ ! -f /etc/ssl/certs/dhparam.pem ]; then - sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 + sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 | tee -a "${currentlog}" fi return fi if [ "$1" == "devinstall" ]; then - echo -e "${GREEN} Certificates should be in place.${NC}\n" + echo -e "${GREEN} Certificates should be in place.${NC}\n" | tee -a "${currentlog}" elif [ "$autoinstall" != "1" ]; then dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 case $? in @@ -196,14 +196,14 @@ installCertbot() elif [ "$autoinstall" == "1" ]; then if [ "$certtype" == "import" ]; then if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then - sudo mkdir -p /etc/letsencrypt/live/${rootdomain} + sudo mkdir -p /etc/letsencrypt/live/${rootdomain} | tee -a "${currentlog}" fi - echo -e "${GREEN} Importing certificates.${NC}" - sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem - sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem - sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem - sudo chown root:${USER} -R /etc/letsencrypt - sudo chmod 755 -R /etc/letsencrypt + echo -e "${GREEN} Importing certificates.${NC}" | tee -a "${currentlog}" + sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem | tee -a "${currentlog}" + sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem | tee -a "${currentlog}" + sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem | tee -a "${currentlog}" + sudo chown root:${USER} -R /etc/letsencrypt | tee -a "${currentlog}" + sudo chmod 755 -R /etc/letsencrypt | tee -a "${currentlog}" elif [ "$certtype" == "webroot" ]; then return fi @@ -211,6 +211,6 @@ installCertbot() # Generate DH if it doesn't exist if [ ! -f /etc/ssl/certs/dhparam.pem ]; then - sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 + sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 | tee -a "${currentlog}" fi } \ No newline at end of file diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 3d7038204b..c1419ce3da 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -12,6 +12,9 @@ CFG_VERSION="8" # Main install function mainInstall() { + # Set log file + currentlog="${installlog}" + # Repo info for Postegres and Mongo # InstallFunctions setInstallRepos; @@ -173,11 +176,11 @@ mainInstall() createMeshNginxConf; # Enable Mesh and RMM sites - sudo ln -s /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-enabled/rmm.conf - sudo ln -s /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-enabled/meshcentral.conf + sudo ln -s /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-enabled/rmm.conf | tee -a "${currentlog}" + sudo ln -s /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-enabled/meshcentral.conf | tee -a "${currentlog}" # Create conf directory - sudo mkdir /etc/conf.d + sudo mkdir /etc/conf.d | tee -a "${currentlog}" # Create Celery systemd service # Misc functions @@ -198,7 +201,7 @@ mainInstall() createCeleryBeatService; # Correct conf dir ownership - sudo chown "${USER}:${USER}" -R /etc/conf.d/ + sudo chown "${USER}:${USER}" -R /etc/conf.d/ | tee -a "${currentlog}" # Create MeshCentral systemd service # Misc functions @@ -207,15 +210,15 @@ mainInstall() createMeshCentralService; # Update services info - sudo systemctl daemon-reload + sudo systemctl daemon-reload | tee -a "${currentlog}" # Verify and correct permissions if [ -d ~/.npm ]; then - sudo chown -R "${USER}:${GROUP}" ~/.npm + sudo chown -R "${USER}:${GROUP}" ~/.npm | tee -a "${currentlog}" fi if [ -d ~/.config ]; then - sudo chown -R "${USER}:${GROUP}" ~/.config + sudo chown -R "${USER}:${GROUP}" ~/.config | tee -a "${currentlog}" fi # Install frontend @@ -231,7 +234,7 @@ mainInstall() createFrontendNginxConf; # Enable Frontend site - sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf + sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf | tee -a "${currentlog}" # Webroot certificate fix if [ "$certtype" == "webroot" ]; then @@ -244,9 +247,9 @@ mainInstall() for i in rmm.service daphne.service celery.service celerybeat.service nginx do - sudo systemctl enable ${i} - sudo systemctl stop ${i} - sudo systemctl start ${i} + sudo systemctl enable ${i} | tee -a "${currentlog}" + sudo systemctl stop ${i} | tee -a "${currentlog}" + sudo systemctl start ${i} | tee -a "${currentlog}" done sleep 5 @@ -275,7 +278,7 @@ mainInstall() enableNatsService; # Disable django admin - sed -i 's/ADMIN_ENABLED = True/ADMIN_ENABLED = False/g' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sed -i 's/ADMIN_ENABLED = True/ADMIN_ENABLED = False/g' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | tee -a "${currentlog}" # Restart core services # Misc functions @@ -283,17 +286,19 @@ mainInstall() for i in rmm.service daphne.service celery.service celerybeat.service do - sudo systemctl stop ${i} - sudo systemctl start ${i} + sudo systemctl stop ${i} | tee -a "${currentlog}" + sudo systemctl start ${i} | tee -a "${currentlog}" done # Yay, we're done! # Misc functions print_yellow "Installation complete!"; - echo -e "${YELLOW} Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n" - echo -e "${YELLOW} Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n" - echo -e "${YELLOW} MeshCentral username: ${GREEN}${meshusername}${NC}" - echo -e "${YELLOW} MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n" + echo -e "${YELLOW} Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n" | tee -a no-peeking.log + echo -e "${YELLOW} Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n" | tee -a no-peeking.log + echo -e "${YELLOW} MeshCentral username: ${GREEN}${meshusername}${NC}" | tee -a no-peeking.log + echo -e "${YELLOW} MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n" | tee -a no-peeking.log + + sudo chmod 600 $PWD/no-peeking.log if [ "$BEHIND_NAT" = true ]; then echo -e "${YELLOW} Read below if your router does NOT support Hairpin NAT:${NC}\n" @@ -314,6 +319,9 @@ mainInstall() # Update function updateTRMM() { + # Set log file + currentlog="${updatelog}" + # Check if user is same as during installation # UpdateRestoreFunctions checkSameUser "$INSTALL_TYPE"; @@ -341,12 +349,12 @@ updateTRMM() # Stop services for i in nginx nats-api nats rmm daphne celery celerybeat do - echo -e "${GREEN} Stopping ${i} service...${NC}" - sudo systemctl stop "${i}" + echo -e "${GREEN} Stopping ${i} service...${NC}" | tee -a "${currentlog}" + sudo systemctl stop "${i}" | tee -a "${currentlog}" done # Rebuild uwsgi config - rm -f /rmm/api/tacticalrmm/app.ini + rm -f /rmm/api/tacticalrmm/app.ini | tee -a "${currentlog}" # Config and Service functions createUwsgiConf; @@ -360,15 +368,15 @@ updateTRMM() # This does stuff if [ -d ~/.npm ]; then - sudo rm -rf ~/.npm + sudo rm -rf ~/.npm | tee -a "${currentlog}" fi if [ -d ~/.cache ]; then - sudo rm -rf ~/.cache + sudo rm -rf ~/.cache | tee -a "${currentlog}" fi if [ -d ~/.config ]; then - sudo chown -R "${USER}:${GROUP}" ~/.config + sudo chown -R "${USER}:${GROUP}" ~/.config | tee -a "${currentlog}" fi # Check NodeJS version, update if needed and update MeshCentral @@ -394,12 +402,12 @@ updateTRMM() cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; # Apply updated Ownership and perms - sudo chown "${USER}:${USER}" -R /rmm - sudo chown "${USER}:${USER}" -R "${SCRIPTS_DIR}" - sudo chown "${USER}:${USER}" /var/log/celery - sudo chown "${USER}:${USER}" -R /etc/conf.d/ - sudo chown "root:${USER}" -R /etc/letsencrypt - sudo chmod 755 -R /etc/letsencrypt + sudo chown "${USER}:${USER}" -R /rmm | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R "${SCRIPTS_DIR}" | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" /var/log/celery | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R /etc/conf.d/ | tee -a "${currentlog}" + sudo chown "root:${USER}" -R /etc/letsencrypt | tee -a "${currentlog}" + sudo chmod 755 -R /etc/letsencrypt | tee -a "${currentlog}" # Check additional Nginx settings and update # InstallFunctions @@ -430,13 +438,13 @@ updateTRMM() # Start services for i in nats nats-api rmm daphne celery celerybeat nginx do - echo -e "${GREEN} Starting ${i} service${NC}" - sudo systemctl start "${i}" + echo -e "${GREEN} Starting ${i} service${NC}" | tee -a "${currentlog}" + sudo systemctl start "${i}" | tee -a "${currentlog}" done sleep 3 # Push agent updates - /rmm/api/env/bin/python /rmm/api/tacticalrmm/manage.py update_agents + /rmm/api/env/bin/python /rmm/api/tacticalrmm/manage.py update_agents | tee -a "${currentlog}" # Update MeshCentral if necessary updateMeshCentral; @@ -446,7 +454,7 @@ updateTRMM() enableMeshService "$INSTALL_TYPE"; # Cleanup - rm -f $TMP_SETTINGS + rm -f $TMP_SETTINGS | tee -a "${currentlog}" # Bye-bye # Misc functions @@ -458,24 +466,27 @@ updateTRMM() # Backup Function backupTRMM() { + # Set log file + currentlog="${backuplog}" + # Pull Postgres info POSTGRES_USER=$(grep -w USER /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//') POSTGRES_PW=$(grep -w PASSWORD /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//') # Check if rmmbackup folder exists, if not create it if [ ! -d /rmmbackups ]; then - sudo mkdir /rmmbackups - sudo chown "${USER}:${USER}" /rmmbackups + sudo mkdir /rmmbackups | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" /rmmbackups | tee -a "${currentlog}" fi # Remove old MeshCentral backups if [ -d /meshcentral/meshcentral-backup ]; then - rm -rf /meshcentral/meshcentral-backup/* + rm -rf /meshcentral/meshcentral-backup/* | tee -a "${currentlog}" fi # Remove old MeshCentral DB backups if [ -d /meshcentral/meshcentral-coredumps ]; then - rm -f /meshcentral/meshcentral-coredumps/* + rm -f /meshcentral/meshcentral-coredumps/* | tee -a "${currentlog}" fi # Set info for backup and folders @@ -484,43 +495,43 @@ backupTRMM() sysd="/etc/systemd/system" # Create temp backup subdirectories - mkdir -p ${tmp_dir}/meshcentral/mongo - mkdir ${tmp_dir}/postgres - mkdir ${tmp_dir}/certs - mkdir ${tmp_dir}/nginx - mkdir ${tmp_dir}/systemd - mkdir ${tmp_dir}/rmm - mkdir ${tmp_dir}/confd + mkdir -p ${tmp_dir}/meshcentral/mongo | tee -a "${currentlog}" + mkdir ${tmp_dir}/postgres | tee -a "${currentlog}" + mkdir ${tmp_dir}/certs | tee -a "${currentlog}" + mkdir ${tmp_dir}/nginx | tee -a "${currentlog}" + mkdir ${tmp_dir}/systemd | tee -a "${currentlog}" + mkdir ${tmp_dir}/rmm | tee -a "${currentlog}" + mkdir ${tmp_dir}/confd | tee -a "${currentlog}" # Dump Postgres database - pg_dump --dbname=postgresql://"${POSTGRES_USER}":"${POSTGRES_PW}"@127.0.0.1:5432/tacticalrmm | gzip -9 > ${tmp_dir}/postgres/db-${dt_now}.psql.gz + pg_dump --dbname=postgresql://"${POSTGRES_USER}":"${POSTGRES_PW}"@127.0.0.1:5432/tacticalrmm | gzip -9 > ${tmp_dir}/postgres/db-${dt_now}.psql.gz | tee -a "${currentlog}" # Backup Mesh stuff - tar -czvf ${tmp_dir}/meshcentral/mesh.tar.gz --exclude=/meshcentral/node_modules /meshcentral - mongodump --gzip --out=${tmp_dir}/meshcentral/mongo + tar -czvf ${tmp_dir}/meshcentral/mesh.tar.gz --exclude=/meshcentral/node_modules /meshcentral | tee -a "${currentlog}" + mongodump --gzip --out=${tmp_dir}/meshcentral/mongo | tee -a "${currentlog}" # Backup certs - sudo tar -czvf ${tmp_dir}/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt . + sudo tar -czvf ${tmp_dir}/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt . | tee -a "${currentlog}" # Backup Nginx configs - sudo tar -czvf ${tmp_dir}/nginx/etc-nginx.tar.gz -C /etc/nginx . + sudo tar -czvf ${tmp_dir}/nginx/etc-nginx.tar.gz -C /etc/nginx . | tee -a "${currentlog}" # Backup other config files - sudo tar -czvf ${tmp_dir}/confd/etc-confd.tar.gz -C /etc/conf.d . + sudo tar -czvf ${tmp_dir}/confd/etc-confd.tar.gz -C /etc/conf.d . | tee -a "${currentlog}" # Copy service files - sudo cp ${sysd}/rmm.service ${sysd}/celery.service ${sysd}/celerybeat.service ${sysd}/meshcentral.service ${sysd}/nats.service ${sysd}/daphne.service ${tmp_dir}/systemd/ + sudo cp ${sysd}/rmm.service ${sysd}/celery.service ${sysd}/celerybeat.service ${sysd}/meshcentral.service ${sysd}/nats.service ${sysd}/daphne.service ${tmp_dir}/systemd/ | tee -a "${currentlog}" if [ -f "${sysd}/nats-api.service" ]; then - sudo cp ${sysd}/nats-api.service ${tmp_dir}/systemd/ + sudo cp ${sysd}/nats-api.service ${tmp_dir}/systemd/ | tee -a "${currentlog}" fi - 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/ + cat /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | gzip -9 > ${tmp_dir}/rmm/debug.log.gz | tee -a "${currentlog}" + cp /rmm/api/tacticalrmm/tacticalrmm/local_settings.py ${tmp_dir}/rmm/ | tee -a "${currentlog}" - tar -cf /rmmbackups/rmm-backup-${dt_now}.tar -C ${tmp_dir} . + tar -cf /rmmbackups/rmm-backup-${dt_now}.tar -C ${tmp_dir} . | tee -a "${currentlog}" # Remove temp files/folders - rm -rf ${tmp_dir} + rm -rf ${tmp_dir} | tee -a "${currentlog}" # Misc functions print_green "Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar"; @@ -530,6 +541,9 @@ backupTRMM() # Restore T-RMM restoreTRMM() { + # Set log file + currentlog="${restorelog}" + # Repo info for Postegres and Mongo # InstallFunctions setInstallRepos; @@ -572,11 +586,11 @@ restoreTRMM() # Misc functions 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 root:${USER} -R /etc/letsencrypt - sudo chmod 755 -R /etc/letsencrypt + sudo rm -rf /etc/letsencrypt | tee -a "${currentlog}" + sudo mkdir /etc/letsencrypt | tee -a "${currentlog}" + sudo tar -xzf $tmp_dir/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt | tee -a "${currentlog}" + sudo chown root:${USER} -R /etc/letsencrypt | tee -a "${currentlog}" + sudo chmod 755 -R /etc/letsencrypt | tee -a "${currentlog}" # Recreate Nginx conf files # Config and Service functions @@ -590,16 +604,16 @@ restoreTRMM() # Misc functions print_green 'Restoring celery configs'; - sudo mkdir /etc/conf.d - sudo tar -xzf $tmp_dir/confd/etc-confd.tar.gz -C /etc/conf.d - sudo chown "${USER}:${USER}" -R /etc/conf.d + sudo mkdir /etc/conf.d | tee -a "${currentlog}" + sudo tar -xzf $tmp_dir/confd/etc-confd.tar.gz -C /etc/conf.d | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R /etc/conf.d | tee -a "${currentlog}" # Restoring services # Misc functions print_green 'Restoring systemd services'; - sudo cp $tmp_dir/systemd/* /etc/systemd/system/ - sudo systemctl daemon-reload + sudo cp $tmp_dir/systemd/* /etc/systemd/system/ | tee -a "${currentlog}" + sudo systemctl daemon-reload | tee -a "${currentlog}" # Install Python # Misc functions @@ -628,7 +642,7 @@ restoreTRMM() # Restore Mongo database # Misc functions print_green 'Restoring MongoDB'; - mongorestore --gzip $tmp_dir/meshcentral/mongo + mongorestore --gzip $tmp_dir/meshcentral/mongo | tee -a "${currentlog}" # Clone main repo # Misc functions @@ -661,10 +675,10 @@ restoreTRMM() createUwsgiConf; # Restoring other misc stuff - cp $tmp_dir/rmm/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/ - cp $tmp_dir/rmm/env /rmm/web/.env - gzip -d $tmp_dir/rmm/debug.log.gz - cp $tmp_dir/rmm/django_debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/ + cp $tmp_dir/rmm/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/ | tee -a "${currentlog}" + cp $tmp_dir/rmm/env /rmm/web/.env | tee -a "${currentlog}" + gzip -d $tmp_dir/rmm/debug.log.gz | tee -a "${currentlog}" + cp $tmp_dir/rmm/django_debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/ | tee -a "${currentlog}" # Install NATS-API # Misc functions @@ -679,11 +693,11 @@ restoreTRMM() 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 "DROP DATABASE IF EXISTS tacticalrmm" | tee -a "${currentlog}" # Database functions createPGDB; - gzip -d $tmp_dir/postgres/*.psql.gz + gzip -d $tmp_dir/postgres/*.psql.gz | tee -a "${currentlog}" PGPASSWORD="${pgpw} psql -h localhost -U ${pgusername} -d tacticalrmm -f $tmp_dir/postgres/db*.psql" # Restore Backend @@ -695,8 +709,8 @@ restoreTRMM() # Start NATS # Misc functions print_green 'Start NATS'; - sudo systemctl enable nats.service - sudo systemctl start nats.service + sudo systemctl enable nats.service | tee -a "${currentlog}" + sudo systemctl start nats.service | tee -a "${currentlog}" # Install frontend # Misc functions @@ -705,15 +719,15 @@ restoreTRMM() installFrontEnd "$INSTALL_TYPE"; # reset perms - sudo chown "${USER}:${USER}" -R /rmm - sudo chown "${USER}:${USER}" /var/log/celery - sudo chown "${USER}:${USER}" -R /etc/conf.d/ - sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.npm - sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.config - sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.cache + sudo chown "${USER}:${USER}" -R /rmm | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" /var/log/celery | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R /etc/conf.d/ | tee -a "${currentlog}" + sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.npm | tee -a "${currentlog}" + sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.config | tee -a "${currentlog}" + sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.cache | tee -a "${currentlog}" # Update services info - sudo systemctl daemon-reload + sudo systemctl daemon-reload | tee -a "${currentlog}" # Enable RMM, Daphne, Celery, Nats-api, and Nginx services # Misc functions @@ -721,17 +735,17 @@ restoreTRMM() for i in celery.service celerybeat.service rmm.service daphne.service nats-api.service nginx do - sudo systemctl enable ${i} - sudo systemctl stop ${i} - sudo systemctl start ${i} + sudo systemctl enable ${i} | tee -a "${currentlog}" + sudo systemctl stop ${i} | tee -a "${currentlog}" + sudo systemctl start ${i} | tee -a "${currentlog}" done sleep 5 # Start MeshCentral # Misc functions print_green 'Starting meshcentral'; - sudo systemctl enable meshcentral - sudo systemctl start meshcentral + sudo systemctl enable meshcentral | tee -a "${currentlog}" + sudo systemctl start meshcentral | tee -a "${currentlog}" # Done!!!! # Misc functions @@ -743,6 +757,9 @@ restoreTRMM() # Troubleshooting utility troubleShoot() { + # Set log file + currentlog="${checklog}" + # Get existing domain info if [ -f /etc/nginx/sites-available/rmm.conf ] && [ -f /etc/nginx/sites-available/rmm.conf ] && [ -f /etc/nginx/sites-available/rmm.conf ]; then # Misc functions @@ -759,7 +776,7 @@ troubleShoot() pingDomain "$meshdomain"; # Verify IPs - echo -e "${GREEN} Checking IPs${NC}" | tee -a checklog.log + echo -e "${GREEN} Checking IPs${NC}" | tee -a "${currentlog}" echo -e "\n" # Troubleshooting functions checkIPisLive "$rmmdomain"; @@ -787,7 +804,7 @@ troubleShoot() # Get WAN IP wanip=$(dig @resolver4.opendns.com myip.opendns.com +short) - echo -e "${GREEN} WAN IP is $wanip.${NC}" | tee -a checklog.log + echo -e "${GREEN} WAN IP is $wanip.${NC}" | tee -a "${currentlog}" echo -e "\n" # Check if ports are open @@ -805,15 +822,15 @@ troubleShoot() checkIfCertIsValid; # Generate log summary - echo -e "${GREEN} Getting summary output of logs.${NC}" | tee -a checklog.log + echo -e "${GREEN} Getting summary output of logs.${NC}" | tee -a "${currentlog}" echo -e "\n" - tail /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | tee -a checklog.log + tail /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | tee -a "${currentlog}" echo -e "\n" - tail /rmm/api/tacticalrmm/tacticalrmm/private/log/error.log | tee -a checklog.log + tail /rmm/api/tacticalrmm/tacticalrmm/private/log/error.log | tee -a "${currentlog}" echo -e "\n" # Misc functions - print_yellow "You will have a log file called checklog.log in the directory you ran this script from."; + print_yellow "You will have a log file called checklog_$rundate.log in the directory you ran this script from."; return } \ No newline at end of file diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index 2ac05b1d30..fc6d8d39ff 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -13,10 +13,10 @@ CFG_VERSION="8" pingDomain() { if ( ping -c 1 $1 &> /dev/null ); then - echo -e "${GREEN} Verified $1 by ping.${NC}" | tee -a checklog.log + echo -e "${GREEN} Verified $1 by ping.${NC}" | tee -a "${currentlog}" echo -e "\n" else - echo -e "${RED} $1 cannot be verified by ping.${NC}" | tee -a checklog.log + echo -e "${RED} $1 cannot be verified by ping.${NC}" | tee -a "${currentlog}" echo -e "\n" fi } @@ -31,12 +31,12 @@ checkIPisLive() reminputip=`dig @8.8.8.8 +short $1` if [ "$locinputip" == "$reminputip" ]; then - echo -e "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log + echo -e "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a "${currentlog}" echo -e "\n" else - echo -e "${YELLOW} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a checklog.log + echo -e "${YELLOW} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a "${currentlog}" echo -e "\n" | tee -a checklog.log - echo -e "${YELLOW} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}" | tee -a checklog.log + echo -e "${YELLOW} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}" | tee -a "${currentlog}" echo -e "\n" fi } @@ -61,10 +61,10 @@ readServicesStatus() checkIfServiceActive() { if [ $1 = active ]; then - echo -e "${GREEN} Success $2 is Running.${NC}" | tee -a checklog.log + echo -e "${GREEN} Success $2 is Running.${NC}" | tee -a "${currentlog}" echo -e "\n" else - echo -e "${RED} $2 is not running. \(Tactical will not work without this\)${NC}" | tee -a checklog.log + echo -e "${RED} $2 is not running. \(Tactical will not work without this\)${NC}" | tee -a "${currentlog}" echo -e "\n" fi } @@ -73,10 +73,10 @@ checkIfServiceActive() isPortOpen() { if ( nc -zv $wanip $1 2>&1 >/dev/null ); then - echo -e "${GREEN} $2 Port is open.${NC}" | tee -a checklog.log + echo -e "${GREEN} $2 Port is open.${NC}" | tee -a "${currentlog}" echo -e "\n" else - echo -e "${YELLOW} $2 port is closed. \(you may want this if running locally only\)${NC}" | tee -a checklog.log + echo -e "${YELLOW} $2 port is closed. \(you may want this if running locally only\)${NC}" | tee -a "${currentlog}" echo -e "\n" fi } @@ -84,7 +84,7 @@ isPortOpen() # Check proxy checkProxy() { - echo -e "${GREEN} Checking For Proxy.${NC}" | tee -a checklog.log + echo -e "${GREEN} Checking For Proxy.${NC}" | tee -a "${currentlog}" echo -e "\n" echo -e "${YELLOW} ......this might take a while!!${NC}" @@ -93,19 +93,19 @@ checkProxy() 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 -e "${GREEN} No Proxy detected using Certificate.${NC}" | tee -a checklog.log + echo -e "${GREEN} No Proxy detected using Certificate.${NC}" | tee -a "${currentlog}" echo -e "\n" else - echo -e "${YELLOW} Proxy detected using Certificate.${NC}" | tee -a checklog.log + echo -e "${YELLOW} Proxy detected using Certificate.${NC}" | tee -a "${currentlog}" echo -e "\n" fi # Detect Proxy via IP if [ "$wanip" != "$remrmmip" ]; then - echo -e "${YELLOW} Proxy detected using IP.${NC}" | tee -a checklog.log + echo -e "${YELLOW} Proxy detected using IP.${NC}" | tee -a "${currentlog}" echo -e "\n" else - echo -e "${GREEN} No Proxy detected using IP.${NC}" | tee -a checklog.log + echo -e "${GREEN} No Proxy detected using IP.${NC}" | tee -a "${currentlog}" echo -e "\n" fi } @@ -113,7 +113,7 @@ checkProxy() # Check for valid cert checkIfCertIsValid() { - echo -e "${YELLOW} Checking if SSL Certificate is up to date.${NC}" | tee -a checklog.log + echo -e "${YELLOW} Checking if SSL Certificate is up to date.${NC}" | tee -a "${currentlog}" echo -e "\n" # SSL Certificate check @@ -123,11 +123,11 @@ checkIfCertIsValid() certexp="$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/${rootdomain}/fullchain.pem | cut -d "=" -f2)" if [[ "$cert" == *"OK"* ]]; then - echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a checklog.log - echo -e "${GREEN} SSL Certificate expires $certexp${NC}" | tee -a checklog.log + echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a "${currentlog}" + echo -e "${GREEN} SSL Certificate expires $certexp${NC}" | tee -a "${currentlog}" echo -e "\n" else - echo -e "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a checklog.log + echo -e "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a "${currentlog}" echo -e "\n" fi # Check Webroot authenticated certs @@ -136,11 +136,11 @@ checkIfCertIsValid() certexp="$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/${rootdomain}/fullchain.pem | cut -d "=" -f2)" if [[ "$cert" == *"OK"* ]]; then - echo -e "${GREEN} SSL Certificate for $rmmdomain , $frontenddomain , and $meshdomain is fine.${NC}" | tee -a checklog.log - echo -e "${GREEN} SSL Certificate expires $certexp${NC}" | tee -a checklog.log + echo -e "${GREEN} SSL Certificate for $rmmdomain , $frontenddomain , and $meshdomain is fine.${NC}" | tee -a "${currentlog}" + echo -e "${GREEN} SSL Certificate expires $certexp${NC}" | tee -a "${currentlog}" echo -e "\n" else - echo -e "${RED} SSL Certificate has expired or doesnt exist for $rmmdomain , $frontenddomain , and $meshdomain.${NC}" | tee -a checklog.log + echo -e "${RED} SSL Certificate has expired or doesnt exist for $rmmdomain , $frontenddomain , and $meshdomain.${NC}" | tee -a "${currentlog}" echo -e "\n" fi fi From acc444170554fa43f9321a206c476fc9fe85e1e9 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 10:59:05 -0500 Subject: [PATCH 147/203] testing logging --- installer-util.sh | 6 +- script-cfg/CertificateFunctions.cfg | 114 +++++------ script-cfg/ConfigAndServiceFunctions.cfg | 240 +++++++++++------------ script-cfg/InstallFunctions.cfg | 76 +++---- 4 files changed, 218 insertions(+), 218 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index ac197a31a2..a272a4a8b8 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -61,14 +61,14 @@ certtype="" # Check if directory exists, if not, create if [ ! -d $PWD/script-cfg ]; then - mkdir $PWD/script-cfg | tee -a "${currentlog}" + mkdir $PWD/script-cfg 2>&1 | tee -a "${currentlog}" fi # Get cfg files function getCfgFiles() { if [ ! -f "$PWD/script-cfg/$2" ]; then - wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" | tee -a "${currentlog}" + wget "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" 2>&1 | tee -a "${currentlog}" fi } @@ -273,7 +273,7 @@ checkTacticalUser; checkLocale; # 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 | tee -a "${currentlog}" +sudo systemctl restart systemd-journald.service 2>&1 | tee -a "${currentlog}" #################### # Menu Functions # diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index ffe9f8f469..6e1ee5ad57 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -34,26 +34,26 @@ importCerts() { dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate, private key, and CA Chain file, in that order.\n\nTo paste the contents, type i , then shift+insert.\n\nAfter pasting the contents, type esc , then shift-: , then wq , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then - sudo mkdir -p /etc/letsencrypt/live/${rootdomain} | tee -a "${currentlog}" + sudo mkdir -p /etc/letsencrypt/live/${rootdomain} 2>&1 | tee -a "${currentlog}" fi if [ -f /etc/letsencrypt/live/${rootdomain}/fullchain.pem ]; then - sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/fullchain.pem | tee -a "${currentlog}" + sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/fullchain.pem 2>&1 | tee -a "${currentlog}" fi - sudo vim /etc/letsencrypt/live/${rootdomain}/fullchain.pem | tee -a "${currentlog}" + sudo vim /etc/letsencrypt/live/${rootdomain}/fullchain.pem 2>&1 | tee -a "${currentlog}" if [ -f /etc/letsencrypt/live/${rootdomain}/privkey.pem ]; then - sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/privkey.pem | tee -a "${currentlog}" + sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/privkey.pem 2>&1 | tee -a "${currentlog}" fi - sudo vim /etc/letsencrypt/live/${rootdomain}/privkey.pem | tee -a "${currentlog}" + sudo vim /etc/letsencrypt/live/${rootdomain}/privkey.pem 2>&1 | tee -a "${currentlog}" if [ -f /etc/letsencrypt/live/${rootdomain}/chain.pem ]; then - sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/chain.pem | tee -a "${currentlog}" + sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/chain.pem 2>&1 | tee -a "${currentlog}" fi - sudo vim /etc/letsencrypt/live/${rootdomain}/chain.pem | tee -a "${currentlog}" + sudo vim /etc/letsencrypt/live/${rootdomain}/chain.pem 2>&1 | tee -a "${currentlog}" - sudo chown root:${USER} -R /etc/letsencrypt | tee -a "${currentlog}" - sudo chmod 755 -R /etc/letsencrypt | tee -a "${currentlog}" + sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" } # Generate certs @@ -64,77 +64,77 @@ generateCerts() echo -e "${GREEN} Getting wildcard certificate...${NC}" | tee -a "${currentlog}" # Get initial DNS text entry - sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email | tee -a "${currentlog}" + sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email 2>&1 | tee -a "${currentlog}" # Ensure TXT record has populated acmeChallengeCheck "$rootdomain"; # Keep going until successful cert issue after adding DNS txt entry while [[ $? -ne 0 ]]; do - sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email | tee -a "${currentlog}" + sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email 2>&1 | tee -a "${currentlog}" done - sudo chown root:${USER} -R /etc/letsencrypt | tee -a "${currentlog}" - sudo chmod 755 -R /etc/letsencrypt | tee -a "${currentlog}" + sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" # Webroot method elif [ "$certtype" == "webroot" ]; then echo -e "${GREEN} Getting webroot certificates...${NC}" | tee -a "${currentlog}" # Edit nginx conf files - sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" - sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" - sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" - sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" - sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" - sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" - sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" - sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" - sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" - sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" - sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" - sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" + sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" # Create folder - sudo mkdir -p /var/www/letsencrypt | tee -a "${currentlog}" + sudo mkdir -p /var/www/letsencrypt 2>&1 | tee -a "${currentlog}" # Start nginx - sudo systemctl start nginx | tee -a "${currentlog}" + sudo systemctl start nginx 2>&1 | tee -a "${currentlog}" # Get webroot certs - sudo certbot certonly --webroot --webroot-path /var/www/letsencrypt/ --agree-tos -m ${letsemail} --no-eff-email -d ${rmmdomain} -d ${frontenddomain} -d ${meshdomain} | tee -a "${currentlog}" + sudo certbot certonly --webroot --webroot-path /var/www/letsencrypt/ --agree-tos -m ${letsemail} --no-eff-email -d ${rmmdomain} -d ${frontenddomain} -d ${meshdomain} 2>&1 | tee -a "${currentlog}" # Stop nginx - sudo systemctl stop nginx | tee -a "${currentlog}" + sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" # Switch from snakeoil to webroot - sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" - sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" - sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/rmm.conf | tee -a "${currentlog}" - sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" - sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" - sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/frontend.conf | tee -a "${currentlog}" - sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" - sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" - sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/meshcentral.conf | tee -a "${currentlog}" + sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/ssl\/certs\/ssl-cert-snakeoil.pem/letsencrypt\/live\/${rootdomain}\/fullchain.pem/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/ssl\/private\/ssl-cert-snakeoil.key/letsencrypt\/live\/${rootdomain}\/privkey.pem/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#ssl_stapling/ssl_stapling/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" # Create dns type folder if it doesn't exist if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then - sudo mkdir -p /etc/letsencrypt/live/${rootdomain} | tee -a "${currentlog}" + sudo mkdir -p /etc/letsencrypt/live/${rootdomain} 2>&1 | tee -a "${currentlog}" fi # Create symlinks so cert paths don't need to be edited - sudo ln -s /etc/letsencrypt/live/${rmmdomain}/fullchain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem | tee -a "${currentlog}" - sudo ln -s /etc/letsencrypt/live/${rmmdomain}/privkey.pem /etc/letsencrypt/live/${rootdomain}/privkey.pem | tee -a "${currentlog}" - sudo ln -s /etc/letsencrypt/live/${rmmdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/chain.pem | tee -a "${currentlog}" + sudo ln -s /etc/letsencrypt/live/${rmmdomain}/fullchain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem 2>&1 | tee -a "${currentlog}" + sudo ln -s /etc/letsencrypt/live/${rmmdomain}/privkey.pem /etc/letsencrypt/live/${rootdomain}/privkey.pem 2>&1 | tee -a "${currentlog}" + sudo ln -s /etc/letsencrypt/live/${rmmdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/chain.pem 2>&1 | tee -a "${currentlog}" sudo echo '#!/usr/bin/env bash' | sudo tee /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh - sudo sed -i "/\#\!\/usr\/bin\/env bash/ a systemctl restart nginx meshcentral rmm celery celerybeat nats" /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh | tee -a "${currentlog}" - sudo chmod +x /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh | tee -a "${currentlog}" + sudo sed -i "/\#\!\/usr\/bin\/env bash/ a systemctl restart nginx meshcentral rmm celery celerybeat nats" /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh 2>&1 | tee -a "${currentlog}" + sudo chmod +x /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh 2>&1 | tee -a "${currentlog}" - sudo chown root:${USER} -R /etc/letsencrypt | tee -a "${currentlog}" - sudo chmod 755 -R /etc/letsencrypt | tee -a "${currentlog}" - sudo systemctl start nginx | tee -a "${currentlog}" + sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo systemctl start nginx 2>&1 | tee -a "${currentlog}" fi } @@ -152,7 +152,7 @@ renewCerts() generateCerts; - sudo systemctl restart nginx.service rmm.service celery celerybeat.service nats-api.service nats.service meshcentral.service | tee -a "${currentlog}" + sudo systemctl restart nginx.service rmm.service celery celerybeat.service nats-api.service nats.service meshcentral.service 2>&1 | tee -a "${currentlog}" } # Select DNS or Webroot @@ -173,11 +173,11 @@ dnsOrWebroot() installCertbot() { # Install Certbot - sudo apt install -y certbot | tee -a "${currentlog}" + sudo apt install -y certbot 2>&1 | tee -a "${currentlog}" if [ "$1" == "restore" ]; then # Generate DH if it doesn't exist if [ ! -f /etc/ssl/certs/dhparam.pem ]; then - sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 | tee -a "${currentlog}" + sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 2>&1 | tee -a "${currentlog}" fi return fi @@ -196,14 +196,14 @@ installCertbot() elif [ "$autoinstall" == "1" ]; then if [ "$certtype" == "import" ]; then if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then - sudo mkdir -p /etc/letsencrypt/live/${rootdomain} | tee -a "${currentlog}" + sudo mkdir -p /etc/letsencrypt/live/${rootdomain} 2>&1 | tee -a "${currentlog}" fi echo -e "${GREEN} Importing certificates.${NC}" | tee -a "${currentlog}" - sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem | tee -a "${currentlog}" - sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem | tee -a "${currentlog}" - sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem | tee -a "${currentlog}" - sudo chown root:${USER} -R /etc/letsencrypt | tee -a "${currentlog}" - sudo chmod 755 -R /etc/letsencrypt | tee -a "${currentlog}" + sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem 2>&1 | tee -a "${currentlog}" + sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem 2>&1 | tee -a "${currentlog}" + sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem 2>&1 | tee -a "${currentlog}" + sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" elif [ "$certtype" == "webroot" ]; then return fi @@ -211,6 +211,6 @@ installCertbot() # Generate DH if it doesn't exist if [ ! -f /etc/ssl/certs/dhparam.pem ]; then - sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 | tee -a "${currentlog}" + sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 2>&1 | tee -a "${currentlog}" fi } \ No newline at end of file diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 9bae5f119c..844c050a70 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -12,24 +12,24 @@ CFG_VERSION="8" # Generate mesh configuration createMeshConfig() { - sudo cp /rmm/default-configs/mesh/config.json /meshcentral/meshcentral-data/config.json + sudo cp /rmm/default-configs/mesh/config.json /meshcentral/meshcentral-data/config.json 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/mesh.example.com/$meshdomain/" /meshcentral/meshcentral-data/config.json + sudo sed -i "s/mesh.example.com/$meshdomain/" /meshcentral/meshcentral-data/config.json 2>&1 | tee -a "${currentlog}" } # Generate local settings file createLocalSettings() { - sudo cp /rmm/default-configs/python/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - - sudo sed -i "s/DJANGO_SEKRET/$DJANGO_SEKRET/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/api.example.com/$rmmdomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/ADMINURL/$ADMINURL/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/rmm.example.com/$frontenddomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/pgusername/$pgusername/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/pgpw/$pgpw/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/meshusername/$meshusername/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/mesh.example.com/$meshdomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo cp /rmm/default-configs/python/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" + + sudo sed -i "s/DJANGO_SEKRET/$DJANGO_SEKRET/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/api.example.com/$rmmdomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/ADMINURL/$ADMINURL/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/rmm.example.com/$frontenddomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/pgusername/$pgusername/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/pgpw/$pgpw/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/meshusername/$meshusername/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/mesh.example.com/$meshdomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" } # Backend configuration @@ -42,67 +42,67 @@ configureBackend() if [ "$1" == "update" ]; then CHECK_ADMIN_ENABLED=$(grep ADMIN_ENABLED /rmm/api/tacticalrmm/tacticalrmm/local_settings.py) if ! [[ $CHECK_ADMIN_ENABLED ]]; then - sudo sed -i '$ a ADMIN_ENABLED = False' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i '$ a ADMIN_ENABLED = False' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" 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 + sudo cp /rmm/natsapi/bin/nats-api /usr/local/bin 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" /usr/local/bin/nats-api 2>&1 | tee -a "${currentlog}" + sudo chmod +x /usr/local/bin/nats-api 2>&1 | tee -a "${currentlog}" if [ "${CURRENT_PIP_VER}" != "${LATEST_PIP_VER}" ] || [ "$UPDATE_TYPE" == "forced" ]; then - rm -rf /rmm/api/env - cd /rmm/api - 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 requirements.txt + rm -rf /rmm/api/env 2>&1 | tee -a "${currentlog}" + cd /rmm/api 2>&1 | tee -a "${currentlog}" + python3.10 -m venv env 2>&1 | tee -a "${currentlog}" + source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" + cd /rmm/api/tacticalrmm 2>&1 | tee -a "${currentlog}" + pip install --no-cache-dir --upgrade pip 2>&1 | tee -a "${currentlog}" + pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER} 2>&1 | tee -a "${currentlog}" + pip install --no-cache-dir -r requirements.txt 2>&1 | tee -a "${currentlog}" else - source /rmm/api/env/bin/activate - cd /rmm/api/tacticalrmm - pip install -r /rmm/api/tacticalrmm/requirements.txt + source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" + cd /rmm/api/tacticalrmm 2>&1 | tee -a "${currentlog}" + pip install -r /rmm/api/tacticalrmm/requirements.txt 2>&1 | tee -a "${currentlog}" fi - python manage.py pre_update_tasks - celery -A tacticalrmm purge -f - python manage.py migrate - python manage.py delete_tokens - python manage.py collectstatic --no-input - python manage.py reload_nats - python manage.py load_chocos - python manage.py create_installer_user - python manage.py create_natsapi_conf - python manage.py post_update_tasks + python manage.py pre_update_tasks 2>&1 | tee -a "${currentlog}" + celery -A tacticalrmm purge -f 2>&1 | tee -a "${currentlog}" + python manage.py migrate 2>&1 | tee -a "${currentlog}" + python manage.py delete_tokens 2>&1 | tee -a "${currentlog}" + python manage.py collectstatic --no-input 2>&1 | tee -a "${currentlog}" + python manage.py reload_nats 2>&1 | tee -a "${currentlog}" + python manage.py load_chocos 2>&1 | tee -a "${currentlog}" + python manage.py create_installer_user 2>&1 | tee -a "${currentlog}" + python manage.py create_natsapi_conf 2>&1 | tee -a "${currentlog}" + python manage.py post_update_tasks 2>&1 | tee -a "${currentlog}" rmmdomain=$(python manage.py get_config api) WEB_VERSION=$(python manage.py get_config webversion) - deactivate + deactivate 2>&1 | tee -a "${currentlog}" elif [ "$1" == "restore" ]; then - cd /rmm/api - 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 reload_nats - python manage.py post_update_tasks + cd /rmm/api 2>&1 | tee -a "${currentlog}" + python3.10 -m venv env 2>&1 | tee -a "${currentlog}" + source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" + cd /rmm/api/tacticalrmm 2>&1 | tee -a "${currentlog}" + pip install --no-cache-dir --upgrade pip 2>&1 | tee -a "${currentlog}" + pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER} 2>&1 | tee -a "${currentlog}" + pip install --no-cache-dir -r /rmm/api/tacticalrmm/requirements.txt 2>&1 | tee -a "${currentlog}" + python manage.py migrate 2>&1 | tee -a "${currentlog}" + python manage.py collectstatic --no-input 2>&1 | tee -a "${currentlog}" + python manage.py create_natsapi_conf 2>&1 | tee -a "${currentlog}" + python manage.py reload_nats 2>&1 | tee -a "${currentlog}" + python manage.py post_update_tasks 2>&1 | tee -a "${currentlog}" rmmdomain=$(python manage.py get_config api) WEB_VERSION=$(python manage.py get_config webversion) - deactivate + deactivate 2>&1 | tee -a "${currentlog}" elif [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then - cd /rmm/api - 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 + cd /rmm/api 2>&1 | tee -a "${currentlog}" + python3.10 -m venv env 2>&1 | tee -a "${currentlog}" + source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" + cd /rmm/api/tacticalrmm 2>&1 | tee -a "${currentlog}" + pip install --no-cache-dir --upgrade pip 2>&1 | tee -a "${currentlog}" + pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER} 2>&1 | tee -a "${currentlog}" + pip install --no-cache-dir -r /rmm/api/tacticalrmm/requirements.txt 2>&1 | tee -a "${currentlog}" + python manage.py migrate 2>&1 | tee -a "${currentlog}" + python manage.py collectstatic --no-input 2>&1 | tee -a "${currentlog}" + python manage.py create_natsapi_conf 2>&1 | tee -a "${currentlog}" + python manage.py load_chocos 2>&1 | tee -a "${currentlog}" + python manage.py load_community_scripts 2>&1 | tee -a "${currentlog}" WEB_VERSION=$(python manage.py get_config webversion) if [ "$autoinstall" == "1" ]; then djangousername="$trmmuser" @@ -121,13 +121,13 @@ configureBackend() userconfirm="n" clear -x - python manage.py createsuperuser --username ${djangousername} --email ${letsemail} - python manage.py create_installer_user + python manage.py createsuperuser --username ${djangousername} --email ${letsemail} 2>&1 | tee -a "${currentlog}" + python manage.py create_installer_user 2>&1 | tee -a "${currentlog}" RANDBASE=$(python manage.py generate_totp) # Misc functions cls; - python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} - deactivate + python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} 2>&1 | tee -a "${currentlog}" + deactivate 2>&1 | tee -a "${currentlog}" read -n 1 -s -r -p "Press any key to continue..." echo -e "\n" fi @@ -137,111 +137,111 @@ configureBackend() # Create UWSGI config createUwsgiConf() { - sudo cp /rmm/default-configs/uwsgi/app.ini /rmm/api/tacticalrmm/app.ini + sudo cp /rmm/default-configs/uwsgi/app.ini /rmm/api/tacticalrmm/app.ini 2>&1 | tee -a "${currentlog}" } # Create UWSGI service createUwsgiService() { - sudo cp /rmm/service-definitions/rmm.service /etc/systemd/system/rmm.service + sudo cp /rmm/service-definitions/rmm.service /etc/systemd/system/rmm.service 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/rmm.service + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/rmm.service 2>&1 | tee -a "${currentlog}" } # Create Daphne service createDaphneService() { - sudo cp /rmm/service-definitions/daphne.service /etc/systemd/system/daphne.service + sudo cp /rmm/service-definitions/daphne.service /etc/systemd/system/daphne.service 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/daphne.service + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/daphne.service 2>&1 | tee -a "${currentlog}" } # Create NATS service createNatsService() { - sudo cp /rmm/service-definitions/nats.service /etc/systemd/system/nats.service + sudo cp /rmm/service-definitions/nats.service /etc/systemd/system/nats.service 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats.service + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats.service 2>&1 | tee -a "${currentlog}" } # Create NATS service createNatsApiService() { - sudo cp /rmm/service-definitions/nats-api.service /etc/systemd/system/nats-api.service + sudo cp /rmm/service-definitions/nats-api.service /etc/systemd/system/nats-api.service 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats-api.service + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats-api.service 2>&1 | tee -a "${currentlog}" } # Create backend nginx conf createBackendNginxConf() { - sudo cp /rmm/default-configs/nginx/rmm.conf /etc/nginx/sites-available/rmm.conf + sudo cp /rmm/default-configs/nginx/rmm.conf /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/api.example.com/$rmmdomain/" /etc/nginx/sites-available/rmm.conf - sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/api.example.com/$rmmdomain/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" if [ "$certtype" == "dns" ]; then - sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" elif [ "$certtype" == "webroot" ]; then - sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/rmm.conf - sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/rmm.conf + sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" fi } # Create Mesh nginx conf createMeshNginxConf() { - sudo cp /rmm/default-configs/nginx/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf + sudo cp /rmm/default-configs/nginx/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/mesh.example.com/$meshdomain/" /etc/nginx/sites-available/meshcentral.conf + sudo sed -i "s/mesh.example.com/$meshdomain/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" if [ "$certtype" == "dns" ]; then - sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/meshcentral.conf + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" elif [ "$certtype" == "webroot" ]; then - sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/meshcentral.conf - sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/meshcentral.conf + sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" fi } # Create Celery service createCeleryService() { - sudo cp /rmm/service-definitions/celery.service /etc/systemd/system/celery.service + sudo cp /rmm/service-definitions/celery.service /etc/systemd/system/celery.service 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/celery.service + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/celery.service 2>&1 | tee -a "${currentlog}" } # Create Celery config createCeleryConf() { - sudo cp /rmm/default-configs/celery/celery.conf /etc/conf.d/celery.conf + sudo cp /rmm/default-configs/celery/celery.conf /etc/conf.d/celery.conf 2>&1 | tee -a "${currentlog}" } # Create CeleryBeat service createCeleryBeatService() { - sudo cp /rmm/service-definitions/celerybeat.service /etc/systemd/system/celerybeat.service + sudo cp /rmm/service-definitions/celerybeat.service /etc/systemd/system/celerybeat.service 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/celerybeat.service + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/celerybeat.service 2>&1 | tee -a "${currentlog}" } # Create MeshCentral service createMeshCentralService() { - sudo cp /rmm/service-definitions/meshcentral.service /etc/systemd/system/meshcentral.service + sudo cp /rmm/service-definitions/meshcentral.service /etc/systemd/system/meshcentral.service 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/meshcentral.service + sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/meshcentral.service 2>&1 | tee -a "${currentlog}" } # Create Frontend Nginx config createFrontendNginxConf() { - sudo cp /rmm/default-configs/nginx/frontend.conf /etc/nginx/sites-available/frontend.conf + sudo cp /rmm/default-configs/nginx/frontend.conf /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/frontend.conf + sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" if [ "$certtype" == "dns" ]; then - sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/frontend.conf + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" elif [ "$certtype" == "webroot" ]; then - sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/frontend.conf - sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/frontend.conf + sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" fi } @@ -249,9 +249,9 @@ createFrontendNginxConf() enableMeshService() { if [ "$1" != "update" ]; then - sudo systemctl enable meshcentral + sudo systemctl enable meshcentral 2>&1 | tee -a "${currentlog}" fi - sudo systemctl restart meshcentral + sudo systemctl restart meshcentral 2>&1 | tee -a "${currentlog}" sleep 3 # The first time we start meshcentral, it will need some time to generate certs and install plugins. @@ -259,7 +259,7 @@ enableMeshService() # We will know it's ready once the last line of the systemd service stdout is 'MeshCentral HTTP server running on port.....' while ! [[ $CHECK_MESH_READY ]]; do CHECK_MESH_READY=$(sudo journalctl -u meshcentral.service -b --no-pager | grep "MeshCentral HTTP server running on port") - echo -e "${YELLOW} Mesh Central not ready yet...${NC}" + echo -e "${YELLOW} Mesh Central not ready yet...${NC}" | tee -a "${currentlog}" sleep 3 done } @@ -269,46 +269,46 @@ generateMeshToken() { MESHTOKENKEY="$(node /meshcentral/node_modules/meshcentral --logintokenkey)" - sudo sed -i '$ a MESH_TOKEN_KEY = "MESHTOKENKEY"' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py - sudo sed -i "s/MESHTOKENKEY/$MESHTOKENKEY/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py + sudo sed -i '$ a MESH_TOKEN_KEY = "MESHTOKENKEY"' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/MESHTOKENKEY/$MESHTOKENKEY/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" } # Configure Mesh user and group, restart service configMeshUserGroup() { - sudo systemctl stop meshcentral + sudo systemctl stop meshcentral 2>&1 | tee -a "${currentlog}" sleep 1 - cd /meshcentral + cd /meshcentral 2>&1 | tee -a "${currentlog}" - node node_modules/meshcentral --createaccount ${meshusername} --pass ${MESHPASSWD} --email ${letsemail} + node node_modules/meshcentral --createaccount ${meshusername} --pass ${MESHPASSWD} --email ${letsemail} 2>&1 | tee -a "${currentlog}" sleep 1 - node node_modules/meshcentral --adminaccount ${meshusername} + node node_modules/meshcentral --adminaccount ${meshusername} 2>&1 | tee -a "${currentlog}" - sudo systemctl start meshcentral + sudo systemctl start meshcentral 2>&1 | tee -a "${currentlog}" 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 -e "${YELLOW} Mesh Central not ready yet...${NC}" + echo -e "${YELLOW} Mesh Central not ready yet...${NC}" | tee -a "${currentlog}" sleep 3 done - node node_modules/meshcentral/meshctrl.js --url wss://${meshdomain} --loginuser ${meshusername} --loginpass ${MESHPASSWD} AddDeviceGroup --name TacticalRMM + node node_modules/meshcentral/meshctrl.js --url wss://${meshdomain} --loginuser ${meshusername} --loginpass ${MESHPASSWD} AddDeviceGroup --name TacticalRMM 2>&1 | tee -a "${currentlog}" sleep 1 } # Configure and enable NATS service enableNatsService() { - sudo systemctl enable nats.service - cd /rmm/api/tacticalrmm - source /rmm/api/env/bin/activate - python manage.py initial_db_setup - python manage.py reload_nats - deactivate - sudo systemctl start nats.service + sudo systemctl enable nats.service 2>&1 | tee -a "${currentlog}" + cd /rmm/api/tacticalrmm 2>&1 | tee -a "${currentlog}" + source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" + python manage.py initial_db_setup 2>&1 | tee -a "${currentlog}" + python manage.py reload_nats 2>&1 | tee -a "${currentlog}" + deactivate 2>&1 | tee -a "${currentlog}" + sudo systemctl start nats.service 2>&1 | tee -a "${currentlog}" sleep 1 - sudo systemctl enable nats-api.service - sudo systemctl start nats-api.service + sudo systemctl enable nats-api.service 2>&1 | tee -a "${currentlog}" + sudo systemctl start nats-api.service 2>&1 | tee -a "${currentlog}" } \ No newline at end of file diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 0dcfa7710b..959d0c4b5b 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -50,11 +50,11 @@ setInstallRepos() installMongo() { if [ "$1" != "devinstall" ]; then - wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/mongo.gpg > /dev/null - 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 + wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/mongo.gpg > /dev/null 2>&1 | tee -a "${currentlog}" + echo "$mongodb_repo" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list 2>&1 | tee -a "${currentlog}" + sudo apt update && sudo apt install -y mongodb-org 2>&1 | tee -a "${currentlog}" + sudo systemctl enable mongod 2>&1 | tee -a "${currentlog}" + sudo systemctl restart mongod 2>&1 | tee -a "${currentlog}" sleep 5 fi } @@ -66,25 +66,25 @@ installNodeJS() if [ "$1" == "update" ]; then CURRENT_NODE_VER=$(node --version | cut -d "v" -f2 | cut -d "." -f1) if [ "$CURRENT_NODE_VER" != "$NODE_MAJOR_VER" ]; then - echo -e "${GREEN} Updating NodeJS to v${NODE_MAJOR_VER}${NC}\n" - rm -rf /rmm/web/node_modules - sudo systemctl stop meshcentral - sudo apt remove -y nodejs - sudo rm -rf /usr/lib/node_modules + echo -e "${GREEN} Updating NodeJS to v${NODE_MAJOR_VER}${NC}\n" | tee -a "${currentlog}" + rm -rf /rmm/web/node_modules 2>&1 | tee -a "${currentlog}" + sudo systemctl stop meshcentral 2>&1 | tee -a "${currentlog}" + sudo apt remove -y nodejs 2>&1 | tee -a "${currentlog}" + sudo rm -rf /usr/lib/node_modules 2>&1 | tee -a "${currentlog}" else - echo -e "${GREEN} NodeJS up to date.${NC}\n" + echo -e "${GREEN} NodeJS up to date.${NC}\n" | tee -a "${currentlog}" return fi fi - 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 + curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - 2>&1 | tee -a "${currentlog}" + sudo apt update && sudo apt install -y nodejs 2>&1 | tee -a "${currentlog}" + sudo npm install -g npm 2>&1 | tee -a "${currentlog}" if [ "$1" == "update" ]; then - sudo chown "${USER}:${USER}" -R /meshcentral - cd /meshcentral - rm -rf node_modules/ - npm install meshcentral@"${LATEST_MESH_VER}" - sudo systemctl start meshcentral + sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" + cd /meshcentral 2>&1 | tee -a "${currentlog}" + rm -rf node_modules/ 2>&1 | tee -a "${currentlog}" + npm install meshcentral@"${LATEST_MESH_VER}" 2>&1 | tee -a "${currentlog}" + sudo systemctl start meshcentral 2>&1 | tee -a "${currentlog}" fi fi } @@ -92,7 +92,7 @@ installNodeJS() # Install Redis installRedis() { - sudo apt install -y redis + sudo apt install -y redis 2>&1 | tee -a "${currentlog}" } # Install Python @@ -101,30 +101,30 @@ installPython() if [ "$1" == "update" ]; then CURRENT_PY=$(python3.10 --version | cut -d " " -f2) if [ "$CURRENT_PY" != "$PYTHON_VER" ]; then - echo -e "${GREEN} Updating to ${PYTHON_VER}.${NC}\n" + echo -e "${GREEN} Updating to ${PYTHON_VER}.${NC}\n" | tee -a "${currentlog}" elif [ "$CURRENT_PY" == "$PYTHON_VER" ]; then - echo -e "${GREEN} Python is up to date.${NC}\n" + echo -e "${GREEN} Python is up to date.${NC}\n" | tee -a "${currentlog}" return fi fi if [ "$1" == "devinstall" ]; then - echo -e "${GREEN} Python already installed${NC}\n" + echo -e "${GREEN} Python already installed${NC}\n" | tee -a "${currentlog}" return else numprocs=$(nproc) - 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 $numprocs - sudo make altinstall - cd ~ - sudo rm -rf Python-${PYTHON_VER} Python-${PYTHON_VER}.tgz + cd ~ 2>&1 | tee -a "${currentlog}" + wget https://www.python.org/ftp/python/${PYTHON_VER}/Python-${PYTHON_VER}.tgz 2>&1 | tee -a "${currentlog}" + tar -xf Python-${PYTHON_VER}.tgz 2>&1 | tee -a "${currentlog}" + cd Python-${PYTHON_VER} 2>&1 | tee -a "${currentlog}" + ./configure --enable-optimizations 2>&1 | tee -a "${currentlog}" + make -j $numprocs 2>&1 | tee -a "${currentlog}" + sudo make altinstall 2>&1 | tee -a "${currentlog}" + cd ~ 2>&1 | tee -a "${currentlog}" + sudo rm -rf Python-${PYTHON_VER} Python-${PYTHON_VER}.tgz 2>&1 | tee -a "${currentlog}" if [ "$1" == "devprep" ]; then # Misc functions - print_green 'All Prereqs installed'; + print_green 'All Prereqs installed' | tee -a "${currentlog}" exit fi fi @@ -133,12 +133,12 @@ installPython() # Install Postgresql installPostgresql() { - echo "$postgresql_repo" | sudo tee /etc/apt/sources.list.d/pgdg.list - wget -qO - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/postgresql.gpg > /dev/null - sudo apt update && sudo apt install -y postgresql-14 + echo "$postgresql_repo" | sudo tee /etc/apt/sources.list.d/pgdg.list 2>&1 | tee -a "${currentlog}" + wget -qO - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/postgresql.gpg > /dev/null 2>&1 | tee -a "${currentlog}" + sudo apt update && sudo apt install -y postgresql-14 2>&1 | tee -a "${currentlog}" sleep 2 - sudo systemctl enable postgresql - sudo systemctl restart postgresql + sudo systemctl enable postgresql 2>&1 | tee -a "${currentlog}" + sudo systemctl restart postgresql 2>&1 | tee -a "${currentlog}" sleep 5 } From dd646ce4284ccadf88347b1d162d0c94a4f3406c Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 11:53:51 -0500 Subject: [PATCH 148/203] more logging --- script-cfg/InstallFunctions.cfg | 182 ++++++++++++++++---------------- script-cfg/MiscFunctions.cfg | 142 ++++++++++++------------- script-cfg/NetworkFunctions.cfg | 12 +-- script-cfg/ParentFunctions.cfg | 106 +++++++++---------- 4 files changed, 221 insertions(+), 221 deletions(-) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 959d0c4b5b..cc6c958b13 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -148,25 +148,25 @@ installNats() if [ "$1" == "update" ]; then HAS_LATEST_NATS=$(/usr/local/bin/nats-server -version | cut -d " " -f2 | cut -d "v" -f2) if [ "$HAS_LATEST_NATS" != "${NATS_SERVER_VER}" ]; then - echo -e "${GREEN} Updating nats to v${NATS_SERVER_VER}${NC}\n" + echo -e "${GREEN} Updating nats to v${NATS_SERVER_VER}${NC}\n" | tee -a "${currentlog}" else - echo -e "${GREEN} Nats is up to date${NC}\n" + echo -e "${GREEN} Nats is up to date${NC}\n" | tee -a "${currentlog}" return fi fi if [ "$1" == "install" ] || [ "$1" == "devinstall" ] || [ "$1" == "restore" ]; then NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') fi - nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) - wget -q 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} + nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) 2>&1 | tee -a "${currentlog}" + wget -q 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} 2>&1 | tee -a "${currentlog}" + tar -xzf ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz -C ${nats_tmp} 2>&1 | tee -a "${currentlog}" if [ "$1" == "update" ]; then - sudo rm -f /usr/local/bin/nats-server + sudo rm -f /usr/local/bin/nats-server 2>&1 | tee -a "${currentlog}" fi - 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 - rm -rf ${nats_tmp} + sudo mv ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64/nats-server /usr/local/bin/ 2>&1 | tee -a "${currentlog}" + sudo chmod +x /usr/local/bin/nats-server 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" /usr/local/bin/nats-server 2>&1 | tee -a "${currentlog}" + rm -rf ${nats_tmp} 2>&1 | tee -a "${currentlog}" } # Install frontend @@ -174,24 +174,24 @@ installFrontEnd() { if [ "$1" == "update" ]; then if [ -d /rmm/web ]; then - sudo rm -rf /rmm/web + sudo rm -rf /rmm/web 2>&1 | tee -a "${currentlog}" fi if [ -d /var/www/rmm/dist ]; then - sudo rm -rf /var/www/rmm/dist + sudo rm -rf /var/www/rmm/dist 2>&1 | tee -a "${currentlog}" fi fi webtar="trmm-web-v${WEB_VERSION}.tar.gz" - wget -q https://github.com/amidaware/tacticalrmm-web/releases/download/v${WEB_VERSION}/${webtar} -O /tmp/${webtar} + wget -q https://github.com/amidaware/tacticalrmm-web/releases/download/v${WEB_VERSION}/${webtar} -O /tmp/${webtar} 2>&1 | tee -a "${currentlog}" if [ ! -d /var/www/rmm ]; then - sudo mkdir -p /var/www/rmm + sudo mkdir -p /var/www/rmm 2>&1 | tee -a "${currentlog}" fi - sudo tar -xzf /tmp/${webtar} -C /var/www/rmm + sudo tar -xzf /tmp/${webtar} -C /var/www/rmm 2>&1 | tee -a "${currentlog}" echo "window._env_ = {PROD_URL: \"https://${rmmdomain}\"}" | sudo tee /var/www/rmm/dist/env-config.js > /dev/null - sudo chown www-data:www-data -R /var/www/rmm/dist - rm -f /tmp/${webtar} + sudo chown www-data:www-data -R /var/www/rmm/dist 2>&1 | tee -a "${currentlog}" + rm -f /tmp/${webtar} 2>&1 | tee -a "${currentlog}" } # Install Nginx @@ -199,33 +199,33 @@ installNginx() { if [ "$1" != "devinstall" ]; then if [ "$1" == "install" ] || [ "$1" == "devprep" ]; then - sudo apt install -y nginx - sudo systemctl stop nginx - sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf - sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf + sudo apt install -y nginx 2>&1 | tee -a "${currentlog}" + sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" + sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart1" ]; then # Check Nginx config if ! sudo nginx -t > /dev/null 2>&1; then - sudo nginx -t - echo -e "${RED} You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script.${NC}\n" - echo -e "${RED} Aborting...${NC}\n" + sudo nginx -t 2>&1 | tee -a "${currentlog}" + echo -e "${RED} You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Aborting...${NC}\n" | tee -a "${currentlog}" exit 1 fi elif [ "$1" == "updatepart2" ]; then CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" /etc/nginx/nginx.conf) if ! [[ $CHECK_NGINX_WORKER_CONN ]]; then - echo -e "${GREEN} Changing nginx worker connections to 2048${NC}\n" - sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf + echo -e "${GREEN} Changing nginx worker connections to 2048${NC}\n" | tee -a "${currentlog}" + sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" fi - sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf + sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "restore" ]; then - sudo apt install -y nginx - sudo systemctl stop nginx - sudo rm -rf /etc/nginx - sudo mkdir /etc/nginx - sudo tar -xzf $tmp_dir/nginx/etc-nginx.tar.gz -C /etc/nginx - sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf - sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf + sudo apt install -y nginx 2>&1 | tee -a "${currentlog}" + sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" + sudo rm -rf /etc/nginx 2>&1 | tee -a "${currentlog}" + sudo mkdir /etc/nginx 2>&1 | tee -a "${currentlog}" + sudo tar -xzf $tmp_dir/nginx/etc-nginx.tar.gz -C /etc/nginx 2>&1 | tee -a "${currentlog}" + sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" # Misc functions getExistingDomainInfo; fi @@ -235,9 +235,9 @@ installNginx() # Install NATS Api installNatsApi() { - 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 + sudo cp /rmm/natsapi/bin/nats-api /usr/local/bin 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" /usr/local/bin/nats-api 2>&1 | tee -a "${currentlog}" + sudo chmod +x /usr/local/bin/nats-api 2>&1 | tee -a "${currentlog}" } # Install MeshCentral @@ -246,77 +246,77 @@ installMeshCentral() MESH_VER=$(grep "^MESH_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') if [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then - sudo mkdir -p /meshcentral/meshcentral-data + sudo mkdir -p /meshcentral/meshcentral-data 2>&1 | tee -a "${currentlog}" elif [ "$1" == "restore" ]; then - sudo tar -xzf $tmp_dir/meshcentral/mesh.tar.gz -C / + sudo tar -xzf $tmp_dir/meshcentral/mesh.tar.gz -C / 2>&1 | tee -a "${currentlog}" fi - sudo chown "${USER}:${USER}" -R /meshcentral - cd /meshcentral - npm install meshcentral@${MESH_VER} - sudo chown "${USER}:${USER}" -R /meshcentral + sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" + cd /meshcentral 2>&1 | tee -a "${currentlog}" + npm install meshcentral@${MESH_VER} 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" } # Install fail2ban installFail2ban() { - sudo apt install -y fail2ban + sudo apt install -y fail2ban 2>&1 | tee -a "${currentlog}" # Copy default jail config to create override config - sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local - sudo truncate -s 0 /etc/fail2ban/jail.local + sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo truncate -s 0 /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" # Write default jail config override - sudo chmod 777 /etc/fail2ban/jail.local - sudo printf '[DEFAULT]' >> /etc/fail2ban/jail.local - sudo printf "\nignoreip = 127.0.0.1/8" >> /etc/fail2ban/jail.local - sudo printf "\n\n" >> /etc/fail2ban/jail.local - sudo printf '[sshd]' >> /etc/fail2ban/jail.local - sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local - sudo printf "\nport = ssh" >> /etc/fail2ban/jail.local - sudo printf "\n\n" >> /etc/fail2ban/jail.local - sudo printf '[nginx-http-auth]' >> /etc/fail2ban/jail.local - sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local - sudo printf "\n\n" >> /etc/fail2ban/jail.local - sudo printf '[nginx-botsearch]' >> /etc/fail2ban/jail.local - sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local - sudo printf "\n\n" >> /etc/fail2ban/jail.local - sudo printf '[tacticalrmm]' >> /etc/fail2ban/jail.local - sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local - sudo printf "\nport = http,https" >> /etc/fail2ban/jail.local - sudo printf "\nfilter = tacticalrmm" >> /etc/fail2ban/jail.local - sudo printf "\n" >> /etc/fail2ban/jail.local - sudo printf 'action = iptables-allports[name=tactical]' >> /etc/fail2ban/jail.local - sudo printf "\n" >> /etc/fail2ban/jail.local - sudo printf 'logpath = /rmm/api/tacticalrmm/tacticalrmm/private/log/access.log' >> /etc/fail2ban/jail.local - sudo printf "\nmaxretry = 5" >> /etc/fail2ban/jail.local - sudo printf "\nbantime = 3600" >> /etc/fail2ban/jail.local - sudo printf "\nfindtime = 3600" >> /etc/fail2ban/jail.local - sudo printf "\n\n" >> /etc/fail2ban/jail.local - sudo printf '[recidive]' >> /etc/fail2ban/jail.local - sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local - sudo printf "\nbantime = 31536000 ; 1 year" >> /etc/fail2ban/jail.local - sudo chmod 644 /etc/fail2ban/jail.local + sudo chmod 777 /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf '[DEFAULT]' >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nignoreip = 127.0.0.1/8" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\n\n" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf '[sshd]' >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nport = ssh" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\n\n" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf '[nginx-http-auth]' >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\n\n" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf '[nginx-botsearch]' >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\n\n" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf '[tacticalrmm]' >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nport = http,https" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nfilter = tacticalrmm" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\n" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf 'action = iptables-allports[name=tactical]' >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\n" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf 'logpath = /rmm/api/tacticalrmm/tacticalrmm/private/log/access.log' >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nmaxretry = 5" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nbantime = 3600" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nfindtime = 3600" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\n\n" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf '[recidive]' >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nenabled = true" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nbantime = 31536000 ; 1 year" >> /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" + sudo chmod 644 /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" # Copy default app config to create override config - sudo cp /etc/fail2ban/fail2ban.conf /etc/fail2ban/fail2ban.local - sudo truncate -s 0 /etc/fail2ban/fail2ban.local + sudo cp /etc/fail2ban/fail2ban.conf /etc/fail2ban/fail2ban.local 2>&1 | tee -a "${currentlog}" + sudo truncate -s 0 /etc/fail2ban/fail2ban.local 2>&1 | tee -a "${currentlog}" # Write default app config override - sudo chmod 777 /etc/fail2ban/fail2ban.local - sudo printf '[Definition]' >> /etc/fail2ban/fail2ban.local - sudo printf "\ndbpurgeage = 31579200" >> /etc/fail2ban/fail2ban.local - sudo printf "\nloglevel = INFO" >> /etc/fail2ban/fail2ban.local - sudo chmod 644 /etc/fail2ban/fail2ban.local + sudo chmod 777 /etc/fail2ban/fail2ban.local 2>&1 | tee -a "${currentlog}" + sudo printf '[Definition]' >> /etc/fail2ban/fail2ban.local 2>&1 | tee -a "${currentlog}" + sudo printf "\ndbpurgeage = 31579200" >> /etc/fail2ban/fail2ban.local 2>&1 | tee -a "${currentlog}" + sudo printf "\nloglevel = INFO" >> /etc/fail2ban/fail2ban.local 2>&1 | tee -a "${currentlog}" + sudo chmod 644 /etc/fail2ban/fail2ban.local 2>&1 | tee -a "${currentlog}" # Add T-RMM definition - sudo echo '[Definition]' | sudo tee /etc/fail2ban/filter.d/tacticalrmm.conf - sudo chmod 777 /etc/fail2ban/filter.d/tacticalrmm.conf - sudo printf "\n" >> /etc/fail2ban/filter.d/tacticalrmm.conf - sudo printf 'failregex = ^.*400.17.*$' >> /etc/fail2ban/filter.d/tacticalrmm.conf - sudo printf "\n" >> /etc/fail2ban/filter.d/tacticalrmm.conf - sudo printf 'ignoreregex = ^.*200.*$' >> /etc/fail2ban/filter.d/tacticalrmm.conf - sudo chmod 644 /etc/fail2ban/filter.d/tacticalrmm.conf + sudo echo '[Definition]' | sudo tee /etc/fail2ban/filter.d/tacticalrmm.conf 2>&1 | tee -a "${currentlog}" + sudo chmod 777 /etc/fail2ban/filter.d/tacticalrmm.conf 2>&1 | tee -a "${currentlog}" + sudo printf "\n" >> /etc/fail2ban/filter.d/tacticalrmm.conf 2>&1 | tee -a "${currentlog}" + sudo printf 'failregex = ^.*400.17.*$' >> /etc/fail2ban/filter.d/tacticalrmm.conf 2>&1 | tee -a "${currentlog}" + sudo printf "\n" >> /etc/fail2ban/filter.d/tacticalrmm.conf 2>&1 | tee -a "${currentlog}" + sudo printf 'ignoreregex = ^.*200.*$' >> /etc/fail2ban/filter.d/tacticalrmm.conf 2>&1 | tee -a "${currentlog}" + sudo chmod 644 /etc/fail2ban/filter.d/tacticalrmm.conf 2>&1 | tee -a "${currentlog}" # Restart Fail2ban - sudo systemctl restart fail2ban + sudo systemctl restart fail2ban 2>&1 | tee -a "${currentlog}" } \ No newline at end of file diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 80f8134ea6..15f99f4a0a 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -86,27 +86,27 @@ checkScriptVer() { # create temp file and download current script to use for comparison TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") - curl -s -L "$2" > ${TMP_FILE} + curl -s -L "$2" > ${TMP_FILE} 2>&1 | tee -a "${currentlog}" NEW_VER=$(grep "^SCRIPT_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') # download new file if available if [ "$1" -ne "${NEW_VER}" ]; then - wget -q "$2" -O "$3" + wget "$2" -O "$3" 2>&1 | tee -a "${currentlog}" if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" - echo -e "${RED} Old $3 detected.${NC}\n" - echo -e "${RED} The latest version has been downloaded.${NC}\n" - echo -e "${RED} Please re-run $3${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Old $3 detected.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} The latest version has been downloaded.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please re-run $3${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 clear -x fi - rm -f $TMP_FILE + rm -f $TMP_FILE 2>&1 | tee -a "${currentlog}" exit 1 fi - rm -f $TMP_FILE + rm -f $TMP_FILE 2>&1 | tee -a "${currentlog}" } # Check for functions updates @@ -116,27 +116,27 @@ checkCfgVer() # create temp file and download current file to use for comparison TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") - curl -s -L "$1/script-cfg/$2" > ${TMP_FILE} + curl -s -L "$1/script-cfg/$2" > ${TMP_FILE} 2>&1 | tee -a "${currentlog}" NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') # download new file if available if [ "$currentcfgver" -ne "${NEW_VER}" ]; then - wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" + wget "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" 2>&1 | tee -a "${currentlog}" if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" - echo -e "${RED} Old $2 detected.${NC}\n" - echo -e "${RED} The latest version has been downloaded.${NC}\n" - echo -e "${RED} Please re-run $3${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Old $2 detected.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} The latest version has been downloaded.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please re-run $3${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 clear -x fi - rm -f $TMP_FILE + rm -f $TMP_FILE 2>&1 | tee -a "${currentlog}" exit 1 fi - rm -f $TMP_FILE + rm -f $TMP_FILE 2>&1 | tee -a "${currentlog}" } # Check for root as user @@ -145,9 +145,9 @@ checkRoot() # if user is root, exit if [ $EUID -eq 0 ]; then if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" - echo -e "${RED} Do NOT run this script as root.${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Do NOT run this script as root.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Do NOT run this script as root. Exiting." 0 0 clear -x @@ -168,10 +168,10 @@ checkTacticalUser() tacticaluser=$(stat -c '%U' /rmm) if [ "$tacticaluser" != "${USER}" ]; then if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" - echo -e "${RED} This script must be run as the Tactical user.${NC}\n" - echo -e "${RED} Please switch users, and run it again.${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} This script must be run as the Tactical user.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please switch users, and run it again.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 clear -x @@ -184,26 +184,26 @@ checkTacticalUser() tacticaluser="$(id -u tactical > /dev/null 2>&1; echo $?)" case $tacticaluser in 0 ) if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" - echo -e "${RED} This script must be run as the Tactical user.${NC}\n" - echo -e "${RED} Please switch users, and run it again.${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} This script must be run as the Tactical user.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please switch users, and run it again.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 clear -x fi exit 1;; - 1 ) print_yellow 'Tactical user does not exist. Creating now.' - sudo useradd -m -G sudo -s /bin/bash tactical + 1 ) print_yellow 'Tactical user does not exist. Creating now.' | tee -a "${currentlog}" + sudo useradd -m -G sudo -s /bin/bash tactical 2>&1 | tee -a "${currentlog}" tacpass="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)" echo "tactical:$tacpass"| sudo chpasswd if [ "$autoinstall" == "1" ]; then - echo -e "${RED} The Tactical user has been created.${NC}\n" - echo -e "${RED} Username: tactical${NC}" - echo -e "${RED} Password: $tacpass${NC}\n" - echo -e "${RED} Please switch users, re-download the script, and run it again.${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} The Tactical user has been created.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Username: tactical${NC}" | tee -a "${currentlog}" + echo -e "${RED} Password: $tacpass${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please switch users, re-download the script, and run it again.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Created" --msgbox "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting." 0 0 clear -x @@ -217,12 +217,12 @@ checkTacticalUser() case $hassudo in 0 ) return;; - 1 ) print_green 'Adding Tactical user to sudo group.' - sudo usermod -a -G sudo tactical + 1 ) print_green 'Adding Tactical user to sudo group.' | tee -a "${currentlog}" + sudo usermod -a -G sudo tactical 2>&1 | tee -a "${currentlog}" if [ "$autoinstall" == "1" ]; then - echo -e "${RED} The Tactical user has been added to the sudo group.${NC}\n" - echo -e "${RED} Please log out of the tactical user, log back in, and try again.${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} The Tactical user has been added to the sudo group.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please log out of the tactical user, log back in, and try again.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Sudo Privileges Added" --msgbox "The Tactical user has been added to the sudo group.\nPlease log out of the tactical user, log back in, and try again.\n\nExiting." 0 0 clear -x @@ -237,28 +237,28 @@ clonePrimaryRepo() { # use only if called from standard or dev install, or restore if [ "$1" == "install" ] || [ "$1" == "devinstall" ] || [ "$1" == "restore" ]; then - sudo mkdir /rmm - sudo chown "${USER}:${USER}" /rmm - sudo mkdir -p /var/log/celery - sudo chown "${USER}:${USER}" /var/log/celery - git clone "$2" /rmm/ + sudo mkdir /rmm 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" /rmm 2>&1 | tee -a "${currentlog}" + sudo mkdir -p /var/log/celery 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" /var/log/celery 2>&1 | tee -a "${currentlog}" + git clone "$2" /rmm/ 2>&1 | tee -a "${currentlog}" fi - cd /rmm - git config user.email "admin@example.com" - git config user.name "Bob" + cd /rmm 2>&1 | tee -a "${currentlog}" + git config user.email "admin@example.com" 2>&1 | tee -a "${currentlog}" + git config user.name "Bob" 2>&1 | tee -a "${currentlog}" # use only if called from standard or dev install, or restore if [ "$1" == "install" ] || [ "$1" == "devinstall" ] || [ "$1" == "restore" ]; then - git checkout "$3" + git checkout "$3" 2>&1 | tee -a "${currentlog}" # use only if called from update elif [ "$1" == "update" ]; then - git fetch - git checkout "$3" - git reset --hard FETCH_HEAD - git clean -df - git pull + git fetch 2>&1 | tee -a "${currentlog}" + git checkout "$3" 2>&1 | tee -a "${currentlog}" + git reset --hard FETCH_HEAD 2>&1 | tee -a "${currentlog}" + git clean -df 2>&1 | tee -a "${currentlog}" + git pull 2>&1 | tee -a "${currentlog}" fi } @@ -267,25 +267,25 @@ cloneScriptsRepo() { # if directory exists, skip, else create it if [ ! -d "${SCRIPTS_DIR}" ]; then - sudo mkdir -p "${SCRIPTS_DIR}" - sudo chown "${USER}:${USER}" "${SCRIPTS_DIR}" - git clone "$2" "${SCRIPTS_DIR}"/ + sudo mkdir -p "${SCRIPTS_DIR}" 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" "${SCRIPTS_DIR}" 2>&1 | tee -a "${currentlog}" + git clone "$2" "${SCRIPTS_DIR}"/ 2>&1 | tee -a "${currentlog}" fi - cd "${SCRIPTS_DIR}" - git config user.email "admin@example.com" - git config user.name "Bob" + cd "${SCRIPTS_DIR}" 2>&1 | tee -a "${currentlog}" + git config user.email "admin@example.com" 2>&1 | tee -a "${currentlog}" + git config user.name "Bob" 2>&1 | tee -a "${currentlog}" # use only if called from standard or dev install, or restore if [ "$1" == "install" ] || [ "$1" == "devinstall" ] || [ "$1" == "restore" ]; then - git checkout main + git checkout main 2>&1 | tee -a "${currentlog}" # use only if called from update elif [ "$1" == "update" ]; then - git fetch - git checkout main - git reset --hard FETCH_HEAD - git clean -df - git pull + git fetch 2>&1 | tee -a "${currentlog}" + git checkout main 2>&1 | tee -a "${currentlog}" + git reset --hard FETCH_HEAD 2>&1 | tee -a "${currentlog}" + git clean -df 2>&1 | tee -a "${currentlog}" + git pull 2>&1 | tee -a "${currentlog}" fi } @@ -294,11 +294,11 @@ verifyRepoExists() { local repostatus=$(curl --output /dev/null --silent --write-out "%{http_code}" "$1") if [ "$repostatus" == "200" ]; then - echo -e "${GREEN} Repo exists.${NC}\n" + echo -e "${GREEN} Repo exists.${NC}\n" | tee -a "${currentlog}" else - echo -e "${RED} The Tactical RMM repository you entered does not exist.${NC}\n" - echo -e "${RED} Please try again.${NC}\n" - echo -e "${RED} Exiting...${NC}\n" + echo -e "${RED} The Tactical RMM repository you entered does not exist.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please try again.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Exiting...${NC}\n" | tee -a "${currentlog}" exit 1 fi } diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index 692fd40487..29ce490a5b 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -29,7 +29,7 @@ setSiteHostname() textcomp=$(sed -n "$line2"p /etc/hosts) if [ "$textcomp" == "" ]; then - sudo sed -i "${runtimes} a\127.0.1.1\t$1.$2 $1" /etc/hosts + sudo sed -i "${runtimes} a\127.0.1.1\t$1.$2 $1" /etc/hosts 2>&1 | tee -a "${currentlog}" fi done @@ -46,19 +46,19 @@ configHosts() # this also allows the install script to properly finish even if DNS has not fully propagated CHECK_LOCALHOST=$(grep "127.0.0.1" /etc/hosts | grep "localhost") if ! [[ $CHECK_LOCALHOST ]]; then - echo -e "${GREEN} Adding localhost to hosts file...${NC}\n" - sudo sed -i "1i 127.0.0.1\tlocalhost" /etc/hosts + echo -e "${GREEN} Adding localhost to hosts file...${NC}\n" | tee -a "${currentlog}" + sudo sed -i "1i 127.0.0.1\tlocalhost" /etc/hosts 2>&1 | tee -a "${currentlog}" fi CHECK_HOSTS=$(grep "127.0.1.1 $rmmdomain $frontenddomain $meshdomain" /etc/hosts) if [[ $CHECK_HOSTS ]]; then - echo -e "${GREEN} Correcting subdomain entries...${NC}\n" - sudo sed -i "/127.0.1.1 $rmmdomain $frontenddomain $meshdomain/d" /etc/hosts + echo -e "${GREEN} Correcting subdomain entries...${NC}\n" | tee -a "${currentlog}" + sudo sed -i "/127.0.1.1 $rmmdomain $frontenddomain $meshdomain/d" /etc/hosts 2>&1 | tee -a "${currentlog}" setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; setSiteHostname "$meshhost" "$rootdomain"; elif [ "$1" != "devinstall" ]; then - echo -e "${GREEN} Adding subdomain entries...${NC}\n" + echo -e "${GREEN} Adding subdomain entries...${NC}\n" | tee -a "${currentlog}" setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; setSiteHostname "$meshhost" "$rootdomain"; diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index c1419ce3da..0a25c0562e 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -33,208 +33,208 @@ mainInstall() # Configure hosts file # Misc functions - print_green 'Configuring Hosts file'; + print_green 'Configuring Hosts file' | tee -a "${currentlog}" # Network functions configHosts "$INSTALL_TYPE"; # Certificate generation # Misc functions - print_green 'Installing Certbot'; + print_green 'Installing Certbot' | tee -a "${currentlog}" # InstallFunctions installCertbot "$INSTALL_TYPE"; # Install Nginx # Misc functions - print_green 'Installing Nginx'; + print_green 'Installing Nginx' | tee -a "${currentlog}" # InstallFunctions installNginx "$INSTALL_TYPE"; # Install NodeJS # Misc functions - print_green 'Installing NodeJS'; + print_green 'Installing NodeJS' | tee -a "${currentlog}" # InstallFunctions installNodeJS "$INSTALL_TYPE"; # Install and enable MongoDB # Misc functions - print_green 'Installing MongoDB'; + print_green 'Installing MongoDB' | tee -a "${currentlog}" # InstallFunctions installMongo "$INSTALL_TYPE"; # Install Python # Misc functions - print_green "Installing Python ${PYTHON_VER}"; + print_green "Installing Python ${PYTHON_VER}" | tee -a "${currentlog}" # InstallFunctions installPython "$INSTALL_TYPE"; # Installing Redis # Misc functions - print_green 'Installing redis'; + print_green 'Installing redis' | tee -a "${currentlog}" # InstallFunctions installRedis; # Install and enable Postgresql # Misc functions - print_green 'Installing postgresql'; + print_green 'Installing postgresql' | tee -a "${currentlog}" # InstallFunctions installPostgresql; # Postgres DB creation # Misc functions - print_green 'Creating database for the rmm'; + print_green 'Creating database for the rmm' | tee -a "${currentlog}" # Database functions createPGDB; # Clone main repo # Misc functions - print_green 'Cloning primary repo'; + print_green 'Cloning primary repo' | tee -a "${currentlog}" # Misc functions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; # Clone scripts repo # Misc functions - print_green 'Cloning community scripts repo'; + print_green 'Cloning community scripts repo' | tee -a "${currentlog}" # Misc functions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; # Installing NATS # Misc functions - print_green 'Installing NATS'; + print_green 'Installing NATS' | tee -a "${currentlog}" # InstallFunctions installNats "$INSTALL_TYPE"; # Install MeshCentral # Misc functions - print_green 'Installing MeshCentral'; + print_green 'Installing MeshCentral' | tee -a "${currentlog}" # InstallFunctions installMeshCentral "$INSTALL_TYPE"; # Create MeshCentral config # Misc functions - print_green 'Generating MeshCentral Config'; + print_green 'Generating MeshCentral Config' | tee -a "${currentlog}" # Config and Service functions createMeshConfig; # Create local settings file # Misc functions - print_green 'Generating Local Settings'; + print_green 'Generating Local Settings' | tee -a "${currentlog}" # Config and Service functions createLocalSettings; # Install NATS-API and correct permissions # Misc functions - print_green 'Installing NATS API'; + print_green 'Installing NATS API' | tee -a "${currentlog}" # InstallFunctions installNatsApi; # Install backend, configure primary admin user, setup admin 2fa # Misc functions - print_green 'Installing the backend'; + print_green 'Installing the backend' | tee -a "${currentlog}" # Config and Service functions configureBackend "$INSTALL_TYPE"; # Create UWSGI config # Misc functions - print_green 'Creating UWSGI configuration'; + print_green 'Creating UWSGI configuration' | tee -a "${currentlog}" # Config and Service functions createUwsgiConf; # Create RMM UWSGI systemd service # Misc functions - print_green 'Creating UWSGI service'; + print_green 'Creating UWSGI service' | tee -a "${currentlog}" # Config and Service functions createUwsgiService; # Create Daphne systemd service # Misc functions - print_green 'Creating Daphne service'; + print_green 'Creating Daphne service' | tee -a "${currentlog}" # Config and Service functions createDaphneService; # Create NATS systemd service # Misc functions - print_green 'Creating NATS service'; + print_green 'Creating NATS service' | tee -a "${currentlog}" # Config and Service functions createNatsService; # Create NATS-api systemd service # Misc functions - print_green 'Creating NATS-API service'; + print_green 'Creating NATS-API service' | tee -a "${currentlog}" # Config and Service functions createNatsApiService; # Create Backend Nginx site config # Misc functions - print_green 'Creating Backend Nginx config'; + print_green 'Creating Backend Nginx config' | tee -a "${currentlog}" # Config and Service functions createBackendNginxConf; # Create MeshCentral Nginx configuration # Misc functions - print_green 'Creating MeshCentral Nginx config'; + print_green 'Creating MeshCentral Nginx config' | tee -a "${currentlog}" # Config and Service functions createMeshNginxConf; # Enable Mesh and RMM sites - sudo ln -s /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-enabled/rmm.conf | tee -a "${currentlog}" - sudo ln -s /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-enabled/meshcentral.conf | tee -a "${currentlog}" + sudo ln -s /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-enabled/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo ln -s /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-enabled/meshcentral.conf 2>&1 | tee -a "${currentlog}" # Create conf directory - sudo mkdir /etc/conf.d | tee -a "${currentlog}" + sudo mkdir /etc/conf.d 2>&1 | tee -a "${currentlog}" # Create Celery systemd service # Misc functions - print_green 'Creating Celery service'; + print_green 'Creating Celery service' | tee -a "${currentlog}" # Config and Service functions createCeleryService; # Configure Celery service # Misc functions - print_green 'Creating Celery config'; + print_green 'Creating Celery config' | tee -a "${currentlog}" # Config and Service functions createCeleryConf; # Create CeleryBeat systemd service # Misc functions - print_green 'Creating CeleryBeat service'; + print_green 'Creating CeleryBeat service' | tee -a "${currentlog}" # Config and Service functions createCeleryBeatService; # Correct conf dir ownership - sudo chown "${USER}:${USER}" -R /etc/conf.d/ | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R /etc/conf.d/ 2>&1 | tee -a "${currentlog}" # Create MeshCentral systemd service # Misc functions - print_green 'Creating MeshCentral service'; + print_green 'Creating MeshCentral service' | tee -a "${currentlog}" # Config and Service functions createMeshCentralService; # Update services info - sudo systemctl daemon-reload | tee -a "${currentlog}" + sudo systemctl daemon-reload 2>&1 | tee -a "${currentlog}" # Verify and correct permissions if [ -d ~/.npm ]; then - sudo chown -R "${USER}:${GROUP}" ~/.npm | tee -a "${currentlog}" + sudo chown -R "${USER}:${GROUP}" ~/.npm 2>&1 | tee -a "${currentlog}" fi if [ -d ~/.config ]; then - sudo chown -R "${USER}:${GROUP}" ~/.config | tee -a "${currentlog}" + sudo chown -R "${USER}:${GROUP}" ~/.config 2>&1 | tee -a "${currentlog}" fi # Install frontend # Misc functions - print_green 'Installing the frontend'; + print_green 'Installing the frontend' | tee -a "${currentlog}" # InstallFunctions installFrontEnd "$INSTALL_TYPE"; # Set front end Nginx config and enable # Misc functions - print_green 'Creating Frontend Nginx config'; + print_green 'Creating Frontend Nginx config' | tee -a "${currentlog}" # Config and Service functions createFrontendNginxConf; # Enable Frontend site - sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf | tee -a "${currentlog}" + sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf 2>&1 | tee -a "${currentlog}" # Webroot certificate fix if [ "$certtype" == "webroot" ]; then @@ -243,62 +243,62 @@ mainInstall() # Enable RMM, Daphne, Celery, and Nginx services # Misc functions - print_green 'Enabling Services'; + print_green 'Enabling Services' | tee -a "${currentlog}" for i in rmm.service daphne.service celery.service celerybeat.service nginx do - sudo systemctl enable ${i} | tee -a "${currentlog}" - sudo systemctl stop ${i} | tee -a "${currentlog}" - sudo systemctl start ${i} | tee -a "${currentlog}" + sudo systemctl enable ${i} 2>&1 | tee -a "${currentlog}" + sudo systemctl stop ${i} 2>&1 | tee -a "${currentlog}" + sudo systemctl start ${i} 2>&1 | tee -a "${currentlog}" done sleep 5 # Enable MeshCentral service # Misc functions - print_green 'Starting meshcentral and waiting for it to install plugins'; + print_green 'Starting meshcentral and waiting for it to install plugins' | tee -a "${currentlog}" # Config and Service functions enableMeshService; # Generating MeshCentral key # Misc functions - print_green 'Generating meshcentral login token key'; + print_green 'Generating meshcentral login token key' | tee -a "${currentlog}" # Config and Service functions generateMeshToken; # Configuring MeshCentral admin user and device group, restart service # Misc functions - print_green 'Creating meshcentral account and group'; + print_green 'Creating meshcentral account and group' | tee -a "${currentlog}" # Config and Service functions configMeshUserGroup; # Enable and configure NATS service # Misc functions - print_green 'Starting NATS service'; + print_green 'Starting NATS service' | tee -a "${currentlog}" # Config and Service functions enableNatsService; # Disable django admin - sed -i 's/ADMIN_ENABLED = True/ADMIN_ENABLED = False/g' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | tee -a "${currentlog}" + sed -i 's/ADMIN_ENABLED = True/ADMIN_ENABLED = False/g' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" # Restart core services # Misc functions - print_green 'Restarting services'; + print_green 'Restarting services' | tee -a "${currentlog}" for i in rmm.service daphne.service celery.service celerybeat.service do - sudo systemctl stop ${i} | tee -a "${currentlog}" - sudo systemctl start ${i} | tee -a "${currentlog}" + sudo systemctl stop ${i} 2>&1 | tee -a "${currentlog}" + sudo systemctl start ${i} 2>&1 | tee -a "${currentlog}" done # Yay, we're done! # Misc functions - print_yellow "Installation complete!"; + print_yellow "Installation complete!" | tee -a "${currentlog}" echo -e "${YELLOW} Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n" | tee -a no-peeking.log echo -e "${YELLOW} Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n" | tee -a no-peeking.log echo -e "${YELLOW} MeshCentral username: ${GREEN}${meshusername}${NC}" | tee -a no-peeking.log echo -e "${YELLOW} MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n" | tee -a no-peeking.log - sudo chmod 600 $PWD/no-peeking.log + sudo chmod 600 $PWD/no-peeking.log 2>&1 | tee -a "${currentlog}" if [ "$BEHIND_NAT" = true ]; then echo -e "${YELLOW} Read below if your router does NOT support Hairpin NAT:${NC}\n" @@ -324,7 +324,7 @@ updateTRMM() # Check if user is same as during installation # UpdateRestoreFunctions - checkSameUser "$INSTALL_TYPE"; + checkSameUser "$INSTALL_TYPE" | tee -a "${currentlog}" # Get current release version and check if update is necessary # UpdateRestoreFunctions From 30de8476a7e377d86857d8665a5475514cd15873 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 12:00:31 -0500 Subject: [PATCH 149/203] switched to apt-get to make apt shut up --- script-cfg/CertificateFunctions.cfg | 2 +- script-cfg/InstallFunctions.cfg | 18 +++++++++--------- script-cfg/SystemLockdown.cfg | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 6e1ee5ad57..e20d546fbf 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -173,7 +173,7 @@ dnsOrWebroot() installCertbot() { # Install Certbot - sudo apt install -y certbot 2>&1 | tee -a "${currentlog}" + sudo apt-get install -y certbot 2>&1 | tee -a "${currentlog}" if [ "$1" == "restore" ]; then # Generate DH if it doesn't exist if [ ! -f /etc/ssl/certs/dhparam.pem ]; then diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index cc6c958b13..bbcb36041f 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -12,13 +12,13 @@ CFG_VERSION="8" # Install script prereqs installPreReqs() { - sudo apt update && sudo apt install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev + sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev } # Install remaining prereqs installAdditionalPreReqs() { - sudo apt install -y software-properties-common dnsutils openssl ca-certificates apt-transport-https gcc g++ make build-essential zlib1g-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev git + sudo apt-get install -y software-properties-common dnsutils openssl ca-certificates apt-transport-https gcc g++ make build-essential zlib1g-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev git } # Configure repos for stuff @@ -52,7 +52,7 @@ installMongo() if [ "$1" != "devinstall" ]; then wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/mongo.gpg > /dev/null 2>&1 | tee -a "${currentlog}" echo "$mongodb_repo" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list 2>&1 | tee -a "${currentlog}" - sudo apt update && sudo apt install -y mongodb-org 2>&1 | tee -a "${currentlog}" + sudo apt-get update && sudo apt-get install -y mongodb-org 2>&1 | tee -a "${currentlog}" sudo systemctl enable mongod 2>&1 | tee -a "${currentlog}" sudo systemctl restart mongod 2>&1 | tee -a "${currentlog}" sleep 5 @@ -77,7 +77,7 @@ installNodeJS() fi fi curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - 2>&1 | tee -a "${currentlog}" - sudo apt update && sudo apt install -y nodejs 2>&1 | tee -a "${currentlog}" + sudo apt-get update && sudo apt-get install -y nodejs 2>&1 | tee -a "${currentlog}" sudo npm install -g npm 2>&1 | tee -a "${currentlog}" if [ "$1" == "update" ]; then sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" @@ -92,7 +92,7 @@ installNodeJS() # Install Redis installRedis() { - sudo apt install -y redis 2>&1 | tee -a "${currentlog}" + sudo apt-get install -y redis 2>&1 | tee -a "${currentlog}" } # Install Python @@ -135,7 +135,7 @@ installPostgresql() { echo "$postgresql_repo" | sudo tee /etc/apt/sources.list.d/pgdg.list 2>&1 | tee -a "${currentlog}" wget -qO - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/postgresql.gpg > /dev/null 2>&1 | tee -a "${currentlog}" - sudo apt update && sudo apt install -y postgresql-14 2>&1 | tee -a "${currentlog}" + sudo apt-get update && sudo apt-get install -y postgresql-14 2>&1 | tee -a "${currentlog}" sleep 2 sudo systemctl enable postgresql 2>&1 | tee -a "${currentlog}" sudo systemctl restart postgresql 2>&1 | tee -a "${currentlog}" @@ -199,7 +199,7 @@ installNginx() { if [ "$1" != "devinstall" ]; then if [ "$1" == "install" ] || [ "$1" == "devprep" ]; then - sudo apt install -y nginx 2>&1 | tee -a "${currentlog}" + sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" @@ -219,7 +219,7 @@ installNginx() fi sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "restore" ]; then - sudo apt install -y nginx 2>&1 | tee -a "${currentlog}" + sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" sudo rm -rf /etc/nginx 2>&1 | tee -a "${currentlog}" sudo mkdir /etc/nginx 2>&1 | tee -a "${currentlog}" @@ -259,7 +259,7 @@ installMeshCentral() # Install fail2ban installFail2ban() { - sudo apt install -y fail2ban 2>&1 | tee -a "${currentlog}" + sudo apt-get install -y fail2ban 2>&1 | tee -a "${currentlog}" # Copy default jail config to create override config sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local 2>&1 | tee -a "${currentlog}" diff --git a/script-cfg/SystemLockdown.cfg b/script-cfg/SystemLockdown.cfg index 9e04b78fb4..8614472c30 100644 --- a/script-cfg/SystemLockdown.cfg +++ b/script-cfg/SystemLockdown.cfg @@ -85,7 +85,7 @@ installSecurity() echo " " # install apps - sudo apt install -y rkhunter chkrootkit + sudo apt-get install -y rkhunter chkrootkit # set chkrootkit to scan daily sudo sed -i 's/RUN_DAILY="false"/RUN_DAILY="true"/' /etc/chkrootkit.conf @@ -125,7 +125,7 @@ installSecurity() # Function to enable automatic security updates only AutoSecurityUpdates() { - sudo apt install -y unattended-upgrades + sudo apt-get install -y unattended-upgrades # Configure allowed automatic update sources - security only sudo sed -i 's|"${distro_id}:${distro_codename}";|//"${distro_id}:${distro_codename}";|' /etc/apt/apt.conf.d/50unattended-upgrades From 856354b4949dca974e9e51261b0599c780e14cfc Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 12:32:17 -0500 Subject: [PATCH 150/203] Hopefully last edits for logging --- script-cfg/DatabaseFunctions.cfg | 12 +- script-cfg/MiscFunctions.cfg | 30 ++-- script-cfg/ParentFunctions.cfg | 198 ++++++++++++------------ script-cfg/SystemInfoFunctions.cfg | 16 +- script-cfg/TroubleshootingFunctions.cfg | 2 +- script-cfg/UpdateRestoreFunctions.cfg | 42 ++--- script-cfg/UserInput.cfg | 18 +-- 7 files changed, 159 insertions(+), 159 deletions(-) diff --git a/script-cfg/DatabaseFunctions.cfg b/script-cfg/DatabaseFunctions.cfg index 13ae6cd2b6..cc5e0cf8f9 100644 --- a/script-cfg/DatabaseFunctions.cfg +++ b/script-cfg/DatabaseFunctions.cfg @@ -12,10 +12,10 @@ CFG_VERSION="8" # Postgres DB creation createPGDB() { - 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 "CREATE DATABASE tacticalrmm" 2>&1 | tee -a "${currentlog}" + sudo -u postgres psql -c "CREATE USER ${pgusername} WITH PASSWORD '${pgpw}'" 2>&1 | tee -a "${currentlog}" + sudo -u postgres psql -c "ALTER ROLE ${pgusername} SET client_encoding TO 'utf8'" 2>&1 | tee -a "${currentlog}" + sudo -u postgres psql -c "ALTER ROLE ${pgusername} SET default_transaction_isolation TO 'read committed'" 2>&1 | tee -a "${currentlog}" + sudo -u postgres psql -c "ALTER ROLE ${pgusername} SET timezone TO 'UTC'" 2>&1 | tee -a "${currentlog}" + sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE tacticalrmm TO ${pgusername}" 2>&1 | tee -a "${currentlog}" } \ No newline at end of file diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 15f99f4a0a..f189ff5c4c 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -96,8 +96,8 @@ checkScriptVer() echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Old $3 detected.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} The latest version has been downloaded.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please re-run $3${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please re-run $3${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 clear -x @@ -126,8 +126,8 @@ checkCfgVer() echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Old $2 detected.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} The latest version has been downloaded.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please re-run $3${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please re-run $3${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 clear -x @@ -147,7 +147,7 @@ checkRoot() if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Do NOT run this script as root.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Do NOT run this script as root. Exiting." 0 0 clear -x @@ -170,8 +170,8 @@ checkTacticalUser() if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" echo -e "${RED} This script must be run as the Tactical user.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please switch users, and run it again.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please switch users, and run it again.${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 clear -x @@ -186,8 +186,8 @@ checkTacticalUser() 0 ) if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" echo -e "${RED} This script must be run as the Tactical user.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please switch users, and run it again.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please switch users, and run it again.${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 clear -x @@ -202,8 +202,8 @@ checkTacticalUser() echo -e "${RED} The Tactical user has been created.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Username: tactical${NC}" | tee -a "${currentlog}" echo -e "${RED} Password: $tacpass${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please switch users, re-download the script, and run it again.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please switch users, re-download the script, and run it again.${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Created" --msgbox "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting." 0 0 clear -x @@ -221,8 +221,8 @@ checkTacticalUser() sudo usermod -a -G sudo tactical 2>&1 | tee -a "${currentlog}" if [ "$autoinstall" == "1" ]; then echo -e "${RED} The Tactical user has been added to the sudo group.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please log out of the tactical user, log back in, and try again.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Exiting.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please log out of the tactical user, log back in, and try again.${NC}\n" + echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Sudo Privileges Added" --msgbox "The Tactical user has been added to the sudo group.\nPlease log out of the tactical user, log back in, and try again.\n\nExiting." 0 0 clear -x @@ -297,8 +297,8 @@ verifyRepoExists() echo -e "${GREEN} Repo exists.${NC}\n" | tee -a "${currentlog}" else echo -e "${RED} The Tactical RMM repository you entered does not exist.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please try again.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Exiting...${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please try again.${NC}\n" + echo -e "${RED} Exiting...${NC}\n" exit 1 fi } diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 0a25c0562e..a6c5cdf4c8 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -350,11 +350,11 @@ updateTRMM() for i in nginx nats-api nats rmm daphne celery celerybeat do echo -e "${GREEN} Stopping ${i} service...${NC}" | tee -a "${currentlog}" - sudo systemctl stop "${i}" | tee -a "${currentlog}" + sudo systemctl stop "${i}" 2>&1 | tee -a "${currentlog}" done # Rebuild uwsgi config - rm -f /rmm/api/tacticalrmm/app.ini | tee -a "${currentlog}" + rm -f /rmm/api/tacticalrmm/app.ini 2>&1 | tee -a "${currentlog}" # Config and Service functions createUwsgiConf; @@ -368,20 +368,20 @@ updateTRMM() # This does stuff if [ -d ~/.npm ]; then - sudo rm -rf ~/.npm | tee -a "${currentlog}" + sudo rm -rf ~/.npm 2>&1 | tee -a "${currentlog}" fi if [ -d ~/.cache ]; then - sudo rm -rf ~/.cache | tee -a "${currentlog}" + sudo rm -rf ~/.cache 2>&1 | tee -a "${currentlog}" fi if [ -d ~/.config ]; then - sudo chown -R "${USER}:${GROUP}" ~/.config | tee -a "${currentlog}" + sudo chown -R "${USER}:${GROUP}" ~/.config 2>&1 | tee -a "${currentlog}" fi # Check NodeJS version, update if needed and update MeshCentral # Misc functions - print_green 'Updating NodeJS'; + print_green 'Updating NodeJS' | tee -a "${currentlog}" # InstallFunctions installNodeJS "$INSTALL_TYPE"; @@ -391,23 +391,23 @@ updateTRMM() # Update from main repo # Misc functions - print_green 'Cloning primary repo'; + print_green 'Cloning primary repo' | tee -a "${currentlog}" # Misc functions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; # Update from community-scripts repo # Misc functions - print_green 'Cloning community scripts repo'; + print_green 'Cloning community scripts repo' | tee -a "${currentlog}" # Misc functions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; # Apply updated Ownership and perms - sudo chown "${USER}:${USER}" -R /rmm | tee -a "${currentlog}" - sudo chown "${USER}:${USER}" -R "${SCRIPTS_DIR}" | tee -a "${currentlog}" - sudo chown "${USER}:${USER}" /var/log/celery | tee -a "${currentlog}" - sudo chown "${USER}:${USER}" -R /etc/conf.d/ | tee -a "${currentlog}" - sudo chown "root:${USER}" -R /etc/letsencrypt | tee -a "${currentlog}" - sudo chmod 755 -R /etc/letsencrypt | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R /rmm 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R "${SCRIPTS_DIR}" 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" /var/log/celery 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R /etc/conf.d/ 2>&1 | tee -a "${currentlog}" + sudo chown "root:${USER}" -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" # Check additional Nginx settings and update # InstallFunctions @@ -439,12 +439,12 @@ updateTRMM() for i in nats nats-api rmm daphne celery celerybeat nginx do echo -e "${GREEN} Starting ${i} service${NC}" | tee -a "${currentlog}" - sudo systemctl start "${i}" | tee -a "${currentlog}" + sudo systemctl start "${i}" 2>&1 | tee -a "${currentlog}" done sleep 3 # Push agent updates - /rmm/api/env/bin/python /rmm/api/tacticalrmm/manage.py update_agents | tee -a "${currentlog}" + /rmm/api/env/bin/python /rmm/api/tacticalrmm/manage.py update_agents 2>&1 | tee -a "${currentlog}" # Update MeshCentral if necessary updateMeshCentral; @@ -454,11 +454,11 @@ updateTRMM() enableMeshService "$INSTALL_TYPE"; # Cleanup - rm -f $TMP_SETTINGS | tee -a "${currentlog}" + rm -f $TMP_SETTINGS 2>&1 | tee -a "${currentlog}" # Bye-bye # Misc functions - print_green "Update finished!"; + print_green "Update finished!" | tee -a "${currentlog}" return } @@ -475,18 +475,18 @@ backupTRMM() # Check if rmmbackup folder exists, if not create it if [ ! -d /rmmbackups ]; then - sudo mkdir /rmmbackups | tee -a "${currentlog}" - sudo chown "${USER}:${USER}" /rmmbackups | tee -a "${currentlog}" + sudo mkdir /rmmbackups 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" /rmmbackups 2>&1 | tee -a "${currentlog}" fi # Remove old MeshCentral backups if [ -d /meshcentral/meshcentral-backup ]; then - rm -rf /meshcentral/meshcentral-backup/* | tee -a "${currentlog}" + rm -rf /meshcentral/meshcentral-backup/* 2>&1 | tee -a "${currentlog}" fi # Remove old MeshCentral DB backups if [ -d /meshcentral/meshcentral-coredumps ]; then - rm -f /meshcentral/meshcentral-coredumps/* | tee -a "${currentlog}" + rm -f /meshcentral/meshcentral-coredumps/* 2>&1 | tee -a "${currentlog}" fi # Set info for backup and folders @@ -495,45 +495,45 @@ backupTRMM() sysd="/etc/systemd/system" # Create temp backup subdirectories - mkdir -p ${tmp_dir}/meshcentral/mongo | tee -a "${currentlog}" - mkdir ${tmp_dir}/postgres | tee -a "${currentlog}" - mkdir ${tmp_dir}/certs | tee -a "${currentlog}" - mkdir ${tmp_dir}/nginx | tee -a "${currentlog}" - mkdir ${tmp_dir}/systemd | tee -a "${currentlog}" - mkdir ${tmp_dir}/rmm | tee -a "${currentlog}" - mkdir ${tmp_dir}/confd | tee -a "${currentlog}" + mkdir -p ${tmp_dir}/meshcentral/mongo 2>&1 | tee -a "${currentlog}" + mkdir ${tmp_dir}/postgres 2>&1 | tee -a "${currentlog}" + mkdir ${tmp_dir}/certs 2>&1 | tee -a "${currentlog}" + mkdir ${tmp_dir}/nginx 2>&1 | tee -a "${currentlog}" + mkdir ${tmp_dir}/systemd 2>&1 | tee -a "${currentlog}" + mkdir ${tmp_dir}/rmm 2>&1 | tee -a "${currentlog}" + mkdir ${tmp_dir}/confd 2>&1 | tee -a "${currentlog}" # Dump Postgres database - pg_dump --dbname=postgresql://"${POSTGRES_USER}":"${POSTGRES_PW}"@127.0.0.1:5432/tacticalrmm | gzip -9 > ${tmp_dir}/postgres/db-${dt_now}.psql.gz | tee -a "${currentlog}" + pg_dump --dbname=postgresql://"${POSTGRES_USER}":"${POSTGRES_PW}"@127.0.0.1:5432/tacticalrmm | gzip -9 > ${tmp_dir}/postgres/db-${dt_now}.psql.gz 2>&1 | tee -a "${currentlog}" # Backup Mesh stuff - tar -czvf ${tmp_dir}/meshcentral/mesh.tar.gz --exclude=/meshcentral/node_modules /meshcentral | tee -a "${currentlog}" - mongodump --gzip --out=${tmp_dir}/meshcentral/mongo | tee -a "${currentlog}" + tar -czvf ${tmp_dir}/meshcentral/mesh.tar.gz --exclude=/meshcentral/node_modules /meshcentral 2>&1 | tee -a "${currentlog}" + mongodump --gzip --out=${tmp_dir}/meshcentral/mongo 2>&1 | tee -a "${currentlog}" # Backup certs - sudo tar -czvf ${tmp_dir}/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt . | tee -a "${currentlog}" + sudo tar -czvf ${tmp_dir}/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt . 2>&1 | tee -a "${currentlog}" # Backup Nginx configs - sudo tar -czvf ${tmp_dir}/nginx/etc-nginx.tar.gz -C /etc/nginx . | tee -a "${currentlog}" + sudo tar -czvf ${tmp_dir}/nginx/etc-nginx.tar.gz -C /etc/nginx . 2>&1 | tee -a "${currentlog}" # Backup other config files - sudo tar -czvf ${tmp_dir}/confd/etc-confd.tar.gz -C /etc/conf.d . | tee -a "${currentlog}" + sudo tar -czvf ${tmp_dir}/confd/etc-confd.tar.gz -C /etc/conf.d . 2>&1 | tee -a "${currentlog}" # Copy service files - sudo cp ${sysd}/rmm.service ${sysd}/celery.service ${sysd}/celerybeat.service ${sysd}/meshcentral.service ${sysd}/nats.service ${sysd}/daphne.service ${tmp_dir}/systemd/ | tee -a "${currentlog}" + sudo cp ${sysd}/rmm.service ${sysd}/celery.service ${sysd}/celerybeat.service ${sysd}/meshcentral.service ${sysd}/nats.service ${sysd}/daphne.service ${tmp_dir}/systemd/ 2>&1 | tee -a "${currentlog}" if [ -f "${sysd}/nats-api.service" ]; then - sudo cp ${sysd}/nats-api.service ${tmp_dir}/systemd/ | tee -a "${currentlog}" + sudo cp ${sysd}/nats-api.service ${tmp_dir}/systemd/ 2>&1 | tee -a "${currentlog}" fi - cat /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | gzip -9 > ${tmp_dir}/rmm/debug.log.gz | tee -a "${currentlog}" - cp /rmm/api/tacticalrmm/tacticalrmm/local_settings.py ${tmp_dir}/rmm/ | tee -a "${currentlog}" + cat /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | gzip -9 > ${tmp_dir}/rmm/debug.log.gz 2>&1 | tee -a "${currentlog}" + cp /rmm/api/tacticalrmm/tacticalrmm/local_settings.py ${tmp_dir}/rmm/ 2>&1 | tee -a "${currentlog}" - tar -cf /rmmbackups/rmm-backup-${dt_now}.tar -C ${tmp_dir} . | tee -a "${currentlog}" + tar -cf /rmmbackups/rmm-backup-${dt_now}.tar -C ${tmp_dir} . 2>&1 | tee -a "${currentlog}" # Remove temp files/folders - rm -rf ${tmp_dir} | tee -a "${currentlog}" + rm -rf ${tmp_dir} 2>&1 | tee -a "${currentlog}" # Misc functions - print_green "Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar"; + print_green "Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar" | tee -a "${currentlog}" return } @@ -562,13 +562,13 @@ restoreTRMM() # Install NodeJS # Misc functions - print_green 'Installing NodeJS'; + print_green 'Installing NodeJS' | tee -a "${currentlog}" # InstallFunctions installNodeJS; # Install Nginx and restore Nginx configuration # Misc functions - print_green 'Installing Nginx and restoring configuration'; + print_green 'Installing Nginx and restoring configuration' | tee -a "${currentlog}" # InstallFunctions installNginx "$INSTALL_TYPE"; @@ -578,19 +578,19 @@ restoreTRMM() # Restore Certbot # Misc functions - print_green 'Installing Certbot'; + print_green 'Installing Certbot' | tee -a "${currentlog}" # InstallFunctions installCertbot "$INSTALL_TYPE"; # Restoring existing certs # Misc functions - print_green 'Restoring certs'; + print_green 'Restoring certs' | tee -a "${currentlog}" - sudo rm -rf /etc/letsencrypt | tee -a "${currentlog}" - sudo mkdir /etc/letsencrypt | tee -a "${currentlog}" - sudo tar -xzf $tmp_dir/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt | tee -a "${currentlog}" - sudo chown root:${USER} -R /etc/letsencrypt | tee -a "${currentlog}" - sudo chmod 755 -R /etc/letsencrypt | tee -a "${currentlog}" + sudo rm -rf /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo mkdir /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo tar -xzf $tmp_dir/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" # Recreate Nginx conf files # Config and Service functions @@ -602,154 +602,154 @@ restoreTRMM() # Restore Celery configs # Misc functions - print_green 'Restoring celery configs'; + print_green 'Restoring celery configs' | tee -a "${currentlog}" - sudo mkdir /etc/conf.d | tee -a "${currentlog}" - sudo tar -xzf $tmp_dir/confd/etc-confd.tar.gz -C /etc/conf.d | tee -a "${currentlog}" - sudo chown "${USER}:${USER}" -R /etc/conf.d | tee -a "${currentlog}" + sudo mkdir /etc/conf.d 2>&1 | tee -a "${currentlog}" + sudo tar -xzf $tmp_dir/confd/etc-confd.tar.gz -C /etc/conf.d 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R /etc/conf.d 2>&1 | tee -a "${currentlog}" # Restoring services # Misc functions - print_green 'Restoring systemd services'; + print_green 'Restoring systemd services' | tee -a "${currentlog}" - sudo cp $tmp_dir/systemd/* /etc/systemd/system/ | tee -a "${currentlog}" - sudo systemctl daemon-reload | tee -a "${currentlog}" + sudo cp $tmp_dir/systemd/* /etc/systemd/system/ 2>&1 | tee -a "${currentlog}" + sudo systemctl daemon-reload 2>&1 | tee -a "${currentlog}" # Install Python # Misc functions - print_green "Installing Python ${PYTHON_VER}"; + print_green "Installing Python ${PYTHON_VER}" | tee -a "${currentlog}" # InstallFunctions installPython; # Installing Redis # Misc functions - print_green 'Installing redis'; + print_green 'Installing redis' | tee -a "${currentlog}" # InstallFunctions installRedis; # Install and enable Postgresql # Misc functions - print_green 'Installing postgresql'; + print_green 'Installing postgresql' | tee -a "${currentlog}" # InstallFunctions installPostgresql; # Install and enable MongoDB # Misc functions - print_green 'Installing MongoDB'; + print_green 'Installing MongoDB' | tee -a "${currentlog}" # InstallFunctions installMongo; # Restore Mongo database # Misc functions - print_green 'Restoring MongoDB'; - mongorestore --gzip $tmp_dir/meshcentral/mongo | tee -a "${currentlog}" + print_green 'Restoring MongoDB' | tee -a "${currentlog}" + mongorestore --gzip $tmp_dir/meshcentral/mongo 2>&1 | tee -a "${currentlog}" # Clone main repo # Misc functions - print_green 'Cloning primary repo'; + print_green 'Cloning primary repo' | tee -a "${currentlog}" # Misc functions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; # Clone scripts repo # Misc functions - print_green 'Cloning community scripts repo'; + print_green 'Cloning community scripts repo' | tee -a "${currentlog}" # Misc functions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; # Installing NATS # Misc functions - print_green 'Installing NATS'; + print_green 'Installing NATS' | tee -a "${currentlog}" # InstallFunctions installNats "$INSTALL_TYPE"; # Restore MeshCentral # Misc functions - print_green 'Restoring MeshCentral'; + print_green 'Restoring MeshCentral' | tee -a "${currentlog}" # InstallFunctions installMeshCentral "$INSTALL_TYPE"; # Restore UWSGI # Misc functions - print_green 'Restoring UWSGI configuration'; + print_green 'Restoring UWSGI configuration' | tee -a "${currentlog}" # Config and Service functions createUwsgiConf; # Restoring other misc stuff - cp $tmp_dir/rmm/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/ | tee -a "${currentlog}" - cp $tmp_dir/rmm/env /rmm/web/.env | tee -a "${currentlog}" - gzip -d $tmp_dir/rmm/debug.log.gz | tee -a "${currentlog}" - cp $tmp_dir/rmm/django_debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/ | tee -a "${currentlog}" + cp $tmp_dir/rmm/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/ 2>&1 | tee -a "${currentlog}" + cp $tmp_dir/rmm/env /rmm/web/.env 2>&1 | tee -a "${currentlog}" + gzip -d $tmp_dir/rmm/debug.log.gz 2>&1 | tee -a "${currentlog}" + cp $tmp_dir/rmm/django_debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/ 2>&1 | tee -a "${currentlog}" # Install NATS-API # Misc functions - print_green 'Installing NATS API'; + print_green 'Installing NATS API' | tee -a "${currentlog}" # InstallFunctions installNatsApi; # Restore Postgres database # Misc functions - print_green 'Restoring the Postgres database'; + print_green 'Restoring the Postgres database' | tee -a "${currentlog}" 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" | tee -a "${currentlog}" + sudo -u postgres psql -c "DROP DATABASE IF EXISTS tacticalrmm" 2>&1 | tee -a "${currentlog}" # Database functions createPGDB; - gzip -d $tmp_dir/postgres/*.psql.gz | tee -a "${currentlog}" + gzip -d $tmp_dir/postgres/*.psql.gz 2>&1 | tee -a "${currentlog}" PGPASSWORD="${pgpw} psql -h localhost -U ${pgusername} -d tacticalrmm -f $tmp_dir/postgres/db*.psql" # Restore Backend # Misc functions - print_green 'Restoring the backend'; + print_green 'Restoring the backend' | tee -a "${currentlog}" # Config and Service functions configureBackend "$INSTALL_TYPE"; # Start NATS # Misc functions - print_green 'Start NATS'; - sudo systemctl enable nats.service | tee -a "${currentlog}" - sudo systemctl start nats.service | tee -a "${currentlog}" + print_green 'Start NATS' | tee -a "${currentlog}" + sudo systemctl enable nats.service 2>&1 | tee -a "${currentlog}" + sudo systemctl start nats.service 2>&1 | tee -a "${currentlog}" # Install frontend # Misc functions - print_green 'Installing the frontend'; + print_green 'Installing the frontend' | tee -a "${currentlog}" # InstallFunctions installFrontEnd "$INSTALL_TYPE"; # reset perms - sudo chown "${USER}:${USER}" -R /rmm | tee -a "${currentlog}" - sudo chown "${USER}:${USER}" /var/log/celery | tee -a "${currentlog}" - sudo chown "${USER}:${USER}" -R /etc/conf.d/ | tee -a "${currentlog}" - sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.npm | tee -a "${currentlog}" - sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.config | tee -a "${currentlog}" - sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.cache | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R /rmm 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" /var/log/celery 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R /etc/conf.d/ 2>&1 | tee -a "${currentlog}" + sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.npm 2>&1 | tee -a "${currentlog}" + sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.config 2>&1 | tee -a "${currentlog}" + sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.cache 2>&1 | tee -a "${currentlog}" # Update services info - sudo systemctl daemon-reload | tee -a "${currentlog}" + sudo systemctl daemon-reload 2>&1 | tee -a "${currentlog}" # Enable RMM, Daphne, Celery, Nats-api, and Nginx services # Misc functions - print_green 'Enabling Services'; + print_green 'Enabling Services' | tee -a "${currentlog}" for i in celery.service celerybeat.service rmm.service daphne.service nats-api.service nginx do - sudo systemctl enable ${i} | tee -a "${currentlog}" - sudo systemctl stop ${i} | tee -a "${currentlog}" - sudo systemctl start ${i} | tee -a "${currentlog}" + sudo systemctl enable ${i} 2>&1 | tee -a "${currentlog}" + sudo systemctl stop ${i} 2>&1 | tee -a "${currentlog}" + sudo systemctl start ${i} 2>&1 | tee -a "${currentlog}" done sleep 5 # Start MeshCentral # Misc functions - print_green 'Starting meshcentral'; - sudo systemctl enable meshcentral | tee -a "${currentlog}" - sudo systemctl start meshcentral | tee -a "${currentlog}" + print_green 'Starting meshcentral' | tee -a "${currentlog}" + sudo systemctl enable meshcentral 2>&1 | tee -a "${currentlog}" + sudo systemctl start meshcentral 2>&1 | tee -a "${currentlog}" # Done!!!! # Misc functions - print_green 'Restore complete!'; + print_green 'Restore complete!' | tee -a "${currentlog}" return } @@ -825,9 +825,9 @@ troubleShoot() echo -e "${GREEN} Getting summary output of logs.${NC}" | tee -a "${currentlog}" echo -e "\n" - tail /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | tee -a "${currentlog}" + tail /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | tee -a "${currentlog}" echo -e "\n" - tail /rmm/api/tacticalrmm/tacticalrmm/private/log/error.log | tee -a "${currentlog}" + tail /rmm/api/tacticalrmm/tacticalrmm/private/log/error.log | tee -a "${currentlog}" echo -e "\n" # Misc functions print_yellow "You will have a log file called checklog_$rundate.log in the directory you ran this script from."; diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 422ead190c..171a5f5d80 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -33,12 +33,12 @@ wutOSThis() verifySupportedOS() { if ([ "$osname" == "ubuntu" ] && ([ "$fullrelno" == "20.04" ] || [ "$fullrelno" == "22.04" ])) || ([ "$osname" == "debian" ] && [ $relno -ge 10 ]); then - echo -e "${GREEN} $fullrel${NC}" + echo -e "${GREEN} $fullrel${NC}" | tee -a "${currentlog}" else if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" - echo -e "${RED} Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11${NC}" - echo -e "${RED} Your system, $fullrel, does not appear to be supported.${NC}\n" + echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11${NC}" | tee -a "${currentlog}" + echo -e "${RED} Your system, $fullrel, does not appear to be supported.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Exiting.${NC}\n" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 @@ -53,8 +53,8 @@ checkLocale() { if [[ "$LANG" != *".UTF-8" ]]; then if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" - echo -e "${RED} System locale must be .UTF-8, not ${LANG}.${NC}\n" + echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} System locale must be .UTF-8, not ${LANG}.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Run the following command and change the default locale to your language of choice:${NC}\n" echo -e "${RED} sudo dpkg-reconfigure locales${NC}\n" echo -e "${RED} You will need to log out and back in for changes to take effect, then re-run this script.${NC}\n" @@ -76,8 +76,8 @@ checkTotalSystemMemory() return else if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error: System does not meet the minimum recommended RAM amount of 2GB.${NC}\n" - echo -e "${RED} Please add RAM to the system to prevent potential issues during install.${NC}\n" + echo -e "${RED} Error: System does not meet the minimum recommended RAM amount of 2GB.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please add RAM to the system to prevent potential issues during install.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Re-run $THIS_SCRIPT after resolving the issue.${NC}\n" echo -e "${RED} Exiting...${NC}\n" exit 1 diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index fc6d8d39ff..953068cc61 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -35,7 +35,7 @@ checkIPisLive() echo -e "\n" else echo -e "${YELLOW} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a "${currentlog}" - echo -e "\n" | tee -a checklog.log + echo -e "\n" echo -e "${YELLOW} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}" | tee -a "${currentlog}" echo -e "\n" fi diff --git a/script-cfg/UpdateRestoreFunctions.cfg b/script-cfg/UpdateRestoreFunctions.cfg index 8e406a672d..b2e8ed42af 100644 --- a/script-cfg/UpdateRestoreFunctions.cfg +++ b/script-cfg/UpdateRestoreFunctions.cfg @@ -20,16 +20,16 @@ checkSameUser() fi if [ "$ORIGUSER" != "$USER" ]; then if [ "$autoinstall" == "1" ]; then - echo -e "${RED} You must run this update script from the same user account used during install: ${ORIGUSER}${NC}\n" - echo -e "${RED} Exiting...${NC}\n" + echo -e "${RED} You must run this update script from the same user account used during install: ${ORIGUSER}${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Exiting...${NC}\n" | tee -a "${currentlog}" if [ "$1" == "restore" ]; then - rm -rf $tmp_dir + rm -rf $tmp_dir 2>&1 | tee -a "${currentlog}" fi exit 1 elif [ "$autoinstall" != "1" ]; then dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "You must run this update script from the same user account used during install: ${ORIGUSER}\n\nExiting." 0 0 if [ "$1" == "restore" ]; then - rm -rf $tmp_dir + rm -rf $tmp_dir 2>&1 | tee -a "${currentlog}" fi clear -x exit 1 @@ -47,8 +47,8 @@ checkIfUpdate() CURRENT_TRMM_VER=$(grep "^TRMM_VERSION" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') if [ "${CURRENT_TRMM_VER}" == "${LATEST_TRMM_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then - echo -e "${GREEN} Already on latest version. Current version:${NC} ${YELLOW}${CURRENT_TRMM_VER}${NC} ${GREEN}Latest version:${NC} ${YELLOW}${LATEST_TRMM_VER}${NC}\n" - rm -f $TMP_SETTINGS + echo -e "${GREEN} Already on latest version. Current version:${NC} ${YELLOW}${CURRENT_TRMM_VER}${NC} ${GREEN}Latest version:${NC} ${YELLOW}${LATEST_TRMM_VER}${NC}\n" | tee -a "${currentlog}" + rm -f $TMP_SETTINGS 2>&1 | tee -a "${currentlog}" exit 0 fi } @@ -67,20 +67,20 @@ checkNatsLimitNoFile() { CHECK_NATS_LIMITNOFILE=$(grep LimitNOFILE /etc/systemd/system/nats.service) if ! [ $CHECK_NATS_LIMITNOFILE ]; then - sudo rm -f /etc/systemd/system/nats.service + sudo rm -f /etc/systemd/system/nats.service 2>&1 | tee -a "${currentlog}" # Config and Service functions createNatsService; - sudo systemctl daemon-reload + sudo systemctl daemon-reload 2>&1 | tee -a "${currentlog}" fi } # Disable Redis append only turnOffRedisAppendOnly() { - echo -e "${GREEN} Turning off redis aof${NC}\n" - sudo redis-cli config set appendonly no - sudo redis-cli config rewrite - sudo rm -f /var/lib/redis/appendonly.aof + echo -e "${GREEN} Turning off redis aof${NC}\n" | tee -a "${currentlog}" + sudo redis-cli config set appendonly no 2>&1 | tee -a "${currentlog}" + sudo redis-cli config rewrite 2>&1 | tee -a "${currentlog}" + sudo rm -f /var/lib/redis/appendonly.aof 2>&1 | tee -a "${currentlog}" } # Update MeshCentral @@ -88,13 +88,13 @@ updateMeshCentral() { CURRENT_MESH_VER=$(cd /meshcentral/node_modules/meshcentral && node -p -e "require('./package.json').version") if [ "${CURRENT_MESH_VER}" != "${LATEST_MESH_VER}" ] || [ "$UPDATE_TYPE" = "forced" ]; then - echo -e "${GREEN} Updating meshcentral from ${CURRENT_MESH_VER} to ${LATEST_MESH_VER}${NC}\n" - sudo systemctl stop meshcentral - sudo chown "${USER}:${USER}" -R /meshcentral - cd /meshcentral - rm -rf node_modules/ - npm install meshcentral@${LATEST_MESH_VER} - sudo chown "${USER}:${USER}" -R /meshcentral + echo -e "${GREEN} Updating meshcentral from ${CURRENT_MESH_VER} to ${LATEST_MESH_VER}${NC}\n" | tee -a "${currentlog}" + sudo systemctl stop meshcentral 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" + cd /meshcentral 2>&1 | tee -a "${currentlog}" + rm -rf node_modules/ 2>&1 | tee -a "${currentlog}" + npm install meshcentral@${LATEST_MESH_VER} 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" fi } @@ -130,8 +130,8 @@ getBackupFileLocation() extractBackup() { # MiscFunctions - print_green 'Unpacking backup'; + print_green 'Unpacking backup' | tee -a "${currentlog}" tmp_dir=$(mktemp -d -t tacticalrmm-XXXXXXXXXXXXXXXXXXXXX) - tar -xf ${1} -C $tmp_dir + tar -xf ${1} -C $tmp_dir 2>&1 | tee -a "${currentlog}" } \ No newline at end of file diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index 30b5243380..1202b6bae6 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -98,13 +98,13 @@ generateUsersAndPass() subdomainFormatCheck() { if [[ $(grep "\." <<< "$1") ]] 2>/dev/null; then - echo -e "${RED} Error: The $2 hostname/subdomain you provided is in the incorrect format.${NC}\n" - echo -e "${RED} Do not include the root domain.${NC}\n" + echo -e "${RED} Error: The $2 hostname/subdomain you provided is in the incorrect format.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Do not include the root domain.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}\n" echo -e "${RED} Exiting...${NC}\n" exit 1 else - echo -e "${GREEN} $2 hostname format ok.${NC}\n" + echo -e "${GREEN} $2 hostname format ok.${NC}\n" | tee -a "${currentlog}" fi } @@ -112,9 +112,9 @@ subdomainFormatCheck() rootDomainFormatCheck() { if [[ $(grep "\." <<< "$1") ]] 2>/dev/null; then - echo -e "${GREEN} Root domain format ok.${NC}\n" + echo -e "${GREEN} Root domain format ok.${NC}\n" | tee -a "${currentlog}" else - echo -e "${RED} Error: The root domain you provided is in the incorrect format.${NC}\n" + echo -e "${RED} Error: The root domain you provided is in the incorrect format.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}\n" echo -e "${RED} Exiting...${NC}\n" exit 1 @@ -125,9 +125,9 @@ rootDomainFormatCheck() checkDNSEntriesExist() { if [[ $(dig +noall +answer $1) ]] 2>/dev/null; then - echo -e "${GREEN} DNS record for $1 exists.${NC}\n" + echo -e "${GREEN} DNS record for $1 exists.${NC}\n" | tee -a "${currentlog}" else - echo -e "${RED} Error: $1 does not resolve via DNS.${NC}\n" + echo -e "${RED} Error: $1 does not resolve via DNS.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Please correct the issue and run $THIS_SCRIPT again.${NC}\n" echo -e "${RED} Exiting...${NC}\n" exit 1 @@ -138,12 +138,12 @@ checkDNSEntriesExist() checkCertExists() { if [ ! -f "$1" ]; then - echo -e "${RED} Error: The $2 path and/or filename you provided is invalid.${NC}\n" + echo -e "${RED} Error: The $2 path and/or filename you provided is invalid.${NC}\n" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}\n" echo -e "${RED} Exiting...${NC}\n" exit 1 else - echo -e "${GREEN} The $2 path you provided is valid.${NC}\n" + echo -e "${GREEN} The $2 path you provided is valid.${NC}\n" | tee -a "${currentlog}" fi } From faae1545b2f1fe3013d5cbe0c0053719a0e2f8dd Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 12:38:45 -0500 Subject: [PATCH 151/203] added missing logging --- script-cfg/InstallFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index bbcb36041f..c566a3aa12 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -12,13 +12,13 @@ CFG_VERSION="8" # Install script prereqs installPreReqs() { - sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev + sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" } # Install remaining prereqs installAdditionalPreReqs() { - sudo apt-get install -y software-properties-common dnsutils openssl ca-certificates apt-transport-https gcc g++ make build-essential zlib1g-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev git + sudo apt-get install -y software-properties-common dnsutils openssl ca-certificates apt-transport-https gcc g++ make build-essential zlib1g-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev git 2>&1 | tee -a "${currentlog}" } # Configure repos for stuff From 3a14ad900600bec252862fcab6d2804d3171a711 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 13:13:30 -0500 Subject: [PATCH 152/203] attempting fixes for logging --- script-cfg/InstallFunctions.cfg | 6 +++--- script-cfg/SystemInfoFunctions.cfg | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index c566a3aa12..9acece00ee 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -81,7 +81,7 @@ installNodeJS() sudo npm install -g npm 2>&1 | tee -a "${currentlog}" if [ "$1" == "update" ]; then sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" - cd /meshcentral 2>&1 | tee -a "${currentlog}" + cd /meshcentral rm -rf node_modules/ 2>&1 | tee -a "${currentlog}" npm install meshcentral@"${LATEST_MESH_VER}" 2>&1 | tee -a "${currentlog}" sudo systemctl start meshcentral 2>&1 | tee -a "${currentlog}" @@ -113,10 +113,10 @@ installPython() return else numprocs=$(nproc) - cd ~ 2>&1 | tee -a "${currentlog}" + cd ~ wget https://www.python.org/ftp/python/${PYTHON_VER}/Python-${PYTHON_VER}.tgz 2>&1 | tee -a "${currentlog}" tar -xf Python-${PYTHON_VER}.tgz 2>&1 | tee -a "${currentlog}" - cd Python-${PYTHON_VER} 2>&1 | tee -a "${currentlog}" + cd Python-${PYTHON_VER} ./configure --enable-optimizations 2>&1 | tee -a "${currentlog}" make -j $numprocs 2>&1 | tee -a "${currentlog}" sudo make altinstall 2>&1 | tee -a "${currentlog}" diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 171a5f5d80..311ef0586b 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -33,7 +33,7 @@ wutOSThis() verifySupportedOS() { if ([ "$osname" == "ubuntu" ] && ([ "$fullrelno" == "20.04" ] || [ "$fullrelno" == "22.04" ])) || ([ "$osname" == "debian" ] && [ $relno -ge 10 ]); then - echo -e "${GREEN} $fullrel${NC}" | tee -a "${currentlog}" + echo -e "\n${GREEN} $fullrel${NC}" | tee -a "${currentlog}" else if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" From b94abf1c17065c686686a8c078eecb891afd0e78 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 13:18:04 -0500 Subject: [PATCH 153/203] same as last --- script-cfg/ConfigAndServiceFunctions.cfg | 18 +++++++++--------- script-cfg/InstallFunctions.cfg | 4 ++-- script-cfg/MiscFunctions.cfg | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 844c050a70..cad4a12d23 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -49,16 +49,16 @@ configureBackend() sudo chmod +x /usr/local/bin/nats-api 2>&1 | tee -a "${currentlog}" if [ "${CURRENT_PIP_VER}" != "${LATEST_PIP_VER}" ] || [ "$UPDATE_TYPE" == "forced" ]; then rm -rf /rmm/api/env 2>&1 | tee -a "${currentlog}" - cd /rmm/api 2>&1 | tee -a "${currentlog}" + cd /rmm/api python3.10 -m venv env 2>&1 | tee -a "${currentlog}" source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" - cd /rmm/api/tacticalrmm 2>&1 | tee -a "${currentlog}" + cd /rmm/api/tacticalrmm pip install --no-cache-dir --upgrade pip 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER} 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir -r requirements.txt 2>&1 | tee -a "${currentlog}" else source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" - cd /rmm/api/tacticalrmm 2>&1 | tee -a "${currentlog}" + cd /rmm/api/tacticalrmm pip install -r /rmm/api/tacticalrmm/requirements.txt 2>&1 | tee -a "${currentlog}" fi python manage.py pre_update_tasks 2>&1 | tee -a "${currentlog}" @@ -75,10 +75,10 @@ configureBackend() WEB_VERSION=$(python manage.py get_config webversion) deactivate 2>&1 | tee -a "${currentlog}" elif [ "$1" == "restore" ]; then - cd /rmm/api 2>&1 | tee -a "${currentlog}" + cd /rmm/api python3.10 -m venv env 2>&1 | tee -a "${currentlog}" source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" - cd /rmm/api/tacticalrmm 2>&1 | tee -a "${currentlog}" + cd /rmm/api/tacticalrmm pip install --no-cache-dir --upgrade pip 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER} 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir -r /rmm/api/tacticalrmm/requirements.txt 2>&1 | tee -a "${currentlog}" @@ -91,10 +91,10 @@ configureBackend() WEB_VERSION=$(python manage.py get_config webversion) deactivate 2>&1 | tee -a "${currentlog}" elif [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then - cd /rmm/api 2>&1 | tee -a "${currentlog}" + cd /rmm/api python3.10 -m venv env 2>&1 | tee -a "${currentlog}" source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" - cd /rmm/api/tacticalrmm 2>&1 | tee -a "${currentlog}" + cd /rmm/api/tacticalrmm pip install --no-cache-dir --upgrade pip 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER} 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir -r /rmm/api/tacticalrmm/requirements.txt 2>&1 | tee -a "${currentlog}" @@ -278,7 +278,7 @@ configMeshUserGroup() { sudo systemctl stop meshcentral 2>&1 | tee -a "${currentlog}" sleep 1 - cd /meshcentral 2>&1 | tee -a "${currentlog}" + cd /meshcentral node node_modules/meshcentral --createaccount ${meshusername} --pass ${MESHPASSWD} --email ${letsemail} 2>&1 | tee -a "${currentlog}" sleep 1 @@ -301,7 +301,7 @@ configMeshUserGroup() enableNatsService() { sudo systemctl enable nats.service 2>&1 | tee -a "${currentlog}" - cd /rmm/api/tacticalrmm 2>&1 | tee -a "${currentlog}" + cd /rmm/api/tacticalrmm source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" python manage.py initial_db_setup 2>&1 | tee -a "${currentlog}" python manage.py reload_nats 2>&1 | tee -a "${currentlog}" diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 9acece00ee..702a9991a3 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -120,7 +120,7 @@ installPython() ./configure --enable-optimizations 2>&1 | tee -a "${currentlog}" make -j $numprocs 2>&1 | tee -a "${currentlog}" sudo make altinstall 2>&1 | tee -a "${currentlog}" - cd ~ 2>&1 | tee -a "${currentlog}" + cd ~ sudo rm -rf Python-${PYTHON_VER} Python-${PYTHON_VER}.tgz 2>&1 | tee -a "${currentlog}" if [ "$1" == "devprep" ]; then # Misc functions @@ -251,7 +251,7 @@ installMeshCentral() sudo tar -xzf $tmp_dir/meshcentral/mesh.tar.gz -C / 2>&1 | tee -a "${currentlog}" fi sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" - cd /meshcentral 2>&1 | tee -a "${currentlog}" + cd /meshcentral npm install meshcentral@${MESH_VER} 2>&1 | tee -a "${currentlog}" sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" } diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index f189ff5c4c..93b30d77a5 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -244,7 +244,7 @@ clonePrimaryRepo() git clone "$2" /rmm/ 2>&1 | tee -a "${currentlog}" fi - cd /rmm 2>&1 | tee -a "${currentlog}" + cd /rmm git config user.email "admin@example.com" 2>&1 | tee -a "${currentlog}" git config user.name "Bob" 2>&1 | tee -a "${currentlog}" @@ -271,7 +271,7 @@ cloneScriptsRepo() sudo chown "${USER}:${USER}" "${SCRIPTS_DIR}" 2>&1 | tee -a "${currentlog}" git clone "$2" "${SCRIPTS_DIR}"/ 2>&1 | tee -a "${currentlog}" fi - cd "${SCRIPTS_DIR}" 2>&1 | tee -a "${currentlog}" + cd "${SCRIPTS_DIR}" git config user.email "admin@example.com" 2>&1 | tee -a "${currentlog}" git config user.name "Bob" 2>&1 | tee -a "${currentlog}" From 3c00ceb2bc9906c205c65be2e45084afd66890ff Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 13:40:56 -0500 Subject: [PATCH 154/203] more fixes to logging --- script-cfg/ConfigAndServiceFunctions.cfg | 20 ++++++++++---------- script-cfg/InstallFunctions.cfg | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index cad4a12d23..f5f1e1dd4f 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -50,14 +50,14 @@ configureBackend() if [ "${CURRENT_PIP_VER}" != "${LATEST_PIP_VER}" ] || [ "$UPDATE_TYPE" == "forced" ]; then rm -rf /rmm/api/env 2>&1 | tee -a "${currentlog}" cd /rmm/api - python3.10 -m venv env 2>&1 | tee -a "${currentlog}" - source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" + python3.10 -m venv env + source /rmm/api/env/bin/activate cd /rmm/api/tacticalrmm pip install --no-cache-dir --upgrade pip 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER} 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir -r requirements.txt 2>&1 | tee -a "${currentlog}" else - source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" + source /rmm/api/env/bin/activate cd /rmm/api/tacticalrmm pip install -r /rmm/api/tacticalrmm/requirements.txt 2>&1 | tee -a "${currentlog}" fi @@ -73,11 +73,11 @@ configureBackend() python manage.py post_update_tasks 2>&1 | tee -a "${currentlog}" rmmdomain=$(python manage.py get_config api) WEB_VERSION=$(python manage.py get_config webversion) - deactivate 2>&1 | tee -a "${currentlog}" + deactivate elif [ "$1" == "restore" ]; then cd /rmm/api - python3.10 -m venv env 2>&1 | tee -a "${currentlog}" - source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" + python3.10 -m venv env + source /rmm/api/env/bin/activate cd /rmm/api/tacticalrmm pip install --no-cache-dir --upgrade pip 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER} 2>&1 | tee -a "${currentlog}" @@ -89,11 +89,11 @@ configureBackend() python manage.py post_update_tasks 2>&1 | tee -a "${currentlog}" rmmdomain=$(python manage.py get_config api) WEB_VERSION=$(python manage.py get_config webversion) - deactivate 2>&1 | tee -a "${currentlog}" + deactivate elif [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then cd /rmm/api - python3.10 -m venv env 2>&1 | tee -a "${currentlog}" - source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" + python3.10 -m venv env + source /rmm/api/env/bin/activate cd /rmm/api/tacticalrmm pip install --no-cache-dir --upgrade pip 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER} 2>&1 | tee -a "${currentlog}" @@ -127,7 +127,7 @@ configureBackend() # Misc functions cls; python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} 2>&1 | tee -a "${currentlog}" - deactivate 2>&1 | tee -a "${currentlog}" + deactivate read -n 1 -s -r -p "Press any key to continue..." echo -e "\n" fi diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 702a9991a3..8dbe53f319 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -158,7 +158,7 @@ installNats() NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') fi nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) 2>&1 | tee -a "${currentlog}" - wget -q 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} 2>&1 | tee -a "${currentlog}" + wget -q 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} 2>&1 | tee -a "${currentlog}" tar -xzf ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz -C ${nats_tmp} 2>&1 | tee -a "${currentlog}" if [ "$1" == "update" ]; then sudo rm -f /usr/local/bin/nats-server 2>&1 | tee -a "${currentlog}" From 2d7c072e44c98a03eb74aa217cce94d4a6bb1449 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 13:44:01 -0500 Subject: [PATCH 155/203] another fix for logging --- script-cfg/InstallFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 8dbe53f319..f737d6b5d5 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -157,8 +157,8 @@ installNats() if [ "$1" == "install" ] || [ "$1" == "devinstall" ] || [ "$1" == "restore" ]; then NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') fi - nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) 2>&1 | tee -a "${currentlog}" - wget -q 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} 2>&1 | tee -a "${currentlog}" + nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) + wget -q 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} 2>&1 | tee -a "${currentlog}" tar -xzf ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz -C ${nats_tmp} 2>&1 | tee -a "${currentlog}" if [ "$1" == "update" ]; then sudo rm -f /usr/local/bin/nats-server 2>&1 | tee -a "${currentlog}" From 6f6f7c7a05fc9c8657fb2f825167655d4737e8fa Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 14:14:03 -0500 Subject: [PATCH 156/203] Please be the last logging fixes --- script-cfg/ConfigAndServiceFunctions.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index f5f1e1dd4f..0bd8627ebc 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -126,7 +126,7 @@ configureBackend() RANDBASE=$(python manage.py generate_totp) # Misc functions cls; - python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} 2>&1 | tee -a "${currentlog}" + python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} deactivate read -n 1 -s -r -p "Press any key to continue..." echo -e "\n" @@ -302,10 +302,10 @@ enableNatsService() { sudo systemctl enable nats.service 2>&1 | tee -a "${currentlog}" cd /rmm/api/tacticalrmm - source /rmm/api/env/bin/activate 2>&1 | tee -a "${currentlog}" + source /rmm/api/env/bin/activate python manage.py initial_db_setup 2>&1 | tee -a "${currentlog}" python manage.py reload_nats 2>&1 | tee -a "${currentlog}" - deactivate 2>&1 | tee -a "${currentlog}" + deactivate sudo systemctl start nats.service 2>&1 | tee -a "${currentlog}" sleep 1 From 29edc1c3852dc877ff025200c971fa5d0804da13 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 14:19:55 -0500 Subject: [PATCH 157/203] removed logging for remaining python issues --- script-cfg/UpdateRestoreFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/UpdateRestoreFunctions.cfg b/script-cfg/UpdateRestoreFunctions.cfg index b2e8ed42af..1148fef422 100644 --- a/script-cfg/UpdateRestoreFunctions.cfg +++ b/script-cfg/UpdateRestoreFunctions.cfg @@ -91,7 +91,7 @@ updateMeshCentral() echo -e "${GREEN} Updating meshcentral from ${CURRENT_MESH_VER} to ${LATEST_MESH_VER}${NC}\n" | tee -a "${currentlog}" sudo systemctl stop meshcentral 2>&1 | tee -a "${currentlog}" sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" - cd /meshcentral 2>&1 | tee -a "${currentlog}" + cd /meshcentral rm -rf node_modules/ 2>&1 | tee -a "${currentlog}" npm install meshcentral@${LATEST_MESH_VER} 2>&1 | tee -a "${currentlog}" sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" From 35df391486c3e1455407a74b0336c91266f58d6a Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 14:23:31 -0500 Subject: [PATCH 158/203] removed checks and text for 4222 --- script-cfg/ParentFunctions.cfg | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index a6c5cdf4c8..58630b00f9 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -305,9 +305,9 @@ mainInstall() echo -e "${GREEN} If you will be accessing the web interface of the RMM from the same LAN as this server,\n you'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" echo -e "${GREEN} This also applies to any agents that will be on the same local network as the rmm.${NC}\n" if [ "$certtype" == "webroot" ]; then - echo -e "${GREEN} You'll also need to setup port forwarding in your router on ports 80, 443, and 4222, if you have not done so already.${NC}\n" + echo -e "${GREEN} You'll also need to setup port forwarding in your router on ports 80 and 443 if you have not done so already.${NC}\n" else - echo -e "${GREEN} You'll also need to setup port forwarding in your router on ports 443 and 4222.${NC}\n" + echo -e "${GREEN} You'll also need to setup port forwarding in your router on port 443.${NC}\n" fi fi # Misc functions @@ -809,7 +809,6 @@ troubleShoot() # Check if ports are open # Troubleshooting functions - isPortOpen "4222" "NATS"; isPortOpen "80" "HTTP"; isPortOpen "443" "HTTPS"; From 0fc1b04b273a6cee08abd19061b927325050bb3b Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 14:31:11 -0500 Subject: [PATCH 159/203] changed name of preinstall log --- installer-util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer-util.sh b/installer-util.sh index a272a4a8b8..ef06e3d3eb 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -21,7 +21,7 @@ restorelog="$PWD/trmm-restore_$rundate.log" updatelog="$PWD/trmm-update_$rundate.log" backuplog="$PWD/trmm-backup_$rundate.log" checklog="$PWD/trmm-checklog_$rundate.log" -preinstalllog="$PWD/trmm-preinstalllog_$rundate.log" +preinstalllog="$PWD/trmm-preinstall-log_$rundate.log" currentlog="$preinstalllog" # Script Info variables From e20357d71277b95d0363aea98f7aff73719afe59 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 15:14:40 -0500 Subject: [PATCH 160/203] Reverted to resolvectl for dns discovery --- script-cfg/TroubleshootingFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index 953068cc61..58e865b7f9 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -25,7 +25,7 @@ pingDomain() checkIPisLive() { # Resolve Locally used DNS server - locdns=$(grep "nameserver" /etc/resolv.conf | awk '{ print $2 }') + locdns=$(resolvectl | grep 'Current DNS Server:' | cut -d: -f2 | awk '{ print $1}') locinputip=`dig @"$locdns" +short $1` reminputip=`dig @8.8.8.8 +short $1` From f358e032a300bab42a4a7bf44eeccdf503df3ee6 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 16:48:33 -0500 Subject: [PATCH 161/203] Fix for issues with update to openssl --- script-cfg/ParentFunctions.cfg | 4 +- script-cfg/TroubleshootingFunctions.cfg | 67 +++++++++---------------- 2 files changed, 26 insertions(+), 45 deletions(-) diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 58630b00f9..d4fc0abce4 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -533,7 +533,7 @@ backupTRMM() # Remove temp files/folders rm -rf ${tmp_dir} 2>&1 | tee -a "${currentlog}" # Misc functions - print_green "Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar" | tee -a "${currentlog}" + print_green "Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar" 2>&1 | tee -a "${currentlog}" return } @@ -829,7 +829,7 @@ troubleShoot() tail /rmm/api/tacticalrmm/tacticalrmm/private/log/error.log | tee -a "${currentlog}" echo -e "\n" # Misc functions - print_yellow "You will have a log file called checklog_$rundate.log in the directory you ran this script from."; + print_yellow "You will have a log file called checklog_$rundate.log in the directory you ran this script from." return } \ No newline at end of file diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index 58e865b7f9..8bad44b923 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -13,11 +13,9 @@ CFG_VERSION="8" pingDomain() { if ( ping -c 1 $1 &> /dev/null ); then - echo -e "${GREEN} Verified $1 by ping.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${GREEN} Verified $1 by ping.${NC}\n" | tee -a "${currentlog}" else - echo -e "${RED} $1 cannot be verified by ping.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${RED} $1 cannot be verified by ping.${NC}\n" | tee -a "${currentlog}" fi } @@ -31,13 +29,10 @@ checkIPisLive() reminputip=`dig @8.8.8.8 +short $1` if [ "$locinputip" == "$reminputip" ]; then - echo -e "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}\n" | tee -a "${currentlog}" else - echo -e "${YELLOW} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}" | tee -a "${currentlog}" - echo -e "\n" - echo -e "${YELLOW} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${YELLOW} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}\n" | tee -a "${currentlog}" + echo -e "${YELLOW} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}\n" | tee -a "${currentlog}" fi } @@ -61,11 +56,9 @@ readServicesStatus() checkIfServiceActive() { if [ $1 = active ]; then - echo -e "${GREEN} Success $2 is Running.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${GREEN} Success $2 is Running.${NC}\n" | tee -a "${currentlog}" else - echo -e "${RED} $2 is not running. \(Tactical will not work without this\)${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${RED} $2 is not running. \(Tactical will not work without this\)${NC}\n" | tee -a "${currentlog}" fi } @@ -73,75 +66,63 @@ checkIfServiceActive() isPortOpen() { if ( nc -zv $wanip $1 2>&1 >/dev/null ); then - echo -e "${GREEN} $2 Port is open.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${GREEN} $2 Port is open.${NC}\n" | tee -a "${currentlog}" else - echo -e "${YELLOW} $2 port is closed. \(you may want this if running locally only\)${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${YELLOW} $2 port is closed. \(you may want this if running locally only\)${NC}\n" | tee -a "${currentlog}" fi } # Check proxy checkProxy() { - echo -e "${GREEN} Checking For Proxy.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${GREEN} Checking For Proxy.${NC}\n" | tee -a "${currentlog}" echo -e "${YELLOW} ......this might take a while!!${NC}" # 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)" + proxyint="$(openssl s_client -showcerts -servername 127.0.1.1 -connect 127.0.1.1:443 2>/dev/null | openssl x509 -inform pem -noout -text)" if [[ "$proxyext" == "$proxyint" ]]; then - echo -e "${GREEN} No Proxy detected using Certificate.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${GREEN} No Proxy detected using Certificate.${NC}\n" | tee -a "${currentlog}" else - echo -e "${YELLOW} Proxy detected using Certificate.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${YELLOW} Proxy detected using Certificate.${NC}\n" | tee -a "${currentlog}" fi # Detect Proxy via IP if [ "$wanip" != "$remrmmip" ]; then - echo -e "${YELLOW} Proxy detected using IP.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${YELLOW} Proxy detected using IP.${NC}\n" | tee -a "${currentlog}" else - echo -e "${GREEN} No Proxy detected using IP.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${GREEN} No Proxy detected using IP.${NC}\n" | tee -a "${currentlog}" fi } # Check for valid cert checkIfCertIsValid() { - echo -e "${YELLOW} Checking if SSL Certificate is up to date.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${YELLOW} Checking if SSL Certificate is up to date.${NC}\n" | tee -a "${currentlog}" # SSL Certificate check # Check DNS-Manual or imported certs if [ ! -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then - cert="$(openssl verify -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem)" + cert="$(openssl verify -partial_chain -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem)" certexp="$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/${rootdomain}/fullchain.pem | cut -d "=" -f2)" if [[ "$cert" == *"OK"* ]]; then - echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}" | tee -a "${currentlog}" - echo -e "${GREEN} SSL Certificate expires $certexp${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} SSL Certificate expires $certexp${NC}\n" | tee -a "${currentlog}" else - echo -e "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}\n" | tee -a "${currentlog}" fi # Check Webroot authenticated certs elif [ -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then - cert="$(openssl verify -no_check_time -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem)" + cert="$(openssl verify -partial_chain -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem)" certexp="$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/${rootdomain}/fullchain.pem | cut -d "=" -f2)" if [[ "$cert" == *"OK"* ]]; then - echo -e "${GREEN} SSL Certificate for $rmmdomain , $frontenddomain , and $meshdomain is fine.${NC}" | tee -a "${currentlog}" - echo -e "${GREEN} SSL Certificate expires $certexp${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${GREEN} SSL Certificate for $rmmdomain , $frontenddomain , and $meshdomain is fine.${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} SSL Certificate expires $certexp${NC}\n" | tee -a "${currentlog}" else - echo -e "${RED} SSL Certificate has expired or doesnt exist for $rmmdomain , $frontenddomain , and $meshdomain.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "${RED} SSL Certificate has expired or doesnt exist for $rmmdomain , $frontenddomain , and $meshdomain.${NC}\n" | tee -a "${currentlog}" fi fi } From f834d62d3c106ba25a0b0ca3946487f4f2911191 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 7 Jul 2022 18:19:32 -0500 Subject: [PATCH 162/203] formatting edits for logging, was ugly af --- installer-util.sh | 36 ++--- script-cfg/CertificateFunctions.cfg | 16 +-- script-cfg/ConfigAndServiceFunctions.cfg | 4 +- script-cfg/InstallFunctions.cfg | 22 +-- script-cfg/MiscFunctions.cfg | 72 +++++----- script-cfg/NetworkFunctions.cfg | 6 +- script-cfg/ParentFunctions.cfg | 162 +++++++++++------------ script-cfg/SystemInfoFunctions.cfg | 30 ++--- script-cfg/TroubleshootingFunctions.cfg | 42 +++--- script-cfg/UpdateRestoreFunctions.cfg | 13 +- script-cfg/UserInput.cfg | 34 ++--- 11 files changed, 217 insertions(+), 220 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index ef06e3d3eb..91178d1c1a 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -130,46 +130,46 @@ if [ "$autoinstall" == "1" ]; then # Check that update type is valid if ([ "$INSTALL_TYPE" == "update" ] && ([ "$UPDATE_TYPE" != "standard" ] && [ "$UPDATE_TYPE" != "forced" ])); then - echo -e "${RED} Error: You've selected update, but not selected an appropriate type.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to select them.${NC}" + echo -e "${RED} Error: You've selected update, but not selected an appropriate type. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to select them. ${NC}" exit 1 fi # Check that backup file exists if ([ "$INSTALL_TYPE" == "restore" ] && ([ -z "$backupfile" ] || [ ! -f "$backupfile" ])); then - echo -e "${RED} Error: You've selected restore, but not provided a valid backup file.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to enter this.${NC}" + echo -e "${RED} Error: You've selected restore, but not provided a valid backup file. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to enter this. ${NC}" exit 1 fi # Check that install type is valid if ([ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ] && [ "$INSTALL_TYPE" != "update" ] && [ "$INSTALL_TYPE" != "restore" ] && [ "$INSTALL_TYPE" != "backup" ]); then - echo -e "${RED} Error: You've selected an invalid function type.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Run $THIS_SCRIPT -h help for details on the available options.${NC}" + echo -e "${RED} Error: You've selected an invalid function type. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Run $THIS_SCRIPT -h help for details on the available options. ${NC}" exit 1 fi # Check all required input is available for install if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]); then if ([ -z "$rmmhost" ] || [ -z "$certtype" ] || [ -z "$rootdomain" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]); then - echo -e "${RED} Error: To perform an automated installation, you must provide all required information.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, and T-RMM username and password are all required.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}" + echo -e "${RED} Error: To perform an automated installation, you must provide all required information. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, and T-RMM username and password are all required. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Run $THIS_SCRIPT -h help for further details. ${NC}" exit 1 fi # Check that certificate install type is valid if ([ "$certtype" != "import" ] && [ "$certtype" != "webroot" ]); then - echo -e "${RED} Error: You've selected an invalid certificate installation type.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Run $THIS_SCRIPT -h help for details on the available options.${NC}" + echo -e "${RED} Error: You've selected an invalid certificate installation type. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Run $THIS_SCRIPT -h help for details on the available options. ${NC}" exit 1 fi # Check for required input if import certificate if ([ "$certtype" == "import" ] && ([ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$sslkey" ])); then - echo -e "${RED} Error: To perform an automated installation using imported certificates, you must provide all required information.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, CA cert path, Cert path, Private key path, and T-RMM username and password are all required.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}" + echo -e "${RED} Error: To perform an automated installation using imported certificates, you must provide all required information. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, CA cert path, Cert path, Private key path, and T-RMM username and password are all required. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Run $THIS_SCRIPT -h help for further details. ${NC}" exit 1 fi fi @@ -177,16 +177,16 @@ if [ "$autoinstall" == "1" ]; then # Check that email address format is valid if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]); then if [[ $letsemail != *[@]*[.]* ]]; then - echo -e "${RED} Error: You've entered an invalid email address.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Run $THIS_SCRIPT -h help for details on the correct format.${NC}" + echo -e "${RED} Error: You've entered an invalid email address. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Run $THIS_SCRIPT -h help for details on the correct format. ${NC}" exit 1 fi fi # Check that repo and branch match install type if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ]) && [ "$BRANCH" == "master" ]; then - echo -e "${RED} Error: You've selected a developer installation type, but not changed the repo, branch, or both.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to select them.${NC}" + echo -e "${RED} Error: You've selected a developer installation type, but not changed the repo, branch, or both. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to select them. ${NC}" exit 1 fi diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index e20d546fbf..95f420059a 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -18,11 +18,11 @@ acmeChallengeCheck() until [ "$acmegood" == "y" ]; do if [[ $(dig +noall +answer -t TXT _acme-challenge.$1) ]] 2>/dev/null; then acmegood="y" - echo -e "${GREEN} Acme Challenge TXT record available.${NC}\n" | tee -a "${currentlog}" - echo -e "${GREEN} Continuing...${NC}" | tee -a "${currentlog}" + echo -e "${GREEN} Acme Challenge TXT record available. ${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} Continuing... ${NC}\n" | tee -a "${currentlog}" else - echo -e "${YELLOW} Acme Challenge TXT record not available yet.${NC}\n" | tee -a "${currentlog}" - echo -e "${YELLOW} Trying again in 30 sec...${NC}\n" | tee -a "${currentlog}" + echo -e "${YELLOW} Acme Challenge TXT record not available yet. ${NC}\n" | tee -a "${currentlog}" + echo -e "${YELLOW} Trying again in 30 sec... ${NC}\n" | tee -a "${currentlog}" acmegood="n" sleep 30 fi @@ -61,7 +61,7 @@ generateCerts() { # Manual DNS method if [ "$certtype" == "dns" ]; then - echo -e "${GREEN} Getting wildcard certificate...${NC}" | tee -a "${currentlog}" + echo -e "\n${GREEN} Getting wildcard certificate... ${NC}\n" | tee -a "${currentlog}" # Get initial DNS text entry sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email 2>&1 | tee -a "${currentlog}" @@ -79,7 +79,7 @@ generateCerts() # Webroot method elif [ "$certtype" == "webroot" ]; then - echo -e "${GREEN} Getting webroot certificates...${NC}" | tee -a "${currentlog}" + echo -e "\n${GREEN} Getting webroot certificates... ${NC}\n" | tee -a "${currentlog}" # Edit nginx conf files sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" @@ -183,7 +183,7 @@ installCertbot() fi if [ "$1" == "devinstall" ]; then - echo -e "${GREEN} Certificates should be in place.${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Certificates should be in place. ${NC}\n" | tee -a "${currentlog}" elif [ "$autoinstall" != "1" ]; then dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 case $? in @@ -198,7 +198,7 @@ installCertbot() if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then sudo mkdir -p /etc/letsencrypt/live/${rootdomain} 2>&1 | tee -a "${currentlog}" fi - echo -e "${GREEN} Importing certificates.${NC}" | tee -a "${currentlog}" + echo -e "\n${GREEN} Importing certificates... ${NC}\n" | tee -a "${currentlog}" sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem 2>&1 | tee -a "${currentlog}" sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem 2>&1 | tee -a "${currentlog}" sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem 2>&1 | tee -a "${currentlog}" diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 0bd8627ebc..82af017f2e 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -259,7 +259,7 @@ enableMeshService() # We will know it's ready once the last line of the systemd service stdout is 'MeshCentral HTTP server running on port.....' while ! [[ $CHECK_MESH_READY ]]; do CHECK_MESH_READY=$(sudo journalctl -u meshcentral.service -b --no-pager | grep "MeshCentral HTTP server running on port") - echo -e "${YELLOW} Mesh Central not ready yet...${NC}" | tee -a "${currentlog}" + echo -e "${YELLOW} Mesh Central not ready yet... ${NC}" | tee -a "${currentlog}" sleep 3 done } @@ -289,7 +289,7 @@ configMeshUserGroup() while ! [[ $CHECK_MESH_READY2 ]]; do CHECK_MESH_READY2=$(sudo journalctl -u meshcentral.service -b --no-pager | grep "MeshCentral HTTP server running on port") - echo -e "${YELLOW} Mesh Central not ready yet...${NC}" | tee -a "${currentlog}" + echo -e "${YELLOW} Mesh Central not ready yet... ${NC}" | tee -a "${currentlog}" sleep 3 done diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index f737d6b5d5..e1da62b0f7 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -66,13 +66,13 @@ installNodeJS() if [ "$1" == "update" ]; then CURRENT_NODE_VER=$(node --version | cut -d "v" -f2 | cut -d "." -f1) if [ "$CURRENT_NODE_VER" != "$NODE_MAJOR_VER" ]; then - echo -e "${GREEN} Updating NodeJS to v${NODE_MAJOR_VER}${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Updating NodeJS to v${NODE_MAJOR_VER}... ${NC}\n" | tee -a "${currentlog}" rm -rf /rmm/web/node_modules 2>&1 | tee -a "${currentlog}" sudo systemctl stop meshcentral 2>&1 | tee -a "${currentlog}" sudo apt remove -y nodejs 2>&1 | tee -a "${currentlog}" sudo rm -rf /usr/lib/node_modules 2>&1 | tee -a "${currentlog}" else - echo -e "${GREEN} NodeJS up to date.${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} NodeJS up to date. ${NC}\n" | tee -a "${currentlog}" return fi fi @@ -101,15 +101,15 @@ installPython() if [ "$1" == "update" ]; then CURRENT_PY=$(python3.10 --version | cut -d " " -f2) if [ "$CURRENT_PY" != "$PYTHON_VER" ]; then - echo -e "${GREEN} Updating to ${PYTHON_VER}.${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Updating to ${PYTHON_VER}... ${NC}\n" | tee -a "${currentlog}" elif [ "$CURRENT_PY" == "$PYTHON_VER" ]; then - echo -e "${GREEN} Python is up to date.${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Python is up to date. ${NC}\n" | tee -a "${currentlog}" return fi fi if [ "$1" == "devinstall" ]; then - echo -e "${GREEN} Python already installed${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Python already installed. ${NC}\n" | tee -a "${currentlog}" return else numprocs=$(nproc) @@ -124,7 +124,7 @@ installPython() sudo rm -rf Python-${PYTHON_VER} Python-${PYTHON_VER}.tgz 2>&1 | tee -a "${currentlog}" if [ "$1" == "devprep" ]; then # Misc functions - print_green 'All Prereqs installed' | tee -a "${currentlog}" + echo -e "\n${GREEN} All Prereqs installed. ${NC}\n" | tee -a "${currentlog}" exit fi fi @@ -148,9 +148,9 @@ installNats() if [ "$1" == "update" ]; then HAS_LATEST_NATS=$(/usr/local/bin/nats-server -version | cut -d " " -f2 | cut -d "v" -f2) if [ "$HAS_LATEST_NATS" != "${NATS_SERVER_VER}" ]; then - echo -e "${GREEN} Updating nats to v${NATS_SERVER_VER}${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Updating nats to v${NATS_SERVER_VER}... ${NC}\n" | tee -a "${currentlog}" else - echo -e "${GREEN} Nats is up to date${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Nats is up to date. ${NC}\n" | tee -a "${currentlog}" return fi fi @@ -207,14 +207,14 @@ installNginx() # Check Nginx config if ! sudo nginx -t > /dev/null 2>&1; then sudo nginx -t 2>&1 | tee -a "${currentlog}" - echo -e "${RED} You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Aborting...${NC}\n" | tee -a "${currentlog}" + echo -e "\n${RED} You have syntax errors in your nginx configs. See errors above. Please fix them and re-run this script. ${NC}\n" | tee -a "${currentlog}" + echo -e "\n${RED} Aborting... ${NC}\n" | tee -a "${currentlog}" exit 1 fi elif [ "$1" == "updatepart2" ]; then CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" /etc/nginx/nginx.conf) if ! [[ $CHECK_NGINX_WORKER_CONN ]]; then - echo -e "${GREEN} Changing nginx worker connections to 2048${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Changing nginx worker connections to 2048 ${NC}\n" | tee -a "${currentlog}" sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" fi sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 93b30d77a5..7a07de33b2 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -25,7 +25,7 @@ cls() } # Purdy install text in green -print_green() +echo -e() { printf >&2 "${GREEN}%0.s-${NC}" {1..80} printf >&2 "\n" @@ -93,11 +93,11 @@ checkScriptVer() if [ "$1" -ne "${NEW_VER}" ]; then wget "$2" -O "$3" 2>&1 | tee -a "${currentlog}" if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Old $3 detected.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} The latest version has been downloaded.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please re-run $3${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Old $3 detected. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} The latest version has been downloaded. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Please re-run $3 ${NC}" + echo -e "${RED} Exiting. ${NC}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 clear -x @@ -123,11 +123,11 @@ checkCfgVer() if [ "$currentcfgver" -ne "${NEW_VER}" ]; then wget "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" 2>&1 | tee -a "${currentlog}" if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Old $2 detected.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} The latest version has been downloaded.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please re-run $3${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Old $2 detected. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} The latest version has been downloaded. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Please re-run $3 ${NC}" + echo -e "${RED} Exiting. ${NC}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 clear -x @@ -145,9 +145,9 @@ checkRoot() # if user is root, exit if [ $EUID -eq 0 ]; then if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Do NOT run this script as root.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Do NOT run this script as root. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Exiting. ${NC}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Do NOT run this script as root. Exiting." 0 0 clear -x @@ -168,10 +168,10 @@ checkTacticalUser() tacticaluser=$(stat -c '%U' /rmm) if [ "$tacticaluser" != "${USER}" ]; then if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} This script must be run as the Tactical user.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please switch users, and run it again.${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" + echo -e "${RED} This script must be run as the Tactical user. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Please switch users, and run it again. ${NC}" + echo -e "${RED} Exiting. ${NC}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 clear -x @@ -184,26 +184,26 @@ checkTacticalUser() tacticaluser="$(id -u tactical > /dev/null 2>&1; echo $?)" case $tacticaluser in 0 ) if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} This script must be run as the Tactical user.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please switch users, and run it again.${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" + echo -e "${RED} This script must be run as the Tactical user. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Please switch users, and run it again. ${NC}" + echo -e "${RED} Exiting. ${NC}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "This script must be run as the Tactical user.\nPlease switch users, and try again.\n\nExiting." 0 0 clear -x fi exit 1;; - 1 ) print_yellow 'Tactical user does not exist. Creating now.' | tee -a "${currentlog}" + 1 ) echo -e "\n${YELLOW} Tactical user does not exist. Creating now. ${NC}\n" | tee -a "${currentlog}" sudo useradd -m -G sudo -s /bin/bash tactical 2>&1 | tee -a "${currentlog}" tacpass="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)" echo "tactical:$tacpass"| sudo chpasswd if [ "$autoinstall" == "1" ]; then - echo -e "${RED} The Tactical user has been created.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Username: tactical${NC}" | tee -a "${currentlog}" - echo -e "${RED} Password: $tacpass${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please switch users, re-download the script, and run it again.${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} The Tactical user has been created. ${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Username: tactical ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Password: $tacpass ${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} Please switch users, re-download the script, and run it again. ${NC}" + echo -e "${RED} Exiting. ${NC}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Created" --msgbox "The Tactical user has been created.\n\nUsername: tactical\n\nPassword: $tacpass\n\nPlease switch users, re-download the script, and try again.\n\nExiting." 0 0 clear -x @@ -217,12 +217,12 @@ checkTacticalUser() case $hassudo in 0 ) return;; - 1 ) print_green 'Adding Tactical user to sudo group.' | tee -a "${currentlog}" + 1 ) echo -e "\n${YELLOW} Adding Tactical user to sudo group. ${NC}\n" | tee -a "${currentlog}" sudo usermod -a -G sudo tactical 2>&1 | tee -a "${currentlog}" if [ "$autoinstall" == "1" ]; then - echo -e "${RED} The Tactical user has been added to the sudo group.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please log out of the tactical user, log back in, and try again.${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} The Tactical user has been added to the sudo group. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Please log out of the tactical user, log back in, and try again. ${NC}" + echo -e "${RED} Exiting.${NC}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Tactical User Sudo Privileges Added" --msgbox "The Tactical user has been added to the sudo group.\nPlease log out of the tactical user, log back in, and try again.\n\nExiting." 0 0 clear -x @@ -294,11 +294,11 @@ verifyRepoExists() { local repostatus=$(curl --output /dev/null --silent --write-out "%{http_code}" "$1") if [ "$repostatus" == "200" ]; then - echo -e "${GREEN} Repo exists.${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Repo exists. ${NC}\n" | tee -a "${currentlog}" else - echo -e "${RED} The Tactical RMM repository you entered does not exist.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please try again.${NC}\n" - echo -e "${RED} Exiting...${NC}\n" + echo -e "${RED} The Tactical RMM repository you entered does not exist. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Please try again. ${NC}" + echo -e "${RED} Exiting... ${NC}" exit 1 fi } diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index 29ce490a5b..09feb77b9b 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -46,19 +46,19 @@ configHosts() # this also allows the install script to properly finish even if DNS has not fully propagated CHECK_LOCALHOST=$(grep "127.0.0.1" /etc/hosts | grep "localhost") if ! [[ $CHECK_LOCALHOST ]]; then - echo -e "${GREEN} Adding localhost to hosts file...${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Adding localhost to hosts file... ${NC}\n" | tee -a "${currentlog}" sudo sed -i "1i 127.0.0.1\tlocalhost" /etc/hosts 2>&1 | tee -a "${currentlog}" fi CHECK_HOSTS=$(grep "127.0.1.1 $rmmdomain $frontenddomain $meshdomain" /etc/hosts) if [[ $CHECK_HOSTS ]]; then - echo -e "${GREEN} Correcting subdomain entries...${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Correcting subdomain entries... ${NC}\n" | tee -a "${currentlog}" sudo sed -i "/127.0.1.1 $rmmdomain $frontenddomain $meshdomain/d" /etc/hosts 2>&1 | tee -a "${currentlog}" setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; setSiteHostname "$meshhost" "$rootdomain"; elif [ "$1" != "devinstall" ]; then - echo -e "${GREEN} Adding subdomain entries...${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Adding subdomain entries... ${NC}\n" | tee -a "${currentlog}" setSiteHostname "$rmmhost" "$rootdomain"; setSiteHostname "$frontendhost" "$rootdomain"; setSiteHostname "$meshhost" "$rootdomain"; diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index d4fc0abce4..4638cdf1dc 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -33,145 +33,145 @@ mainInstall() # Configure hosts file # Misc functions - print_green 'Configuring Hosts file' | tee -a "${currentlog}" + echo -e "\n${GREEN} Configuring Hosts file... ${NC}\n" | tee -a "${currentlog}" # Network functions configHosts "$INSTALL_TYPE"; # Certificate generation # Misc functions - print_green 'Installing Certbot' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing Certbot... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installCertbot "$INSTALL_TYPE"; # Install Nginx # Misc functions - print_green 'Installing Nginx' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing Nginx... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installNginx "$INSTALL_TYPE"; # Install NodeJS # Misc functions - print_green 'Installing NodeJS' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing NodeJS... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installNodeJS "$INSTALL_TYPE"; # Install and enable MongoDB # Misc functions - print_green 'Installing MongoDB' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing MongoDB... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installMongo "$INSTALL_TYPE"; # Install Python # Misc functions - print_green "Installing Python ${PYTHON_VER}" | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing Python ${PYTHON_VER}... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installPython "$INSTALL_TYPE"; # Installing Redis # Misc functions - print_green 'Installing redis' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing redis... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installRedis; # Install and enable Postgresql # Misc functions - print_green 'Installing postgresql' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing postgresql... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installPostgresql; # Postgres DB creation # Misc functions - print_green 'Creating database for the rmm' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating database for the rmm... ${NC}\n" | tee -a "${currentlog}" # Database functions createPGDB; # Clone main repo # Misc functions - print_green 'Cloning primary repo' | tee -a "${currentlog}" + echo -e "\n${GREEN} Cloning primary repo... ${NC}\n" | tee -a "${currentlog}" # Misc functions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; # Clone scripts repo # Misc functions - print_green 'Cloning community scripts repo' | tee -a "${currentlog}" + echo -e "\n${GREEN} Cloning community scripts repo... ${NC}\n" | tee -a "${currentlog}" # Misc functions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; # Installing NATS # Misc functions - print_green 'Installing NATS' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing NATS... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installNats "$INSTALL_TYPE"; # Install MeshCentral # Misc functions - print_green 'Installing MeshCentral' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing MeshCentral... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installMeshCentral "$INSTALL_TYPE"; # Create MeshCentral config # Misc functions - print_green 'Generating MeshCentral Config' | tee -a "${currentlog}" + echo -e "\n${GREEN} Generating MeshCentral Config... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createMeshConfig; # Create local settings file # Misc functions - print_green 'Generating Local Settings' | tee -a "${currentlog}" + echo -e "\n${GREEN} Generating Local Settings... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createLocalSettings; # Install NATS-API and correct permissions # Misc functions - print_green 'Installing NATS API' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing NATS API... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installNatsApi; # Install backend, configure primary admin user, setup admin 2fa # Misc functions - print_green 'Installing the backend' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing the backend... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions configureBackend "$INSTALL_TYPE"; # Create UWSGI config # Misc functions - print_green 'Creating UWSGI configuration' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating UWSGI configuration... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createUwsgiConf; # Create RMM UWSGI systemd service # Misc functions - print_green 'Creating UWSGI service' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating UWSGI service... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createUwsgiService; # Create Daphne systemd service # Misc functions - print_green 'Creating Daphne service' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating Daphne service... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createDaphneService; # Create NATS systemd service # Misc functions - print_green 'Creating NATS service' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating NATS service... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createNatsService; # Create NATS-api systemd service # Misc functions - print_green 'Creating NATS-API service' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating NATS-API service... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createNatsApiService; # Create Backend Nginx site config # Misc functions - print_green 'Creating Backend Nginx config' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating Backend Nginx config... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createBackendNginxConf; # Create MeshCentral Nginx configuration # Misc functions - print_green 'Creating MeshCentral Nginx config' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating MeshCentral Nginx config... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createMeshNginxConf; @@ -184,19 +184,19 @@ mainInstall() # Create Celery systemd service # Misc functions - print_green 'Creating Celery service' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating Celery service... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createCeleryService; # Configure Celery service # Misc functions - print_green 'Creating Celery config' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating Celery config... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createCeleryConf; # Create CeleryBeat systemd service # Misc functions - print_green 'Creating CeleryBeat service' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating CeleryBeat service... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createCeleryBeatService; @@ -205,7 +205,7 @@ mainInstall() # Create MeshCentral systemd service # Misc functions - print_green 'Creating MeshCentral service' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating MeshCentral service... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createMeshCentralService; @@ -223,13 +223,13 @@ mainInstall() # Install frontend # Misc functions - print_green 'Installing the frontend' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing the frontend... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installFrontEnd "$INSTALL_TYPE"; # Set front end Nginx config and enable # Misc functions - print_green 'Creating Frontend Nginx config' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating Frontend Nginx config... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createFrontendNginxConf; @@ -243,7 +243,7 @@ mainInstall() # Enable RMM, Daphne, Celery, and Nginx services # Misc functions - print_green 'Enabling Services' | tee -a "${currentlog}" + echo -e "\n${GREEN} Enabling Services... ${NC}\n" | tee -a "${currentlog}" for i in rmm.service daphne.service celery.service celerybeat.service nginx do @@ -255,25 +255,25 @@ mainInstall() # Enable MeshCentral service # Misc functions - print_green 'Starting meshcentral and waiting for it to install plugins' | tee -a "${currentlog}" + echo -e "\n${GREEN} Starting meshcentral and waiting for it to install plugins... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions enableMeshService; # Generating MeshCentral key # Misc functions - print_green 'Generating meshcentral login token key' | tee -a "${currentlog}" + echo -e "\n${GREEN} Generating meshcentral login token key... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions generateMeshToken; # Configuring MeshCentral admin user and device group, restart service # Misc functions - print_green 'Creating meshcentral account and group' | tee -a "${currentlog}" + echo -e "\n${GREEN} Creating meshcentral account and group... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions configMeshUserGroup; # Enable and configure NATS service # Misc functions - print_green 'Starting NATS service' | tee -a "${currentlog}" + echo -e "\n${GREEN} Starting NATS service... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions enableNatsService; @@ -282,7 +282,7 @@ mainInstall() # Restart core services # Misc functions - print_green 'Restarting services' | tee -a "${currentlog}" + echo -e "\n${GREEN} Restarting services... ${NC}\n" | tee -a "${currentlog}" for i in rmm.service daphne.service celery.service celerybeat.service do @@ -292,8 +292,8 @@ mainInstall() # Yay, we're done! # Misc functions - print_yellow "Installation complete!" | tee -a "${currentlog}" - echo -e "${YELLOW} Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n" | tee -a no-peeking.log + print_yellow "Installation complete!" + echo -e "\n${YELLOW} Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n" | tee -a no-peeking.log echo -e "${YELLOW} Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n" | tee -a no-peeking.log echo -e "${YELLOW} MeshCentral username: ${GREEN}${meshusername}${NC}" | tee -a no-peeking.log echo -e "${YELLOW} MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n" | tee -a no-peeking.log @@ -301,17 +301,17 @@ mainInstall() sudo chmod 600 $PWD/no-peeking.log 2>&1 | tee -a "${currentlog}" if [ "$BEHIND_NAT" = true ]; then - echo -e "${YELLOW} Read below if your router does NOT support Hairpin NAT:${NC}\n" + echo -e "\n${YELLOW} Read below if your router does NOT support Hairpin NAT:${NC}\n" echo -e "${GREEN} If you will be accessing the web interface of the RMM from the same LAN as this server,\n you'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" echo -e "${GREEN} This also applies to any agents that will be on the same local network as the rmm.${NC}\n" if [ "$certtype" == "webroot" ]; then - echo -e "${GREEN} You'll also need to setup port forwarding in your router on ports 80 and 443 if you have not done so already.${NC}\n" + echo -e "\n${GREEN} You'll also need to setup port forwarding in your router on ports 80 and 443 if you have not done so already.${NC}\n" else - echo -e "${GREEN} You'll also need to setup port forwarding in your router on port 443.${NC}\n" + echo -e "\n${GREEN} You'll also need to setup port forwarding in your router on port 443.${NC}\n" fi fi # Misc functions - print_yellow "Please refer to the github README for next steps."; + print_yellow "Please refer to the github README for next steps." return } @@ -324,7 +324,7 @@ updateTRMM() # Check if user is same as during installation # UpdateRestoreFunctions - checkSameUser "$INSTALL_TYPE" | tee -a "${currentlog}" + checkSameUser "$INSTALL_TYPE"; # Get current release version and check if update is necessary # UpdateRestoreFunctions @@ -349,7 +349,7 @@ updateTRMM() # Stop services for i in nginx nats-api nats rmm daphne celery celerybeat do - echo -e "${GREEN} Stopping ${i} service...${NC}" | tee -a "${currentlog}" + echo -e "${GREEN} Stopping ${i} service... ${NC}\n" | tee -a "${currentlog}" sudo systemctl stop "${i}" 2>&1 | tee -a "${currentlog}" done @@ -381,7 +381,7 @@ updateTRMM() # Check NodeJS version, update if needed and update MeshCentral # Misc functions - print_green 'Updating NodeJS' | tee -a "${currentlog}" + echo -e "\n${GREEN} Updating NodeJS... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installNodeJS "$INSTALL_TYPE"; @@ -391,13 +391,13 @@ updateTRMM() # Update from main repo # Misc functions - print_green 'Cloning primary repo' | tee -a "${currentlog}" + echo -e "\n${GREEN} Cloning primary repo... ${NC}\n" | tee -a "${currentlog}" # Misc functions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; # Update from community-scripts repo # Misc functions - print_green 'Cloning community scripts repo' | tee -a "${currentlog}" + echo -e "\n${GREEN} Cloning community scripts repo... ${NC}\n" | tee -a "${currentlog}" # Misc functions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; @@ -438,7 +438,7 @@ updateTRMM() # Start services for i in nats nats-api rmm daphne celery celerybeat nginx do - echo -e "${GREEN} Starting ${i} service${NC}" | tee -a "${currentlog}" + echo -e "${GREEN} Starting ${i} service... ${NC}\n" | tee -a "${currentlog}" sudo systemctl start "${i}" 2>&1 | tee -a "${currentlog}" done sleep 3 @@ -458,7 +458,7 @@ updateTRMM() # Bye-bye # Misc functions - print_green "Update finished!" | tee -a "${currentlog}" + print_green "Update finished!" return } @@ -533,7 +533,7 @@ backupTRMM() # Remove temp files/folders rm -rf ${tmp_dir} 2>&1 | tee -a "${currentlog}" # Misc functions - print_green "Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar" 2>&1 | tee -a "${currentlog}" + echo -e "\n${GREEN} Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar ${NC}\n" | tee -a "${currentlog}" return } @@ -562,13 +562,13 @@ restoreTRMM() # Install NodeJS # Misc functions - print_green 'Installing NodeJS' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing NodeJS... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installNodeJS; # Install Nginx and restore Nginx configuration # Misc functions - print_green 'Installing Nginx and restoring configuration' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing Nginx and restoring configuration... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installNginx "$INSTALL_TYPE"; @@ -578,13 +578,13 @@ restoreTRMM() # Restore Certbot # Misc functions - print_green 'Installing Certbot' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing Certbot... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installCertbot "$INSTALL_TYPE"; # Restoring existing certs # Misc functions - print_green 'Restoring certs' | tee -a "${currentlog}" + echo -e "\n${GREEN} Restoring certs... ${NC}\n" | tee -a "${currentlog}" sudo rm -rf /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo mkdir /etc/letsencrypt 2>&1 | tee -a "${currentlog}" @@ -602,7 +602,7 @@ restoreTRMM() # Restore Celery configs # Misc functions - print_green 'Restoring celery configs' | tee -a "${currentlog}" + echo -e "\n${GREEN} Restoring celery configs... ${NC}\n" | tee -a "${currentlog}" sudo mkdir /etc/conf.d 2>&1 | tee -a "${currentlog}" sudo tar -xzf $tmp_dir/confd/etc-confd.tar.gz -C /etc/conf.d 2>&1 | tee -a "${currentlog}" @@ -610,67 +610,67 @@ restoreTRMM() # Restoring services # Misc functions - print_green 'Restoring systemd services' | tee -a "${currentlog}" + echo -e "\n${GREEN} Restoring systemd services... ${NC}\n" | tee -a "${currentlog}" sudo cp $tmp_dir/systemd/* /etc/systemd/system/ 2>&1 | tee -a "${currentlog}" sudo systemctl daemon-reload 2>&1 | tee -a "${currentlog}" # Install Python # Misc functions - print_green "Installing Python ${PYTHON_VER}" | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing Python ${PYTHON_VER}... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installPython; # Installing Redis # Misc functions - print_green 'Installing redis' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing redis... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installRedis; # Install and enable Postgresql # Misc functions - print_green 'Installing postgresql' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing postgresql... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installPostgresql; # Install and enable MongoDB # Misc functions - print_green 'Installing MongoDB' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing MongoDB... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installMongo; # Restore Mongo database # Misc functions - print_green 'Restoring MongoDB' | tee -a "${currentlog}" + echo -e "\n${GREEN} Restoring MongoDB... ${NC}\n" | tee -a "${currentlog}" mongorestore --gzip $tmp_dir/meshcentral/mongo 2>&1 | tee -a "${currentlog}" # Clone main repo # Misc functions - print_green 'Cloning primary repo' | tee -a "${currentlog}" + echo -e "\n${GREEN} Cloning primary repo... ${NC}\n" | tee -a "${currentlog}" # Misc functions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; # Clone scripts repo # Misc functions - print_green 'Cloning community scripts repo' | tee -a "${currentlog}" + echo -e "\n${GREEN} Cloning community scripts repo... ${NC}\n" | tee -a "${currentlog}" # Misc functions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; # Installing NATS # Misc functions - print_green 'Installing NATS' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing NATS... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installNats "$INSTALL_TYPE"; # Restore MeshCentral # Misc functions - print_green 'Restoring MeshCentral' | tee -a "${currentlog}" + echo -e "\n${GREEN} Restoring MeshCentral... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installMeshCentral "$INSTALL_TYPE"; # Restore UWSGI # Misc functions - print_green 'Restoring UWSGI configuration' | tee -a "${currentlog}" + echo -e "\n${GREEN} Restoring UWSGI configuration... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions createUwsgiConf; @@ -682,13 +682,13 @@ restoreTRMM() # Install NATS-API # Misc functions - print_green 'Installing NATS API' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing NATS API... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installNatsApi; # Restore Postgres database # Misc functions - print_green 'Restoring the Postgres database' | tee -a "${currentlog}" + echo -e "\n${GREEN} Restoring the Postgres database... ${NC}\n" | tee -a "${currentlog}" 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}$//')" @@ -702,19 +702,19 @@ restoreTRMM() # Restore Backend # Misc functions - print_green 'Restoring the backend' | tee -a "${currentlog}" + echo -e "\n${GREEN} Restoring the backend... ${NC}\n" | tee -a "${currentlog}" # Config and Service functions configureBackend "$INSTALL_TYPE"; # Start NATS # Misc functions - print_green 'Start NATS' | tee -a "${currentlog}" + echo -e "\n${GREEN} Starting NATS... ${NC}\n" | tee -a "${currentlog}" sudo systemctl enable nats.service 2>&1 | tee -a "${currentlog}" sudo systemctl start nats.service 2>&1 | tee -a "${currentlog}" # Install frontend # Misc functions - print_green 'Installing the frontend' | tee -a "${currentlog}" + echo -e "\n${GREEN} Installing the frontend... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installFrontEnd "$INSTALL_TYPE"; @@ -731,7 +731,7 @@ restoreTRMM() # Enable RMM, Daphne, Celery, Nats-api, and Nginx services # Misc functions - print_green 'Enabling Services' | tee -a "${currentlog}" + echo -e "\n${GREEN} Enabling Services... ${NC}\n" | tee -a "${currentlog}" for i in celery.service celerybeat.service rmm.service daphne.service nats-api.service nginx do @@ -743,13 +743,13 @@ restoreTRMM() # Start MeshCentral # Misc functions - print_green 'Starting meshcentral' | tee -a "${currentlog}" + echo -e "\n${GREEN} Starting meshcentral... ${NC}\n" | tee -a "${currentlog}" sudo systemctl enable meshcentral 2>&1 | tee -a "${currentlog}" sudo systemctl start meshcentral 2>&1 | tee -a "${currentlog}" # Done!!!! # Misc functions - print_green 'Restore complete!' | tee -a "${currentlog}" + print_green 'Restore complete!' return } @@ -776,8 +776,8 @@ troubleShoot() pingDomain "$meshdomain"; # Verify IPs - echo -e "${GREEN} Checking IPs${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "\n${GREEN} Checking IPs... ${NC}\n" | tee -a "${currentlog}" + # Troubleshooting functions checkIPisLive "$rmmdomain"; remapiip="${reminputip}" @@ -804,8 +804,7 @@ troubleShoot() # Get WAN IP wanip=$(dig @resolver4.opendns.com myip.opendns.com +short) - echo -e "${GREEN} WAN IP is $wanip.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "\n${GREEN} WAN IP is $wanip. ${NC}\n" | tee -a "${currentlog}" # Check if ports are open # Troubleshooting functions @@ -821,13 +820,12 @@ troubleShoot() checkIfCertIsValid; # Generate log summary - echo -e "${GREEN} Getting summary output of logs.${NC}" | tee -a "${currentlog}" - echo -e "\n" + echo -e "\n${GREEN} Getting summary output of logs... ${NC}\n" | tee -a "${currentlog}" tail /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | tee -a "${currentlog}" - echo -e "\n" + echo -e "\n" | tee -a "${currentlog}" tail /rmm/api/tacticalrmm/tacticalrmm/private/log/error.log | tee -a "${currentlog}" - echo -e "\n" + echo -e "\n" | tee -a "${currentlog}" # Misc functions print_yellow "You will have a log file called checklog_$rundate.log in the directory you ran this script from." diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 311ef0586b..6a66377cfd 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -33,13 +33,13 @@ wutOSThis() verifySupportedOS() { if ([ "$osname" == "ubuntu" ] && ([ "$fullrelno" == "20.04" ] || [ "$fullrelno" == "22.04" ])) || ([ "$osname" == "debian" ] && [ $relno -ge 10 ]); then - echo -e "\n${GREEN} $fullrel${NC}" | tee -a "${currentlog}" + echo -e "\n${GREEN} $fullrel ${NC}\n" | tee -a "${currentlog}" else if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11${NC}" | tee -a "${currentlog}" - echo -e "${RED} Your system, $fullrel, does not appear to be supported.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11 ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Your system, $fullrel, does not appear to be supported. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Exiting. ${NC}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 clear -x @@ -53,12 +53,12 @@ checkLocale() { if [[ "$LANG" != *".UTF-8" ]]; then if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error:${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} System locale must be .UTF-8, not ${LANG}.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Run the following command and change the default locale to your language of choice:${NC}\n" - echo -e "${RED} sudo dpkg-reconfigure locales${NC}\n" - echo -e "${RED} You will need to log out and back in for changes to take effect, then re-run this script.${NC}\n" - echo -e "${RED} Exiting.${NC}\n" + echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" + echo -e "${RED} System locale must be .UTF-8, not ${LANG}. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Run the following command and change the default locale to your language of choice: ${NC}" + echo -e "${RED} sudo dpkg-reconfigure locales ${NC}" + echo -e "${RED} You will need to log out and back in for changes to take effect, then re-run this script. ${NC}" + echo -e "${RED} Exiting. ${NC}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "System locale must be .UTF-8, not ${LANG}.\nRun the following command and change the default locale to your language of choice:\n\nsudo dpkg-reconfigure locales\n\nYou will need to log out and back in for changes to take effect, then re-run this script.\n\nExiting." 0 0 clear -x @@ -76,10 +76,10 @@ checkTotalSystemMemory() return else if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error: System does not meet the minimum recommended RAM amount of 2GB.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please add RAM to the system to prevent potential issues during install.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Re-run $THIS_SCRIPT after resolving the issue.${NC}\n" - echo -e "${RED} Exiting...${NC}\n" + echo -e "${RED} Error: System does not meet the minimum recommended RAM amount of 2GB. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Please add RAM to the system to prevent potential issues during install. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Re-run $THIS_SCRIPT after resolving the issue. ${NC}" + echo -e "${RED} Exiting... ${NC}" exit 1 elif [ "$autoinstall" != "1" ]; then dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended RAM amount of 2GB.\n\nYou may experience issues during install.\n\nIt's recommended to exit and add RAM to the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index 8bad44b923..0b80d8970f 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -13,9 +13,9 @@ CFG_VERSION="8" pingDomain() { if ( ping -c 1 $1 &> /dev/null ); then - echo -e "${GREEN} Verified $1 by ping.${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} Verified $1 by ping. ${NC}\n" | tee -a "${currentlog}" else - echo -e "${RED} $1 cannot be verified by ping.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} $1 cannot be verified by ping. ${NC}\n" | tee -a "${currentlog}" fi } @@ -29,10 +29,10 @@ checkIPisLive() reminputip=`dig @8.8.8.8 +short $1` if [ "$locinputip" == "$reminputip" ]; then - echo -e "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip} ${NC}\n" | tee -a "${currentlog}" else - echo -e "${YELLOW} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip}${NC}\n" | tee -a "${currentlog}" - echo -e "${YELLOW} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server.${NC}\n" | tee -a "${currentlog}" + echo -e "${YELLOW} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip} ${NC}\n" | tee -a "${currentlog}" + echo -e "${YELLOW} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server. ${NC}\n" | tee -a "${currentlog}" fi } @@ -56,9 +56,9 @@ readServicesStatus() checkIfServiceActive() { if [ $1 = active ]; then - echo -e "${GREEN} Success $2 is Running.${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} Success $2 is Running. ${NC}\n" | tee -a "${currentlog}" else - echo -e "${RED} $2 is not running. \(Tactical will not work without this\)${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} $2 is not running. \(Tactical will not work without this\) ${NC}\n" | tee -a "${currentlog}" fi } @@ -66,33 +66,33 @@ checkIfServiceActive() isPortOpen() { if ( nc -zv $wanip $1 2>&1 >/dev/null ); then - echo -e "${GREEN} $2 Port is open.${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} $2 Port is open. ${NC}\n" | tee -a "${currentlog}" else - echo -e "${YELLOW} $2 port is closed. \(you may want this if running locally only\)${NC}\n" | tee -a "${currentlog}" + echo -e "${YELLOW} $2 port is closed. \(you may want this if running locally only\) ${NC}\n" | tee -a "${currentlog}" fi } # Check proxy checkProxy() { - echo -e "${GREEN} Checking For Proxy.${NC}\n" | tee -a "${currentlog}" - echo -e "${YELLOW} ......this might take a while!!${NC}" + echo -e "${GREEN} Checking For Proxy. ${NC}\n" | tee -a "${currentlog}" + echo -e "${YELLOW} ......this might take a while!! ${NC}" # 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.1.1 -connect 127.0.1.1:443 2>/dev/null | openssl x509 -inform pem -noout -text)" if [[ "$proxyext" == "$proxyint" ]]; then - echo -e "${GREEN} No Proxy detected using Certificate.${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} No Proxy detected using Certificate. ${NC}\n" | tee -a "${currentlog}" else - echo -e "${YELLOW} Proxy detected using Certificate.${NC}\n" | tee -a "${currentlog}" + echo -e "${YELLOW} Proxy detected using Certificate. ${NC}\n" | tee -a "${currentlog}" fi # Detect Proxy via IP if [ "$wanip" != "$remrmmip" ]; then - echo -e "${YELLOW} Proxy detected using IP.${NC}\n" | tee -a "${currentlog}" + echo -e "${YELLOW} Proxy detected using IP. ${NC}\n" | tee -a "${currentlog}" else - echo -e "${GREEN} No Proxy detected using IP.${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} No Proxy detected using IP. ${NC}\n" | tee -a "${currentlog}" fi } @@ -108,10 +108,10 @@ checkIfCertIsValid() certexp="$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/${rootdomain}/fullchain.pem | cut -d "=" -f2)" if [[ "$cert" == *"OK"* ]]; then - echo -e "${GREEN} SSL Certificate for $rootdomain is fine.${NC}\n" | tee -a "${currentlog}" - echo -e "${GREEN} SSL Certificate expires $certexp${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} SSL Certificate for $rootdomain is fine. ${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} SSL Certificate expires $certexp ${NC}\n" | tee -a "${currentlog}" else - echo -e "${RED} SSL Certificate has expired or doesnt exist for $rootdomain.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} SSL Certificate has expired or doesnt exist for $rootdomain. ${NC}\n" | tee -a "${currentlog}" fi # Check Webroot authenticated certs elif [ -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then @@ -119,10 +119,10 @@ checkIfCertIsValid() certexp="$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/${rootdomain}/fullchain.pem | cut -d "=" -f2)" if [[ "$cert" == *"OK"* ]]; then - echo -e "${GREEN} SSL Certificate for $rmmdomain , $frontenddomain , and $meshdomain is fine.${NC}\n" | tee -a "${currentlog}" - echo -e "${GREEN} SSL Certificate expires $certexp${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} SSL Certificate for $rmmdomain , $frontenddomain , and $meshdomain is fine. ${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} SSL Certificate expires $certexp ${NC}\n" | tee -a "${currentlog}" else - echo -e "${RED} SSL Certificate has expired or doesnt exist for $rmmdomain , $frontenddomain , and $meshdomain.${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} SSL Certificate has expired or doesnt exist for $rmmdomain , $frontenddomain , and $meshdomain. ${NC}\n" | tee -a "${currentlog}" fi fi } diff --git a/script-cfg/UpdateRestoreFunctions.cfg b/script-cfg/UpdateRestoreFunctions.cfg index 1148fef422..1370f6134d 100644 --- a/script-cfg/UpdateRestoreFunctions.cfg +++ b/script-cfg/UpdateRestoreFunctions.cfg @@ -20,8 +20,8 @@ checkSameUser() fi if [ "$ORIGUSER" != "$USER" ]; then if [ "$autoinstall" == "1" ]; then - echo -e "${RED} You must run this update script from the same user account used during install: ${ORIGUSER}${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Exiting...${NC}\n" | tee -a "${currentlog}" + echo -e "${RED} You must run this update script from the same user account used during install: ${ORIGUSER} ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Exiting... ${NC}" | tee -a "${currentlog}" if [ "$1" == "restore" ]; then rm -rf $tmp_dir 2>&1 | tee -a "${currentlog}" fi @@ -47,7 +47,7 @@ checkIfUpdate() CURRENT_TRMM_VER=$(grep "^TRMM_VERSION" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') if [ "${CURRENT_TRMM_VER}" == "${LATEST_TRMM_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then - echo -e "${GREEN} Already on latest version. Current version:${NC} ${YELLOW}${CURRENT_TRMM_VER}${NC} ${GREEN}Latest version:${NC} ${YELLOW}${LATEST_TRMM_VER}${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} Already on latest version. Current version:${NC} ${YELLOW}${CURRENT_TRMM_VER}${NC} ${GREEN}Latest version:${NC} ${YELLOW}${LATEST_TRMM_VER} ${NC}" | tee -a "${currentlog}" rm -f $TMP_SETTINGS 2>&1 | tee -a "${currentlog}" exit 0 fi @@ -77,7 +77,7 @@ checkNatsLimitNoFile() # Disable Redis append only turnOffRedisAppendOnly() { - echo -e "${GREEN} Turning off redis aof${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} Turning off redis aof ${NC}\n" | tee -a "${currentlog}" sudo redis-cli config set appendonly no 2>&1 | tee -a "${currentlog}" sudo redis-cli config rewrite 2>&1 | tee -a "${currentlog}" sudo rm -f /var/lib/redis/appendonly.aof 2>&1 | tee -a "${currentlog}" @@ -88,7 +88,7 @@ updateMeshCentral() { CURRENT_MESH_VER=$(cd /meshcentral/node_modules/meshcentral && node -p -e "require('./package.json').version") if [ "${CURRENT_MESH_VER}" != "${LATEST_MESH_VER}" ] || [ "$UPDATE_TYPE" = "forced" ]; then - echo -e "${GREEN} Updating meshcentral from ${CURRENT_MESH_VER} to ${LATEST_MESH_VER}${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} Updating meshcentral from ${CURRENT_MESH_VER} to ${LATEST_MESH_VER} ${NC}\n" | tee -a "${currentlog}" sudo systemctl stop meshcentral 2>&1 | tee -a "${currentlog}" sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" cd /meshcentral @@ -129,8 +129,7 @@ getBackupFileLocation() # Extract backup extractBackup() { - # MiscFunctions - print_green 'Unpacking backup' | tee -a "${currentlog}" + echo -e "\n${GREEN} Unpacking backup... ${NC}\n" | tee -a "${currentlog}" tmp_dir=$(mktemp -d -t tacticalrmm-XXXXXXXXXXXXXXXXXXXXX) tar -xf ${1} -C $tmp_dir 2>&1 | tee -a "${currentlog}" diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index 1202b6bae6..d09c02cacd 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -98,13 +98,13 @@ generateUsersAndPass() subdomainFormatCheck() { if [[ $(grep "\." <<< "$1") ]] 2>/dev/null; then - echo -e "${RED} Error: The $2 hostname/subdomain you provided is in the incorrect format.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Do not include the root domain.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}\n" - echo -e "${RED} Exiting...${NC}\n" + echo -e "${RED} Error: The $2 hostname/subdomain you provided is in the incorrect format. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Do not include the root domain. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Run $THIS_SCRIPT -h help for further details. ${NC}" + echo -e "${RED} Exiting... ${NC}" exit 1 else - echo -e "${GREEN} $2 hostname format ok.${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} $2 hostname format ok. ${NC}" | tee -a "${currentlog}" fi } @@ -112,11 +112,11 @@ subdomainFormatCheck() rootDomainFormatCheck() { if [[ $(grep "\." <<< "$1") ]] 2>/dev/null; then - echo -e "${GREEN} Root domain format ok.${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} Root domain format ok. ${NC}" | tee -a "${currentlog}" else - echo -e "${RED} Error: The root domain you provided is in the incorrect format.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}\n" - echo -e "${RED} Exiting...${NC}\n" + echo -e "${RED} Error: The root domain you provided is in the incorrect format. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Run $THIS_SCRIPT -h help for further details. ${NC}" + echo -e "${RED} Exiting... ${NC}" exit 1 fi } @@ -125,11 +125,11 @@ rootDomainFormatCheck() checkDNSEntriesExist() { if [[ $(dig +noall +answer $1) ]] 2>/dev/null; then - echo -e "${GREEN} DNS record for $1 exists.${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} DNS record for $1 exists. ${NC}" | tee -a "${currentlog}" else - echo -e "${RED} Error: $1 does not resolve via DNS.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Please correct the issue and run $THIS_SCRIPT again.${NC}\n" - echo -e "${RED} Exiting...${NC}\n" + echo -e "${RED} Error: $1 does not resolve via DNS. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Please correct the issue and run $THIS_SCRIPT again. ${NC}" + echo -e "${RED} Exiting... ${NC}" exit 1 fi } @@ -138,12 +138,12 @@ checkDNSEntriesExist() checkCertExists() { if [ ! -f "$1" ]; then - echo -e "${RED} Error: The $2 path and/or filename you provided is invalid.${NC}\n" | tee -a "${currentlog}" - echo -e "${RED} Run $THIS_SCRIPT -h help for further details.${NC}\n" - echo -e "${RED} Exiting...${NC}\n" + echo -e "${RED} Error: The $2 path and/or filename you provided is invalid. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Run $THIS_SCRIPT -h help for further details. ${NC}" + echo -e "${RED} Exiting... ${NC}" exit 1 else - echo -e "${GREEN} The $2 path you provided is valid.${NC}\n" | tee -a "${currentlog}" + echo -e "${GREEN} The $2 path you provided is valid. ${NC}" | tee -a "${currentlog}" fi } From d6e91944d9b84a11a8cb57cf7f8d0d67fe769724 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 9 Jul 2022 08:46:12 -0500 Subject: [PATCH 163/203] Updated to match current default nginx config --- script-cfg/InstallFunctions.cfg | 21 ++++++++++++++------- script-cfg/MiscFunctions.cfg | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index e1da62b0f7..eba5fc4482 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -198,11 +198,14 @@ installFrontEnd() installNginx() { if [ "$1" != "devinstall" ]; then + nginxdefaultconf='/etc/nginx/nginx.conf' if [ "$1" == "install" ] || [ "$1" == "devprep" ]; then sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" - sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "/worker_rlimit_nofile.*/d" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/worker_connections.*/worker_connections 2048;/" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" + sudo sed -i "1i worker_rlimit_nofile 1000000;" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart1" ]; then # Check Nginx config if ! sudo nginx -t > /dev/null 2>&1; then @@ -212,20 +215,24 @@ installNginx() exit 1 fi elif [ "$1" == "updatepart2" ]; then - CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" /etc/nginx/nginx.conf) + CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" $nginxdefaultconf) if ! [[ $CHECK_NGINX_WORKER_CONN ]]; then echo -e "\n${GREEN} Changing nginx worker connections to 2048 ${NC}\n" | tee -a "${currentlog}" - sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/worker_connections.*/worker_connections 2048;/" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" fi - sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "/worker_rlimit_nofile.*/d" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" + sudo sed -i "1i worker_rlimit_nofile 1000000;" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "restore" ]; then sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" sudo rm -rf /etc/nginx 2>&1 | tee -a "${currentlog}" sudo mkdir /etc/nginx 2>&1 | tee -a "${currentlog}" sudo tar -xzf $tmp_dir/nginx/etc-nginx.tar.gz -C /etc/nginx 2>&1 | tee -a "${currentlog}" - sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i 's/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "/worker_rlimit_nofile.*/d" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/worker_connections.*/worker_connections 2048;/" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" + sudo sed -i "1i worker_rlimit_nofile 1000000;" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" # Misc functions getExistingDomainInfo; fi diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 7a07de33b2..b18939e690 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -25,7 +25,7 @@ cls() } # Purdy install text in green -echo -e() +print_green() { printf >&2 "${GREEN}%0.s-${NC}" {1..80} printf >&2 "\n" From 2d3beb43f60246a81f01a4e274ed486fa62ed4c6 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sun, 10 Jul 2022 14:20:18 -0500 Subject: [PATCH 164/203] Deleting unnecessary file --- script-cfg/SystemLockdown.cfg | 163 ---------------------------------- 1 file changed, 163 deletions(-) delete mode 100644 script-cfg/SystemLockdown.cfg diff --git a/script-cfg/SystemLockdown.cfg b/script-cfg/SystemLockdown.cfg deleted file mode 100644 index 8614472c30..0000000000 --- a/script-cfg/SystemLockdown.cfg +++ /dev/null @@ -1,163 +0,0 @@ -# Function to harden system against intruders -hardenOperatingSystem() -{ - echo " " - echo "############ Hardening system against intruders ############" - echo "############################################################" - - # prevent tmpfs exploits - sudo chmod 777 /etc/fstab - sudo printf "\ntmpfs /run/shm tmpfs defaults,noexec,nosuid 0 0" >> /etc/fstab - sudo chmod 644 /etc/fstab - - # enable general good security settings for ip traffic - sudo chmod 777 /etc/sysctl.conf - sudo printf "\n" >> /etc/sysctl.conf - sudo printf "\n# IP Spoofing protection" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.conf.all.rp_filter = 1" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.conf.default.rp_filter = 1" >> /etc/sysctl.conf - sudo printf "\n" >> /etc/sysctl.conf - sudo printf "\n# Ignore ICMP broadcast requests" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.icmp_echo_ignore_broadcasts = 1" >> /etc/sysctl.conf - sudo printf "\n" >> /etc/sysctl.conf - sudo printf "\n# Disable source packet routing" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.conf.all.accept_source_route = 0" >> /etc/sysctl.conf - sudo printf "\nnet.ipv6.conf.all.accept_source_route = 0" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.conf.default.accept_source_route = 0" >> /etc/sysctl.conf - sudo printf "\nnet.ipv6.conf.default.accept_source_route = 0" >> /etc/sysctl.conf - sudo printf "\n" >> /etc/sysctl.conf - sudo printf "\n# Ignore send redirects" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.conf.all.send_redirects = 0" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.conf.default.send_redirects = 0" >> /etc/sysctl.conf - sudo printf "\n" >> /etc/sysctl.conf - sudo printf "\n# Block SYN attacks" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.tcp_syncookies = 1" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.tcp_max_syn_backlog = 2048" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.tcp_synack_retries = 2" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.tcp_syn_retries = 5" >> /etc/sysctl.conf - sudo printf "\n" >> /etc/sysctl.conf - sudo printf "\n# Log Martians" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.conf.all.log_martians = 1" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.icmp_ignore_bogus_error_responses = 1" >> /etc/sysctl.conf - sudo printf "\n" >> /etc/sysctl.conf - sudo printf "\n# Ignore ICMP redirects" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.conf.all.accept_redirects = 0" >> /etc/sysctl.conf - sudo printf "\nnet.ipv6.conf.all.accept_redirects = 0" >> /etc/sysctl.conf - sudo printf "\nnet.ipv4.conf.default.accept_redirects = 0" >> /etc/sysctl.conf - sudo printf "\nnet.ipv6.conf.default.accept_redirects = 0" >> /etc/sysctl.conf - sudo printf "\n" >> /etc/sysctl.conf - sudo chmod 644 /etc/sysctl.conf - sudo sysctl -p - - # check dns first, use hosts as a backup option, prevent spoofing - sudo sed -i "s/order hosts,bind/order bind,hosts/" /etc/host.conf - - # create admin group - sudo groupadd admin - - # Add current user to admin group - sudo usermod -a -G admin $currentuser - - # Block root access to ssh and limit access to admin group - sudo sed -i "s/PermitRootLogin prohibit-password/PermitRootLogin no/" /etc/ssh/sshd_config - sudo sed -i "/PermitRootLogin no/ a DebianBanner no" /etc/ssh/sshd_config - sudo sed -i "/DebianBanner no/ a AllowGroups admin" /etc/ssh/sshd_config - - # override setting so admin is default root group - sudo dpkg-statoverride --update --add root admin 4750 /bin/su - - # rebuild kernel images with new information - sudo update-initramfs -c -k all - - # update boot menu with new images - sudo update-grub - - return -} - - -# Function to install and configure Fail2Ban, Tripwire, etc -installSecurity() -{ - echo " " - echo "############ Installing additional security software ############" - echo "#################################################################" - echo " " - - # install apps - sudo apt-get install -y rkhunter chkrootkit - - # set chkrootkit to scan daily - sudo sed -i 's/RUN_DAILY="false"/RUN_DAILY="true"/' /etc/chkrootkit.conf - - # set rkhunter to update and scan daily, as well as scan new installs to add to internal database - sudo sed -i 's/APT_AUTOGEN="false"/APT_AUTOGEN="true"/' /etc/default/rkhunter - sudo sed -i 's/CRON_DAILY_RUN=""/CRON_DAILY_RUN="true"/' /etc/default/rkhunter - sudo sed -i 's/CRON_DB_UPDATE=""/CRON_DB_UPDATE="true"/' /etc/default/rkhunter - - # remove common false positive from database and fix misconfig - sudo sed -i 's|#ALLOWHIDDENDIR=/etc/.java|ALLOWHIDDENDIR=/etc/.java|' /etc/rkhunter.conf - sudo sed -i 's|#ALLOWHIDDENDIR=/etc/.git|ALLOWHIDDENDIR=/etc/.git|' /etc/rkhunter.conf - sudo sed -i 's|#ALLOWHIDDENDIR=/dev/.lxc|ALLOWHIDDENDIR=/dev/.lxc|' /etc/rkhunter.conf - sudo sed -i 's|MIRRORS_MODE=1|MIRRORS_MODE=0|' /etc/rkhunter.conf - sudo sed -i 's|UPDATE_MIRRORS=0|UPDATE_MIRRORS=1|' /etc/rkhunter.conf - sudo sed -i 's|WEB_CMD="/bin/false"|WEB_CMD=""|' /etc/rkhunter.conf - - # allow local network clients to attempt logins and fail without being immediately banned - sudo sed -i -e "\$aALL: $subnetip\/$subnetmask" /etc/hosts.allow - - # update fkhunter database - sudo rkhunter --update - wait - - # update rkhunter based on new info - sudo rkhunter --propupd - wait - - # run rkhunter in non-interactive mode - sudo rkhunter --check --rwo - wait - - return -} - - -# Function to enable automatic security updates only -AutoSecurityUpdates() -{ - sudo apt-get install -y unattended-upgrades - - # Configure allowed automatic update sources - security only - sudo sed -i 's|"${distro_id}:${distro_codename}";|//"${distro_id}:${distro_codename}";|' /etc/apt/apt.conf.d/50unattended-upgrades - sudo sed -i 's|//Unattended-Upgrade::Mail "";|Unattended-Upgrade::Mail "root";|' /etc/apt/apt.conf.d/50unattended-upgrades - sudo sed -i 's|//Unattended-Upgrade::Remove-Unused-Dependencies "false";|Unattended-Upgrade::Remove-Unused-Dependencies "true";|' /etc/apt/apt.conf.d/50unattended-upgrades - sudo sed -i 's|// Unattended-Upgrade::OnlyOnACPower "true";|Unattended-Upgrade::OnlyOnACPower "true";|' /etc/apt/apt.conf.d/50unattended-upgrades - - # enable automatic updates - sudo truncate -s 0 /etc/apt/apt.conf.d/20auto-upgrades - sudo chmod 777 /etc/apt/apt.conf.d/20auto-upgrades - sudo printf 'APT::Periodic::Update-Package-Lists "1";' >> /etc/apt/apt.conf.d/20auto-upgrades - sudo printf "\n" >> /etc/apt/apt.conf.d/20auto-upgrades - sudo printf 'APT::Periodic::Download-Upgradeable-Packages "1";' >> /etc/apt/apt.conf.d/20auto-upgrades - sudo printf "\n" >> /etc/apt/apt.conf.d/20auto-upgrades - sudo printf 'APT::Periodic::AutocleanInterval "3";' >> /etc/apt/apt.conf.d/20auto-upgrades - sudo printf "\n" >> /etc/apt/apt.conf.d/20auto-upgrades - sudo printf 'APT::Periodic::Unattended-Upgrade "1";' >> /etc/apt/apt.conf.d/20auto-upgrades - sudo chmod 644 /etc/apt/apt.conf.d/20auto-upgrades - - # enable reboot check and email notification - sudo echo '#!/usr/bin/env bash' | sudo tee /etc/cron.hourly/reboot-check - sudo chmod 777 /etc/cron.hourly/reboot-check - sudo printf "\n\n" >> /etc/cron.hourly/reboot-check - sudo printf 'if [ -f /var/run/reboot-required ]; then' >> /etc/cron.hourly/reboot-check - sudo printf "\n\t" >> /etc/cron.hourly/reboot-check - sudo printf 'echo "A reboot is required following updates to server $(hostname -f)" | mail -s "Reboot Required" admin-email' >> /etc/cron.hourly/reboot-check - sudo printf "\nfi" >> /etc/cron.hourly/reboot-check - - sudo sed -i "s/admin-email/$smtplogin/" /etc/cron.hourly/reboot-check - - sudo chown root:root /etc/cron.hourly/reboot-check - sudo chmod 755 /etc/cron.hourly/reboot-check - - return -} \ No newline at end of file From cb9794aeb2bd85241b19c95bde573e245db96bec Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 12 Jul 2022 09:23:50 -0500 Subject: [PATCH 165/203] Add commenting to various functions --- script-cfg/CertificateFunctions.cfg | 15 +++++++++- script-cfg/ConfigAndServiceFunctions.cfg | 35 ++++++++++++++++++++++-- script-cfg/InputAndError.cfg | 2 +- script-cfg/MiscFunctions.cfg | 16 ----------- script-cfg/NetworkFunctions.cfg | 8 ++---- script-cfg/ParentFunctions.cfg | 8 ++---- 6 files changed, 54 insertions(+), 30 deletions(-) diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 95f420059a..8ebc38690d 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -33,25 +33,31 @@ acmeChallengeCheck() importCerts() { dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Importing Certificates" --msgbox "A VIM window will open for you to paste the contents of your SSL certificate, private key, and CA Chain file, in that order.\n\nTo paste the contents, type i , then shift+insert.\n\nAfter pasting the contents, type esc , then shift-: , then wq , then enter to close the window and continue.\n\nPress enter when you're ready to begin:" 0 0 + + # Create directory if it doesn't exist if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then sudo mkdir -p /etc/letsencrypt/live/${rootdomain} 2>&1 | tee -a "${currentlog}" fi + # Check if cert file exists, if so, wipe and import data if [ -f /etc/letsencrypt/live/${rootdomain}/fullchain.pem ]; then sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/fullchain.pem 2>&1 | tee -a "${currentlog}" fi sudo vim /etc/letsencrypt/live/${rootdomain}/fullchain.pem 2>&1 | tee -a "${currentlog}" + # Check if key file exists, if so, wipe and import data if [ -f /etc/letsencrypt/live/${rootdomain}/privkey.pem ]; then sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/privkey.pem 2>&1 | tee -a "${currentlog}" fi sudo vim /etc/letsencrypt/live/${rootdomain}/privkey.pem 2>&1 | tee -a "${currentlog}" + # Check if ca file exists, if so, wipe and import data if [ -f /etc/letsencrypt/live/${rootdomain}/chain.pem ]; then sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/chain.pem 2>&1 | tee -a "${currentlog}" fi sudo vim /etc/letsencrypt/live/${rootdomain}/chain.pem 2>&1 | tee -a "${currentlog}" - + + # Fix dir/file perms and ownership sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" } @@ -74,6 +80,7 @@ generateCerts() sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email 2>&1 | tee -a "${currentlog}" done + # Fix dir/file perms and ownership sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" @@ -128,10 +135,12 @@ generateCerts() sudo ln -s /etc/letsencrypt/live/${rmmdomain}/privkey.pem /etc/letsencrypt/live/${rootdomain}/privkey.pem 2>&1 | tee -a "${currentlog}" sudo ln -s /etc/letsencrypt/live/${rmmdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/chain.pem 2>&1 | tee -a "${currentlog}" + # Create renewal post hook to restart services after renewal sudo echo '#!/usr/bin/env bash' | sudo tee /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh sudo sed -i "/\#\!\/usr\/bin\/env bash/ a systemctl restart nginx meshcentral rmm celery celerybeat nats" /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh 2>&1 | tee -a "${currentlog}" sudo chmod +x /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh 2>&1 | tee -a "${currentlog}" + # Fix dir/file ownership and perms sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo systemctl start nginx 2>&1 | tee -a "${currentlog}" @@ -152,6 +161,7 @@ renewCerts() generateCerts; + # Restart services after cert generation sudo systemctl restart nginx.service rmm.service celery celerybeat.service nats-api.service nats.service meshcentral.service 2>&1 | tee -a "${currentlog}" } @@ -182,8 +192,10 @@ installCertbot() return fi + # Skip if devinstall if [ "$1" == "devinstall" ]; then echo -e "\n${GREEN} Certificates should be in place. ${NC}\n" | tee -a "${currentlog}" + # Get preferred method if not automated elif [ "$autoinstall" != "1" ]; then dialog --cr-wrap --clear --yes-label "LetsEncrypt" --no-label "Import" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Certificate Generation" --yesno "Would you like to have certificates generated using LetsEncrypt, or import your own existing certificates?" 0 0 case $? in @@ -193,6 +205,7 @@ installCertbot() # Import certs using vim 1 ) importCerts;; esac + # Determine type and import or generate certs elif [ "$autoinstall" == "1" ]; then if [ "$certtype" == "import" ]; then if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 82af017f2e..332e4ade08 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -12,16 +12,20 @@ CFG_VERSION="8" # Generate mesh configuration createMeshConfig() { + # Copy default config file into place sudo cp /rmm/default-configs/mesh/config.json /meshcentral/meshcentral-data/config.json 2>&1 | tee -a "${currentlog}" + # Swap out generic placeholders sudo sed -i "s/mesh.example.com/$meshdomain/" /meshcentral/meshcentral-data/config.json 2>&1 | tee -a "${currentlog}" } # Generate local settings file createLocalSettings() { + # Copy default config file into place sudo cp /rmm/default-configs/python/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" + # Swap out generic placeholders sudo sed -i "s/DJANGO_SEKRET/$DJANGO_SEKRET/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" sudo sed -i "s/api.example.com/$rmmdomain/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" sudo sed -i "s/ADMINURL/$ADMINURL/" /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" @@ -124,8 +128,7 @@ configureBackend() python manage.py createsuperuser --username ${djangousername} --email ${letsemail} 2>&1 | tee -a "${currentlog}" python manage.py create_installer_user 2>&1 | tee -a "${currentlog}" RANDBASE=$(python manage.py generate_totp) - # Misc functions - cls; + clear -x python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} deactivate read -n 1 -s -r -p "Press any key to continue..." @@ -137,46 +140,57 @@ configureBackend() # Create UWSGI config createUwsgiConf() { + # Copy default config file into place sudo cp /rmm/default-configs/uwsgi/app.ini /rmm/api/tacticalrmm/app.ini 2>&1 | tee -a "${currentlog}" } # Create UWSGI service createUwsgiService() { + # Copy default service file into place sudo cp /rmm/service-definitions/rmm.service /etc/systemd/system/rmm.service 2>&1 | tee -a "${currentlog}" + # Swap out generic placeholders sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/rmm.service 2>&1 | tee -a "${currentlog}" } # Create Daphne service createDaphneService() { + # Copy default service file into place sudo cp /rmm/service-definitions/daphne.service /etc/systemd/system/daphne.service 2>&1 | tee -a "${currentlog}" + # Swap out generic placeholders sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/daphne.service 2>&1 | tee -a "${currentlog}" } # Create NATS service createNatsService() { + # Copy default service file into place sudo cp /rmm/service-definitions/nats.service /etc/systemd/system/nats.service 2>&1 | tee -a "${currentlog}" + # Swap out generic placeholders sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats.service 2>&1 | tee -a "${currentlog}" } # Create NATS service createNatsApiService() { + # Copy default service file into place sudo cp /rmm/service-definitions/nats-api.service /etc/systemd/system/nats-api.service 2>&1 | tee -a "${currentlog}" + # Swap out generic placeholders sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats-api.service 2>&1 | tee -a "${currentlog}" } # Create backend nginx conf createBackendNginxConf() { + # Copy default config file into place sudo cp /rmm/default-configs/nginx/rmm.conf /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + # Swap out generic placeholders sudo sed -i "s/api.example.com/$rmmdomain/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" if [ "$certtype" == "dns" ]; then @@ -190,8 +204,10 @@ createBackendNginxConf() # Create Mesh nginx conf createMeshNginxConf() { + # Copy default config file into place sudo cp /rmm/default-configs/nginx/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" + # Swap out generic placeholders sudo sed -i "s/mesh.example.com/$meshdomain/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" if [ "$certtype" == "dns" ]; then sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" @@ -204,38 +220,47 @@ createMeshNginxConf() # Create Celery service createCeleryService() { + # Copy default service file into place sudo cp /rmm/service-definitions/celery.service /etc/systemd/system/celery.service 2>&1 | tee -a "${currentlog}" + # Swap out generic placeholders sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/celery.service 2>&1 | tee -a "${currentlog}" } # Create Celery config createCeleryConf() { + # Copy default config file into place sudo cp /rmm/default-configs/celery/celery.conf /etc/conf.d/celery.conf 2>&1 | tee -a "${currentlog}" } # Create CeleryBeat service createCeleryBeatService() { + # Copy default service file into place sudo cp /rmm/service-definitions/celerybeat.service /etc/systemd/system/celerybeat.service 2>&1 | tee -a "${currentlog}" + # Swap out generic placeholders sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/celerybeat.service 2>&1 | tee -a "${currentlog}" } # Create MeshCentral service createMeshCentralService() { + # Copy default service file into place sudo cp /rmm/service-definitions/meshcentral.service /etc/systemd/system/meshcentral.service 2>&1 | tee -a "${currentlog}" + # Swap out generic placeholders sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/meshcentral.service 2>&1 | tee -a "${currentlog}" } # Create Frontend Nginx config createFrontendNginxConf() { + # Copy default config file into place sudo cp /rmm/default-configs/nginx/frontend.conf /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + # Swap out generic placeholders sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" if [ "$certtype" == "dns" ]; then sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" @@ -267,6 +292,7 @@ enableMeshService() # Generate Mesh Token generateMeshToken() { + # MESHTOKENKEY="$(node /meshcentral/node_modules/meshcentral --logintokenkey)" sudo sed -i '$ a MESH_TOKEN_KEY = "MESHTOKENKEY"' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" @@ -276,23 +302,28 @@ generateMeshToken() # Configure Mesh user and group, restart service configMeshUserGroup() { + # Stop service and switch dir sudo systemctl stop meshcentral 2>&1 | tee -a "${currentlog}" sleep 1 cd /meshcentral + # Create mesh user and make admin node node_modules/meshcentral --createaccount ${meshusername} --pass ${MESHPASSWD} --email ${letsemail} 2>&1 | tee -a "${currentlog}" sleep 1 node node_modules/meshcentral --adminaccount ${meshusername} 2>&1 | tee -a "${currentlog}" + # Restart mesh sudo systemctl start meshcentral 2>&1 | tee -a "${currentlog}" sleep 5 + # Wait for mesh to be ready while ! [[ $CHECK_MESH_READY2 ]]; do CHECK_MESH_READY2=$(sudo journalctl -u meshcentral.service -b --no-pager | grep "MeshCentral HTTP server running on port") echo -e "${YELLOW} Mesh Central not ready yet... ${NC}" | tee -a "${currentlog}" sleep 3 done + # Create mesh device group node node_modules/meshcentral/meshctrl.js --url wss://${meshdomain} --loginuser ${meshusername} --loginpass ${MESHPASSWD} AddDeviceGroup --name TacticalRMM 2>&1 | tee -a "${currentlog}" sleep 1 } diff --git a/script-cfg/InputAndError.cfg b/script-cfg/InputAndError.cfg index 96a4adddaf..45f85e83ae 100644 --- a/script-cfg/InputAndError.cfg +++ b/script-cfg/InputAndError.cfg @@ -19,7 +19,7 @@ translateToLowerCase() echo "$lowercase" } -# Function to track ID10T errors +# Function to track and mock ID10T errors derpDerp() { if [ "$errortrack" -lt 12 ]; then diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index b18939e690..a0508983b4 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -18,12 +18,6 @@ setColors() NC='\033[0m' } -# Clear screen -cls() -{ - printf "\033c" -} - # Purdy install text in green print_green() { @@ -34,16 +28,6 @@ print_green() printf >&2 "\n" } -# Purdy install text in red -print_red() -{ - printf >&2 "${RED}%0.s-${NC}" {1..80} - printf >&2 "\n" - printf >&2 "${RED}${1}${NC}\n" - printf >&2 "${RED}%0.s-${NC}" {1..80} - printf >&2 "\n" -} - # Purdy install text in yellow print_yellow() { diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/NetworkFunctions.cfg index 09feb77b9b..4a358e190f 100644 --- a/script-cfg/NetworkFunctions.cfg +++ b/script-cfg/NetworkFunctions.cfg @@ -39,17 +39,14 @@ setSiteHostname() # Check hosts file, add hosts configHosts() { - # 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 + # Check if localhost exists in hosts file, if not add it CHECK_LOCALHOST=$(grep "127.0.0.1" /etc/hosts | grep "localhost") if ! [[ $CHECK_LOCALHOST ]]; then echo -e "\n${GREEN} Adding localhost to hosts file... ${NC}\n" | tee -a "${currentlog}" sudo sed -i "1i 127.0.0.1\tlocalhost" /etc/hosts 2>&1 | tee -a "${currentlog}" fi + # Check for t-rmm hosts definitions. If they exist in old form, replace, if not, insert them CHECK_HOSTS=$(grep "127.0.1.1 $rmmdomain $frontenddomain $meshdomain" /etc/hosts) if [[ $CHECK_HOSTS ]]; then echo -e "\n${GREEN} Correcting subdomain entries... ${NC}\n" | tee -a "${currentlog}" @@ -64,6 +61,7 @@ configHosts() setSiteHostname "$meshhost" "$rootdomain"; fi + # Check if likely behind nat BEHIND_NAT=false IPV4=$(ip -4 addr | sed -ne 's|^.* inet \([^/]*\)/.* scope global.*$|\1|p' | head -1) if echo "$IPV4" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index 4638cdf1dc..a219c30a90 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -23,9 +23,8 @@ mainInstall() # User Input generateUsersAndPass "$INSTALL_TYPE"; - # This does... something - # Misc functions - cls; + # Clear screen + clear -x # Get host/domain info # User Input @@ -335,8 +334,7 @@ updateTRMM() checkAdditionalAppsVers; # Clear screen - # Misc functions - cls; + clear -x # Check CHECK_NATS_LIMITNOFILE, whatever that means # UpdateRestoreFunctions From e33daa365c987afb6f8e335ad77b192e811b9115 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 13 Jul 2022 08:12:30 -0500 Subject: [PATCH 166/203] added cli arg for sudo password --- installer-util.sh | 8 +++++--- script-cfg/InstallFunctions.cfg | 6 +++++- script-cfg/MiscFunctions.cfg | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 91178d1c1a..c476b62068 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -58,6 +58,7 @@ trmmpass="" backupfile="" troubleshoot="" certtype="" +sudopass="" # Check if directory exists, if not, create if [ ! -d $PWD/script-cfg ]; then @@ -97,7 +98,7 @@ done setColors; # Get commandline input -while getopts i:a:b:c:e:d:m:f:h:k:s:p:r:o:t:u:n:w: option +while getopts i:a:b:c:e:d:m:f:g:h:k:s:p:r:o:t:u:n:w: option do case $option in i) autoinstall="1" @@ -109,6 +110,7 @@ do d) rootdomain="$(translateToLowerCase ${OPTARG})";; m) letsemail="$(translateToLowerCase ${OPTARG})";; f) backupfile="${OPTARG}";; + g) sudopass="${OPTARG}";; h) helpText exit 1;; k) sslkey="${OPTARG}";; @@ -151,9 +153,9 @@ if [ "$autoinstall" == "1" ]; then # Check all required input is available for install if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]); then - if ([ -z "$rmmhost" ] || [ -z "$certtype" ] || [ -z "$rootdomain" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]); then + if ([ -z "$rmmhost" ] || [ -z "$sudopass" ] || [ -z "$certtype" ] || [ -z "$rootdomain" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]); then echo -e "${RED} Error: To perform an automated installation, you must provide all required information. ${NC}" | tee -a "${currentlog}" - echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, and T-RMM username and password are all required. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} sudo password, install type, api host, mesh host, rmm host, root domain, email address, certificate install type, and T-RMM username and password are all required. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for further details. ${NC}" exit 1 fi diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index eba5fc4482..4c9f9a0e01 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -12,7 +12,11 @@ CFG_VERSION="8" # Install script prereqs installPreReqs() { - sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" + if [ "$autoinstall" == "1" ]; then + echo "$sudopass" | sudo -S apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" + elif [ "$autoinstall" != "1" ]; then + sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" + fi } # Install remaining prereqs diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index a0508983b4..80aad230c9 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -42,7 +42,7 @@ print_yellow() helpText() { echo -e "" - echo -e 'Syntax: ./installer-util.sh [-i|a|b|c|e|d|m|f|h|k|s|p|r|o|t|u|n|w]' + echo -e 'Syntax: ./installer-util.sh [-i|a|b|c|e|d|m|f|g|h|k|s|p|r|o|t|u|n|w]' echo -e "" echo -e "Options:\n" echo -e "i Select type of automated function. Options are ${YELLOW}install${NC},${YELLOW} devprep${NC},${YELLOW} devinstall${NC},${YELLOW} backup${NC}, or ${YELLOW}restore${NC}.\n" @@ -53,6 +53,7 @@ helpText() echo -e "d Provide the root domain, eg rmm.${YELLOW}example.com${NC}\n" echo -e "m Provide a valid email address for LetsEncrypt cert generation and primary T-RMM user.\n" echo -e "f Provide the full path to the backup file, including file name.\n" + echo -e "g Provide the sudo password to allow non-interactive use." echo -e "h Type ${YELLOW}help${NC} to show this help text.\n" echo -e "k Full path to SSL private key for import. Must be in .pem format. Include the filename.\n" echo -e "s Provide the mesh hostname/subdomain, eg ${YELLOW}mesh${NC}.example.com\n" From e4d6474ef46b7d8f07eced74a5c6589d392b7663 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 13 Jul 2022 09:20:50 -0500 Subject: [PATCH 167/203] Added removal of history logging of sudo password --- installer-util.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/installer-util.sh b/installer-util.sh index c476b62068..6c75c0f9ee 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -60,6 +60,9 @@ troubleshoot="" certtype="" sudopass="" +# Remove script run command from history to prevent sudo password leak +history -d $(($(history 1 | awk '{print $1}')-1)) + # Check if directory exists, if not, create if [ ! -d $PWD/script-cfg ]; then mkdir $PWD/script-cfg 2>&1 | tee -a "${currentlog}" From 8618000577cf1158f6225243924787deb22041a7 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 13 Jul 2022 10:25:19 -0500 Subject: [PATCH 168/203] Added commands to extend sudo timeout for auto --- installer-util.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/installer-util.sh b/installer-util.sh index 6c75c0f9ee..772100f574 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -398,19 +398,29 @@ mainMenu() { # Automated install types install, devprep, or devinstall if [ "$autoinstall" == "1" ] && ([ "$INSTALL_TYPE" == "install" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "devprep" ]); then + echo 'Defaults timestamp_timeout=15' | sudo tee /etc/sudoers.d/timeout mainInstall; + sudo rm /etc/sudoers.d/timeout # Automated update elif [ "$autoinstall" == "1" ] && [ "$INSTALL_TYPE" == "update" ]; then + echo 'Defaults timestamp_timeout=15' | sudo tee /etc/sudoers.d/timeout updateTRMM; + sudo rm /etc/sudoers.d/timeout # Automated restore elif [ "$autoinstall" == "1" ] && [ "$INSTALL_TYPE" == "restore" ]; then + echo 'Defaults timestamp_timeout=15' | sudo tee /etc/sudoers.d/timeout restoreTRMM; + sudo rm /etc/sudoers.d/timeout # Automated backup elif [ "$autoinstall" == "1" ] && [ "$INSTALL_TYPE" == "backup" ]; then + echo 'Defaults timestamp_timeout=15' | sudo tee /etc/sudoers.d/timeout backupTRMM; + sudo rm /etc/sudoers.d/timeout # Automated troubleshoot elif [ "$autoinstall" != "1" ] && [ "$troubleshoot" == "1" ]; then + echo 'Defaults timestamp_timeout=15' | sudo tee /etc/sudoers.d/timeout troubleShoot; + sudo rm /etc/sudoers.d/timeout else until [ "$menuselection" = "0" ]; do dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Main Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections." 0 0 0 \ From c7f4a43739dde064cf109bdb6f5a0470ca6d61ef Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 13 Jul 2022 11:12:05 -0500 Subject: [PATCH 169/203] Added second history wipe to remove passwd --- script-cfg/InstallFunctions.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 4c9f9a0e01..acb37f55be 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -14,6 +14,8 @@ installPreReqs() { if [ "$autoinstall" == "1" ]; then echo "$sudopass" | sudo -S apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" + # Remove script run command from history to prevent sudo password leak + history -d $(($(history 1 | awk '{print $1}')-1)) elif [ "$autoinstall" != "1" ]; then sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" fi From af93a8eb9c9cb34dd83cb4967a6e059a0a98447f Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 13 Jul 2022 12:30:20 -0500 Subject: [PATCH 170/203] Removed 22.04 options --- script-cfg/InstallFunctions.cfg | 10 +++++----- script-cfg/SystemInfoFunctions.cfg | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index acb37f55be..5f1528bdce 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -14,7 +14,7 @@ installPreReqs() { if [ "$autoinstall" == "1" ]; then echo "$sudopass" | sudo -S apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" - # Remove script run command from history to prevent sudo password leak + # Remove passed sudo password from history to prevent leak history -d $(($(history 1 | awk '{print $1}')-1)) elif [ "$autoinstall" != "1" ]; then sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" @@ -35,10 +35,10 @@ setInstallRepos() # There is no Jammy repo yet so use Focal for Ubuntu 22.04 if ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "20.04" ]); then mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" - elif ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "22.04" ]); then - codename="focal" - mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" - codename="$tempcodename" + #elif ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "22.04" ]); then + # codename="focal" + # mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" + # codename="$tempcodename" # There is no bullseye repo yet for mongo so just use Buster on Debian 11 elif ([ "$osname" == "debian" ] && [ $relno -eq 10 ]); then mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 main" diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 6a66377cfd..8ffb2399c2 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -32,12 +32,12 @@ wutOSThis() # Verify Debian or Ubuntu and version verifySupportedOS() { - if ([ "$osname" == "ubuntu" ] && ([ "$fullrelno" == "20.04" ] || [ "$fullrelno" == "22.04" ])) || ([ "$osname" == "debian" ] && [ $relno -ge 10 ]); then + if ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "20.04" ]) || ([ "$osname" == "debian" ] && [ $relno -ge 10 ]); then echo -e "\n${GREEN} $fullrel ${NC}\n" | tee -a "${currentlog}" else if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" - echo -e "${RED} Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11 ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Supported versions: Ubuntu 20.04, Debian 10 and 11 ${NC}" | tee -a "${currentlog}" echo -e "${RED} Your system, $fullrel, does not appear to be supported. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Exiting. ${NC}" else From 3a9f783b156776747b44619d9e5036f74ac6d390 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 13 Jul 2022 15:40:25 -0500 Subject: [PATCH 171/203] Fixed webroot automated install --- installer-util.sh | 4 ++-- script-cfg/CertificateFunctions.cfg | 2 +- script-cfg/InstallFunctions.cfg | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 772100f574..27db8a3673 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -61,7 +61,7 @@ certtype="" sudopass="" # Remove script run command from history to prevent sudo password leak -history -d $(($(history 1 | awk '{print $1}')-1)) +#history -d $(($(history 1 | awk '{print $1}')-1)) # Check if directory exists, if not, create if [ ! -d $PWD/script-cfg ]; then @@ -156,7 +156,7 @@ if [ "$autoinstall" == "1" ]; then # Check all required input is available for install if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]); then - if ([ -z "$rmmhost" ] || [ -z "$sudopass" ] || [ -z "$certtype" ] || [ -z "$rootdomain" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass"] || [ -z "$letsemail" ]); then + if ([ -z "$rmmhost" ] || [ -z "$sudopass" ] || [ -z "$certtype" ] || [ -z "$rootdomain" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass" ] || [ -z "$letsemail" ]); then echo -e "${RED} Error: To perform an automated installation, you must provide all required information. ${NC}" | tee -a "${currentlog}" echo -e "${RED} sudo password, install type, api host, mesh host, rmm host, root domain, email address, certificate install type, and T-RMM username and password are all required. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for further details. ${NC}" diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index 8ebc38690d..d41e50d4eb 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -218,7 +218,7 @@ installCertbot() sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" elif [ "$certtype" == "webroot" ]; then - return + echo -e "" fi fi diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 5f1528bdce..fdf6f45910 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -15,7 +15,7 @@ installPreReqs() if [ "$autoinstall" == "1" ]; then echo "$sudopass" | sudo -S apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" # Remove passed sudo password from history to prevent leak - history -d $(($(history 1 | awk '{print $1}')-1)) + #history -d $(($(history 1 | awk '{print $1}')-1)) elif [ "$autoinstall" != "1" ]; then sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" fi From 9d8757e7e877f4697a968433d68be023c4862012 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 13 Jul 2022 15:53:40 -0500 Subject: [PATCH 172/203] changes to make sudo password optional for cli --- installer-util.sh | 4 ++-- script-cfg/InstallFunctions.cfg | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 27db8a3673..6a78ead44e 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -156,9 +156,9 @@ if [ "$autoinstall" == "1" ]; then # Check all required input is available for install if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]); then - if ([ -z "$rmmhost" ] || [ -z "$sudopass" ] || [ -z "$certtype" ] || [ -z "$rootdomain" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass" ] || [ -z "$letsemail" ]); then + if ([ -z "$rmmhost" ] || [ -z "$certtype" ] || [ -z "$rootdomain" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass" ] || [ -z "$letsemail" ]); then echo -e "${RED} Error: To perform an automated installation, you must provide all required information. ${NC}" | tee -a "${currentlog}" - echo -e "${RED} sudo password, install type, api host, mesh host, rmm host, root domain, email address, certificate install type, and T-RMM username and password are all required. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, and T-RMM username and password are all required. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for further details. ${NC}" exit 1 fi diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index fdf6f45910..ef62111c52 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -13,9 +13,13 @@ CFG_VERSION="8" installPreReqs() { if [ "$autoinstall" == "1" ]; then - echo "$sudopass" | sudo -S apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" - # Remove passed sudo password from history to prevent leak - #history -d $(($(history 1 | awk '{print $1}')-1)) + if [ -z "$sudopass" ]; then + sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" + elif [ ! -z "$sudopass" ]; then + echo "$sudopass" | sudo -S apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" + # Remove passed sudo password from history to prevent leak + #history -d $(($(history 1 | awk '{print $1}')-1)) + fi elif [ "$autoinstall" != "1" ]; then sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" fi From 05b082b2efcd2bfcb57d553ae0b0ce785bac9c7b Mon Sep 17 00:00:00 2001 From: silversword411 Date: Fri, 15 Jul 2022 01:44:43 -0400 Subject: [PATCH 173/203] tweaking cpu check verbage --- script-cfg/SystemInfoFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 8ffb2399c2..821a3e47a6 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -101,7 +101,7 @@ checkCPUAndThreadCount() if [ $threadcount -ge 2 ] || [ "$autoinstall" == "1" ]; then return else - dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended CPU core or thread count of 2.\n\nYou may experience issues during install and use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 + dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "TRMM is CPU intensive, and Amidaware recommends 2+ CPUs. Your system does not meet the minimum recommended CPU core or thread count of 2+.\n\nYou may experience issues during install and use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 case $? in 0 ) return;; From 82fda9f7030bd2939bf55cec56089659e22aeb6b Mon Sep 17 00:00:00 2001 From: silversword411 Date: Fri, 15 Jul 2022 01:48:21 -0400 Subject: [PATCH 174/203] sys newline --- script-cfg/SystemInfoFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 821a3e47a6..bff0e40e26 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -82,7 +82,7 @@ checkTotalSystemMemory() echo -e "${RED} Exiting... ${NC}" exit 1 elif [ "$autoinstall" != "1" ]; then - dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended RAM amount of 2GB.\n\nYou may experience issues during install.\n\nIt's recommended to exit and add RAM to the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 + dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended RAM amount of 2GB.\n\nYou may experience issues during install.\n\nIt's recommended to exit and add RAM to the system before continuing \n\nwith installation,though you may continue with the install now if you wish." 0 0 case $? in 0 ) return;; From a7daf63016d887c28e75a0aca9c4c0183233a53d Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 15 Jul 2022 09:42:52 -0500 Subject: [PATCH 175/203] Fixes per shellscript checker --- .vscode/settings.json | 3 ++ default-configs/nginx/nginx.conf | 63 ++++++++++++++++++++++ installer-util.sh | 48 ++++++++--------- script-cfg/CertificateFunctions.cfg | 52 +++++++++---------- script-cfg/ConfigAndServiceFunctions.cfg | 16 +++--- script-cfg/InstallFunctions.cfg | 56 ++++++++------------ script-cfg/MiscFunctions.cfg | 18 ++++--- script-cfg/ParentFunctions.cfg | 66 ++++++++++++------------ script-cfg/SystemInfoFunctions.cfg | 18 ++++--- script-cfg/TroubleshootingFunctions.cfg | 20 +++---- script-cfg/UpdateRestoreFunctions.cfg | 16 +++--- script-cfg/UserInput.cfg | 24 ++++----- 12 files changed, 228 insertions(+), 172 deletions(-) create mode 100644 default-configs/nginx/nginx.conf diff --git a/.vscode/settings.json b/.vscode/settings.json index 7eebc2f2a0..c8fb154376 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -65,5 +65,8 @@ "usePlaceholders": true, "completeUnimported": true, "staticcheck": true + }, + "files.associations": { + "*.cfg": "shellscript" } } diff --git a/default-configs/nginx/nginx.conf b/default-configs/nginx/nginx.conf new file mode 100644 index 0000000000..26ea21a532 --- /dev/null +++ b/default-configs/nginx/nginx.conf @@ -0,0 +1,63 @@ +worker_rlimit_nofile 1000000; +user www-data; +worker_processes auto; +pid /run/nginx.pid; +include /etc/nginx/modules-enabled/*.conf; + +events { + worker_connections 2048; + # multi_accept on; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + # server_tokens off; + + server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings + ## + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + + ## + # Logging Settings + ## + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + ## + # Gzip Settings + ## + + gzip on; + + # gzip_vary on; + # gzip_proxied any; + # gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + ## + # Virtual Host Configs + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} \ No newline at end of file diff --git a/installer-util.sh b/installer-util.sh index 6a78ead44e..761e935d94 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -64,8 +64,8 @@ sudopass="" #history -d $(($(history 1 | awk '{print $1}')-1)) # Check if directory exists, if not, create -if [ ! -d $PWD/script-cfg ]; then - mkdir $PWD/script-cfg 2>&1 | tee -a "${currentlog}" +if [ ! -d "$PWD"/script-cfg ]; then + mkdir "$PWD"/script-cfg 2>&1 | tee -a "${currentlog}" fi # Get cfg files function @@ -83,18 +83,18 @@ do done # Import functions -. $PWD/script-cfg/InputAndError.cfg -. $PWD/script-cfg/MiscFunctions.cfg -. $PWD/script-cfg/SystemInfoFunctions.cfg -. $PWD/script-cfg/UserInput.cfg -. $PWD/script-cfg/NetworkFunctions.cfg -. $PWD/script-cfg/InstallFunctions.cfg -. $PWD/script-cfg/DatabaseFunctions.cfg -. $PWD/script-cfg/CertificateFunctions.cfg -. $PWD/script-cfg/ConfigAndServiceFunctions.cfg -. $PWD/script-cfg/UpdateRestoreFunctions.cfg -. $PWD/script-cfg/TroubleshootingFunctions.cfg -. $PWD/script-cfg/ParentFunctions.cfg +. "$PWD"/script-cfg/InputAndError.cfg +. "$PWD"/script-cfg/MiscFunctions.cfg +. "$PWD"/script-cfg/SystemInfoFunctions.cfg +. "$PWD"/script-cfg/UserInput.cfg +. "$PWD"/script-cfg/NetworkFunctions.cfg +. "$PWD"/script-cfg/InstallFunctions.cfg +. "$PWD"/script-cfg/DatabaseFunctions.cfg +. "$PWD"/script-cfg/CertificateFunctions.cfg +. "$PWD"/script-cfg/ConfigAndServiceFunctions.cfg +. "$PWD"/script-cfg/UpdateRestoreFunctions.cfg +. "$PWD"/script-cfg/TroubleshootingFunctions.cfg +. "$PWD"/script-cfg/ParentFunctions.cfg # Set colors # MiscFunctions @@ -134,29 +134,29 @@ done if [ "$autoinstall" == "1" ]; then # Check that update type is valid - if ([ "$INSTALL_TYPE" == "update" ] && ([ "$UPDATE_TYPE" != "standard" ] && [ "$UPDATE_TYPE" != "forced" ])); then + if [ "$INSTALL_TYPE" == "update" ] && ([ "$UPDATE_TYPE" != "standard" ] && [ "$UPDATE_TYPE" != "forced" ]); then echo -e "${RED} Error: You've selected update, but not selected an appropriate type. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to select them. ${NC}" exit 1 fi # Check that backup file exists - if ([ "$INSTALL_TYPE" == "restore" ] && ([ -z "$backupfile" ] || [ ! -f "$backupfile" ])); then + if [ "$INSTALL_TYPE" == "restore" ] && ([ -z "$backupfile" ] || [ ! -f "$backupfile" ]); then echo -e "${RED} Error: You've selected restore, but not provided a valid backup file. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for details on how to enter this. ${NC}" exit 1 fi # Check that install type is valid - if ([ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ] && [ "$INSTALL_TYPE" != "update" ] && [ "$INSTALL_TYPE" != "restore" ] && [ "$INSTALL_TYPE" != "backup" ]); then + if [ "$INSTALL_TYPE" != "devprep" ] && [ "$INSTALL_TYPE" != "devinstall" ] && [ "$INSTALL_TYPE" != "install" ] && [ "$INSTALL_TYPE" != "update" ] && [ "$INSTALL_TYPE" != "restore" ] && [ "$INSTALL_TYPE" != "backup" ]; then echo -e "${RED} Error: You've selected an invalid function type. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for details on the available options. ${NC}" exit 1 fi # Check all required input is available for install - if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]); then - if ([ -z "$rmmhost" ] || [ -z "$certtype" ] || [ -z "$rootdomain" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass" ] || [ -z "$letsemail" ]); then + if [ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]; then + if [ -z "$rmmhost" ] || [ -z "$certtype" ] || [ -z "$rootdomain" ] || [ -z "$meshhost" ] || [ -z "$frontendhost" ] || [ -z "$trmmuser" ] || [ -z "$trmmpass" ] || [ -z "$letsemail" ]; then echo -e "${RED} Error: To perform an automated installation, you must provide all required information. ${NC}" | tee -a "${currentlog}" echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, and T-RMM username and password are all required. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for further details. ${NC}" @@ -164,14 +164,14 @@ if [ "$autoinstall" == "1" ]; then fi # Check that certificate install type is valid - if ([ "$certtype" != "import" ] && [ "$certtype" != "webroot" ]); then + if [ "$certtype" != "import" ] && [ "$certtype" != "webroot" ]; then echo -e "${RED} Error: You've selected an invalid certificate installation type. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for details on the available options. ${NC}" exit 1 fi # Check for required input if import certificate - if ([ "$certtype" == "import" ] && ([ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$sslkey" ])); then + if [ "$certtype" == "import" ] && ([ -z "$sslcacert" ] || [ -z "$sslcert" ] || [ -z "$sslkey" ]); then echo -e "${RED} Error: To perform an automated installation using imported certificates, you must provide all required information. ${NC}" | tee -a "${currentlog}" echo -e "${RED} install type, api host, mesh host, rmm host, root domain, email address, certificate install type, CA cert path, Cert path, Private key path, and T-RMM username and password are all required. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for further details. ${NC}" @@ -180,7 +180,7 @@ if [ "$autoinstall" == "1" ]; then fi # Check that email address format is valid - if ([ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]); then + if [ "$INSTALL_TYPE" == "devprep" ] || [ "$INSTALL_TYPE" == "devinstall" ] || [ "$INSTALL_TYPE" == "install" ]; then if [[ $letsemail != *[@]*[.]* ]]; then echo -e "${RED} Error: You've entered an invalid email address. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Run $THIS_SCRIPT -h help for details on the correct format. ${NC}" @@ -195,7 +195,7 @@ if [ "$autoinstall" == "1" ]; then exit 1 fi - if ([ ! -z "$rmmhost" ] && [ ! -z "$meshhost" ] && [ ! -z "$frontendhost" ] && [ ! -z "$rootdomain" ]); then + if [ -n "$rmmhost" ] && [ -n "$meshhost" ] && [ -n "$frontendhost" ] && [ -n "$rootdomain" ]; then # Check subdomains are valid format # User Input subdomainFormatCheck "$rmmhost" "api"; @@ -216,7 +216,7 @@ if [ "$autoinstall" == "1" ]; then checkDNSEntriesExist "$meshdomain"; fi - if ([ ! -z "$sslcacert" ] && [ ! -z "$sslcert" ] && [ ! -z "$sslkey" ]); then + if [ -n "$sslcacert" ] && [ -n "$sslcert" ] && [ -n "$sslkey" ]; then # Check that cert file exists # User Input checkCertExists "$sslcacert" "CA Chain"; diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/CertificateFunctions.cfg index d41e50d4eb..2c6467a75b 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/CertificateFunctions.cfg @@ -16,7 +16,7 @@ acmeChallengeCheck() local acmegood="n" until [ "$acmegood" == "y" ]; do - if [[ $(dig +noall +answer -t TXT _acme-challenge.$1) ]] 2>/dev/null; then + if [[ $(dig +noall +answer -t TXT _acme-challenge."$1") ]] 2>/dev/null; then acmegood="y" echo -e "${GREEN} Acme Challenge TXT record available. ${NC}\n" | tee -a "${currentlog}" echo -e "${GREEN} Continuing... ${NC}\n" | tee -a "${currentlog}" @@ -36,29 +36,29 @@ importCerts() # Create directory if it doesn't exist if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then - sudo mkdir -p /etc/letsencrypt/live/${rootdomain} 2>&1 | tee -a "${currentlog}" + sudo mkdir -p /etc/letsencrypt/live/"${rootdomain}" 2>&1 | tee -a "${currentlog}" fi # Check if cert file exists, if so, wipe and import data - if [ -f /etc/letsencrypt/live/${rootdomain}/fullchain.pem ]; then - sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/fullchain.pem 2>&1 | tee -a "${currentlog}" + if [ -f /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem ]; then + sudo truncate -s 0 /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem 2>&1 | tee -a "${currentlog}" fi - sudo vim /etc/letsencrypt/live/${rootdomain}/fullchain.pem 2>&1 | tee -a "${currentlog}" + sudo vim /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem 2>&1 | tee -a "${currentlog}" # Check if key file exists, if so, wipe and import data - if [ -f /etc/letsencrypt/live/${rootdomain}/privkey.pem ]; then - sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/privkey.pem 2>&1 | tee -a "${currentlog}" + if [ -f /etc/letsencrypt/live/"${rootdomain}"/privkey.pem ]; then + sudo truncate -s 0 /etc/letsencrypt/live/"${rootdomain}"/privkey.pem 2>&1 | tee -a "${currentlog}" fi - sudo vim /etc/letsencrypt/live/${rootdomain}/privkey.pem 2>&1 | tee -a "${currentlog}" + sudo vim /etc/letsencrypt/live/"${rootdomain}"/privkey.pem 2>&1 | tee -a "${currentlog}" # Check if ca file exists, if so, wipe and import data - if [ -f /etc/letsencrypt/live/${rootdomain}/chain.pem ]; then - sudo truncate -s 0 /etc/letsencrypt/live/${rootdomain}/chain.pem 2>&1 | tee -a "${currentlog}" + if [ -f /etc/letsencrypt/live/"${rootdomain}"/chain.pem ]; then + sudo truncate -s 0 /etc/letsencrypt/live/"${rootdomain}"/chain.pem 2>&1 | tee -a "${currentlog}" fi - sudo vim /etc/letsencrypt/live/${rootdomain}/chain.pem 2>&1 | tee -a "${currentlog}" + sudo vim /etc/letsencrypt/live/"${rootdomain}"/chain.pem 2>&1 | tee -a "${currentlog}" # Fix dir/file perms and ownership - sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo chown root:"${USER}" -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" } @@ -70,18 +70,18 @@ generateCerts() echo -e "\n${GREEN} Getting wildcard certificate... ${NC}\n" | tee -a "${currentlog}" # Get initial DNS text entry - sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email 2>&1 | tee -a "${currentlog}" + sudo certbot certonly --manual -d *."${rootdomain}" --agree-tos --no-bootstrap --preferred-challenges dns -m "${letsemail}" --no-eff-email 2>&1 | tee -a "${currentlog}" # Ensure TXT record has populated acmeChallengeCheck "$rootdomain"; # Keep going until successful cert issue after adding DNS txt entry while [[ $? -ne 0 ]]; do - sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email 2>&1 | tee -a "${currentlog}" + sudo certbot certonly --manual -d *."${rootdomain}" --agree-tos --no-bootstrap --preferred-challenges dns -m "${letsemail}" --no-eff-email 2>&1 | tee -a "${currentlog}" done # Fix dir/file perms and ownership - sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo chown root:"${USER}" -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" # Webroot method @@ -109,7 +109,7 @@ generateCerts() sudo systemctl start nginx 2>&1 | tee -a "${currentlog}" # Get webroot certs - sudo certbot certonly --webroot --webroot-path /var/www/letsencrypt/ --agree-tos -m ${letsemail} --no-eff-email -d ${rmmdomain} -d ${frontenddomain} -d ${meshdomain} 2>&1 | tee -a "${currentlog}" + sudo certbot certonly --webroot --webroot-path /var/www/letsencrypt/ --agree-tos -m "${letsemail}" --no-eff-email -d "${rmmdomain}" -d "${frontenddomain}" -d "${meshdomain}" 2>&1 | tee -a "${currentlog}" # Stop nginx sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" @@ -127,13 +127,13 @@ generateCerts() # Create dns type folder if it doesn't exist if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then - sudo mkdir -p /etc/letsencrypt/live/${rootdomain} 2>&1 | tee -a "${currentlog}" + sudo mkdir -p /etc/letsencrypt/live/"${rootdomain}" 2>&1 | tee -a "${currentlog}" fi # Create symlinks so cert paths don't need to be edited - sudo ln -s /etc/letsencrypt/live/${rmmdomain}/fullchain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem 2>&1 | tee -a "${currentlog}" - sudo ln -s /etc/letsencrypt/live/${rmmdomain}/privkey.pem /etc/letsencrypt/live/${rootdomain}/privkey.pem 2>&1 | tee -a "${currentlog}" - sudo ln -s /etc/letsencrypt/live/${rmmdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/chain.pem 2>&1 | tee -a "${currentlog}" + sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/fullchain.pem /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem 2>&1 | tee -a "${currentlog}" + sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/privkey.pem /etc/letsencrypt/live/"${rootdomain}"/privkey.pem 2>&1 | tee -a "${currentlog}" + sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/chain.pem /etc/letsencrypt/live/"${rootdomain}"/chain.pem 2>&1 | tee -a "${currentlog}" # Create renewal post hook to restart services after renewal sudo echo '#!/usr/bin/env bash' | sudo tee /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh @@ -141,7 +141,7 @@ generateCerts() sudo chmod +x /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh 2>&1 | tee -a "${currentlog}" # Fix dir/file ownership and perms - sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo chown root:"${USER}" -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo systemctl start nginx 2>&1 | tee -a "${currentlog}" fi @@ -209,13 +209,13 @@ installCertbot() elif [ "$autoinstall" == "1" ]; then if [ "$certtype" == "import" ]; then if [ ! -d "/etc/letsencrypt/live/${rootdomain}" ]; then - sudo mkdir -p /etc/letsencrypt/live/${rootdomain} 2>&1 | tee -a "${currentlog}" + sudo mkdir -p /etc/letsencrypt/live/"${rootdomain}" 2>&1 | tee -a "${currentlog}" fi echo -e "\n${GREEN} Importing certificates... ${NC}\n" | tee -a "${currentlog}" - sudo cp "$sslcert" /etc/letsencrypt/live/${rootdomain}/fullchain.pem 2>&1 | tee -a "${currentlog}" - sudo cp "$sslkey" /etc/letsencrypt/live/${rootdomain}/privkey.pem 2>&1 | tee -a "${currentlog}" - sudo cp "$sslcacert" /etc/letsencrypt/live/${rootdomain}/chain.pem 2>&1 | tee -a "${currentlog}" - sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo cp "$sslcert" /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem 2>&1 | tee -a "${currentlog}" + sudo cp "$sslkey" /etc/letsencrypt/live/"${rootdomain}"/privkey.pem 2>&1 | tee -a "${currentlog}" + sudo cp "$sslcacert" /etc/letsencrypt/live/"${rootdomain}"/chain.pem 2>&1 | tee -a "${currentlog}" + sudo chown root:"${USER}" -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" elif [ "$certtype" == "webroot" ]; then echo -e "" diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 332e4ade08..713fb5911b 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -58,7 +58,7 @@ configureBackend() source /rmm/api/env/bin/activate cd /rmm/api/tacticalrmm pip install --no-cache-dir --upgrade pip 2>&1 | tee -a "${currentlog}" - pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER} 2>&1 | tee -a "${currentlog}" + pip install --no-cache-dir setuptools=="${SETUPTOOLS_VER}" wheel=="${WHEEL_VER}" 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir -r requirements.txt 2>&1 | tee -a "${currentlog}" else source /rmm/api/env/bin/activate @@ -84,7 +84,7 @@ configureBackend() source /rmm/api/env/bin/activate cd /rmm/api/tacticalrmm pip install --no-cache-dir --upgrade pip 2>&1 | tee -a "${currentlog}" - pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER} 2>&1 | tee -a "${currentlog}" + pip install --no-cache-dir setuptools=="${SETUPTOOLS_VER}" wheel=="${WHEEL_VER}" 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir -r /rmm/api/tacticalrmm/requirements.txt 2>&1 | tee -a "${currentlog}" python manage.py migrate 2>&1 | tee -a "${currentlog}" python manage.py collectstatic --no-input 2>&1 | tee -a "${currentlog}" @@ -100,7 +100,7 @@ configureBackend() source /rmm/api/env/bin/activate cd /rmm/api/tacticalrmm pip install --no-cache-dir --upgrade pip 2>&1 | tee -a "${currentlog}" - pip install --no-cache-dir setuptools==${SETUPTOOLS_VER} wheel==${WHEEL_VER} 2>&1 | tee -a "${currentlog}" + pip install --no-cache-dir setuptools=="${SETUPTOOLS_VER}" wheel=="${WHEEL_VER}" 2>&1 | tee -a "${currentlog}" pip install --no-cache-dir -r /rmm/api/tacticalrmm/requirements.txt 2>&1 | tee -a "${currentlog}" python manage.py migrate 2>&1 | tee -a "${currentlog}" python manage.py collectstatic --no-input 2>&1 | tee -a "${currentlog}" @@ -125,11 +125,11 @@ configureBackend() userconfirm="n" clear -x - python manage.py createsuperuser --username ${djangousername} --email ${letsemail} 2>&1 | tee -a "${currentlog}" + python manage.py createsuperuser --username "${djangousername}" --email "${letsemail}" 2>&1 | tee -a "${currentlog}" python manage.py create_installer_user 2>&1 | tee -a "${currentlog}" RANDBASE=$(python manage.py generate_totp) clear -x - python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain} + python manage.py generate_barcode "${RANDBASE}" "${djangousername}" "${frontenddomain}" deactivate read -n 1 -s -r -p "Press any key to continue..." echo -e "\n" @@ -308,9 +308,9 @@ configMeshUserGroup() cd /meshcentral # Create mesh user and make admin - node node_modules/meshcentral --createaccount ${meshusername} --pass ${MESHPASSWD} --email ${letsemail} 2>&1 | tee -a "${currentlog}" + node node_modules/meshcentral --createaccount "${meshusername}" --pass "${MESHPASSWD}" --email "${letsemail}" 2>&1 | tee -a "${currentlog}" sleep 1 - node node_modules/meshcentral --adminaccount ${meshusername} 2>&1 | tee -a "${currentlog}" + node node_modules/meshcentral --adminaccount "${meshusername}" 2>&1 | tee -a "${currentlog}" # Restart mesh sudo systemctl start meshcentral 2>&1 | tee -a "${currentlog}" @@ -324,7 +324,7 @@ configMeshUserGroup() done # Create mesh device group - node node_modules/meshcentral/meshctrl.js --url wss://${meshdomain} --loginuser ${meshusername} --loginpass ${MESHPASSWD} AddDeviceGroup --name TacticalRMM 2>&1 | tee -a "${currentlog}" + node node_modules/meshcentral/meshctrl.js --url wss://"${meshdomain}" --loginuser "${meshusername}" --loginpass "${MESHPASSWD}" AddDeviceGroup --name TacticalRMM 2>&1 | tee -a "${currentlog}" sleep 1 } diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index ef62111c52..856c7acc39 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -15,7 +15,7 @@ installPreReqs() if [ "$autoinstall" == "1" ]; then if [ -z "$sudopass" ]; then sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" - elif [ ! -z "$sudopass" ]; then + elif [ -n "$sudopass" ]; then echo "$sudopass" | sudo -S apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" # Remove passed sudo password from history to prevent leak #history -d $(($(history 1 | awk '{print $1}')-1)) @@ -37,14 +37,14 @@ setInstallRepos() local tempcodename="$codename" # There is no Jammy repo yet so use Focal for Ubuntu 22.04 - if ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "20.04" ]); then + if [ "$osname" == "ubuntu" ] && [ "$fullrelno" == "20.04" ]; then mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" #elif ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "22.04" ]); then # codename="focal" # mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" # codename="$tempcodename" # There is no bullseye repo yet for mongo so just use Buster on Debian 11 - elif ([ "$osname" == "debian" ] && [ $relno -eq 10 ]); then + elif [ "$osname" == "debian" ] && [ "$relno" -eq 10 ]; then mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 main" postgresql_repo="deb [arch=amd64] https://apt.postgresql.org/pub/repos/apt/ $codename-pgdg main" else @@ -124,14 +124,14 @@ installPython() else numprocs=$(nproc) cd ~ - wget https://www.python.org/ftp/python/${PYTHON_VER}/Python-${PYTHON_VER}.tgz 2>&1 | tee -a "${currentlog}" - tar -xf Python-${PYTHON_VER}.tgz 2>&1 | tee -a "${currentlog}" - cd Python-${PYTHON_VER} + wget https://www.python.org/ftp/python/"${PYTHON_VER}"/Python-"${PYTHON_VER}".tgz 2>&1 | tee -a "${currentlog}" + tar -xf Python-"${PYTHON_VER}".tgz 2>&1 | tee -a "${currentlog}" + cd Python-"${PYTHON_VER}" ./configure --enable-optimizations 2>&1 | tee -a "${currentlog}" - make -j $numprocs 2>&1 | tee -a "${currentlog}" + make -j "$numprocs" 2>&1 | tee -a "${currentlog}" sudo make altinstall 2>&1 | tee -a "${currentlog}" cd ~ - sudo rm -rf Python-${PYTHON_VER} Python-${PYTHON_VER}.tgz 2>&1 | tee -a "${currentlog}" + sudo rm -rf Python-"${PYTHON_VER}" Python-"${PYTHON_VER}".tgz 2>&1 | tee -a "${currentlog}" if [ "$1" == "devprep" ]; then # Misc functions echo -e "\n${GREEN} All Prereqs installed. ${NC}\n" | tee -a "${currentlog}" @@ -168,15 +168,15 @@ installNats() NATS_SERVER_VER=$(grep "^NATS_SERVER_VER" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') fi nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) - wget -q 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} 2>&1 | tee -a "${currentlog}" - tar -xzf ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64.tar.gz -C ${nats_tmp} 2>&1 | tee -a "${currentlog}" + wget -q 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}" 2>&1 | tee -a "${currentlog}" + tar -xzf "${nats_tmp}"/nats-server-v"${NATS_SERVER_VER}"-linux-amd64.tar.gz -C "${nats_tmp}" 2>&1 | tee -a "${currentlog}" if [ "$1" == "update" ]; then sudo rm -f /usr/local/bin/nats-server 2>&1 | tee -a "${currentlog}" fi - sudo mv ${nats_tmp}/nats-server-v${NATS_SERVER_VER}-linux-amd64/nats-server /usr/local/bin/ 2>&1 | tee -a "${currentlog}" + sudo mv "${nats_tmp}"/nats-server-v"${NATS_SERVER_VER}"-linux-amd64/nats-server /usr/local/bin/ 2>&1 | tee -a "${currentlog}" sudo chmod +x /usr/local/bin/nats-server 2>&1 | tee -a "${currentlog}" sudo chown "${USER}:${USER}" /usr/local/bin/nats-server 2>&1 | tee -a "${currentlog}" - rm -rf ${nats_tmp} 2>&1 | tee -a "${currentlog}" + rm -rf "${nats_tmp}" 2>&1 | tee -a "${currentlog}" } # Install frontend @@ -192,30 +192,26 @@ installFrontEnd() fi webtar="trmm-web-v${WEB_VERSION}.tar.gz" - wget -q https://github.com/amidaware/tacticalrmm-web/releases/download/v${WEB_VERSION}/${webtar} -O /tmp/${webtar} 2>&1 | tee -a "${currentlog}" + wget -q https://github.com/amidaware/tacticalrmm-web/releases/download/v"${WEB_VERSION}"/"${webtar}" -O /tmp/"${webtar}" 2>&1 | tee -a "${currentlog}" if [ ! -d /var/www/rmm ]; then sudo mkdir -p /var/www/rmm 2>&1 | tee -a "${currentlog}" fi - sudo tar -xzf /tmp/${webtar} -C /var/www/rmm 2>&1 | tee -a "${currentlog}" + sudo tar -xzf /tmp/"${webtar}" -C /var/www/rmm 2>&1 | tee -a "${currentlog}" echo "window._env_ = {PROD_URL: \"https://${rmmdomain}\"}" | sudo tee /var/www/rmm/dist/env-config.js > /dev/null sudo chown www-data:www-data -R /var/www/rmm/dist 2>&1 | tee -a "${currentlog}" - rm -f /tmp/${webtar} 2>&1 | tee -a "${currentlog}" + rm -f /tmp/"${webtar}" 2>&1 | tee -a "${currentlog}" } # Install Nginx installNginx() { if [ "$1" != "devinstall" ]; then - nginxdefaultconf='/etc/nginx/nginx.conf' if [ "$1" == "install" ] || [ "$1" == "devprep" ]; then sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" - sudo sed -i "/worker_rlimit_nofile.*/d" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/worker_connections.*/worker_connections 2048;/" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/\# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" - sudo sed -i "1i worker_rlimit_nofile 1000000;" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" + sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart1" ]; then # Check Nginx config if ! sudo nginx -t > /dev/null 2>&1; then @@ -225,24 +221,14 @@ installNginx() exit 1 fi elif [ "$1" == "updatepart2" ]; then - CHECK_NGINX_WORKER_CONN=$(grep "worker_connections 2048" $nginxdefaultconf) - if ! [[ $CHECK_NGINX_WORKER_CONN ]]; then - echo -e "\n${GREEN} Changing nginx worker connections to 2048 ${NC}\n" | tee -a "${currentlog}" - sudo sed -i "s/worker_connections.*/worker_connections 2048;/" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" - fi - sudo sed -i "/worker_rlimit_nofile.*/d" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/\# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" - sudo sed -i "1i worker_rlimit_nofile 1000000;" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" + sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "restore" ]; then sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" sudo rm -rf /etc/nginx 2>&1 | tee -a "${currentlog}" sudo mkdir /etc/nginx 2>&1 | tee -a "${currentlog}" - sudo tar -xzf $tmp_dir/nginx/etc-nginx.tar.gz -C /etc/nginx 2>&1 | tee -a "${currentlog}" - sudo sed -i "/worker_rlimit_nofile.*/d" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/worker_connections.*/worker_connections 2048;/" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/\# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" - sudo sed -i "1i worker_rlimit_nofile 1000000;" $nginxdefaultconf 2>&1 | tee -a "${currentlog}" + sudo tar -xzf "$tmp_dir"/nginx/etc-nginx.tar.gz -C /etc/nginx 2>&1 | tee -a "${currentlog}" + sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" # Misc functions getExistingDomainInfo; fi @@ -265,11 +251,11 @@ installMeshCentral() if [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then sudo mkdir -p /meshcentral/meshcentral-data 2>&1 | tee -a "${currentlog}" elif [ "$1" == "restore" ]; then - sudo tar -xzf $tmp_dir/meshcentral/mesh.tar.gz -C / 2>&1 | tee -a "${currentlog}" + sudo tar -xzf "$tmp_dir"/meshcentral/mesh.tar.gz -C / 2>&1 | tee -a "${currentlog}" fi sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" cd /meshcentral - npm install meshcentral@${MESH_VER} 2>&1 | tee -a "${currentlog}" + npm install meshcentral@"${MESH_VER}" 2>&1 | tee -a "${currentlog}" sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" } diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 80aad230c9..8fd3f9c501 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -71,7 +71,7 @@ checkScriptVer() { # create temp file and download current script to use for comparison TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") - curl -s -L "$2" > ${TMP_FILE} 2>&1 | tee -a "${currentlog}" + curl -s -L "$2" > "$TMP_FILE" 2>&1 | tee -a "${currentlog}" NEW_VER=$(grep "^SCRIPT_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') # download new file if available @@ -87,21 +87,22 @@ checkScriptVer() dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 clear -x fi - rm -f $TMP_FILE 2>&1 | tee -a "${currentlog}" + rm -f "$TMP_FILE" 2>&1 | tee -a "${currentlog}" exit 1 fi - rm -f $TMP_FILE 2>&1 | tee -a "${currentlog}" + rm -f "$TMP_FILE" 2>&1 | tee -a "${currentlog}" } # Check for functions updates checkCfgVer() { - local currentcfgver=$(grep "^CFG_VERSION" "$PWD/script-cfg/$2" | awk -F'[="]' '{print $3}') + local currentcfgver="" + currentcfgver=$(grep "^CFG_VERSION" "$PWD/script-cfg/$2" | awk -F'[="]' '{print $3}') # create temp file and download current file to use for comparison TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") - curl -s -L "$1/script-cfg/$2" > ${TMP_FILE} 2>&1 | tee -a "${currentlog}" + curl -s -L "$1/script-cfg/$2" > "$TMP_FILE" 2>&1 | tee -a "${currentlog}" NEW_VER=$(grep "^CFG_VERSION" "$TMP_FILE" | awk -F'[="]' '{print $3}') # download new file if available @@ -117,11 +118,11 @@ checkCfgVer() dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 clear -x fi - rm -f $TMP_FILE 2>&1 | tee -a "${currentlog}" + rm -f "$TMP_FILE" 2>&1 | tee -a "${currentlog}" exit 1 fi - rm -f $TMP_FILE 2>&1 | tee -a "${currentlog}" + rm -f "$TMP_FILE" 2>&1 | tee -a "${currentlog}" } # Check for root as user @@ -277,7 +278,8 @@ cloneScriptsRepo() # Verify repo exists verifyRepoExists() { - local repostatus=$(curl --output /dev/null --silent --write-out "%{http_code}" "$1") + local repostatus="" + repostatus=$(curl --output /dev/null --silent --write-out "%{http_code}" "$1") if [ "$repostatus" == "200" ]; then echo -e "\n${GREEN} Repo exists. ${NC}\n" | tee -a "${currentlog}" else diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index a219c30a90..f4d4d4fe2b 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -297,7 +297,7 @@ mainInstall() echo -e "${YELLOW} MeshCentral username: ${GREEN}${meshusername}${NC}" | tee -a no-peeking.log echo -e "${YELLOW} MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n" | tee -a no-peeking.log - sudo chmod 600 $PWD/no-peeking.log 2>&1 | tee -a "${currentlog}" + sudo chmod 600 "$PWD"/no-peeking.log 2>&1 | tee -a "${currentlog}" if [ "$BEHIND_NAT" = true ]; then echo -e "\n${YELLOW} Read below if your router does NOT support Hairpin NAT:${NC}\n" @@ -452,7 +452,7 @@ updateTRMM() enableMeshService "$INSTALL_TYPE"; # Cleanup - rm -f $TMP_SETTINGS 2>&1 | tee -a "${currentlog}" + rm -f "$TMP_SETTINGS" 2>&1 | tee -a "${currentlog}" # Bye-bye # Misc functions @@ -493,45 +493,45 @@ backupTRMM() sysd="/etc/systemd/system" # Create temp backup subdirectories - mkdir -p ${tmp_dir}/meshcentral/mongo 2>&1 | tee -a "${currentlog}" - mkdir ${tmp_dir}/postgres 2>&1 | tee -a "${currentlog}" - mkdir ${tmp_dir}/certs 2>&1 | tee -a "${currentlog}" - mkdir ${tmp_dir}/nginx 2>&1 | tee -a "${currentlog}" - mkdir ${tmp_dir}/systemd 2>&1 | tee -a "${currentlog}" - mkdir ${tmp_dir}/rmm 2>&1 | tee -a "${currentlog}" - mkdir ${tmp_dir}/confd 2>&1 | tee -a "${currentlog}" + mkdir -p "$tmp_dir"/meshcentral/mongo 2>&1 | tee -a "${currentlog}" + mkdir "$tmp_dir"/postgres 2>&1 | tee -a "${currentlog}" + mkdir "$tmp_dir"/certs 2>&1 | tee -a "${currentlog}" + mkdir "$tmp_dir"/nginx 2>&1 | tee -a "${currentlog}" + mkdir "$tmp_dir"/systemd 2>&1 | tee -a "${currentlog}" + mkdir "$tmp_dir"/rmm 2>&1 | tee -a "${currentlog}" + mkdir "$tmp_dir"/confd 2>&1 | tee -a "${currentlog}" # Dump Postgres database - pg_dump --dbname=postgresql://"${POSTGRES_USER}":"${POSTGRES_PW}"@127.0.0.1:5432/tacticalrmm | gzip -9 > ${tmp_dir}/postgres/db-${dt_now}.psql.gz 2>&1 | tee -a "${currentlog}" + pg_dump --dbname=postgresql://"${POSTGRES_USER}":"${POSTGRES_PW}"@127.0.0.1:5432/tacticalrmm | gzip -9 > "$tmp_dir"/postgres/db-"$dt_now".psql.gz 2>&1 | tee -a "${currentlog}" # Backup Mesh stuff - tar -czvf ${tmp_dir}/meshcentral/mesh.tar.gz --exclude=/meshcentral/node_modules /meshcentral 2>&1 | tee -a "${currentlog}" - mongodump --gzip --out=${tmp_dir}/meshcentral/mongo 2>&1 | tee -a "${currentlog}" + tar -czvf "$tmp_dir"/meshcentral/mesh.tar.gz --exclude=/meshcentral/node_modules /meshcentral 2>&1 | tee -a "${currentlog}" + mongodump --gzip --out="$tmp_dir"/meshcentral/mongo 2>&1 | tee -a "${currentlog}" # Backup certs - sudo tar -czvf ${tmp_dir}/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt . 2>&1 | tee -a "${currentlog}" + sudo tar -czvf "$tmp_dir"/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt . 2>&1 | tee -a "${currentlog}" # Backup Nginx configs - sudo tar -czvf ${tmp_dir}/nginx/etc-nginx.tar.gz -C /etc/nginx . 2>&1 | tee -a "${currentlog}" + sudo tar -czvf "$tmp_dir"/nginx/etc-nginx.tar.gz -C /etc/nginx . 2>&1 | tee -a "${currentlog}" # Backup other config files - sudo tar -czvf ${tmp_dir}/confd/etc-confd.tar.gz -C /etc/conf.d . 2>&1 | tee -a "${currentlog}" + sudo tar -czvf "$tmp_dir"/confd/etc-confd.tar.gz -C /etc/conf.d . 2>&1 | tee -a "${currentlog}" # Copy service files - sudo cp ${sysd}/rmm.service ${sysd}/celery.service ${sysd}/celerybeat.service ${sysd}/meshcentral.service ${sysd}/nats.service ${sysd}/daphne.service ${tmp_dir}/systemd/ 2>&1 | tee -a "${currentlog}" - if [ -f "${sysd}/nats-api.service" ]; then - sudo cp ${sysd}/nats-api.service ${tmp_dir}/systemd/ 2>&1 | tee -a "${currentlog}" + sudo cp "$sysd"/rmm.service "$sysd"/celery.service "$sysd"/celerybeat.service "$sysd"/meshcentral.service "$sysd"/nats.service "$sysd"/daphne.service "$tmp_dir"/systemd/ 2>&1 | tee -a "${currentlog}" + if [ -f "$sysd/nats-api.service" ]; then + sudo cp "$sysd"/nats-api.service "$tmp_dir"/systemd/ 2>&1 | tee -a "${currentlog}" fi - cat /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | gzip -9 > ${tmp_dir}/rmm/debug.log.gz 2>&1 | tee -a "${currentlog}" - cp /rmm/api/tacticalrmm/tacticalrmm/local_settings.py ${tmp_dir}/rmm/ 2>&1 | tee -a "${currentlog}" + cat /rmm/api/tacticalrmm/tacticalrmm/private/log/django_debug.log | gzip -9 > "$tmp_dir"/rmm/debug.log.gz 2>&1 | tee -a "${currentlog}" + cp /rmm/api/tacticalrmm/tacticalrmm/local_settings.py "$tmp_dir"/rmm/ 2>&1 | tee -a "${currentlog}" - tar -cf /rmmbackups/rmm-backup-${dt_now}.tar -C ${tmp_dir} . 2>&1 | tee -a "${currentlog}" + tar -cf /rmmbackups/rmm-backup-"$dt_now".tar -C "$tmp_dir" . 2>&1 | tee -a "${currentlog}" # Remove temp files/folders - rm -rf ${tmp_dir} 2>&1 | tee -a "${currentlog}" + rm -rf "$tmp_dir" 2>&1 | tee -a "${currentlog}" # Misc functions - echo -e "\n${GREEN} Backup saved to /rmmbackups/rmm-backup-${dt_now}.tar ${NC}\n" | tee -a "${currentlog}" + echo -e "\n${GREEN} Backup saved to /rmmbackups/rmm-backup-$dt_now.tar ${NC}\n" | tee -a "${currentlog}" return } @@ -586,8 +586,8 @@ restoreTRMM() sudo rm -rf /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo mkdir /etc/letsencrypt 2>&1 | tee -a "${currentlog}" - sudo tar -xzf $tmp_dir/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt 2>&1 | tee -a "${currentlog}" - sudo chown root:${USER} -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo tar -xzf "$tmp_dir"/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + sudo chown root:"$USER" -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" # Recreate Nginx conf files @@ -603,14 +603,14 @@ restoreTRMM() echo -e "\n${GREEN} Restoring celery configs... ${NC}\n" | tee -a "${currentlog}" sudo mkdir /etc/conf.d 2>&1 | tee -a "${currentlog}" - sudo tar -xzf $tmp_dir/confd/etc-confd.tar.gz -C /etc/conf.d 2>&1 | tee -a "${currentlog}" + sudo tar -xzf "$tmp_dir"/confd/etc-confd.tar.gz -C /etc/conf.d 2>&1 | tee -a "${currentlog}" sudo chown "${USER}:${USER}" -R /etc/conf.d 2>&1 | tee -a "${currentlog}" # Restoring services # Misc functions echo -e "\n${GREEN} Restoring systemd services... ${NC}\n" | tee -a "${currentlog}" - sudo cp $tmp_dir/systemd/* /etc/systemd/system/ 2>&1 | tee -a "${currentlog}" + sudo cp "$tmp_dir"/systemd/* /etc/systemd/system/ 2>&1 | tee -a "${currentlog}" sudo systemctl daemon-reload 2>&1 | tee -a "${currentlog}" # Install Python @@ -640,7 +640,7 @@ restoreTRMM() # Restore Mongo database # Misc functions echo -e "\n${GREEN} Restoring MongoDB... ${NC}\n" | tee -a "${currentlog}" - mongorestore --gzip $tmp_dir/meshcentral/mongo 2>&1 | tee -a "${currentlog}" + mongorestore --gzip "$tmp_dir"/meshcentral/mongo 2>&1 | tee -a "${currentlog}" # Clone main repo # Misc functions @@ -673,10 +673,10 @@ restoreTRMM() createUwsgiConf; # Restoring other misc stuff - cp $tmp_dir/rmm/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/ 2>&1 | tee -a "${currentlog}" - cp $tmp_dir/rmm/env /rmm/web/.env 2>&1 | tee -a "${currentlog}" - gzip -d $tmp_dir/rmm/debug.log.gz 2>&1 | tee -a "${currentlog}" - cp $tmp_dir/rmm/django_debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/ 2>&1 | tee -a "${currentlog}" + cp "$tmp_dir"/rmm/local_settings.py /rmm/api/tacticalrmm/tacticalrmm/ 2>&1 | tee -a "${currentlog}" + cp "$tmp_dir"/rmm/env /rmm/web/.env 2>&1 | tee -a "${currentlog}" + gzip -d "$tmp_dir"/rmm/debug.log.gz 2>&1 | tee -a "${currentlog}" + cp "$tmp_dir"/rmm/django_debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/ 2>&1 | tee -a "${currentlog}" # Install NATS-API # Misc functions @@ -695,7 +695,7 @@ restoreTRMM() # Database functions createPGDB; - gzip -d $tmp_dir/postgres/*.psql.gz 2>&1 | tee -a "${currentlog}" + gzip -d "$tmp_dir"/postgres/*.psql.gz 2>&1 | tee -a "${currentlog}" PGPASSWORD="${pgpw} psql -h localhost -U ${pgusername} -d tacticalrmm -f $tmp_dir/postgres/db*.psql" # Restore Backend diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index 8ffb2399c2..793b5d1634 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -13,7 +13,7 @@ CFG_VERSION="8" getOSInfo() { osname=$(lsb_release -si); osname=${osname^} - osname=$(echo "$osname" | tr '[A-Z]' '[a-z]') + osname=$(echo "$osname" | tr '[:upper:]' '[:lower:]') fullrel=$(lsb_release -sd) codename=$(lsb_release -sc) relno=$(lsb_release -sr | cut -d. -f1) @@ -32,7 +32,7 @@ wutOSThis() # Verify Debian or Ubuntu and version verifySupportedOS() { - if ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "20.04" ]) || ([ "$osname" == "debian" ] && [ $relno -ge 10 ]); then + if ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "20.04" ]) || ([ "$osname" == "debian" ] && [ "$relno" -ge 10 ]); then echo -e "\n${GREEN} $fullrel ${NC}\n" | tee -a "${currentlog}" else if [ "$autoinstall" == "1" ]; then @@ -41,7 +41,7 @@ verifySupportedOS() echo -e "${RED} Your system, $fullrel, does not appear to be supported. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Exiting. ${NC}" else - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04 and 22.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 clear -x fi exit 1 @@ -70,9 +70,10 @@ checkLocale() # Check total system memory checkTotalSystemMemory() { - local totsysmemory=$(grep MemTotal /proc/meminfo | awk '{print $2 / 1024 / 1000}' | cut -d '.' -f1) + local totsysmemory="" + totsysmemory=$(grep MemTotal /proc/meminfo | awk '{print $2 / 1024 / 1000}' | cut -d '.' -f1) - if [ $totsysmemory -ge 2 ]; then + if [ "$totsysmemory" -ge 2 ]; then return else if [ "$autoinstall" == "1" ]; then @@ -96,12 +97,13 @@ checkTotalSystemMemory() # Check cpu core/thread count checkCPUAndThreadCount() { - local threadcount=$(nproc) + local threadcount="" + threadcount=$(nproc) - if [ $threadcount -ge 2 ] || [ "$autoinstall" == "1" ]; then + if [ "$threadcount" -ge 2 ] || [ "$autoinstall" == "1" ]; then return else - dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended CPU core or thread count of 2.\n\nYou may experience issues during install and use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 + dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "T-RMM is CPU intensive, and Amidaware recommends 2+ CPUs.\n\n Your system does not meet the minimum recommended CPU core or thread count of 2+.\n\nYou may experience issues during install and use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 case $? in 0 ) return;; diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index 0b80d8970f..87c77bbcde 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -12,7 +12,7 @@ CFG_VERSION="8" # Ping to test if domain is live pingDomain() { - if ( ping -c 1 $1 &> /dev/null ); then + if ( ping -c 1 "$1" &> /dev/null ); then echo -e "${GREEN} Verified $1 by ping. ${NC}\n" | tee -a "${currentlog}" else echo -e "${RED} $1 cannot be verified by ping. ${NC}\n" | tee -a "${currentlog}" @@ -25,8 +25,8 @@ checkIPisLive() # Resolve Locally used DNS server locdns=$(resolvectl | grep 'Current DNS Server:' | cut -d: -f2 | awk '{ print $1}') - locinputip=`dig @"$locdns" +short $1` - reminputip=`dig @8.8.8.8 +short $1` + locinputip=$(dig @"$locdns" +short "$1") + reminputip=$(dig @8.8.8.8 +short "$1") if [ "$locinputip" == "$reminputip" ]; then echo -e "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip} ${NC}\n" | tee -a "${currentlog}" @@ -55,7 +55,7 @@ readServicesStatus() # Verify services active checkIfServiceActive() { - if [ $1 = active ]; then + if [ "$1" = active ]; then echo -e "${GREEN} Success $2 is Running. ${NC}\n" | tee -a "${currentlog}" else echo -e "${RED} $2 is not running. \(Tactical will not work without this\) ${NC}\n" | tee -a "${currentlog}" @@ -65,7 +65,7 @@ checkIfServiceActive() # Check for open ports isPortOpen() { - if ( nc -zv $wanip $1 2>&1 >/dev/null ); then + if ( nc -zv "$wanip" "$1" 2>&1 >/dev/null ); then echo -e "${GREEN} $2 Port is open. ${NC}\n" | tee -a "${currentlog}" else echo -e "${YELLOW} $2 port is closed. \(you may want this if running locally only\) ${NC}\n" | tee -a "${currentlog}" @@ -79,7 +79,7 @@ checkProxy() echo -e "${YELLOW} ......this might take a while!! ${NC}" # Detect Proxy via cert - proxyext="$(openssl s_client -showcerts -servername $remapiip -connect $remapiip:443 2>/dev/null | openssl x509 -inform pem -noout -text)" + 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.1.1 -connect 127.0.1.1:443 2>/dev/null | openssl x509 -inform pem -noout -text)" if [[ "$proxyext" == "$proxyint" ]]; then @@ -104,8 +104,8 @@ checkIfCertIsValid() # SSL Certificate check # Check DNS-Manual or imported certs if [ ! -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then - cert="$(openssl verify -partial_chain -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem)" - certexp="$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/${rootdomain}/fullchain.pem | cut -d "=" -f2)" + cert="$(openssl verify -partial_chain -CAfile /etc/letsencrypt/live/"${rootdomain}"/chain.pem /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem)" + certexp="$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem | cut -d "=" -f2)" if [[ "$cert" == *"OK"* ]]; then echo -e "${GREEN} SSL Certificate for $rootdomain is fine. ${NC}\n" | tee -a "${currentlog}" @@ -115,8 +115,8 @@ checkIfCertIsValid() fi # Check Webroot authenticated certs elif [ -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then - cert="$(openssl verify -partial_chain -CAfile /etc/letsencrypt/live/${rootdomain}/chain.pem /etc/letsencrypt/live/${rootdomain}/fullchain.pem)" - certexp="$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/${rootdomain}/fullchain.pem | cut -d "=" -f2)" + cert="$(openssl verify -partial_chain -CAfile /etc/letsencrypt/live/"${rootdomain}"/chain.pem /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem)" + certexp="$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem | cut -d "=" -f2)" if [[ "$cert" == *"OK"* ]]; then echo -e "${GREEN} SSL Certificate for $rmmdomain , $frontenddomain , and $meshdomain is fine. ${NC}\n" | tee -a "${currentlog}" diff --git a/script-cfg/UpdateRestoreFunctions.cfg b/script-cfg/UpdateRestoreFunctions.cfg index 1370f6134d..b757f01e32 100644 --- a/script-cfg/UpdateRestoreFunctions.cfg +++ b/script-cfg/UpdateRestoreFunctions.cfg @@ -16,20 +16,20 @@ checkSameUser() if [ "$1" == "update" ]; then ORIGUSER=$(grep ${strip} /etc/systemd/system/rmm.service | sed -e "s/^${strip}//") elif [ "$1" == "restore" ]; then - ORIGUSER=$(grep ${strip} $tmp_dir/systemd/rmm.service | sed -e "s/^${strip}//") + ORIGUSER=$(grep ${strip} "$tmp_dir"/systemd/rmm.service | sed -e "s/^${strip}//") fi if [ "$ORIGUSER" != "$USER" ]; then if [ "$autoinstall" == "1" ]; then echo -e "${RED} You must run this update script from the same user account used during install: ${ORIGUSER} ${NC}" | tee -a "${currentlog}" echo -e "${RED} Exiting... ${NC}" | tee -a "${currentlog}" if [ "$1" == "restore" ]; then - rm -rf $tmp_dir 2>&1 | tee -a "${currentlog}" + rm -rf "$tmp_dir" 2>&1 | tee -a "${currentlog}" fi exit 1 elif [ "$autoinstall" != "1" ]; then dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "You must run this update script from the same user account used during install: ${ORIGUSER}\n\nExiting." 0 0 if [ "$1" == "restore" ]; then - rm -rf $tmp_dir 2>&1 | tee -a "${currentlog}" + rm -rf "$tmp_dir" 2>&1 | tee -a "${currentlog}" fi clear -x exit 1 @@ -41,14 +41,14 @@ checkSameUser() checkIfUpdate() { TMP_SETTINGS=$(mktemp -p "" "rmmsettings_XXXXXXXXXX") - curl -s -L "${LATEST_SETTINGS_URL}" > ${TMP_SETTINGS} + curl -s -L "${LATEST_SETTINGS_URL}" > "$TMP_SETTINGS" LATEST_TRMM_VER=$(grep "^TRMM_VERSION" "$TMP_SETTINGS" | awk -F'[= "]' '{print $5}') CURRENT_TRMM_VER=$(grep "^TRMM_VERSION" "$SETTINGS_FILE" | awk -F'[= "]' '{print $5}') if [ "${CURRENT_TRMM_VER}" == "${LATEST_TRMM_VER}" ] && [ "$UPDATE_TYPE" == "standard" ]; then echo -e "${GREEN} Already on latest version. Current version:${NC} ${YELLOW}${CURRENT_TRMM_VER}${NC} ${GREEN}Latest version:${NC} ${YELLOW}${LATEST_TRMM_VER} ${NC}" | tee -a "${currentlog}" - rm -f $TMP_SETTINGS 2>&1 | tee -a "${currentlog}" + rm -f "$TMP_SETTINGS" 2>&1 | tee -a "${currentlog}" exit 0 fi } @@ -66,7 +66,7 @@ checkAdditionalAppsVers() checkNatsLimitNoFile() { CHECK_NATS_LIMITNOFILE=$(grep LimitNOFILE /etc/systemd/system/nats.service) - if ! [ $CHECK_NATS_LIMITNOFILE ]; then + if ! [ "$CHECK_NATS_LIMITNOFILE" ]; then sudo rm -f /etc/systemd/system/nats.service 2>&1 | tee -a "${currentlog}" # Config and Service functions createNatsService; @@ -93,7 +93,7 @@ updateMeshCentral() sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" cd /meshcentral rm -rf node_modules/ 2>&1 | tee -a "${currentlog}" - npm install meshcentral@${LATEST_MESH_VER} 2>&1 | tee -a "${currentlog}" + npm install meshcentral@"${LATEST_MESH_VER}" 2>&1 | tee -a "${currentlog}" sudo chown "${USER}:${USER}" -R /meshcentral 2>&1 | tee -a "${currentlog}" fi } @@ -132,5 +132,5 @@ extractBackup() echo -e "\n${GREEN} Unpacking backup... ${NC}\n" | tee -a "${currentlog}" tmp_dir=$(mktemp -d -t tacticalrmm-XXXXXXXXXXXXXXXXXXXXX) - tar -xf ${1} -C $tmp_dir 2>&1 | tee -a "${currentlog}" + tar -xf "$1" -C "$tmp_dir" 2>&1 | tee -a "${currentlog}" } \ No newline at end of file diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index d09c02cacd..c7b0593e65 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -20,17 +20,17 @@ generateUsersAndPass() # prompt to see if user wants to manually enter info or have it generated if [ "$autoinstall" == "1" ]; then 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) + pgusername=$(cat /dev/urandom | tr -dc '[:lower:]' | 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) + meshusername=$(cat /dev/urandom | tr -dc '[:lower:]' | fold -w 8 | head -n 1) else dialog --cr-wrap --clear --yes-label "Automatic" --no-label "Manual" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "User and Password Generation" --yesno "Would you like to have Postgresql and MeshCentral usernames and passwords automatically randomly generated, or enter your own manually?" 0 0 case $? in # auto gen info for user 0 ) 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) + pgusername=$(cat /dev/urandom | tr -dc '[:lower:]' | 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) + meshusername=$(cat /dev/urandom | tr -dc '[:lower:]' | fold -w 8 | head -n 1) clear -x;; 1 ) userconfirm="n" @@ -124,7 +124,7 @@ rootDomainFormatCheck() # Check host/domain entries exist in DNS checkDNSEntriesExist() { - if [[ $(dig +noall +answer $1) ]] 2>/dev/null; then + if [[ $(dig +noall +answer "$1") ]] 2>/dev/null; then echo -e "${GREEN} DNS record for $1 exists. ${NC}" | tee -a "${currentlog}" else echo -e "${RED} Error: $1 does not resolve via DNS. ${NC}" | tee -a "${currentlog}" @@ -151,10 +151,10 @@ checkCertExists() getEmailAddress() { # Get Admin email - while [[ $letsemail != *[@]*[.]* ]]; do + while [[ "$letsemail" != *[@]*[.]* ]]; do letsemail=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Admin E-Mail Address" --inputbox "Enter a valid e-mail address for Django, MeshCentral, and LetsEncrypt:" 10 90 3>&1 1>&2 2>&3) letsemail="$(translateToLowerCase $letsemail)" - if [[ $letsemail != *[@]*[.]* ]]; then + if [[ "$letsemail" != *[@]*[.]* ]]; then derpDerp; dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "The e-mail address you entered is not correctly formatted.\n\nPlease try again." 0 0 fi @@ -167,7 +167,7 @@ getHostAndDomainInfo() if [ "$autoinstall" != "1" ]; then hostsconfirm="n" - until [ $hostsconfirm == "y" ]; do + until [ "$hostsconfirm" == "y" ]; do rootdomain="none" letsemail="none" local dnsgood="n" @@ -186,7 +186,7 @@ getHostAndDomainInfo() done # Get backend hostname - until [ $dnsgood == "y" ]; do + until [ "$dnsgood" == "y" ]; do rmmhost=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Enter Backend Hostname" --inputbox "Enter the hostname for the backend (e.g. api):" 10 90 3>&1 1>&2 2>&3) rmmhost="$(translateToLowerCase $rmmhost)" if [[ $(grep "\." <<< "$rmmhost") ]] 2>/dev/null; then @@ -195,7 +195,7 @@ getHostAndDomainInfo() dnsgood="n" else rmmdomain="$rmmhost.$rootdomain" - if [[ $(dig +noall +answer $rmmdomain) ]] 2>/dev/null; then + if [[ $(dig +noall +answer "$rmmdomain") ]] 2>/dev/null; then dnsgood="y" else derpDerp; @@ -216,7 +216,7 @@ getHostAndDomainInfo() dnsgood="n" else frontenddomain="$frontendhost.$rootdomain" - if [[ $(dig +noall +answer $frontenddomain) ]] 2>/dev/null; then + if [[ $(dig +noall +answer "$frontenddomain") ]] 2>/dev/null; then dnsgood="y" else derpDerp; @@ -237,7 +237,7 @@ getHostAndDomainInfo() dnsgood="n" else meshdomain="$meshhost.$rootdomain" - if [[ $(dig +noall +answer $meshdomain) ]] 2>/dev/null; then + if [[ $(dig +noall +answer "$meshdomain") ]] 2>/dev/null; then dnsgood="y" else derpDerp; From 461e862e3edbd4801556b8d411a8348c7b3b9f3b Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 15 Jul 2022 09:51:44 -0500 Subject: [PATCH 176/203] cleaned up extra whitespaces --- script-cfg/ConfigAndServiceFunctions.cfg | 1 - script-cfg/InstallFunctions.cfg | 6 +++--- script-cfg/MiscFunctions.cfg | 2 +- script-cfg/ParentFunctions.cfg | 4 ++-- script-cfg/TroubleshootingFunctions.cfg | 2 +- script-cfg/UserInput.cfg | 2 +- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/ConfigAndServiceFunctions.cfg index 713fb5911b..3a10ed82d4 100644 --- a/script-cfg/ConfigAndServiceFunctions.cfg +++ b/script-cfg/ConfigAndServiceFunctions.cfg @@ -292,7 +292,6 @@ enableMeshService() # Generate Mesh Token generateMeshToken() { - # MESHTOKENKEY="$(node /meshcentral/node_modules/meshcentral --logintokenkey)" sudo sed -i '$ a MESH_TOKEN_KEY = "MESHTOKENKEY"' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/InstallFunctions.cfg index 856c7acc39..7b2dc3ec36 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/InstallFunctions.cfg @@ -209,8 +209,8 @@ installNginx() { if [ "$1" != "devinstall" ]; then if [ "$1" == "install" ] || [ "$1" == "devprep" ]; then - sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" - sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" + sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" + sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart1" ]; then # Check Nginx config @@ -224,7 +224,7 @@ installNginx() sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "restore" ]; then sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" - sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" + sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" sudo rm -rf /etc/nginx 2>&1 | tee -a "${currentlog}" sudo mkdir /etc/nginx 2>&1 | tee -a "${currentlog}" sudo tar -xzf "$tmp_dir"/nginx/etc-nginx.tar.gz -C /etc/nginx 2>&1 | tee -a "${currentlog}" diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/MiscFunctions.cfg index 8fd3f9c501..e76289e5ae 100644 --- a/script-cfg/MiscFunctions.cfg +++ b/script-cfg/MiscFunctions.cfg @@ -343,7 +343,7 @@ decideMainRepos() # Check for new functions versions, include url, filename, and script name as variables for i in "${cfgfiles[@]}" do - checkCfgVer "$CFG_URL" "$i" "$THIS_SCRIPT"; + checkCfgVer "$CFG_URL" "$i" "$THIS_SCRIPT"; done # Check for new script version, pass script version, url, and script name variables in that order checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/ParentFunctions.cfg index f4d4d4fe2b..d9dbdf47dc 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/ParentFunctions.cfg @@ -89,7 +89,7 @@ mainInstall() echo -e "\n${GREEN} Cloning primary repo... ${NC}\n" | tee -a "${currentlog}" # Misc functions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; - + # Clone scripts repo # Misc functions echo -e "\n${GREEN} Cloning community scripts repo... ${NC}\n" | tee -a "${currentlog}" @@ -107,7 +107,7 @@ mainInstall() echo -e "\n${GREEN} Installing MeshCentral... ${NC}\n" | tee -a "${currentlog}" # InstallFunctions installMeshCentral "$INSTALL_TYPE"; - + # Create MeshCentral config # Misc functions echo -e "\n${GREEN} Generating MeshCentral Config... ${NC}\n" | tee -a "${currentlog}" diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/TroubleshootingFunctions.cfg index 87c77bbcde..02b1dcab32 100644 --- a/script-cfg/TroubleshootingFunctions.cfg +++ b/script-cfg/TroubleshootingFunctions.cfg @@ -31,7 +31,7 @@ checkIPisLive() if [ "$locinputip" == "$reminputip" ]; then echo -e "${GREEN} Success $1 is Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip} ${NC}\n" | tee -a "${currentlog}" else - echo -e "${YELLOW} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip} ${NC}\n" | tee -a "${currentlog}" + echo -e "${YELLOW} Locally Resolved: ${locinputip} Remotely Resolved: ${reminputip} ${NC}\n" | tee -a "${currentlog}" echo -e "${YELLOW} Your Local and Remote IP for $1 all agents will require non-public DNS to find TRMM server. ${NC}\n" | tee -a "${currentlog}" fi } diff --git a/script-cfg/UserInput.cfg b/script-cfg/UserInput.cfg index c7b0593e65..0af97984de 100644 --- a/script-cfg/UserInput.cfg +++ b/script-cfg/UserInput.cfg @@ -128,7 +128,7 @@ checkDNSEntriesExist() echo -e "${GREEN} DNS record for $1 exists. ${NC}" | tee -a "${currentlog}" else echo -e "${RED} Error: $1 does not resolve via DNS. ${NC}" | tee -a "${currentlog}" - echo -e "${RED} Please correct the issue and run $THIS_SCRIPT again. ${NC}" + echo -e "${RED} Please correct the issue and run $THIS_SCRIPT again. ${NC}" echo -e "${RED} Exiting... ${NC}" exit 1 fi From a99283afeff230396baa5f940bc97a153440adb1 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 15 Jul 2022 10:04:52 -0500 Subject: [PATCH 177/203] Updates to error text --- installer-util.sh | 68 +++++++++++++++--------------- script-cfg/SystemInfoFunctions.cfg | 10 ++--- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/installer-util.sh b/installer-util.sh index 761e935d94..b32efc3251 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -104,7 +104,7 @@ setColors; while getopts i:a:b:c:e:d:m:f:g:h:k:s:p:r:o:t:u:n:w: option do case $option in - i) autoinstall="1" + i) autoinstall="1" INSTALL_TYPE="$(translateToLowerCase ${OPTARG})";; a) rmmhost="$(translateToLowerCase ${OPTARG})";; b) BRANCH="$(translateToLowerCase ${OPTARG})";; @@ -125,7 +125,7 @@ do u) UPDATE_TYPE="$(translateToLowerCase ${OPTARG})";; n) trmmuser="${OPTARG}";; w) certtype="$(translateToLowerCase ${OPTARG})";; - \?) echo -e "Error: Invalid option" + \?) echo -e "Error: Invalid option" helpText exit 1;; esac @@ -287,25 +287,25 @@ sudo systemctl restart systemd-journald.service 2>&1 | tee -a "${currentlog}" # Installation menu installMenu() { - until [ "$menuselection" = "0" ]; do + until [ "$menuselection" = "0" ]; do dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Installation Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections.\n\nSelect Return to return to the previous menu." 0 0 0 \ 1 "${installmenuoptions[0]}" \ - 2 "${installmenuoptions[1]}" \ - 3 "${installmenuoptions[2]}" \ - 4 "${installmenuoptions[3]}" \ + 2 "${installmenuoptions[1]}" \ + 3 "${installmenuoptions[2]}" \ + 4 "${installmenuoptions[3]}" \ 5 "${installmenuoptions[4]}" 2>"${INPUT}" menuselection=$(<"${INPUT}") case $menuselection in 1 ) INSTALL_TYPE="install" - mainInstall;; - 2 ) INSTALL_TYPE="devprep" - mainInstall;; - 3 ) INSTALL_TYPE="devinstall" - decideMainRepos - mainInstall;; - 4 ) return;; + mainInstall;; + 2 ) INSTALL_TYPE="devprep" + mainInstall;; + 3 ) INSTALL_TYPE="devinstall" + decideMainRepos + mainInstall;; + 4 ) return;; 5 ) [ -f $INPUT ] && rm $INPUT clear -x exit;; @@ -319,13 +319,13 @@ installMenu() # Utilities menu utilityMenu() { - until [ "$menuselection" = "0" ]; do + until [ "$menuselection" = "0" ]; do dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Utility Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections.\n\nSelect Return to return to the previous menu." 0 0 0 \ 1 "${utilitymenuoptions[0]}" \ - 2 "${utilitymenuoptions[1]}" \ - 3 "${utilitymenuoptions[2]}" \ - 4 "${utilitymenuoptions[3]}" \ - 5 "${utilitymenuoptions[4]}" \ + 2 "${utilitymenuoptions[1]}" \ + 3 "${utilitymenuoptions[2]}" \ + 4 "${utilitymenuoptions[3]}" \ + 5 "${utilitymenuoptions[4]}" \ 6 "${utilitymenuoptions[5]}" \ 7 "${utilitymenuoptions[6]}" \ 8 "${utilitymenuoptions[7]}" 2>"${INPUT}" @@ -334,9 +334,9 @@ utilityMenu() case $menuselection in 1 ) backupTRMM;; - 2 ) INSTALL_TYPE="restore" + 2 ) INSTALL_TYPE="restore" restoreTRMM;; - 3 ) getHostAndDomainInfo + 3 ) getHostAndDomainInfo renewCerts;; 4 ) if [ ! -f /etc/nginx/sites-available/rmm.conf ]; then troubleshoot="1" @@ -346,8 +346,8 @@ utilityMenu() fi importCerts;; 5 ) installFail2ban;; - 6 ) troubleShoot;; - 7 ) return;; + 6 ) troubleShoot;; + 7 ) return;; 8 ) [ -f $INPUT ] && rm $INPUT clear -x exit;; @@ -361,11 +361,11 @@ utilityMenu() # Update menu updateMenu() { - until [ "$menuselection" = "0" ]; do + until [ "$menuselection" = "0" ]; do dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Update Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections.\n\nSelect Return to return to the previous menu." 0 0 0 \ 1 "${updatemenuoptions[0]}" \ - 2 "${updatemenuoptions[1]}" \ - 3 "${updatemenuoptions[2]}" \ + 2 "${updatemenuoptions[1]}" \ + 3 "${updatemenuoptions[2]}" \ 4 "${updatemenuoptions[3]}" \ 5 "${updatemenuoptions[4]}" 2>"${INPUT}" @@ -374,15 +374,15 @@ updateMenu() case $menuselection in 1 ) INSTALL_TYPE="update" UPDATE_TYPE="standard" - updateTRMM;; - 2 ) INSTALL_TYPE="update" + updateTRMM;; + 2 ) INSTALL_TYPE="update" UPDATE_TYPE="standard" backupTRMM - updateTRMM;; + updateTRMM;; 3 ) INSTALL_TYPE="update" UPDATE_TYPE="forced" - updateTRMM;; - 4 ) return;; + updateTRMM;; + 4 ) return;; 5 ) [ -f $INPUT ] && rm $INPUT clear -x exit;; @@ -425,16 +425,16 @@ mainMenu() until [ "$menuselection" = "0" ]; do dialog --cr-wrap --clear --no-ok --no-cancel --backtitle "Tactical RMM Installation and Maintenance Utility" --title "Main Menu" --menu "Use the 'Up' and 'Down' keys to navigate, and the 'Enter' key to make your selections." 0 0 0 \ 1 "${mainmenuoptions[0]}" \ - 2 "${mainmenuoptions[1]}" \ - 3 "${mainmenuoptions[2]}" \ + 2 "${mainmenuoptions[1]}" \ + 3 "${mainmenuoptions[2]}" \ 4 "${mainmenuoptions[3]}" 2>"${INPUT}" menuselection=$(<"${INPUT}") case $menuselection in 1 ) installMenu;; - 2 ) updateMenu;; - 3 ) utilityMenu;; + 2 ) updateMenu;; + 3 ) utilityMenu;; 4 ) [ -f $INPUT ] && rm $INPUT clear -x exit;; diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/SystemInfoFunctions.cfg index a7219e5e36..092a4047a0 100644 --- a/script-cfg/SystemInfoFunctions.cfg +++ b/script-cfg/SystemInfoFunctions.cfg @@ -37,11 +37,11 @@ verifySupportedOS() else if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" - echo -e "${RED} Supported versions: Ubuntu 20.04, Debian 10 and 11 ${NC}" | tee -a "${currentlog}" - echo -e "${RED} Your system, $fullrel, does not appear to be supported. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} T-RMM server supported OS versions: Ubuntu 20.04, Debian 10 and 11 ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Your OS, ${fullrel}, does not appear to be supported. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Exiting. ${NC}" else - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Supported versions: Ubuntu 20.04, Debian 10 and 11.\nYour system, $fullrel, does not appear to be supported.\n\nExiting." 0 0 + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "T-RMM server supported OS versions: Ubuntu 20.04, Debian 10 and 11.\n\nYour OS, ${fullrel}, does not appear to be supported.\n\nExiting." 0 0 clear -x fi exit 1 @@ -83,7 +83,7 @@ checkTotalSystemMemory() echo -e "${RED} Exiting... ${NC}" exit 1 elif [ "$autoinstall" != "1" ]; then - dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "System does not meet the minimum recommended RAM amount of 2GB.\n\nYou may experience issues during install.\n\nIt's recommended to exit and add RAM to the system before continuing \n\nwith installation,though you may continue with the install now if you wish." 0 0 + dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "Amidaware recommends a minimum of 2GB of RAM for a T-RMM server.\n\nYour system does not meet the minimum recommended RAM amount of 2GB.\n\nYou may experience issues during install.\n\nIt's recommended to exit and add RAM to the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 case $? in 0 ) return;; @@ -103,7 +103,7 @@ checkCPUAndThreadCount() if [ "$threadcount" -ge 2 ] || [ "$autoinstall" == "1" ]; then return else - dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "T-RMM is CPU intensive, and Amidaware recommends 2+ CPUs.\n\n Your system does not meet the minimum recommended CPU core or thread count of 2+.\n\nYou may experience issues during install and use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 + dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "T-RMM is CPU intensive, and Amidaware recommends 2+ CPUs.\n\nYour system does not meet the minimum recommended CPU core or thread count of 2+.\n\nYou may experience issues during install and use.\n\nIt's recommended to exit and upgrade the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 case $? in 0 ) return;; From 586e760d1e1b040a73343f000004afaf8c1cb5c7 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 15 Jul 2022 11:51:24 -0500 Subject: [PATCH 178/203] Change file names --- installer-util.sh | 50 ++-- ...InputAndError.cfg => 01-InputAndError.cfg} | 0 ...MiscFunctions.cfg => 02-MiscFunctions.cfg} | 0 ...nctions.cfg => 03-SystemInfoFunctions.cfg} | 0 .../{UserInput.cfg => 04-UserInput.cfg} | 0 ...kFunctions.cfg => 05-NetworkFunctions.cfg} | 0 ...lFunctions.cfg => 06-InstallFunctions.cfg} | 4 +- ...Functions.cfg => 07-DatabaseFunctions.cfg} | 0 ...ctions.cfg => 08-CertificateFunctions.cfg} | 4 +- ...s.cfg => 09-ConfigAndServiceFunctions.cfg} | 0 ...ions.cfg => 10-UpdateRestoreFunctions.cfg} | 2 +- ...ns.cfg => 11-TroubleshootingFunctions.cfg} | 0 ...ntFunctions.cfg => 12-ParentFunctions.cfg} | 259 +++++++----------- 13 files changed, 129 insertions(+), 190 deletions(-) rename script-cfg/{InputAndError.cfg => 01-InputAndError.cfg} (100%) rename script-cfg/{MiscFunctions.cfg => 02-MiscFunctions.cfg} (100%) rename script-cfg/{SystemInfoFunctions.cfg => 03-SystemInfoFunctions.cfg} (100%) rename script-cfg/{UserInput.cfg => 04-UserInput.cfg} (100%) rename script-cfg/{NetworkFunctions.cfg => 05-NetworkFunctions.cfg} (100%) rename script-cfg/{InstallFunctions.cfg => 06-InstallFunctions.cfg} (99%) rename script-cfg/{DatabaseFunctions.cfg => 07-DatabaseFunctions.cfg} (100%) rename script-cfg/{CertificateFunctions.cfg => 08-CertificateFunctions.cfg} (99%) rename script-cfg/{ConfigAndServiceFunctions.cfg => 09-ConfigAndServiceFunctions.cfg} (100%) rename script-cfg/{UpdateRestoreFunctions.cfg => 10-UpdateRestoreFunctions.cfg} (99%) rename script-cfg/{TroubleshootingFunctions.cfg => 11-TroubleshootingFunctions.cfg} (100%) rename script-cfg/{ParentFunctions.cfg => 12-ParentFunctions.cfg} (86%) diff --git a/installer-util.sh b/installer-util.sh index b32efc3251..b2dba2472a 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -12,7 +12,7 @@ declare -a mainmenuoptions=('Installation' 'Update' 'Utilities' 'Exit') declare -a installmenuoptions=('Standard Install' 'Dev Test Prereqs' 'Dev Test Install' 'Return' 'Exit') declare -a updatemenuoptions=('Standard Update' 'Backup and Update' 'Force Update' 'Return' 'Exit') declare -a utilitymenuoptions=('Backup' 'Restore' 'Renew Certs' 'Import Certs' 'Add Fail2ban - Use at your own risk' 'Run Server Troubleshooter' 'Return' 'Exit') -declare -a cfgfiles=('InputAndError.cfg' 'MiscFunctions.cfg' 'SystemInfoFunctions.cfg' 'UserInput.cfg' 'NetworkFunctions.cfg' 'InstallFunctions.cfg' 'DatabaseFunctions.cfg' 'CertificateFunctions.cfg' 'ConfigAndServiceFunctions.cfg' 'UpdateRestoreFunctions.cfg' 'TroubleshootingFunctions.cfg' 'ParentFunctions.cfg') +declare -a cfgfiles=('01-InputAndError.cfg' '02-MiscFunctions.cfg' '03-SystemInfoFunctions.cfg' '04-UserInput.cfg' '05-NetworkFunctions.cfg' '06-InstallFunctions.cfg' '07-DatabaseFunctions.cfg' '08-CertificateFunctions.cfg' '09-ConfigAndServiceFunctions.cfg' '10-UpdateRestoreFunctions.cfg' '11-TroubleshootingFunctions.cfg' '12-ParentFunctions.cfg') # Log file variables rundate="$(date '+%Y_%m_%d__%H_%M_%S')" @@ -83,18 +83,18 @@ do done # Import functions -. "$PWD"/script-cfg/InputAndError.cfg -. "$PWD"/script-cfg/MiscFunctions.cfg -. "$PWD"/script-cfg/SystemInfoFunctions.cfg -. "$PWD"/script-cfg/UserInput.cfg -. "$PWD"/script-cfg/NetworkFunctions.cfg -. "$PWD"/script-cfg/InstallFunctions.cfg -. "$PWD"/script-cfg/DatabaseFunctions.cfg -. "$PWD"/script-cfg/CertificateFunctions.cfg -. "$PWD"/script-cfg/ConfigAndServiceFunctions.cfg -. "$PWD"/script-cfg/UpdateRestoreFunctions.cfg -. "$PWD"/script-cfg/TroubleshootingFunctions.cfg -. "$PWD"/script-cfg/ParentFunctions.cfg +. "$PWD"/script-cfg/01-InputAndError.cfg +. "$PWD"/script-cfg/02-MiscFunctions.cfg +. "$PWD"/script-cfg/03-SystemInfoFunctions.cfg +. "$PWD"/script-cfg/04-UserInput.cfg +. "$PWD"/script-cfg/05-NetworkFunctions.cfg +. "$PWD"/script-cfg/06-InstallFunctions.cfg +. "$PWD"/script-cfg/07-DatabaseFunctions.cfg +. "$PWD"/script-cfg/08-CertificateFunctions.cfg +. "$PWD"/script-cfg/09-ConfigAndServiceFunctions.cfg +. "$PWD"/script-cfg/10-UpdateRestoreFunctions.cfg +. "$PWD"/script-cfg/11-TroubleshootingFunctions.cfg +. "$PWD"/script-cfg/12-ParentFunctions.cfg # Set colors # MiscFunctions @@ -225,56 +225,56 @@ if [ "$autoinstall" == "1" ]; then fi # Verify repo exists - # MiscFunctions + # 02-MiscFunctions verifyRepoExists "$SCRIPT_URL"; fi # Gather OS info -# SystemInfoFunctions +# 03-SystemInfoFunctions getOSInfo; # Install script pre-reqs -# InstallFunctions +# 06-InstallFunctions installPreReqs; # Check for new functions versions, include url, filename, and script name as variables for i in "${cfgfiles[@]}" do - # MiscFunctions + # 02-MiscFunctions checkCfgVer "$CFG_URL" "$i" "$THIS_SCRIPT"; done # Check for new script version, pass script version, url, and script name variables in that order -# MiscFunctions +# 02-MiscFunctions checkScriptVer "$SCRIPT_VERSION" "$SCRIPT_URL" "$THIS_SCRIPT"; # Install additional prereqs -# InstallFunctions +# 06-InstallFunctions installAdditionalPreReqs; # Fallback if lsb_release -si returns anything else than Ubuntu, Debian, or Raspbian -# SystemInfoFunctions +# 03-SystemInfoFunctions wutOSThis; # Verify compatible OS and version -# SystemInfoFunctions +# 03-SystemInfoFunctions verifySupportedOS; # Verify system meets minimum recommended specs -# SystemInfoFunctions +# 03-SystemInfoFunctions checkTotalSystemMemory; checkCPUAndThreadCount; # Check if root -# MiscFunctions +# 02-MiscFunctions checkRoot; # Check if Tactical user exists, if not prompt to create it -# MiscFunctions +# 02-MiscFunctions checkTacticalUser; # Check language/locale -# SystemInfoFunctions +# 03-SystemInfoFunctions checkLocale; # Prevents logging issues with some VPS providers like Vultr if this is a freshly provisioned instance that hasn't been rebooted yet diff --git a/script-cfg/InputAndError.cfg b/script-cfg/01-InputAndError.cfg similarity index 100% rename from script-cfg/InputAndError.cfg rename to script-cfg/01-InputAndError.cfg diff --git a/script-cfg/MiscFunctions.cfg b/script-cfg/02-MiscFunctions.cfg similarity index 100% rename from script-cfg/MiscFunctions.cfg rename to script-cfg/02-MiscFunctions.cfg diff --git a/script-cfg/SystemInfoFunctions.cfg b/script-cfg/03-SystemInfoFunctions.cfg similarity index 100% rename from script-cfg/SystemInfoFunctions.cfg rename to script-cfg/03-SystemInfoFunctions.cfg diff --git a/script-cfg/UserInput.cfg b/script-cfg/04-UserInput.cfg similarity index 100% rename from script-cfg/UserInput.cfg rename to script-cfg/04-UserInput.cfg diff --git a/script-cfg/NetworkFunctions.cfg b/script-cfg/05-NetworkFunctions.cfg similarity index 100% rename from script-cfg/NetworkFunctions.cfg rename to script-cfg/05-NetworkFunctions.cfg diff --git a/script-cfg/InstallFunctions.cfg b/script-cfg/06-InstallFunctions.cfg similarity index 99% rename from script-cfg/InstallFunctions.cfg rename to script-cfg/06-InstallFunctions.cfg index 7b2dc3ec36..319d94db01 100644 --- a/script-cfg/InstallFunctions.cfg +++ b/script-cfg/06-InstallFunctions.cfg @@ -133,7 +133,7 @@ installPython() cd ~ sudo rm -rf Python-"${PYTHON_VER}" Python-"${PYTHON_VER}".tgz 2>&1 | tee -a "${currentlog}" if [ "$1" == "devprep" ]; then - # Misc functions + # 02-MiscFunctions echo -e "\n${GREEN} All Prereqs installed. ${NC}\n" | tee -a "${currentlog}" exit fi @@ -229,7 +229,7 @@ installNginx() sudo mkdir /etc/nginx 2>&1 | tee -a "${currentlog}" sudo tar -xzf "$tmp_dir"/nginx/etc-nginx.tar.gz -C /etc/nginx 2>&1 | tee -a "${currentlog}" sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" - # Misc functions + # 02-MiscFunctions getExistingDomainInfo; fi fi diff --git a/script-cfg/DatabaseFunctions.cfg b/script-cfg/07-DatabaseFunctions.cfg similarity index 100% rename from script-cfg/DatabaseFunctions.cfg rename to script-cfg/07-DatabaseFunctions.cfg diff --git a/script-cfg/CertificateFunctions.cfg b/script-cfg/08-CertificateFunctions.cfg similarity index 99% rename from script-cfg/CertificateFunctions.cfg rename to script-cfg/08-CertificateFunctions.cfg index 2c6467a75b..4655104008 100644 --- a/script-cfg/CertificateFunctions.cfg +++ b/script-cfg/08-CertificateFunctions.cfg @@ -153,10 +153,10 @@ renewCerts() # generate certs and restart services certtype="dns" - # UserInput + # 04-UserInput getEmailAddress; - # MiscFunctions + # 02-MiscFunctions getExistingDomainInfo; generateCerts; diff --git a/script-cfg/ConfigAndServiceFunctions.cfg b/script-cfg/09-ConfigAndServiceFunctions.cfg similarity index 100% rename from script-cfg/ConfigAndServiceFunctions.cfg rename to script-cfg/09-ConfigAndServiceFunctions.cfg diff --git a/script-cfg/UpdateRestoreFunctions.cfg b/script-cfg/10-UpdateRestoreFunctions.cfg similarity index 99% rename from script-cfg/UpdateRestoreFunctions.cfg rename to script-cfg/10-UpdateRestoreFunctions.cfg index b757f01e32..60c751c5db 100644 --- a/script-cfg/UpdateRestoreFunctions.cfg +++ b/script-cfg/10-UpdateRestoreFunctions.cfg @@ -68,7 +68,7 @@ checkNatsLimitNoFile() CHECK_NATS_LIMITNOFILE=$(grep LimitNOFILE /etc/systemd/system/nats.service) if ! [ "$CHECK_NATS_LIMITNOFILE" ]; then sudo rm -f /etc/systemd/system/nats.service 2>&1 | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createNatsService; sudo systemctl daemon-reload 2>&1 | tee -a "${currentlog}" fi diff --git a/script-cfg/TroubleshootingFunctions.cfg b/script-cfg/11-TroubleshootingFunctions.cfg similarity index 100% rename from script-cfg/TroubleshootingFunctions.cfg rename to script-cfg/11-TroubleshootingFunctions.cfg diff --git a/script-cfg/ParentFunctions.cfg b/script-cfg/12-ParentFunctions.cfg similarity index 86% rename from script-cfg/ParentFunctions.cfg rename to script-cfg/12-ParentFunctions.cfg index d9dbdf47dc..12f73a87ca 100644 --- a/script-cfg/ParentFunctions.cfg +++ b/script-cfg/12-ParentFunctions.cfg @@ -16,162 +16,138 @@ mainInstall() currentlog="${installlog}" # Repo info for Postegres and Mongo - # InstallFunctions + # 06-InstallFunctions setInstallRepos; # Create usernames and passwords - # User Input + # 04-UserInput generateUsersAndPass "$INSTALL_TYPE"; # Clear screen clear -x # Get host/domain info - # User Input + # 04-UserInput getHostAndDomainInfo; # Configure hosts file - # Misc functions echo -e "\n${GREEN} Configuring Hosts file... ${NC}\n" | tee -a "${currentlog}" - # Network functions + # 05-NetworkFunctions configHosts "$INSTALL_TYPE"; # Certificate generation - # Misc functions echo -e "\n${GREEN} Installing Certbot... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installCertbot "$INSTALL_TYPE"; # Install Nginx - # Misc functions echo -e "\n${GREEN} Installing Nginx... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installNginx "$INSTALL_TYPE"; # Install NodeJS - # Misc functions echo -e "\n${GREEN} Installing NodeJS... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installNodeJS "$INSTALL_TYPE"; # Install and enable MongoDB - # Misc functions echo -e "\n${GREEN} Installing MongoDB... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installMongo "$INSTALL_TYPE"; # Install Python - # Misc functions echo -e "\n${GREEN} Installing Python ${PYTHON_VER}... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installPython "$INSTALL_TYPE"; # Installing Redis - # Misc functions echo -e "\n${GREEN} Installing redis... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installRedis; # Install and enable Postgresql - # Misc functions echo -e "\n${GREEN} Installing postgresql... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installPostgresql; # Postgres DB creation - # Misc functions echo -e "\n${GREEN} Creating database for the rmm... ${NC}\n" | tee -a "${currentlog}" - # Database functions + # 07-DatabaseFunctions createPGDB; # Clone main repo - # Misc functions echo -e "\n${GREEN} Cloning primary repo... ${NC}\n" | tee -a "${currentlog}" - # Misc functions + # 02-MiscFunctions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; # Clone scripts repo - # Misc functions echo -e "\n${GREEN} Cloning community scripts repo... ${NC}\n" | tee -a "${currentlog}" - # Misc functions + # 02-MiscFunctions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; # Installing NATS - # Misc functions echo -e "\n${GREEN} Installing NATS... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installNats "$INSTALL_TYPE"; # Install MeshCentral - # Misc functions echo -e "\n${GREEN} Installing MeshCentral... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installMeshCentral "$INSTALL_TYPE"; # Create MeshCentral config - # Misc functions echo -e "\n${GREEN} Generating MeshCentral Config... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createMeshConfig; # Create local settings file - # Misc functions echo -e "\n${GREEN} Generating Local Settings... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createLocalSettings; # Install NATS-API and correct permissions - # Misc functions echo -e "\n${GREEN} Installing NATS API... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installNatsApi; # Install backend, configure primary admin user, setup admin 2fa - # Misc functions echo -e "\n${GREEN} Installing the backend... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions configureBackend "$INSTALL_TYPE"; # Create UWSGI config - # Misc functions echo -e "\n${GREEN} Creating UWSGI configuration... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createUwsgiConf; # Create RMM UWSGI systemd service - # Misc functions echo -e "\n${GREEN} Creating UWSGI service... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createUwsgiService; # Create Daphne systemd service - # Misc functions echo -e "\n${GREEN} Creating Daphne service... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createDaphneService; # Create NATS systemd service - # Misc functions echo -e "\n${GREEN} Creating NATS service... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createNatsService; # Create NATS-api systemd service - # Misc functions echo -e "\n${GREEN} Creating NATS-API service... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createNatsApiService; # Create Backend Nginx site config - # Misc functions echo -e "\n${GREEN} Creating Backend Nginx config... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createBackendNginxConf; # Create MeshCentral Nginx configuration - # Misc functions echo -e "\n${GREEN} Creating MeshCentral Nginx config... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createMeshNginxConf; # Enable Mesh and RMM sites @@ -182,30 +158,26 @@ mainInstall() sudo mkdir /etc/conf.d 2>&1 | tee -a "${currentlog}" # Create Celery systemd service - # Misc functions echo -e "\n${GREEN} Creating Celery service... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createCeleryService; # Configure Celery service - # Misc functions echo -e "\n${GREEN} Creating Celery config... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createCeleryConf; # Create CeleryBeat systemd service - # Misc functions echo -e "\n${GREEN} Creating CeleryBeat service... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createCeleryBeatService; # Correct conf dir ownership sudo chown "${USER}:${USER}" -R /etc/conf.d/ 2>&1 | tee -a "${currentlog}" # Create MeshCentral systemd service - # Misc functions echo -e "\n${GREEN} Creating MeshCentral service... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createMeshCentralService; # Update services info @@ -221,27 +193,25 @@ mainInstall() fi # Install frontend - # Misc functions echo -e "\n${GREEN} Installing the frontend... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installFrontEnd "$INSTALL_TYPE"; # Set front end Nginx config and enable - # Misc functions echo -e "\n${GREEN} Creating Frontend Nginx config... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createFrontendNginxConf; # Enable Frontend site sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf 2>&1 | tee -a "${currentlog}" # Webroot certificate fix + # 08-CertificateFunctions if [ "$certtype" == "webroot" ]; then generateCerts; fi # Enable RMM, Daphne, Celery, and Nginx services - # Misc functions echo -e "\n${GREEN} Enabling Services... ${NC}\n" | tee -a "${currentlog}" for i in rmm.service daphne.service celery.service celerybeat.service nginx @@ -253,34 +223,29 @@ mainInstall() sleep 5 # Enable MeshCentral service - # Misc functions echo -e "\n${GREEN} Starting meshcentral and waiting for it to install plugins... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions enableMeshService; # Generating MeshCentral key - # Misc functions echo -e "\n${GREEN} Generating meshcentral login token key... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions generateMeshToken; # Configuring MeshCentral admin user and device group, restart service - # Misc functions echo -e "\n${GREEN} Creating meshcentral account and group... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions configMeshUserGroup; # Enable and configure NATS service - # Misc functions echo -e "\n${GREEN} Starting NATS service... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions enableNatsService; # Disable django admin sed -i 's/ADMIN_ENABLED = True/ADMIN_ENABLED = False/g' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py 2>&1 | tee -a "${currentlog}" # Restart core services - # Misc functions echo -e "\n${GREEN} Restarting services... ${NC}\n" | tee -a "${currentlog}" for i in rmm.service daphne.service celery.service celerybeat.service @@ -290,7 +255,7 @@ mainInstall() done # Yay, we're done! - # Misc functions + # 02-MiscFunctions print_yellow "Installation complete!" echo -e "\n${YELLOW} Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n" | tee -a no-peeking.log echo -e "${YELLOW} Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n" | tee -a no-peeking.log @@ -309,7 +274,7 @@ mainInstall() echo -e "\n${GREEN} You'll also need to setup port forwarding in your router on port 443.${NC}\n" fi fi - # Misc functions + # 02-MiscFunctions print_yellow "Please refer to the github README for next steps." return @@ -322,26 +287,26 @@ updateTRMM() currentlog="${updatelog}" # Check if user is same as during installation - # UpdateRestoreFunctions + # 10-UpdateRestoreFunctions checkSameUser "$INSTALL_TYPE"; # Get current release version and check if update is necessary - # UpdateRestoreFunctions + # 10-UpdateRestoreFunctions checkIfUpdate; # Get current versions of necessary included apps - # UpdateRestoreFunctions + # 10-UpdateRestoreFunctions checkAdditionalAppsVers; # Clear screen clear -x # Check CHECK_NATS_LIMITNOFILE, whatever that means - # UpdateRestoreFunctions + # 10-UpdateRestoreFunctions checkNatsLimitNoFile; # Check Nginx config - # InstallFunctions + # 06-InstallFunctions installNginx "updatepart1"; # Stop services @@ -353,15 +318,15 @@ updateTRMM() # Rebuild uwsgi config rm -f /rmm/api/tacticalrmm/app.ini 2>&1 | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createUwsgiConf; # Check if Python is up to date, if not, update - # InstallFunctions + # 06-InstallFunctions installPython "$INSTALL_TYPE"; # Check if NATS is up to date, if not, update - # InstallFunctions + # 06-InstallFunctions installNats "$INSTALL_TYPE"; # This does stuff @@ -378,25 +343,22 @@ updateTRMM() fi # Check NodeJS version, update if needed and update MeshCentral - # Misc functions echo -e "\n${GREEN} Updating NodeJS... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installNodeJS "$INSTALL_TYPE"; # Pull domain info from existing Nginx confs - # Misc functions + # 02-MiscFunctions getExistingDomainInfo; # Update from main repo - # Misc functions echo -e "\n${GREEN} Cloning primary repo... ${NC}\n" | tee -a "${currentlog}" - # Misc functions + # 02-MiscFunctions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; # Update from community-scripts repo - # Misc functions echo -e "\n${GREEN} Cloning community scripts repo... ${NC}\n" | tee -a "${currentlog}" - # Misc functions + # 02-MiscFunctions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; # Apply updated Ownership and perms @@ -408,29 +370,29 @@ updateTRMM() sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" # Check additional Nginx settings and update - # InstallFunctions + # 06-InstallFunctions installNginx "updatepart2"; # Update Nginx conf files - # Config and Service functions + # 09-ConfigAndServiceFunctions createMeshNginxConf; - # Config and Service functions + # 09-ConfigAndServiceFunctions createFrontendNginxConf; - # Config and Service functions + # 09-ConfigAndServiceFunctions createBackendNginxConf; # Reconfigure backend - # Config and Service functions + # 09-ConfigAndServiceFunctions createCeleryConf; - # Config and Service functions + # 09-ConfigAndServiceFunctions configureBackend "$INSTALL_TYPE"; # Disable Redis append only - # UpdateRestoreFunctions + # 10-UpdateRestoreFunctions turnOffRedisAppendOnly; # Update Frontend - # InstallFunctions + # 06-InstallFunctions installFrontEnd "$INSTALL_TYPE"; # Start services @@ -446,16 +408,16 @@ updateTRMM() # Update MeshCentral if necessary updateMeshCentral; - # Config and Service functions + # 09-ConfigAndServiceFunctions createMeshConfig; - # Config and Service functions + # 09-ConfigAndServiceFunctions enableMeshService "$INSTALL_TYPE"; # Cleanup rm -f "$TMP_SETTINGS" 2>&1 | tee -a "${currentlog}" # Bye-bye - # Misc functions + # 02-MiscFunctions print_green "Update finished!" return @@ -530,7 +492,7 @@ backupTRMM() # Remove temp files/folders rm -rf "$tmp_dir" 2>&1 | tee -a "${currentlog}" - # Misc functions + echo -e "\n${GREEN} Backup saved to /rmmbackups/rmm-backup-$dt_now.tar ${NC}\n" | tee -a "${currentlog}" return @@ -543,45 +505,41 @@ restoreTRMM() currentlog="${restorelog}" # Repo info for Postegres and Mongo - # InstallFunctions + # 06-InstallFunctions setInstallRepos; # Get backup file location - # UpdateRestoreFunctions + # 10-UpdateRestoreFunctions getBackupFileLocation; # Extract backup - # UpdateRestoreFunctions + # 10-UpdateRestoreFunctions extractBackup "$backupfile"; # Check if original user - # UpdateRestoreFunctions + # 10-UpdateRestoreFunctions checkSameUser "$INSTALL_TYPE"; # Install NodeJS - # Misc functions echo -e "\n${GREEN} Installing NodeJS... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installNodeJS; # Install Nginx and restore Nginx configuration - # Misc functions echo -e "\n${GREEN} Installing Nginx and restoring configuration... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installNginx "$INSTALL_TYPE"; # Restore hosts config - # Network functions + # 05-NetworkFunctions configHosts; # Restore Certbot - # Misc functions echo -e "\n${GREEN} Installing Certbot... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installCertbot "$INSTALL_TYPE"; # Restoring existing certs - # Misc functions echo -e "\n${GREEN} Restoring certs... ${NC}\n" | tee -a "${currentlog}" sudo rm -rf /etc/letsencrypt 2>&1 | tee -a "${currentlog}" @@ -591,15 +549,14 @@ restoreTRMM() sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" # Recreate Nginx conf files - # Config and Service functions + # 09-ConfigAndServiceFunctions createMeshNginxConf; - # Config and Service functions + # 09-ConfigAndServiceFunctions createFrontendNginxConf; - # Config and Service functions + # 09-ConfigAndServiceFunctions createBackendNginxConf; # Restore Celery configs - # Misc functions echo -e "\n${GREEN} Restoring celery configs... ${NC}\n" | tee -a "${currentlog}" sudo mkdir /etc/conf.d 2>&1 | tee -a "${currentlog}" @@ -607,69 +564,58 @@ restoreTRMM() sudo chown "${USER}:${USER}" -R /etc/conf.d 2>&1 | tee -a "${currentlog}" # Restoring services - # Misc functions echo -e "\n${GREEN} Restoring systemd services... ${NC}\n" | tee -a "${currentlog}" sudo cp "$tmp_dir"/systemd/* /etc/systemd/system/ 2>&1 | tee -a "${currentlog}" sudo systemctl daemon-reload 2>&1 | tee -a "${currentlog}" # Install Python - # Misc functions echo -e "\n${GREEN} Installing Python ${PYTHON_VER}... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installPython; # Installing Redis - # Misc functions echo -e "\n${GREEN} Installing redis... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installRedis; # Install and enable Postgresql - # Misc functions echo -e "\n${GREEN} Installing postgresql... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installPostgresql; # Install and enable MongoDB - # Misc functions echo -e "\n${GREEN} Installing MongoDB... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installMongo; # Restore Mongo database - # Misc functions echo -e "\n${GREEN} Restoring MongoDB... ${NC}\n" | tee -a "${currentlog}" mongorestore --gzip "$tmp_dir"/meshcentral/mongo 2>&1 | tee -a "${currentlog}" # Clone main repo - # Misc functions echo -e "\n${GREEN} Cloning primary repo... ${NC}\n" | tee -a "${currentlog}" - # Misc functions + # 02-MiscFunctions clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; # Clone scripts repo - # Misc functions echo -e "\n${GREEN} Cloning community scripts repo... ${NC}\n" | tee -a "${currentlog}" - # Misc functions + # 02-MiscFunctions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; # Installing NATS - # Misc functions echo -e "\n${GREEN} Installing NATS... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installNats "$INSTALL_TYPE"; # Restore MeshCentral - # Misc functions echo -e "\n${GREEN} Restoring MeshCentral... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installMeshCentral "$INSTALL_TYPE"; # Restore UWSGI - # Misc functions echo -e "\n${GREEN} Restoring UWSGI configuration... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions createUwsgiConf; # Restoring other misc stuff @@ -679,41 +625,36 @@ restoreTRMM() cp "$tmp_dir"/rmm/django_debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/ 2>&1 | tee -a "${currentlog}" # Install NATS-API - # Misc functions echo -e "\n${GREEN} Installing NATS API... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installNatsApi; # Restore Postgres database - # Misc functions echo -e "\n${GREEN} Restoring the Postgres database... ${NC}\n" | tee -a "${currentlog}" 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" 2>&1 | tee -a "${currentlog}" - # Database functions + # 07-DatabaseFunctions createPGDB; gzip -d "$tmp_dir"/postgres/*.psql.gz 2>&1 | tee -a "${currentlog}" PGPASSWORD="${pgpw} psql -h localhost -U ${pgusername} -d tacticalrmm -f $tmp_dir/postgres/db*.psql" # Restore Backend - # Misc functions echo -e "\n${GREEN} Restoring the backend... ${NC}\n" | tee -a "${currentlog}" - # Config and Service functions + # 09-ConfigAndServiceFunctions configureBackend "$INSTALL_TYPE"; # Start NATS - # Misc functions echo -e "\n${GREEN} Starting NATS... ${NC}\n" | tee -a "${currentlog}" sudo systemctl enable nats.service 2>&1 | tee -a "${currentlog}" sudo systemctl start nats.service 2>&1 | tee -a "${currentlog}" # Install frontend - # Misc functions echo -e "\n${GREEN} Installing the frontend... ${NC}\n" | tee -a "${currentlog}" - # InstallFunctions + # 06-InstallFunctions installFrontEnd "$INSTALL_TYPE"; # reset perms @@ -728,7 +669,6 @@ restoreTRMM() sudo systemctl daemon-reload 2>&1 | tee -a "${currentlog}" # Enable RMM, Daphne, Celery, Nats-api, and Nginx services - # Misc functions echo -e "\n${GREEN} Enabling Services... ${NC}\n" | tee -a "${currentlog}" for i in celery.service celerybeat.service rmm.service daphne.service nats-api.service nginx @@ -740,13 +680,12 @@ restoreTRMM() sleep 5 # Start MeshCentral - # Misc functions echo -e "\n${GREEN} Starting meshcentral... ${NC}\n" | tee -a "${currentlog}" sudo systemctl enable meshcentral 2>&1 | tee -a "${currentlog}" sudo systemctl start meshcentral 2>&1 | tee -a "${currentlog}" # Done!!!! - # Misc functions + # 02-MiscFunctions print_green 'Restore complete!' return @@ -760,15 +699,15 @@ troubleShoot() # Get existing domain info if [ -f /etc/nginx/sites-available/rmm.conf ] && [ -f /etc/nginx/sites-available/rmm.conf ] && [ -f /etc/nginx/sites-available/rmm.conf ]; then - # Misc functions + # 02-MiscFunctions getExistingDomainInfo; else - # User Input + # 04-UserInput getHostAndDomainInfo; fi # Verify domains are live - # Troubleshooting functions + # 11-TroubleshootingFunctions pingDomain "$rmmdomain"; pingDomain "$frontenddomain"; pingDomain "$meshdomain"; @@ -776,18 +715,18 @@ troubleShoot() # Verify IPs echo -e "\n${GREEN} Checking IPs... ${NC}\n" | tee -a "${currentlog}" - # Troubleshooting functions + # 11-TroubleshootingFunctions checkIPisLive "$rmmdomain"; remapiip="${reminputip}" checkIPisLive "$frontenddomain"; checkIPisLive "$meshdomain"; # Get services status - # Troubleshooting functions + # 11-TroubleshootingFunctions readServicesStatus; # Verify services active - # Troubleshooting functions + # 11-TroubleshootingFunctions checkIfServiceActive "$rmmstatus" "RMM Service"; checkIfServiceActive "$daphnestatus" "Daphne Service"; checkIfServiceActive "$celerystatus" "Celery Service"; @@ -805,16 +744,16 @@ troubleShoot() echo -e "\n${GREEN} WAN IP is $wanip. ${NC}\n" | tee -a "${currentlog}" # Check if ports are open - # Troubleshooting functions + # 11-TroubleshootingFunctions isPortOpen "80" "HTTP"; isPortOpen "443" "HTTPS"; # Checking Proxy - # Troubleshooting functions + # 11-TroubleshootingFunctions checkProxy; # Check for valid cert - # Troubleshooting functions + # 11-TroubleshootingFunctions checkIfCertIsValid; # Generate log summary @@ -824,7 +763,7 @@ troubleShoot() echo -e "\n" | tee -a "${currentlog}" tail /rmm/api/tacticalrmm/tacticalrmm/private/log/error.log | tee -a "${currentlog}" echo -e "\n" | tee -a "${currentlog}" - # Misc functions + # 02-MiscFunctions print_yellow "You will have a log file called checklog_$rundate.log in the directory you ran this script from." return From 040305f3da2109b49a0cc2a0fc1559a3b0bef3d5 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 15 Jul 2022 12:18:06 -0500 Subject: [PATCH 179/203] Added backups for existing nginx confs --- script-cfg/06-InstallFunctions.cfg | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/script-cfg/06-InstallFunctions.cfg b/script-cfg/06-InstallFunctions.cfg index 319d94db01..4beeea75ff 100644 --- a/script-cfg/06-InstallFunctions.cfg +++ b/script-cfg/06-InstallFunctions.cfg @@ -211,6 +211,7 @@ installNginx() if [ "$1" == "install" ] || [ "$1" == "devprep" ]; then sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak 2>&1 | tee -a "${currentlog}" sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart1" ]; then # Check Nginx config @@ -221,6 +222,10 @@ installNginx() exit 1 fi elif [ "$1" == "updatepart2" ]; then + sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-available/rmm.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-available/frontend.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "restore" ]; then sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" @@ -228,6 +233,10 @@ installNginx() sudo rm -rf /etc/nginx 2>&1 | tee -a "${currentlog}" sudo mkdir /etc/nginx 2>&1 | tee -a "${currentlog}" sudo tar -xzf "$tmp_dir"/nginx/etc-nginx.tar.gz -C /etc/nginx 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-available/rmm.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-available/frontend.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" # 02-MiscFunctions getExistingDomainInfo; From 152e405c79cac957cf56b238aa39769765dce831 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 15 Jul 2022 12:46:41 -0500 Subject: [PATCH 180/203] changes to script and cfg updates --- script-cfg/02-MiscFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/02-MiscFunctions.cfg b/script-cfg/02-MiscFunctions.cfg index e76289e5ae..4eac19263a 100644 --- a/script-cfg/02-MiscFunctions.cfg +++ b/script-cfg/02-MiscFunctions.cfg @@ -76,7 +76,7 @@ checkScriptVer() # download new file if available if [ "$1" -ne "${NEW_VER}" ]; then - wget "$2" -O "$3" 2>&1 | tee -a "${currentlog}" + wget -q "$2" -O "$3" 2>&1 | tee -a "${currentlog}" if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" echo -e "${RED} Old $3 detected. ${NC}" | tee -a "${currentlog}" @@ -107,7 +107,7 @@ checkCfgVer() # download new file if available if [ "$currentcfgver" -ne "${NEW_VER}" ]; then - wget "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" 2>&1 | tee -a "${currentlog}" + wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" 2>&1 | tee -a "${currentlog}" if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" echo -e "${RED} Old $2 detected. ${NC}" | tee -a "${currentlog}" From f14131cf9d14013d423d260ccf12e6b173625578 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 15 Jul 2022 18:59:03 -0500 Subject: [PATCH 181/203] include dates in nginx backups --- script-cfg/06-InstallFunctions.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script-cfg/06-InstallFunctions.cfg b/script-cfg/06-InstallFunctions.cfg index 4beeea75ff..0a0dc31019 100644 --- a/script-cfg/06-InstallFunctions.cfg +++ b/script-cfg/06-InstallFunctions.cfg @@ -222,7 +222,7 @@ installNginx() exit 1 fi elif [ "$1" == "updatepart2" ]; then - sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-available/rmm.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-available/frontend.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" @@ -233,7 +233,7 @@ installNginx() sudo rm -rf /etc/nginx 2>&1 | tee -a "${currentlog}" sudo mkdir /etc/nginx 2>&1 | tee -a "${currentlog}" sudo tar -xzf "$tmp_dir"/nginx/etc-nginx.tar.gz -C /etc/nginx 2>&1 | tee -a "${currentlog}" - sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-available/rmm.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-available/frontend.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" From 8150898311f1c021d4089b354b09b0f627099b60 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 16 Jul 2022 18:32:35 -0500 Subject: [PATCH 182/203] Added date to nginx.conf install backup --- script-cfg/06-InstallFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/06-InstallFunctions.cfg b/script-cfg/06-InstallFunctions.cfg index 0a0dc31019..5ecfba7753 100644 --- a/script-cfg/06-InstallFunctions.cfg +++ b/script-cfg/06-InstallFunctions.cfg @@ -211,7 +211,7 @@ installNginx() if [ "$1" == "install" ] || [ "$1" == "devprep" ]; then sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" - sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart1" ]; then # Check Nginx config From 2155f45bc4c43d3abada70fcf0566bae47d10c8c Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 16 Jul 2022 18:37:46 -0500 Subject: [PATCH 183/203] Update to nginx.conf default file --- default-configs/nginx/nginx.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default-configs/nginx/nginx.conf b/default-configs/nginx/nginx.conf index 26ea21a532..d5bfe12a52 100644 --- a/default-configs/nginx/nginx.conf +++ b/default-configs/nginx/nginx.conf @@ -20,7 +20,7 @@ http { tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; - # server_tokens off; + server_tokens off; server_names_hash_bucket_size 64; # server_name_in_redirect off; From 72d9b9a57a1cc5149aef7ee76196dcf60468e6bc Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 19 Jul 2022 10:40:40 -0500 Subject: [PATCH 184/203] Corrected repo to current branch --- installer-util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer-util.sh b/installer-util.sh index b2dba2472a..82362dcf4b 100644 --- a/installer-util.sh +++ b/installer-util.sh @@ -26,7 +26,7 @@ currentlog="$preinstalllog" # Script Info variables REPO_OWNER="ninjamonkey198206" -BRANCH="develop-installer-update-ws" +BRANCH="develop-installer-update" SCRIPT_VERSION="69" CFG_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}" SCRIPT_URL="https://raw.githubusercontent.com/${REPO_OWNER}/tacticalrmm/${BRANCH}/installer-util.sh" From 558a2fd90a3bc340bb338b23107d2a428647b4a7 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 19 Jul 2022 10:50:39 -0500 Subject: [PATCH 185/203] Moved default nginx conf config for install --- script-cfg/06-InstallFunctions.cfg | 2 -- script-cfg/09-ConfigAndServiceFunctions.cfg | 10 ++++++++++ script-cfg/12-ParentFunctions.cfg | 5 +++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/script-cfg/06-InstallFunctions.cfg b/script-cfg/06-InstallFunctions.cfg index 5ecfba7753..4743f7e6e6 100644 --- a/script-cfg/06-InstallFunctions.cfg +++ b/script-cfg/06-InstallFunctions.cfg @@ -211,8 +211,6 @@ installNginx() if [ "$1" == "install" ] || [ "$1" == "devprep" ]; then sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" - sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" - sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart1" ]; then # Check Nginx config if ! sudo nginx -t > /dev/null 2>&1; then diff --git a/script-cfg/09-ConfigAndServiceFunctions.cfg b/script-cfg/09-ConfigAndServiceFunctions.cfg index 3a10ed82d4..308b3c1837 100644 --- a/script-cfg/09-ConfigAndServiceFunctions.cfg +++ b/script-cfg/09-ConfigAndServiceFunctions.cfg @@ -184,6 +184,16 @@ createNatsApiService() sudo sed -i "s/REPLACEME/${USER}/" /etc/systemd/system/nats-api.service 2>&1 | tee -a "${currentlog}" } +# Create backend nginx conf +createDefaultNginxConf() +{ + # Backup original conf file + sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" + + # Copy default config file into place + sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" +} + # Create backend nginx conf createBackendNginxConf() { diff --git a/script-cfg/12-ParentFunctions.cfg b/script-cfg/12-ParentFunctions.cfg index 12f73a87ca..20c46b9055 100644 --- a/script-cfg/12-ParentFunctions.cfg +++ b/script-cfg/12-ParentFunctions.cfg @@ -140,6 +140,11 @@ mainInstall() # 09-ConfigAndServiceFunctions createNatsApiService; + # Create Default Nginx site config + echo -e "\n${GREEN} Creating Default Nginx config... ${NC}\n" | tee -a "${currentlog}" + # 09-ConfigAndServiceFunctions + createDefaultNginxConf; + # Create Backend Nginx site config echo -e "\n${GREEN} Creating Backend Nginx config... ${NC}\n" | tee -a "${currentlog}" # 09-ConfigAndServiceFunctions From 9025f62396bd86d5235dab131989ccce00009715 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Tue, 19 Jul 2022 12:31:02 -0500 Subject: [PATCH 186/203] merged json case change --- default-configs/mesh/config.json | 46 ++++++++++++++++---------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/default-configs/mesh/config.json b/default-configs/mesh/config.json index a288815e08..889d05d074 100644 --- a/default-configs/mesh/config.json +++ b/default-configs/mesh/config.json @@ -1,33 +1,33 @@ { "settings": { - "Cert": "mesh.example.com", - "MongoDb": "mongodb://127.0.0.1:27017", - "MongoDbName": "meshcentral", + "cert": "mesh.example.com", + "mongoDb": "mongodb://127.0.0.1:27017", + "mongoDbName": "meshcentral", "WANonly": true, - "Minify": 1, - "Port": 4443, - "AgentAliasPort": 443, - "AliasPort": 443, - "AllowLoginToken": true, - "AllowFraming": true, - "_AgentPing": 60, - "AgentPong": 300, - "AllowHighQualityDesktop": true, - "TlsOffload": "127.0.0.1", + "minify": 1, + "port": 4443, + "agentAliasPort": 443, + "aliasPort": 443, + "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 } + "compression": true, + "wsCompression": true, + "agentWsCompression": true, + "maxInvalidLogin": { "time": 5, "count": 5, "coolofftime": 30 } }, "domains": { "": { - "Title": "Tactical RMM", - "Title2": "Tactical RMM", - "NewAccounts": false, - "CertUrl": "https://mesh.example.com:443/", - "GeoLocation": true, - "CookieIpCheck": false, + "title": "Tactical RMM", + "title2": "Tactical RMM", + "newAccounts": false, + "certUrl": "https://mesh.example.com:443/", + "geoLocation": true, + "cookieIpCheck": false, "mstsc": true } } From be88cc713418c4dd13cca86d55a129cedba1d3d1 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 20 Jul 2022 13:48:50 -0500 Subject: [PATCH 187/203] Added fix from niceguyit for daphne power failure --- service-definitions/daphne.service | 2 ++ 1 file changed, 2 insertions(+) diff --git a/service-definitions/daphne.service b/service-definitions/daphne.service index a1576ad889..8fbee4fded 100644 --- a/service-definitions/daphne.service +++ b/service-definitions/daphne.service @@ -8,6 +8,8 @@ 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 +ExecStartPre=rm -f /rmm/daphne.sock +ExecStartPre=rm -f /rmm/daphne.sock.lock Restart=always RestartSec=3s From 5ef8c40dabcb845ec45840c22286f931e7cc48ac Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 20 Jul 2022 20:21:16 -0500 Subject: [PATCH 188/203] Updated nginx.conf to match ansible config --- default-configs/nginx/nginx.conf | 38 -------------------------------- 1 file changed, 38 deletions(-) diff --git a/default-configs/nginx/nginx.conf b/default-configs/nginx/nginx.conf index d5bfe12a52..6ca4f61b10 100644 --- a/default-configs/nginx/nginx.conf +++ b/default-configs/nginx/nginx.conf @@ -6,58 +6,20 @@ include /etc/nginx/modules-enabled/*.conf; events { worker_connections 2048; - # multi_accept on; } http { - - ## - # Basic Settings - ## - sendfile on; tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 65; types_hash_max_size 2048; - server_tokens off; - server_names_hash_bucket_size 64; - # server_name_in_redirect off; - include /etc/nginx/mime.types; default_type application/octet-stream; - - ## - # SSL Settings - ## - ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; - - ## - # Logging Settings - ## - access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; - - ## - # Gzip Settings - ## - gzip on; - - # gzip_vary on; - # gzip_proxied any; - # gzip_comp_level 6; - # gzip_buffers 16 8k; - # gzip_http_version 1.1; - # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; - - ## - # Virtual Host Configs - include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } \ No newline at end of file From be8b46fdf671b8d77150d23d08d8ca7adc6b9568 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 21 Jul 2022 15:42:57 -0500 Subject: [PATCH 189/203] testing env files and fix for nats json format --- api/tacticalrmm/tacticalrmm/utils.py | 2 +- script-cfg/02-MiscFunctions.cfg | 29 +++++++++++++++++++++ script-cfg/04-UserInput.cfg | 20 +++++++------- script-cfg/09-ConfigAndServiceFunctions.cfg | 4 +-- script-cfg/12-ParentFunctions.cfg | 10 ++++++- 5 files changed, 51 insertions(+), 14 deletions(-) diff --git a/api/tacticalrmm/tacticalrmm/utils.py b/api/tacticalrmm/tacticalrmm/utils.py index 12dbbd5d7d..6ddbf95e46 100644 --- a/api/tacticalrmm/tacticalrmm/utils.py +++ b/api/tacticalrmm/tacticalrmm/utils.py @@ -211,7 +211,7 @@ def reload_nats() -> None: conf = os.path.join(settings.BASE_DIR, "nats-rmm.conf") with open(conf, "w") as f: - json.dump(config, f) + json.dumps(config, f, indent=4) if not settings.DOCKER_BUILD: time.sleep(0.5) diff --git a/script-cfg/02-MiscFunctions.cfg b/script-cfg/02-MiscFunctions.cfg index 4eac19263a..a37e25ef7d 100644 --- a/script-cfg/02-MiscFunctions.cfg +++ b/script-cfg/02-MiscFunctions.cfg @@ -66,6 +66,35 @@ helpText() echo -e "w Select certificate install type. Options are ${YELLOW}import${NC} or ${YELLOW}webroot${NC}.\n" } +# Create env dirs and files +createEnvDir() +{ + if [ ! -d /etc/trmm ]; then + # Create directory + mkdir /etc/trmm 2>&1 | tee -a "${currentlog}" + sudo chown "${USER}:${USER}" /etc/trmm 2>&1 | tee -a "${currentlog}" + fi +} + +# Create env dirs and files +createSysInfoEnv() +{ + echo "RMMHOST=$rmmhost" | tee -a /etc/trmm/sysinfo.env + echo "FRONTENDHOST=$frontendhost" | tee -a /etc/trmm/sysinfo.env + echo "MESHHOST=$meshhost" | tee -a /etc/trmm/sysinfo.env + echo "ROOTDOMAIN=$rootdomain" | tee -a /etc/trmm/sysinfo.env + echo "RMMDOMAIN=$rmmdomain" | tee -a /etc/trmm/sysinfo.env + echo "FRONTENDDOMAIN=$frontenddomain" | tee -a /etc/trmm/sysinfo.env + echo "MESHDOMAIN=$meshdomain" | tee -a /etc/trmm/sysinfo.env + echo "LETSEMAIL=$letsemail" | tee -a /etc/trmm/sysinfo.env +} + +# Create env dirs and files +createUserInfoEnv() +{ + echo "TRMMUSER=$trmmuser" | tee -a /etc/trmm/userinfo.env +} + # Check for new script version checkScriptVer() { diff --git a/script-cfg/04-UserInput.cfg b/script-cfg/04-UserInput.cfg index 0af97984de..110c552d40 100644 --- a/script-cfg/04-UserInput.cfg +++ b/script-cfg/04-UserInput.cfg @@ -14,22 +14,22 @@ generateUsersAndPass() { if [ "$1" != "devprep" ]; then # generate django key and admin url - DJANGO_SEKRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1) - ADMINURL=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 70 | head -n 1) + DJANGO_SEKRET=$(cat /dev/urandom | tr -dc '[:alnum:]' | fold -w 80 | head -n 1) + ADMINURL=$(cat /dev/urandom | tr -dc '[:alnum:]' | fold -w 70 | head -n 1) # prompt to see if user wants to manually enter info or have it generated if [ "$autoinstall" == "1" ]; then - MESHPASSWD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 25 | head -n 1) + meshpasswd=$(cat /dev/urandom | tr -dc '[:alnum:]' | fold -w 25 | head -n 1) pgusername=$(cat /dev/urandom | tr -dc '[:lower:]' | fold -w 8 | head -n 1) - pgpw=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1) + pgpw=$(cat /dev/urandom | tr -dc '[:alnum:]' | fold -w 20 | head -n 1) meshusername=$(cat /dev/urandom | tr -dc '[:lower:]' | fold -w 8 | head -n 1) else dialog --cr-wrap --clear --yes-label "Automatic" --no-label "Manual" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "User and Password Generation" --yesno "Would you like to have Postgresql and MeshCentral usernames and passwords automatically randomly generated, or enter your own manually?" 0 0 case $? in # auto gen info for user - 0 ) MESHPASSWD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 25 | head -n 1) + 0 ) meshpasswd=$(cat /dev/urandom | tr -dc '[:alnum:]' | fold -w 25 | head -n 1) pgusername=$(cat /dev/urandom | tr -dc '[:lower:]' | fold -w 8 | head -n 1) - pgpw=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1) + pgpw=$(cat /dev/urandom | tr -dc '[:alnum:]' | fold -w 20 | head -n 1) meshusername=$(cat /dev/urandom | tr -dc '[:lower:]' | fold -w 8 | head -n 1) clear -x;; @@ -49,12 +49,12 @@ generateUsersAndPass() userconfirm="n" # Get MeshCentral admin password - MESHPASSWD="dont" + meshpasswd="dont" passinput="match" - until [ "$passinput" == "$MESHPASSWD" ]; do - MESHPASSWD=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) + until [ "$passinput" == "$meshpasswd" ]; do + meshpasswd=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) passinput=$(dialog --cr-wrap --no-cancel --clear --backtitle "Tactical RMM Installation and Maintenance Utility" --title "MeshCentral Admin Password" --passwordbox "Re-enter the MeshCentral Admin password you wish to use:" 10 90 3>&1 1>&2 2>&3) - if [ "$passinput" != "$MESHPASSWD" ]; then + if [ "$passinput" != "$meshpasswd" ]; then dialog --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Passwords do not match." 0 0 derpDerp; else diff --git a/script-cfg/09-ConfigAndServiceFunctions.cfg b/script-cfg/09-ConfigAndServiceFunctions.cfg index 308b3c1837..d771aff07e 100644 --- a/script-cfg/09-ConfigAndServiceFunctions.cfg +++ b/script-cfg/09-ConfigAndServiceFunctions.cfg @@ -317,7 +317,7 @@ configMeshUserGroup() cd /meshcentral # Create mesh user and make admin - node node_modules/meshcentral --createaccount "${meshusername}" --pass "${MESHPASSWD}" --email "${letsemail}" 2>&1 | tee -a "${currentlog}" + node node_modules/meshcentral --createaccount "${meshusername}" --pass "${meshpasswd}" --email "${letsemail}" 2>&1 | tee -a "${currentlog}" sleep 1 node node_modules/meshcentral --adminaccount "${meshusername}" 2>&1 | tee -a "${currentlog}" @@ -333,7 +333,7 @@ configMeshUserGroup() done # Create mesh device group - node node_modules/meshcentral/meshctrl.js --url wss://"${meshdomain}" --loginuser "${meshusername}" --loginpass "${MESHPASSWD}" AddDeviceGroup --name TacticalRMM 2>&1 | tee -a "${currentlog}" + node node_modules/meshcentral/meshctrl.js --url wss://"${meshdomain}" --loginuser "${meshusername}" --loginpass "${meshpasswd}" AddDeviceGroup --name TacticalRMM 2>&1 | tee -a "${currentlog}" sleep 1 } diff --git a/script-cfg/12-ParentFunctions.cfg b/script-cfg/12-ParentFunctions.cfg index 20c46b9055..f0261679ce 100644 --- a/script-cfg/12-ParentFunctions.cfg +++ b/script-cfg/12-ParentFunctions.cfg @@ -19,6 +19,10 @@ mainInstall() # 06-InstallFunctions setInstallRepos; + # Create ENV dir + # 02-MiscFunctions + createEnvDir; + # Create usernames and passwords # 04-UserInput generateUsersAndPass "$INSTALL_TYPE"; @@ -265,7 +269,7 @@ mainInstall() echo -e "\n${YELLOW} Access your rmm at: ${GREEN}https://${frontenddomain}${NC}\n" | tee -a no-peeking.log echo -e "${YELLOW} Django admin url (disabled by default): ${GREEN}https://${rmmdomain}/${ADMINURL}/${NC}\n" | tee -a no-peeking.log echo -e "${YELLOW} MeshCentral username: ${GREEN}${meshusername}${NC}" | tee -a no-peeking.log - echo -e "${YELLOW} MeshCentral password: ${GREEN}${MESHPASSWD}${NC}\n" | tee -a no-peeking.log + echo -e "${YELLOW} MeshCentral password: ${GREEN}${meshpasswd}${NC}\n" | tee -a no-peeking.log sudo chmod 600 "$PWD"/no-peeking.log 2>&1 | tee -a "${currentlog}" @@ -306,6 +310,10 @@ updateTRMM() # Clear screen clear -x + # Create ENV dir + # 02-MiscFunctions + createEnvDir; + # Check CHECK_NATS_LIMITNOFILE, whatever that means # 10-UpdateRestoreFunctions checkNatsLimitNoFile; From a215d0fd5b1be1beb2e412ac07e928ad9366ee93 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 21 Jul 2022 16:27:21 -0500 Subject: [PATCH 190/203] undoing utils.py change --- api/tacticalrmm/tacticalrmm/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/tacticalrmm/tacticalrmm/utils.py b/api/tacticalrmm/tacticalrmm/utils.py index 6ddbf95e46..12dbbd5d7d 100644 --- a/api/tacticalrmm/tacticalrmm/utils.py +++ b/api/tacticalrmm/tacticalrmm/utils.py @@ -211,7 +211,7 @@ def reload_nats() -> None: conf = os.path.join(settings.BASE_DIR, "nats-rmm.conf") with open(conf, "w") as f: - json.dumps(config, f, indent=4) + json.dump(config, f) if not settings.DOCKER_BUILD: time.sleep(0.5) From 218e49c825062dbcf4991b17ac8209ced348103f Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 21 Jul 2022 20:53:16 -0500 Subject: [PATCH 191/203] trying different nats py method --- api/tacticalrmm/tacticalrmm/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/tacticalrmm/tacticalrmm/utils.py b/api/tacticalrmm/tacticalrmm/utils.py index 12dbbd5d7d..c258486528 100644 --- a/api/tacticalrmm/tacticalrmm/utils.py +++ b/api/tacticalrmm/tacticalrmm/utils.py @@ -211,7 +211,7 @@ def reload_nats() -> None: conf = os.path.join(settings.BASE_DIR, "nats-rmm.conf") with open(conf, "w") as f: - json.dump(config, f) + json.dump(config, f, indent=4) if not settings.DOCKER_BUILD: time.sleep(0.5) From 244903b8369118279b534a20d3e4da402e7636ee Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Wed, 27 Jul 2022 12:05:01 -0500 Subject: [PATCH 192/203] Removing support for Debian 10 --- script-cfg/03-SystemInfoFunctions.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/script-cfg/03-SystemInfoFunctions.cfg b/script-cfg/03-SystemInfoFunctions.cfg index 092a4047a0..0895daeb94 100644 --- a/script-cfg/03-SystemInfoFunctions.cfg +++ b/script-cfg/03-SystemInfoFunctions.cfg @@ -32,16 +32,16 @@ wutOSThis() # Verify Debian or Ubuntu and version verifySupportedOS() { - if ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "20.04" ]) || ([ "$osname" == "debian" ] && [ "$relno" -ge 10 ]); then + if ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "20.04" ]) || ([ "$osname" == "debian" ] && [ "$relno" -ge 11 ]); then echo -e "\n${GREEN} $fullrel ${NC}\n" | tee -a "${currentlog}" else if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" - echo -e "${RED} T-RMM server supported OS versions: Ubuntu 20.04, Debian 10 and 11 ${NC}" | tee -a "${currentlog}" + echo -e "${RED} T-RMM server supported OS versions: Ubuntu 20.04 and Debian 11 ${NC}" | tee -a "${currentlog}" echo -e "${RED} Your OS, ${fullrel}, does not appear to be supported. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Exiting. ${NC}" else - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "T-RMM server supported OS versions: Ubuntu 20.04, Debian 10 and 11.\n\nYour OS, ${fullrel}, does not appear to be supported.\n\nExiting." 0 0 + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "T-RMM server supported OS versions: Ubuntu 20.04 and Debian 11.\n\nYour OS, ${fullrel}, does not appear to be supported.\n\nExiting." 0 0 clear -x fi exit 1 From e373473ca1ed87caea21e4c0e6317864cf0cd7fd Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Sat, 30 Jul 2022 13:28:38 -0500 Subject: [PATCH 193/203] Updated to support nginx repo and resolve issues --- default-configs/nginx/nginx.conf | 2 +- default-configs/nginx/rmm.conf | 2 +- script-cfg/03-SystemInfoFunctions.cfg | 6 +-- script-cfg/06-InstallFunctions.cfg | 53 +++++++++++++++++++-------- script-cfg/12-ParentFunctions.cfg | 30 ++++++--------- 5 files changed, 54 insertions(+), 39 deletions(-) diff --git a/default-configs/nginx/nginx.conf b/default-configs/nginx/nginx.conf index 6ca4f61b10..7412f87cfe 100644 --- a/default-configs/nginx/nginx.conf +++ b/default-configs/nginx/nginx.conf @@ -5,7 +5,7 @@ pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { - worker_connections 2048; + worker_connections 4096; } http { diff --git a/default-configs/nginx/rmm.conf b/default-configs/nginx/rmm.conf index 611d47346f..44383f7694 100644 --- a/default-configs/nginx/rmm.conf +++ b/default-configs/nginx/rmm.conf @@ -25,7 +25,7 @@ server { } server { - listen 443 ssl; + listen 443 ssl reuseport; listen [::]:443 ssl; server_name api.example.com; client_max_body_size 300M; diff --git a/script-cfg/03-SystemInfoFunctions.cfg b/script-cfg/03-SystemInfoFunctions.cfg index 0895daeb94..e909605fdc 100644 --- a/script-cfg/03-SystemInfoFunctions.cfg +++ b/script-cfg/03-SystemInfoFunctions.cfg @@ -32,16 +32,16 @@ wutOSThis() # Verify Debian or Ubuntu and version verifySupportedOS() { - if ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "20.04" ]) || ([ "$osname" == "debian" ] && [ "$relno" -ge 11 ]); then + if ([ "$osname" == "ubuntu" ] && ([ "$fullrelno" == "20.04" ] || [ "$fullrelno" == "22.04" ])) || ([ "$osname" == "debian" ] && [ "$relno" -ge 10 ]); then echo -e "\n${GREEN} $fullrel ${NC}\n" | tee -a "${currentlog}" else if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" - echo -e "${RED} T-RMM server supported OS versions: Ubuntu 20.04 and Debian 11 ${NC}" | tee -a "${currentlog}" + echo -e "${RED} T-RMM server supported OS versions: Ubuntu 20.04 and 22.04, and Debian 10 and 11 ${NC}" | tee -a "${currentlog}" echo -e "${RED} Your OS, ${fullrel}, does not appear to be supported. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Exiting. ${NC}" else - dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "T-RMM server supported OS versions: Ubuntu 20.04 and Debian 11.\n\nYour OS, ${fullrel}, does not appear to be supported.\n\nExiting." 0 0 + dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "T-RMM server supported OS versions: Ubuntu 20.04 and 22.04, and Debian 10 and 11.\n\nYour OS, ${fullrel}, does not appear to be supported.\n\nExiting." 0 0 clear -x fi exit 1 diff --git a/script-cfg/06-InstallFunctions.cfg b/script-cfg/06-InstallFunctions.cfg index 4743f7e6e6..cbb2c7a025 100644 --- a/script-cfg/06-InstallFunctions.cfg +++ b/script-cfg/06-InstallFunctions.cfg @@ -17,8 +17,6 @@ installPreReqs() sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" elif [ -n "$sudopass" ]; then echo "$sudopass" | sudo -S apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" - # Remove passed sudo password from history to prevent leak - #history -d $(($(history 1 | awk '{print $1}')-1)) fi elif [ "$autoinstall" != "1" ]; then sudo apt-get update && sudo apt-get install -y curl vim wget dirmngr gnupg lsb-release ncurses-base ncurses-bin ncurses-doc ncurses-examples ncurses-term dialog libncurses5 libncursesw5 libncurses5-dev libncursesw5-dev 2>&1 | tee -a "${currentlog}" @@ -39,20 +37,22 @@ setInstallRepos() # There is no Jammy repo yet so use Focal for Ubuntu 22.04 if [ "$osname" == "ubuntu" ] && [ "$fullrelno" == "20.04" ]; then mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" - #elif ([ "$osname" == "ubuntu" ] && [ "$fullrelno" == "22.04" ]); then - # codename="focal" - # mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" - # codename="$tempcodename" + elif [ "$osname" == "ubuntu" ] && [ "$fullrelno" == "22.04" ]; then + codename="focal" + mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 multiverse" + codename="$tempcodename" # There is no bullseye repo yet for mongo so just use Buster on Debian 11 elif [ "$osname" == "debian" ] && [ "$relno" -eq 10 ]; then mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 main" - postgresql_repo="deb [arch=amd64] https://apt.postgresql.org/pub/repos/apt/ $codename-pgdg main" - else + elif [ "$osname" == "debian" ] && [ "$relno" -eq 11 ]; then codename="buster" mongodb_repo="deb [arch=amd64] https://repo.mongodb.org/apt/$osname $codename/mongodb-org/4.4 main" codename="$tempcodename" fi + nginx_repo="deb https://nginx.org/packages/$osname/ $codename nginx" + nginx_src_repo="deb-src https://nginx.org/packages/$osname/ $codename nginx" + postgresql_repo="deb [arch=amd64] https://apt.postgresql.org/pub/repos/apt/ $codename-pgdg main" } @@ -199,7 +199,7 @@ installFrontEnd() fi sudo tar -xzf /tmp/"${webtar}" -C /var/www/rmm 2>&1 | tee -a "${currentlog}" - echo "window._env_ = {PROD_URL: \"https://${rmmdomain}\"}" | sudo tee /var/www/rmm/dist/env-config.js > /dev/null + echo "window._env_ = {PROD_URL: \"https://${rmmdomain}\"}" | sudo tee /var/www/rmm/dist/env-config.js > /dev/null 2>&1 | tee -a "${currentlog}" sudo chown www-data:www-data -R /var/www/rmm/dist 2>&1 | tee -a "${currentlog}" rm -f /tmp/"${webtar}" 2>&1 | tee -a "${currentlog}" } @@ -209,9 +209,34 @@ installNginx() { if [ "$1" != "devinstall" ]; then if [ "$1" == "install" ] || [ "$1" == "devprep" ]; then + wget -qO - https://nginx.org/packages/keys/nginx_signing.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/nginx.gpg > /dev/null 2>&1 | tee -a "${currentlog}" + echo "$nginx_repo" | sudo tee /etc/apt/sources.list.d/nginx.list 2>&1 | tee -a "${currentlog}" + echo "$nginx_src_repo" | sudo tee -a /etc/apt/sources.list.d/nginx.list 2>&1 | tee -a "${currentlog}" + sudo apt-get update 2>&1 | tee -a "${currentlog}" sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" + sudo mkdir -p /etc/nginx/sites-available 2>&1 | tee -a "${currentlog}" + sudo mkdir -p /etc/nginx/sites-enabled 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart1" ]; then + sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-available/rmm.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-available/frontend.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" + if [ ! -f /etc/apt/trusted.gpg.d/nginx.gpg ]; then + wget -qO - https://nginx.org/packages/keys/nginx_signing.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/nginx.gpg > /dev/null 2>&1 | tee -a "${currentlog}" + fi + if [ ! -f /etc/apt/sources.list.d/nginx.list ]; then + echo "$nginx_repo" | sudo tee /etc/apt/sources.list.d/nginx.list 2>&1 | tee -a "${currentlog}" + echo "$nginx_src_repo" | sudo tee -a /etc/apt/sources.list.d/nginx.list 2>&1 | tee -a "${currentlog}" + sudo apt-get update 2>&1 | tee -a "${currentlog}" + sudo rm -f /etc/nginx/modules-enabled/*.conf 2>&1 | tee -a "${currentlog}" + sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" + sudo apt-get -y --fix-broken install 2>&1 | tee -a "${currentlog}" + sudo apt-get -y upgrade 2>&1 | tee -a "${currentlog}" + sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" + fi + sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" + elif [ "$1" == "updatepart2" ]; then # Check Nginx config if ! sudo nginx -t > /dev/null 2>&1; then sudo nginx -t 2>&1 | tee -a "${currentlog}" @@ -219,13 +244,11 @@ installNginx() echo -e "\n${RED} Aborting... ${NC}\n" | tee -a "${currentlog}" exit 1 fi - elif [ "$1" == "updatepart2" ]; then - sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" - sudo cp /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-available/rmm.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" - sudo cp /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" - sudo cp /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-available/frontend.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" - sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "restore" ]; then + wget -qO - https://nginx.org/packages/keys/nginx_signing.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/nginx.gpg > /dev/null 2>&1 | tee -a "${currentlog}" + echo "$nginx_repo" | sudo tee /etc/apt/sources.list.d/nginx.list 2>&1 | tee -a "${currentlog}" + echo "$nginx_src_repo" | sudo tee -a /etc/apt/sources.list.d/nginx.list 2>&1 | tee -a "${currentlog}" + sudo apt-get update 2>&1 | tee -a "${currentlog}" sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" sudo rm -rf /etc/nginx 2>&1 | tee -a "${currentlog}" diff --git a/script-cfg/12-ParentFunctions.cfg b/script-cfg/12-ParentFunctions.cfg index f0261679ce..6e73a912ca 100644 --- a/script-cfg/12-ParentFunctions.cfg +++ b/script-cfg/12-ParentFunctions.cfg @@ -19,10 +19,6 @@ mainInstall() # 06-InstallFunctions setInstallRepos; - # Create ENV dir - # 02-MiscFunctions - createEnvDir; - # Create usernames and passwords # 04-UserInput generateUsersAndPass "$INSTALL_TYPE"; @@ -310,18 +306,10 @@ updateTRMM() # Clear screen clear -x - # Create ENV dir - # 02-MiscFunctions - createEnvDir; - # Check CHECK_NATS_LIMITNOFILE, whatever that means # 10-UpdateRestoreFunctions checkNatsLimitNoFile; - # Check Nginx config - # 06-InstallFunctions - installNginx "updatepart1"; - # Stop services for i in nginx nats-api nats rmm daphne celery celerybeat do @@ -329,11 +317,6 @@ updateTRMM() sudo systemctl stop "${i}" 2>&1 | tee -a "${currentlog}" done - # Rebuild uwsgi config - rm -f /rmm/api/tacticalrmm/app.ini 2>&1 | tee -a "${currentlog}" - # 09-ConfigAndServiceFunctions - createUwsgiConf; - # Check if Python is up to date, if not, update # 06-InstallFunctions installPython "$INSTALL_TYPE"; @@ -374,6 +357,11 @@ updateTRMM() # 02-MiscFunctions cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; + # Rebuild uwsgi config + rm -f /rmm/api/tacticalrmm/app.ini 2>&1 | tee -a "${currentlog}" + # 09-ConfigAndServiceFunctions + createUwsgiConf; + # Apply updated Ownership and perms sudo chown "${USER}:${USER}" -R /rmm 2>&1 | tee -a "${currentlog}" sudo chown "${USER}:${USER}" -R "${SCRIPTS_DIR}" 2>&1 | tee -a "${currentlog}" @@ -382,9 +370,9 @@ updateTRMM() sudo chown "root:${USER}" -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" - # Check additional Nginx settings and update + # Backup Nginx settings # 06-InstallFunctions - installNginx "updatepart2"; + installNginx "updatepart1"; # Update Nginx conf files # 09-ConfigAndServiceFunctions @@ -394,6 +382,10 @@ updateTRMM() # 09-ConfigAndServiceFunctions createBackendNginxConf; + # Check additional Nginx settings and update + # 06-InstallFunctions + installNginx "updatepart2"; + # Reconfigure backend # 09-ConfigAndServiceFunctions createCeleryConf; From 3155253741016bacac2bfd88db2a240d47434dad Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 4 Aug 2022 11:27:35 -0500 Subject: [PATCH 194/203] Updates to allow for webroot cert during backup --- script-cfg/06-InstallFunctions.cfg | 2 ++ script-cfg/08-CertificateFunctions.cfg | 2 +- script-cfg/12-ParentFunctions.cfg | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/script-cfg/06-InstallFunctions.cfg b/script-cfg/06-InstallFunctions.cfg index cbb2c7a025..13ffc1d735 100644 --- a/script-cfg/06-InstallFunctions.cfg +++ b/script-cfg/06-InstallFunctions.cfg @@ -217,6 +217,8 @@ installNginx() sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" sudo mkdir -p /etc/nginx/sites-available 2>&1 | tee -a "${currentlog}" sudo mkdir -p /etc/nginx/sites-enabled 2>&1 | tee -a "${currentlog}" + sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" + sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart1" ]; then sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-available/rmm.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" diff --git a/script-cfg/08-CertificateFunctions.cfg b/script-cfg/08-CertificateFunctions.cfg index 4655104008..8a008dfe7a 100644 --- a/script-cfg/08-CertificateFunctions.cfg +++ b/script-cfg/08-CertificateFunctions.cfg @@ -136,7 +136,7 @@ generateCerts() sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/chain.pem /etc/letsencrypt/live/"${rootdomain}"/chain.pem 2>&1 | tee -a "${currentlog}" # Create renewal post hook to restart services after renewal - sudo echo '#!/usr/bin/env bash' | sudo tee /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh + echo '#!/usr/bin/env bash' | sudo tee /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh sudo sed -i "/\#\!\/usr\/bin\/env bash/ a systemctl restart nginx meshcentral rmm celery celerybeat nats" /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh 2>&1 | tee -a "${currentlog}" sudo chmod +x /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh 2>&1 | tee -a "${currentlog}" diff --git a/script-cfg/12-ParentFunctions.cfg b/script-cfg/12-ParentFunctions.cfg index 6e73a912ca..42955ab179 100644 --- a/script-cfg/12-ParentFunctions.cfg +++ b/script-cfg/12-ParentFunctions.cfg @@ -552,6 +552,9 @@ restoreTRMM() sudo tar -xzf "$tmp_dir"/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chown root:"$USER" -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" + if [ -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then + echo "" + fi # Recreate Nginx conf files # 09-ConfigAndServiceFunctions From ff6b478d7405e3f999c79ce3732de5559aa36549 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 4 Aug 2022 11:39:27 -0500 Subject: [PATCH 195/203] fixes for new nginx repo --- script-cfg/06-InstallFunctions.cfg | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/script-cfg/06-InstallFunctions.cfg b/script-cfg/06-InstallFunctions.cfg index 13ffc1d735..e062eaf6d6 100644 --- a/script-cfg/06-InstallFunctions.cfg +++ b/script-cfg/06-InstallFunctions.cfg @@ -217,8 +217,6 @@ installNginx() sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" sudo mkdir -p /etc/nginx/sites-available 2>&1 | tee -a "${currentlog}" sudo mkdir -p /etc/nginx/sites-enabled 2>&1 | tee -a "${currentlog}" - sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" - sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart1" ]; then sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-available/rmm.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" @@ -234,9 +232,9 @@ installNginx() sudo rm -f /etc/nginx/modules-enabled/*.conf 2>&1 | tee -a "${currentlog}" sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo apt-get -y --fix-broken install 2>&1 | tee -a "${currentlog}" - sudo apt-get -y upgrade 2>&1 | tee -a "${currentlog}" - sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" fi + sudo apt-get -y upgrade 2>&1 | tee -a "${currentlog}" + sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart2" ]; then # Check Nginx config From 7a5f558b058c882f82e85828d7f8d560f88758e0 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 4 Aug 2022 12:03:29 -0500 Subject: [PATCH 196/203] Order of ops fixes for default conf files --- script-cfg/06-InstallFunctions.cfg | 5 +---- script-cfg/12-ParentFunctions.cfg | 28 +++++++++++++++++----------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/script-cfg/06-InstallFunctions.cfg b/script-cfg/06-InstallFunctions.cfg index e062eaf6d6..207184f0c3 100644 --- a/script-cfg/06-InstallFunctions.cfg +++ b/script-cfg/06-InstallFunctions.cfg @@ -218,7 +218,6 @@ installNginx() sudo mkdir -p /etc/nginx/sites-available 2>&1 | tee -a "${currentlog}" sudo mkdir -p /etc/nginx/sites-enabled 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart1" ]; then - sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-available/rmm.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-available/frontend.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" @@ -233,9 +232,9 @@ installNginx() sudo apt-get install -y nginx 2>&1 | tee -a "${currentlog}" sudo apt-get -y --fix-broken install 2>&1 | tee -a "${currentlog}" fi + sudo apt-get update 2>&1 | tee -a "${currentlog}" sudo apt-get -y upgrade 2>&1 | tee -a "${currentlog}" sudo systemctl stop nginx 2>&1 | tee -a "${currentlog}" - sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" elif [ "$1" == "updatepart2" ]; then # Check Nginx config if ! sudo nginx -t > /dev/null 2>&1; then @@ -254,11 +253,9 @@ installNginx() sudo rm -rf /etc/nginx 2>&1 | tee -a "${currentlog}" sudo mkdir /etc/nginx 2>&1 | tee -a "${currentlog}" sudo tar -xzf "$tmp_dir"/nginx/etc-nginx.tar.gz -C /etc/nginx 2>&1 | tee -a "${currentlog}" - sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-available/rmm.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-available/frontend.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" - sudo cp /rmm/default-configs/nginx/nginx.conf /etc/nginx/nginx.conf 2>&1 | tee -a "${currentlog}" # 02-MiscFunctions getExistingDomainInfo; fi diff --git a/script-cfg/12-ParentFunctions.cfg b/script-cfg/12-ParentFunctions.cfg index 42955ab179..45d75317ee 100644 --- a/script-cfg/12-ParentFunctions.cfg +++ b/script-cfg/12-ParentFunctions.cfg @@ -376,6 +376,8 @@ updateTRMM() # Update Nginx conf files # 09-ConfigAndServiceFunctions + createDefaultNginxConf; + # 09-ConfigAndServiceFunctions createMeshNginxConf; # 09-ConfigAndServiceFunctions createFrontendNginxConf; @@ -530,6 +532,16 @@ restoreTRMM() # 06-InstallFunctions installNodeJS; + # Clone main repo + echo -e "\n${GREEN} Cloning primary repo... ${NC}\n" | tee -a "${currentlog}" + # 02-MiscFunctions + clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; + + # Clone scripts repo + echo -e "\n${GREEN} Cloning community scripts repo... ${NC}\n" | tee -a "${currentlog}" + # 02-MiscFunctions + cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; + # Install Nginx and restore Nginx configuration echo -e "\n${GREEN} Installing Nginx and restoring configuration... ${NC}\n" | tee -a "${currentlog}" # 06-InstallFunctions @@ -558,6 +570,8 @@ restoreTRMM() # Recreate Nginx conf files # 09-ConfigAndServiceFunctions + createDefaultNginxConf; + # 09-ConfigAndServiceFunctions createMeshNginxConf; # 09-ConfigAndServiceFunctions createFrontendNginxConf; @@ -601,16 +615,6 @@ restoreTRMM() echo -e "\n${GREEN} Restoring MongoDB... ${NC}\n" | tee -a "${currentlog}" mongorestore --gzip "$tmp_dir"/meshcentral/mongo 2>&1 | tee -a "${currentlog}" - # Clone main repo - echo -e "\n${GREEN} Cloning primary repo... ${NC}\n" | tee -a "${currentlog}" - # 02-MiscFunctions - clonePrimaryRepo "$INSTALL_TYPE" "$REPO_URL" "$BRANCH"; - - # Clone scripts repo - echo -e "\n${GREEN} Cloning community scripts repo... ${NC}\n" | tee -a "${currentlog}" - # 02-MiscFunctions - cloneScriptsRepo "$INSTALL_TYPE" "$SCRIPTS_REPO_URL"; - # Installing NATS echo -e "\n${GREEN} Installing NATS... ${NC}\n" | tee -a "${currentlog}" # 06-InstallFunctions @@ -753,7 +757,9 @@ troubleShoot() # Check if ports are open # 11-TroubleshootingFunctions - isPortOpen "80" "HTTP"; + if [ -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then + isPortOpen "80" "HTTP"; + fi isPortOpen "443" "HTTPS"; # Checking Proxy From 30b719eb13151d9acdc5cab2a8d112bced357c71 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 4 Aug 2022 19:05:46 -0500 Subject: [PATCH 197/203] Fixes to restore and update for webroot method --- script-cfg/06-InstallFunctions.cfg | 1 + script-cfg/08-CertificateFunctions.cfg | 24 ++++++---- script-cfg/09-ConfigAndServiceFunctions.cfg | 36 ++++++++++----- script-cfg/12-ParentFunctions.cfg | 49 ++++++++++++++------- 4 files changed, 72 insertions(+), 38 deletions(-) diff --git a/script-cfg/06-InstallFunctions.cfg b/script-cfg/06-InstallFunctions.cfg index 207184f0c3..4393b461fb 100644 --- a/script-cfg/06-InstallFunctions.cfg +++ b/script-cfg/06-InstallFunctions.cfg @@ -256,6 +256,7 @@ installNginx() sudo cp /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-available/rmm.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/meshcentral.conf /etc/nginx/sites-available/meshcentral.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" sudo cp /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-available/frontend.conf.bak-"$rundate" 2>&1 | tee -a "${currentlog}" + # Get previous domain info # 02-MiscFunctions getExistingDomainInfo; fi diff --git a/script-cfg/08-CertificateFunctions.cfg b/script-cfg/08-CertificateFunctions.cfg index 8a008dfe7a..c427a465ff 100644 --- a/script-cfg/08-CertificateFunctions.cfg +++ b/script-cfg/08-CertificateFunctions.cfg @@ -62,6 +62,20 @@ importCerts() sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" } +# Enable webroot nginx conf +enableWebrootNginxConf() +{ + sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" +} + # Generate certs generateCerts() { @@ -89,17 +103,9 @@ generateCerts() echo -e "\n${GREEN} Getting webroot certificates... ${NC}\n" | tee -a "${currentlog}" # Edit nginx conf files - sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + enableWebrootNginxConf; sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/\#location/location/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/\#root/root/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/\#\}/\}/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" sudo sed -i "s/ssl_stapling/\#ssl_stapling/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" # Create folder diff --git a/script-cfg/09-ConfigAndServiceFunctions.cfg b/script-cfg/09-ConfigAndServiceFunctions.cfg index d771aff07e..b68921fda1 100644 --- a/script-cfg/09-ConfigAndServiceFunctions.cfg +++ b/script-cfg/09-ConfigAndServiceFunctions.cfg @@ -203,11 +203,15 @@ createBackendNginxConf() # Swap out generic placeholders sudo sed -i "s/api.example.com/$rmmdomain/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" - if [ "$certtype" == "dns" ]; then + if [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then + if [ "$certtype" == "dns" ]; then + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + elif [ "$certtype" == "webroot" ]; then + sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" + fi + elif [ "$1" == "update" ] || [ "$1" == "restore" ]; then sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" - elif [ "$certtype" == "webroot" ]; then - sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/rmm.conf 2>&1 | tee -a "${currentlog}" fi } @@ -219,11 +223,15 @@ createMeshNginxConf() # Swap out generic placeholders sudo sed -i "s/mesh.example.com/$meshdomain/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" - if [ "$certtype" == "dns" ]; then + if [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then + if [ "$certtype" == "dns" ]; then + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" + elif [ "$certtype" == "webroot" ]; then + sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" + fi + elif [ "$1" == "update" ] || [ "$1" == "restore" ]; then sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" - elif [ "$certtype" == "webroot" ]; then - sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/meshcentral.conf 2>&1 | tee -a "${currentlog}" fi } @@ -272,11 +280,15 @@ createFrontendNginxConf() # Swap out generic placeholders sudo sed -i "s/rmm.example.com/$frontenddomain/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" - if [ "$certtype" == "dns" ]; then + if [ "$1" == "install" ] || [ "$1" == "devinstall" ]; then + if [ "$certtype" == "dns" ]; then + sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + elif [ "$certtype" == "webroot" ]; then + sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" + fi + elif [ "$1" == "update" ] || [ "$1" == "restore" ]; then sudo sed -i "s/rootdomain/$rootdomain/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" - elif [ "$certtype" == "webroot" ]; then - sudo sed -i "s/letsencrypt\/live\/rootdomain\/fullchain.pem/ssl\/certs\/ssl-cert-snakeoil.pem/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" - sudo sed -i "s/letsencrypt\/live\/rootdomain\/privkey.pem/ssl\/private\/ssl-cert-snakeoil.key/" /etc/nginx/sites-available/frontend.conf 2>&1 | tee -a "${currentlog}" fi } diff --git a/script-cfg/12-ParentFunctions.cfg b/script-cfg/12-ParentFunctions.cfg index 45d75317ee..33d0cd1c7b 100644 --- a/script-cfg/12-ParentFunctions.cfg +++ b/script-cfg/12-ParentFunctions.cfg @@ -143,17 +143,17 @@ mainInstall() # Create Default Nginx site config echo -e "\n${GREEN} Creating Default Nginx config... ${NC}\n" | tee -a "${currentlog}" # 09-ConfigAndServiceFunctions - createDefaultNginxConf; + createDefaultNginxConf "$INSTALL_TYPE"; # Create Backend Nginx site config echo -e "\n${GREEN} Creating Backend Nginx config... ${NC}\n" | tee -a "${currentlog}" # 09-ConfigAndServiceFunctions - createBackendNginxConf; + createBackendNginxConf "$INSTALL_TYPE"; # Create MeshCentral Nginx configuration echo -e "\n${GREEN} Creating MeshCentral Nginx config... ${NC}\n" | tee -a "${currentlog}" # 09-ConfigAndServiceFunctions - createMeshNginxConf; + createMeshNginxConf "$INSTALL_TYPE"; # Enable Mesh and RMM sites sudo ln -s /etc/nginx/sites-available/rmm.conf /etc/nginx/sites-enabled/rmm.conf 2>&1 | tee -a "${currentlog}" @@ -205,7 +205,7 @@ mainInstall() # Set front end Nginx config and enable echo -e "\n${GREEN} Creating Frontend Nginx config... ${NC}\n" | tee -a "${currentlog}" # 09-ConfigAndServiceFunctions - createFrontendNginxConf; + createFrontendNginxConf "$INSTALL_TYPE"; # Enable Frontend site sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf 2>&1 | tee -a "${currentlog}" @@ -376,13 +376,23 @@ updateTRMM() # Update Nginx conf files # 09-ConfigAndServiceFunctions - createDefaultNginxConf; + createDefaultNginxConf "$INSTALL_TYPE"; # 09-ConfigAndServiceFunctions - createMeshNginxConf; + createMeshNginxConf "$INSTALL_TYPE"; # 09-ConfigAndServiceFunctions - createFrontendNginxConf; + createFrontendNginxConf "$INSTALL_TYPE"; # 09-ConfigAndServiceFunctions - createBackendNginxConf; + createBackendNginxConf "$INSTALL_TYPE"; + + # Enable webroot cert method nginx conf if necessary + if [ -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then + # 08-CertificateFunctions + enableWebrootNginxConf; + # Create symlinks so cert paths don't need to be edited + sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/fullchain.pem /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem 2>&1 | tee -a "${currentlog}" + sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/privkey.pem /etc/letsencrypt/live/"${rootdomain}"/privkey.pem 2>&1 | tee -a "${currentlog}" + sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/chain.pem /etc/letsencrypt/live/"${rootdomain}"/chain.pem 2>&1 | tee -a "${currentlog}" + fi # Check additional Nginx settings and update # 06-InstallFunctions @@ -564,19 +574,26 @@ restoreTRMM() sudo tar -xzf "$tmp_dir"/certs/etc-letsencrypt.tar.gz -C /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chown root:"$USER" -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" sudo chmod 755 -R /etc/letsencrypt 2>&1 | tee -a "${currentlog}" - if [ -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then - echo "" - fi # Recreate Nginx conf files # 09-ConfigAndServiceFunctions - createDefaultNginxConf; + createDefaultNginxConf "$INSTALL_TYPE"; # 09-ConfigAndServiceFunctions - createMeshNginxConf; + createMeshNginxConf "$INSTALL_TYPE"; # 09-ConfigAndServiceFunctions - createFrontendNginxConf; + createFrontendNginxConf "$INSTALL_TYPE"; # 09-ConfigAndServiceFunctions - createBackendNginxConf; + createBackendNginxConf "$INSTALL_TYPE"; + + # Enable webroot cert method nginx conf if necessary + if [ -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then + # 08-CertificateFunctions + enableWebrootNginxConf; + # Create symlinks so cert paths don't need to be edited + sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/fullchain.pem /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem 2>&1 | tee -a "${currentlog}" + sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/privkey.pem /etc/letsencrypt/live/"${rootdomain}"/privkey.pem 2>&1 | tee -a "${currentlog}" + sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/chain.pem /etc/letsencrypt/live/"${rootdomain}"/chain.pem 2>&1 | tee -a "${currentlog}" + fi # Restore Celery configs echo -e "\n${GREEN} Restoring celery configs... ${NC}\n" | tee -a "${currentlog}" @@ -674,8 +691,6 @@ restoreTRMM() sudo chown "${USER}:${USER}" /var/log/celery 2>&1 | tee -a "${currentlog}" sudo chown "${USER}:${USER}" -R /etc/conf.d/ 2>&1 | tee -a "${currentlog}" sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.npm 2>&1 | tee -a "${currentlog}" - sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.config 2>&1 | tee -a "${currentlog}" - sudo chown -R "${USER}:${GROUP}" /home/"${USER}"/.cache 2>&1 | tee -a "${currentlog}" # Update services info sudo systemctl daemon-reload 2>&1 | tee -a "${currentlog}" From d83ec587995fc59001337a5653c2723530733db5 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 4 Aug 2022 19:57:05 -0500 Subject: [PATCH 198/203] removed unnecessary symlink creations --- script-cfg/12-ParentFunctions.cfg | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/script-cfg/12-ParentFunctions.cfg b/script-cfg/12-ParentFunctions.cfg index 33d0cd1c7b..533aad5aad 100644 --- a/script-cfg/12-ParentFunctions.cfg +++ b/script-cfg/12-ParentFunctions.cfg @@ -2,7 +2,7 @@ # CFG file info # ################### -CFG_VERSION="8" +CFG_VERSION="9" ###################### @@ -388,10 +388,6 @@ updateTRMM() if [ -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then # 08-CertificateFunctions enableWebrootNginxConf; - # Create symlinks so cert paths don't need to be edited - sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/fullchain.pem /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem 2>&1 | tee -a "${currentlog}" - sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/privkey.pem /etc/letsencrypt/live/"${rootdomain}"/privkey.pem 2>&1 | tee -a "${currentlog}" - sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/chain.pem /etc/letsencrypt/live/"${rootdomain}"/chain.pem 2>&1 | tee -a "${currentlog}" fi # Check additional Nginx settings and update @@ -589,10 +585,6 @@ restoreTRMM() if [ -f /etc/letsencrypt/renewal-hooks/post/001-restart-services.sh ]; then # 08-CertificateFunctions enableWebrootNginxConf; - # Create symlinks so cert paths don't need to be edited - sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/fullchain.pem /etc/letsencrypt/live/"${rootdomain}"/fullchain.pem 2>&1 | tee -a "${currentlog}" - sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/privkey.pem /etc/letsencrypt/live/"${rootdomain}"/privkey.pem 2>&1 | tee -a "${currentlog}" - sudo ln -s /etc/letsencrypt/live/"${rmmdomain}"/chain.pem /etc/letsencrypt/live/"${rootdomain}"/chain.pem 2>&1 | tee -a "${currentlog}" fi # Restore Celery configs From e3b8c1553a8c3f12c026446fcf8a3a3d7269b86c Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 4 Aug 2022 20:20:53 -0500 Subject: [PATCH 199/203] Fix for postgres import?... --- script-cfg/12-ParentFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/12-ParentFunctions.cfg b/script-cfg/12-ParentFunctions.cfg index 533aad5aad..117c5f4adb 100644 --- a/script-cfg/12-ParentFunctions.cfg +++ b/script-cfg/12-ParentFunctions.cfg @@ -661,7 +661,7 @@ restoreTRMM() createPGDB; gzip -d "$tmp_dir"/postgres/*.psql.gz 2>&1 | tee -a "${currentlog}" - PGPASSWORD="${pgpw} psql -h localhost -U ${pgusername} -d tacticalrmm -f $tmp_dir/postgres/db*.psql" + psql -U "${pgusername}" -d tacticalrmm < "$tmp_dir"/postgres/db*.psql # Restore Backend echo -e "\n${GREEN} Restoring the backend... ${NC}\n" | tee -a "${currentlog}" From bfec7d62a368c99348caf1fc87b1999312115d29 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 4 Aug 2022 22:55:44 -0500 Subject: [PATCH 200/203] change to restore postgres database import --- script-cfg/12-ParentFunctions.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script-cfg/12-ParentFunctions.cfg b/script-cfg/12-ParentFunctions.cfg index 117c5f4adb..2acdd09edb 100644 --- a/script-cfg/12-ParentFunctions.cfg +++ b/script-cfg/12-ParentFunctions.cfg @@ -661,7 +661,7 @@ restoreTRMM() createPGDB; gzip -d "$tmp_dir"/postgres/*.psql.gz 2>&1 | tee -a "${currentlog}" - psql -U "${pgusername}" -d tacticalrmm < "$tmp_dir"/postgres/db*.psql + PGPASSWORD=${pgpw} psql -h localhost -U "${pgusername}" -d tacticalrmm < "$tmp_dir"/postgres/db*.psql 2>&1 | tee -a "${currentlog}" # Restore Backend echo -e "\n${GREEN} Restoring the backend... ${NC}\n" | tee -a "${currentlog}" From 2cd2827cae595310951d9a205cb4f8f224cc3455 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 4 Aug 2022 23:04:23 -0500 Subject: [PATCH 201/203] Updated ram requirement to 3GB --- script-cfg/03-SystemInfoFunctions.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/script-cfg/03-SystemInfoFunctions.cfg b/script-cfg/03-SystemInfoFunctions.cfg index e909605fdc..12aad9be9f 100644 --- a/script-cfg/03-SystemInfoFunctions.cfg +++ b/script-cfg/03-SystemInfoFunctions.cfg @@ -73,17 +73,17 @@ checkTotalSystemMemory() local totsysmemory="" totsysmemory=$(grep MemTotal /proc/meminfo | awk '{print $2 / 1024 / 1000}' | cut -d '.' -f1) - if [ "$totsysmemory" -ge 2 ]; then + if [ "$totsysmemory" -ge 3 ]; then return else if [ "$autoinstall" == "1" ]; then - echo -e "${RED} Error: System does not meet the minimum recommended RAM amount of 2GB. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Error: System does not meet the minimum recommended RAM amount of 3GB. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Please add RAM to the system to prevent potential issues during install. ${NC}" | tee -a "${currentlog}" echo -e "${RED} Re-run $THIS_SCRIPT after resolving the issue. ${NC}" echo -e "${RED} Exiting... ${NC}" exit 1 elif [ "$autoinstall" != "1" ]; then - dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "Amidaware recommends a minimum of 2GB of RAM for a T-RMM server.\n\nYour system does not meet the minimum recommended RAM amount of 2GB.\n\nYou may experience issues during install.\n\nIt's recommended to exit and add RAM to the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 + dialog --keep-tite --cr-wrap --yes-label "Continue" --no-label "Exit" --backtitle "Tactical RMM Installation and Maintenance Utility" --title "WARNING" --yesno "Amidaware recommends a minimum of 3GB of RAM for a T-RMM server.\n\nYour system does not meet the minimum recommended RAM amount of 3GB.\n\nYou may experience issues during install.\n\nIt's recommended to exit and add RAM to the system before continuing with installation,\nthough you may continue with the install now if you wish." 0 0 case $? in 0 ) return;; From 6b2f98e75047bbc3645d720ea3e491764690ec09 Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Thu, 4 Aug 2022 23:11:14 -0500 Subject: [PATCH 202/203] script and cfg message update --- script-cfg/02-MiscFunctions.cfg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/script-cfg/02-MiscFunctions.cfg b/script-cfg/02-MiscFunctions.cfg index a37e25ef7d..fcc76aeb21 100644 --- a/script-cfg/02-MiscFunctions.cfg +++ b/script-cfg/02-MiscFunctions.cfg @@ -108,9 +108,9 @@ checkScriptVer() wget -q "$2" -O "$3" 2>&1 | tee -a "${currentlog}" if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" - echo -e "${RED} Old $3 detected. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Old ${3} detected. ${NC}" | tee -a "${currentlog}" echo -e "${RED} The latest version has been downloaded. ${NC}" | tee -a "${currentlog}" - echo -e "${RED} Please re-run $3 ${NC}" + echo -e "${RED} Please re-run ${3} ${NC}" echo -e "${RED} Exiting. ${NC}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $3 detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 @@ -139,9 +139,9 @@ checkCfgVer() wget -q "$1/script-cfg/$2" -O "$PWD/script-cfg/$2" 2>&1 | tee -a "${currentlog}" if [ "$autoinstall" == "1" ]; then echo -e "${RED} Error: ${NC}" | tee -a "${currentlog}" - echo -e "${RED} Old $2 detected. ${NC}" | tee -a "${currentlog}" + echo -e "${RED} Old ${2} detected. ${NC}" | tee -a "${currentlog}" echo -e "${RED} The latest version has been downloaded. ${NC}" | tee -a "${currentlog}" - echo -e "${RED} Please re-run $3 ${NC}" + echo -e "${RED} Please re-run ${3} ${NC}" echo -e "${RED} Exiting. ${NC}" else dialog --keep-tite --cr-wrap --backtitle "Tactical RMM Installation and Maintenance Utility" --title "ERROR" --msgbox "Old $2 file detected.\nThe latest version has been downloaded.\n\nPlease re-run $3" 10 40 From 5630f7768f34290665cf5fb18b44f6501538b54a Mon Sep 17 00:00:00 2001 From: Kevin Ruffus Date: Fri, 5 Aug 2022 11:29:56 -0500 Subject: [PATCH 203/203] Added Ubuntu 22.04 Mongodb support --- script-cfg/06-InstallFunctions.cfg | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/script-cfg/06-InstallFunctions.cfg b/script-cfg/06-InstallFunctions.cfg index 4393b461fb..1d6f7cc2b8 100644 --- a/script-cfg/06-InstallFunctions.cfg +++ b/script-cfg/06-InstallFunctions.cfg @@ -62,6 +62,16 @@ installMongo() if [ "$1" != "devinstall" ]; then wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/mongo.gpg > /dev/null 2>&1 | tee -a "${currentlog}" echo "$mongodb_repo" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list 2>&1 | tee -a "${currentlog}" + + # Temp fix for Ubuntu 22.04 openssl1.1.1 missing + if [ "$osname" == "ubuntu" ] && [ "$fullrelno" == "22.04" ]; then + wget -q http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1l-1ubuntu1.5_amd64.deb 2>&1 | tee -a "${currentlog}" + wget -q http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl-dev_1.1.1l-1ubuntu1.5_amd64.deb 2>&1 | tee -a "${currentlog}" + sudo dpkg -i libssl1.1_1.1.1l-1ubuntu1.5_amd64.deb + sudo dpkg -i libssl-dev_1.1.1l-1ubuntu1.5_amd64.deb + rm libssl1.1_1.1.1l-1ubuntu1.5_amd64 + rm libssl-dev_1.1.1l-1ubuntu1.5_amd64.deb + fi sudo apt-get update && sudo apt-get install -y mongodb-org 2>&1 | tee -a "${currentlog}" sudo systemctl enable mongod 2>&1 | tee -a "${currentlog}" sudo systemctl restart mongod 2>&1 | tee -a "${currentlog}"