Files
Wireguard-Peer-Manager/bot.py

172 lines
6.4 KiB
Python
Raw Normal View History

2021-05-18 15:16:49 -07:00
#!/usr/bin/env python3
# Author: 'UltraDesu <ab@hexor.ru>'
# Home: https://github.com/house-of-vanity/Wireguard-Peer-Manager
2021-05-06 17:36:18 +03:00
import logging
import os
import sys
2022-03-16 14:14:35 +03:00
import configparser
from time import sleep
2022-06-07 15:43:57 +00:00
from hurry.filesize import size
from subprocess import call
2021-05-06 17:36:18 +03:00
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import Updater, MessageHandler, CommandHandler, filters, CallbackQueryHandler, CallbackContext
2022-06-20 15:51:28 +03:00
from gen import wg_if_status
2021-05-06 17:36:18 +03:00
from gen import add_peer as wg_add_peer
from gen import update_configs
from gen import list_peers as wg_list_peers
from gen import del_peer as wg_del_peer
2021-05-06 17:36:18 +03:00
2022-06-07 15:43:57 +00:00
tg_max_len = 4096
2021-05-06 17:36:18 +03:00
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log = logging.getLogger(__name__)
token = os.environ.get('TG_TOKEN')
2022-04-25 11:56:05 +00:00
admin = os.environ.get('TG_ADMIN').replace('"', '').replace(' ', '').split(',')
2021-05-06 17:36:18 +03:00
if not token or not admin:
log.error("Env var TG_TOKEN or TG_ADMIN aren't set.")
sys.exit(1)
2022-03-16 14:14:35 +03:00
wpm_config = configparser.ConfigParser()
if wpm_config.read('wpm.conf'):
config = wpm_config['Interface'].get('config', 'wg0')
else:
config = "wg0"
2021-05-06 17:36:18 +03:00
def _help(update, context):
2022-06-07 15:43:57 +00:00
update.message.reply_text(
2022-06-08 10:57:02 +03:00
'<b>Help:</b>\n <b>*</b> /add <i>peer name</i>\n <b>*</b> /del <i>peer name</i>\n <b>*</b> /list [<i>peer name</i>]\n<b>*</b> /status - show status\n<b>*</b> /restart - restart WG interface',
2022-06-07 15:43:57 +00:00
parse_mode='HTML',
disable_web_page_preview=True)
2021-05-06 17:36:18 +03:00
def auth(handler):
def wrapper(update, context):
2022-04-25 11:56:05 +00:00
if update.message.chat.username not in admin:
update.message.reply_text(
2022-06-07 15:43:57 +00:00
'You are not allowed to do that.',
parse_mode='HTML',
disable_web_page_preview=True)
return False
handler(update, context)
return wrapper
@auth
def list_peers(update, context):
if len(update.message.text.split()) == 1:
n = 1
message = "Peers:\n<code>"
for peer in wg_list_peers():
message += f"{n} * {peer['ip']}: {peer['name']}\n"
n += 1
2022-06-07 15:43:57 +00:00
update.message.reply_text(
f"{message}</code>",
parse_mode='HTML',
disable_web_page_preview=True)
else:
peer_name = "_".join(update.message.text.split()[1:])
2022-06-05 16:11:08 +00:00
if peer_name.isnumeric():
n = 1
for peer in wg_list_peers():
if int(peer_name) == n:
peer_name = peer['name']
break
n += 1
try:
2022-06-05 16:14:03 +00:00
msg = open(f'/etc/wireguard/clients_{config}/{peer_name}.conf', 'r').read()
2022-06-07 15:43:57 +00:00
update.message.reply_photo(
open(f'/etc/wireguard/clients_{config}/{peer_name}-qr.png', 'rb'),
parse_mode='HTML',
filename=f'{peer_name} QR.png',
quote=True,
caption=f"Install Wireguard VPN app and scan or open config.\n<code>{msg}</code>")
update.message.reply_document(
open(f'/etc/wireguard/clients_{config}/{peer_name}.conf', 'rb'))
except:
update.message.reply_text("Wrong client name.")
@auth
def del_peer(update, context):
if len(update.message.text.split()) < 2:
_help(update, context)
2021-05-06 17:36:18 +03:00
return False
peer_name = "_".join(update.message.text.split()[1:])
log.info("Deleting peer %s", peer_name)
wg_del_peer(peer_name)
update.message.reply_text("Done.")
2022-06-07 15:43:57 +00:00
@auth
def status(update, context):
2022-06-20 15:51:28 +03:00
stat = wg_if_status(config)
2022-06-08 11:51:02 +03:00
peer_names = dict()
for peer in wg_list_peers():
peer_names[peer['ip']] = peer['name']
2022-06-07 15:43:57 +00:00
msg = []
for _if in stat.items():
msg.append(f"<b>{_if[0]}</b>\nStarted {_if[1]['started']}")
peers = {}
for peer in _if[1]['peers']:
peers[peer['allowed_ips'][0]] = {
"tx": peer['transfer_rx'],
"rx": peer['transfer_tx'],
2022-06-08 11:51:02 +03:00
"name": peer_names[peer['allowed_ips'][0]],
2022-06-07 15:43:57 +00:00
"total": peer['transfer_rx'] + peer['transfer_tx']}
peers_sorted = sorted(peers.items(), key=lambda x: x[1]['total'], reverse=True)
peers_sorted = list(filter(lambda x: (x[1]['total'] != 0), peers_sorted))
for peer in peers_sorted:
t_msg = (
f" 🔹 <b>{peer[1]['name']}\n {peer[0]}</b>\n "
f"<b>Since last run</b> {size(peer[1]['total'])} RX/TX: {size(peer[1]['rx'])}"
f"/{size(peer[1]['tx'])}")
2022-06-07 15:43:57 +00:00
if len(t_msg + "\n".join(msg)) >= tg_max_len:
msg = "\n".join(msg)
update.message.reply_text(f"{msg}", parse_mode='HTML',)
msg = []
msg.append(t_msg)
2022-06-08 11:51:02 +03:00
msg.append("<i>Clients without any activity are skipped.</i>")
2022-06-07 15:43:57 +00:00
msg = "\n".join(msg)
update.message.reply_text(f"{msg}", parse_mode='HTML',)
@auth
def restart(update, context):
call(f"systemctl restart wg-quick@{config}.service", shell=True)
update.message.reply_text(f"Restarted {config} interface.")
@auth
def add_peer(update, context):
2021-05-06 17:36:18 +03:00
if len(update.message.text.split()) < 2:
_help(update, context)
2021-05-06 18:23:36 +03:00
return False
2021-05-06 17:36:18 +03:00
peer_name = "_".join(update.message.text.split()[1:])
log.info("Creating peer %s", peer_name)
wg_add_peer(peer_name)
2022-06-05 16:01:00 +00:00
msg = open(f'/etc/wireguard/clients_{config}/{peer_name}.conf', 'r').read()
2022-06-07 15:43:57 +00:00
update.message.reply_photo(
open(f'/etc/wireguard/clients_{config}/{peer_name}-qr.png', 'rb'),
parse_mode='HTML',
filename=f'{peer_name} QR.png',
quote=True, caption=f"Install Wireguard VPN app and scan or open config.\n<code>{msg}</code>")
2022-03-16 14:14:35 +03:00
update.message.reply_document(open(f'/etc/wireguard/clients_{config}/{peer_name}.conf', 'rb'))
2021-05-06 17:36:18 +03:00
def error(update, context):
update.message.reply_text("Something went wrong...")
2021-05-06 17:36:18 +03:00
def main():
updater = Updater(token, use_context=True)
updater.dispatcher.add_error_handler(error)
2021-05-06 17:36:18 +03:00
updater.dispatcher.add_handler(CommandHandler('add', add_peer))
updater.dispatcher.add_handler(CommandHandler('list', list_peers))
updater.dispatcher.add_handler(CommandHandler('del', del_peer))
2022-06-07 15:43:57 +00:00
updater.dispatcher.add_handler(CommandHandler('restart', restart))
updater.dispatcher.add_handler(CommandHandler('status', status))
2021-05-06 17:36:18 +03:00
updater.dispatcher.add_handler(MessageHandler(filters.Filters.text, _help))
updater.start_polling()
updater.idle()
if __name__ == '__main__':
log = logging.getLogger('WireGuard-GenBot')
main()