Compare commits
No commits in common. "main" and "dev" have entirely different histories.
5 changed files with 84 additions and 115 deletions
|
|
@ -1,2 +0,0 @@
|
||||||
AUTHORIZED_USER_ID_1
|
|
||||||
AUTHORIZED_USER_ID_2
|
|
||||||
1
.env
1
.env
|
|
@ -1 +0,0 @@
|
||||||
YOUR_TOKEN_HERE
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,2 +0,0 @@
|
||||||
test.py
|
|
||||||
venv/
|
|
||||||
116
README.md
116
README.md
|
|
@ -1,71 +1,54 @@
|
||||||
# lainmonitor
|
# LainMonitor
|
||||||
|
|
||||||
LainMonitor is a Telegram bot designed to monitor your system, providing real-time updates on the system’s status, essential services, and disk usage. It can also verify connectivity to a specific Tailscale IP address.
|
LainMonitor is a Telegram bot designed to monitor your system by providing real-time information about the system's status, services, and disk usage. It can also check connectivity to a specific Tailscale IP address.
|
||||||
Current version: v1.2
|
|
||||||
|
|
||||||
### Key Features:
|
## Features
|
||||||
|
- Retrieve system hostname, uptime, and status of essential services such as:
|
||||||
|
- Zerotier
|
||||||
|
- Prosody
|
||||||
|
- PostgreSQL
|
||||||
|
- Tailscale
|
||||||
|
- Check disk usage
|
||||||
|
- Ping a Tailscale IP to verify connectivity
|
||||||
|
- Use via Telegram commands like `/status`, `/ping`, and `/help`
|
||||||
|
|
||||||
Retrieve system information:
|
## Dependencies
|
||||||
Hostname
|
- [Telebot](https://github.com/eternnoir/pyTelegramBotAPI) - A Python library for Telegram bot API.
|
||||||
Uptime
|
|
||||||
Status of critical services:
|
|
||||||
Zerotier
|
|
||||||
Prosody
|
|
||||||
PostgreSQL
|
|
||||||
Tailscale
|
|
||||||
nginx
|
|
||||||
Check disk usage
|
|
||||||
Ping a Tailscale IP for connectivity verification
|
|
||||||
Restart critical services
|
|
||||||
Reboot the host
|
|
||||||
Accessible via Telegram commands
|
|
||||||
|
|
||||||
### Prerequisites:
|
|
||||||
|
|
||||||
Python 3
|
|
||||||
Telebot — Python library for interacting with the Telegram bot API.
|
|
||||||
|
|
||||||
### Installation Guide:
|
|
||||||
|
|
||||||
Clone the repository:
|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
1. Clone this repository:
|
||||||
|
```bash
|
||||||
git clone https://git.lainlounge.xyz/hornet/lainmonitor.git
|
git clone https://git.lainlounge.xyz/hornet/lainmonitor.git
|
||||||
cd lainmonitor
|
cd lainmonitor
|
||||||
|
|
||||||
RECOMMENDED: Create a virtual environment for python with:
|
|
||||||
```
|
```
|
||||||
python3 -m venv venv
|
2. Install the required Python library:
|
||||||
source venv/bin/activate
|
```bash
|
||||||
|
pip install pyTelegramBotAPI
|
||||||
```
|
```
|
||||||
Install dependencies:
|
3. Replace the placeholder in the code with your Telegram bot token:
|
||||||
|
```python
|
||||||
```
|
TOKEN = 'PLACE_YOUR_TOKEN_HERE'
|
||||||
pip3 install -r requirements.txt
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Configure your bot token: Open the .env file and replace the placeholder with your Telegram bot token.
|
4. Set up permissions for the bot to check system services (run as a user with `sudo` access).
|
||||||
|
|
||||||
Configure authorized users: Open the .authorized_users file and replace the placeholders with Telegram user ID(s).
|
## Usage
|
||||||
|
|
||||||
Set up service access: Ensure the bot can check system services by running it with sudo or appropriate permissions.
|
### Running Directly
|
||||||
|
You can run the bot directly using Python:
|
||||||
### Usage:
|
|
||||||
#### Running the Bot Manually:
|
|
||||||
|
|
||||||
You can run LainMonitor directly from the command line:
|
|
||||||
|
|
||||||
|
```bash
|
||||||
python3 lainmonitor.py
|
python3 lainmonitor.py
|
||||||
|
```
|
||||||
|
|
||||||
#### Running as a Systemd Service:
|
### Running as a Service
|
||||||
|
To run LainMonitor as a service, follow these steps:
|
||||||
To run the bot as a systemd service, follow these steps:
|
1. Create a systemd service file:
|
||||||
|
```bash
|
||||||
Create a service file:
|
|
||||||
|
|
||||||
sudo nano /etc/systemd/system/lainmonitor.service
|
sudo nano /etc/systemd/system/lainmonitor.service
|
||||||
|
```
|
||||||
Add the following configuration:
|
2. Add the following configuration:
|
||||||
|
```ini
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=LainMonitor Telegram Bot
|
Description=LainMonitor Telegram Bot
|
||||||
After=network.target
|
After=network.target
|
||||||
|
|
@ -76,24 +59,21 @@ Add the following configuration:
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
Enable and start the service:
|
3. Enable and start the service:
|
||||||
|
```bash
|
||||||
sudo systemctl enable lainmonitor
|
sudo systemctl enable lainmonitor
|
||||||
sudo systemctl start lainmonitor
|
sudo systemctl start lainmonitor
|
||||||
|
```
|
||||||
|
|
||||||
### Available Commands:
|
## Telegram Bot Commands
|
||||||
|
- `/start`: Initialize the bot and receive a welcome message.
|
||||||
|
- `/help`: Display available commands.
|
||||||
|
- `/status`: Get the system hostname, status, uptime, and the status of monitored services.
|
||||||
|
- `/ping`: Ping a Tailscale IP and return the connectivity status.
|
||||||
|
- `/reboot`: (Work in progress) Placeholder for a reboot command.
|
||||||
|
|
||||||
/start — Initialize the bot and receive a welcome message.
|
## Author
|
||||||
/help — Display a list of available commands.
|
Created by **hornetmaidan**
|
||||||
/status — Retrieve system hostname, uptime, and status of monitored services.
|
|
||||||
/ping — Ping a Tailscale IP and return connectivity status.
|
|
||||||
/restart hostname- Restart a specific service on a specified machine.
|
|
||||||
/reboot hostname — Placeholder for a system reboot command.
|
|
||||||
|
|
||||||
### Contributions:
|
Feel free to contribute or suggest features!
|
||||||
|
|
||||||
Created by hornetmaidan.
|
|
||||||
With Contributions from h@x.
|
|
||||||
|
|
||||||
Any new features and suggestions are welcome!
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
# usage: python3 lainmonitor.py | or run it as a service
|
# usage: python3 lainmonitor.py | or run it as a service
|
||||||
# author: hornetmaidan
|
# author: hornetmaidan
|
||||||
# contributors: h@x
|
# contributors: h@x
|
||||||
# version: 1.2
|
# version: 1.1.6
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import threading
|
import threading
|
||||||
|
|
@ -32,7 +32,7 @@ except FileNotFoundError:
|
||||||
|
|
||||||
# Load the authorized users
|
# Load the authorized users
|
||||||
try:
|
try:
|
||||||
authorized_users = [str(line.strip()) for line in open(auth_users_path, 'r').readlines()]
|
authorized_users = [line.strip() for line in open(auth_users_path, 'r').readlines()]
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
logging.error('Authorized users file not found. Exiting...')
|
logging.error('Authorized users file not found. Exiting...')
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
@ -72,7 +72,7 @@ def get_service_status(service):
|
||||||
subprocess.run(['sudo', 'systemctl', 'is-active', '--quiet', service], check=True)
|
subprocess.run(['sudo', 'systemctl', 'is-active', '--quiet', service], check=True)
|
||||||
return f'{service} is active'
|
return f'{service} is active'
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
return f'{service} is inactive/not present'
|
return f'{service} is inactive'
|
||||||
|
|
||||||
# Function to ping a Tailscale node
|
# Function to ping a Tailscale node
|
||||||
def ping_node(node, hostname):
|
def ping_node(node, hostname):
|
||||||
|
|
@ -150,21 +150,14 @@ def reboot():
|
||||||
logging.info('Rebooting system...')
|
logging.info('Rebooting system...')
|
||||||
subprocess.run(['sudo', 'reboot'], check=True)
|
subprocess.run(['sudo', 'reboot'], check=True)
|
||||||
|
|
||||||
# Populate teh variables on first start
|
|
||||||
get_system_info()
|
|
||||||
|
|
||||||
# Message handlers
|
# Message handlers
|
||||||
@bot.message_handler(commands=['start', 'help', 'status', 'restart', 'reboot', 'ping'])
|
@bot.message_handler(commands=['start', 'help', 'status', 'restart', 'reboot', 'ping'])
|
||||||
def handle(message):
|
def handle(message):
|
||||||
user_id = str(message.from_user.id)
|
user_id = str(message.from_user.id)
|
||||||
if user_id not in authorized_users:
|
|
||||||
bot.reply_to(message, 'You are not authorized for this action')
|
|
||||||
else:
|
|
||||||
if message.text == '/start':
|
if message.text == '/start':
|
||||||
bot.reply_to(message, 'lainmonitor v1.2 --- standing by...')
|
bot.reply_to(message, 'lainmonitor v1.0 --- standing by...')
|
||||||
elif message.text == '/help':
|
elif message.text == '/help':
|
||||||
bot.reply_to(message, 'commands: /start, /help, /status, /restart, /reboot, /ping')
|
bot.reply_to(message, 'commands: /start, /help, /status, /restart, /reboot, /ping')
|
||||||
bot.reply_to(message, 'commands: /start, /help, /status, /restart, /reboot, /ping')
|
|
||||||
elif message.text == '/status':
|
elif message.text == '/status':
|
||||||
get_system_info()
|
get_system_info()
|
||||||
status_message = (
|
status_message = (
|
||||||
|
|
@ -179,16 +172,17 @@ def handle(message):
|
||||||
)
|
)
|
||||||
bot.reply_to(message, status_message)
|
bot.reply_to(message, status_message)
|
||||||
bot.reply_to(message, f'Filesystem info for {hostname}:\n\n{disk}')
|
bot.reply_to(message, f'Filesystem info for {hostname}:\n\n{disk}')
|
||||||
elif message.text == f'/restart {hostname}':
|
elif message.text == f'/restart {hostname}' and user_id in authorized_users:
|
||||||
bot.send_message(message.chat.id, 'Select a service to restart:', reply_markup=restart_menu())
|
bot.send_message(message.chat.id, 'Select a service to restart:', reply_markup=restart_menu())
|
||||||
elif message.text == f'/reboot {hostname}':
|
elif message.text == f'/reboot {hostname}' and user_id in authorized_users:
|
||||||
bot.reply_to(message, f'Rebooting {hostname}...')
|
bot.reply_to(message, f'Rebooting {hostname}...')
|
||||||
reboot()
|
reboot()
|
||||||
elif message.text == '/ping':
|
elif message.text == '/ping' and user_id in authorized_users:
|
||||||
reach = check_tailscale_nodes()
|
reach = check_tailscale_nodes()
|
||||||
bot.reply_to(message, f'Ping status:\n\n{"\n".join(reach)}')
|
bot.reply_to(message, f'Ping status:\n\n{"\n".join(reach)}')
|
||||||
else:
|
else:
|
||||||
pass
|
bot.reply_to(message, 'You are not authorized for this action')
|
||||||
|
|
||||||
# Polling with timeout and error handling
|
# Polling with timeout and error handling
|
||||||
try:
|
try:
|
||||||
bot.polling(none_stop=True, timeout=60, long_polling_timeout=60)
|
bot.polling(none_stop=True, timeout=60, long_polling_timeout=60)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue