Искал плагин под Xfce для WireGuard, так ничего нормального и не нашел. Набросал свой на скорую руку, правда python 2, но работает стабильно. На тройку что-то никак не перепишу, да не оформлю в GitHub, может здесь кому-то пригодится пока:
#!/usr/bin/python
#coding=utf-8
# RUN: sudo ./vpnwidget.py wg0-client
import gtk, json, urllib2, socket, sys, os, subprocess
import netifaces as ni
class VPNWidget:
def __init__(self):
self.VPN_INTERFACE_NAME = sys.argv[1]
self.vpn_state = "down"
self.tray = gtk.StatusIcon()
self.tray.connect('popup-menu', self.on_right_click)
self.get_info()
def get_info(self):
ipaddr = socket.gethostbyname(socket.gethostname())
gateway = realip = city = country = " - "
vpn_state_path = '/sys/class/net/' + self.VPN_INTERFACE_NAME
self.vpn_state = "down"
if os.path.exists(vpn_state_path):
self.vpn_state = "up"
self.tray.set_from_stock(gtk.STOCK_CONNECT)
vpn_state_text = "Подключен"
else:
self.tray.set_from_stock(gtk.STOCK_DISCONNECT)
vpn_state_text = "Отключен"
try:
gw = os.popen("ip -4 route show default").read().split()
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((gw[2], 0))
ipaddr = s.getsockname()[0]
gateway = gw[2]
try:
url = 'http://ipinfo.io/json'
response = urllib2.urlopen(url)
data = json.load(response)
realip = data['ip']
city = data['city']
country = data['country']
except:
self.notify_message("ОШИБКА :: Проблемы с Интернетом")
except:
self.notify_message("ОШИБКА :: Проблемы с интерфейсом")
vpn_ipaddr = ""
if self.vpn_state == "up":
vpn_ipaddr = ni.ifaddresses(self.VPN_INTERFACE_NAME)[ni.AF_INET][0]['addr']
result = ("VPN: " + vpn_state_text
+ "\nЧастный IP: " + ipaddr + ((", " + vpn_ipaddr) if vpn_ipaddr else "")
+ "\nШлюз: " + gateway
+ "\nПубличный IP: " + realip
+ "\nГород: " + city + " (" + country + ")")
self.tray.set_tooltip((result))
self.notify_message(result)
return result
def notify_message(self, message):
subprocess.Popen(['notify-send', message])
return
def on_right_click(self, icon, event_button, event_time):
self.make_menu(event_button, event_time)
def make_menu(self, event_button, event_time):
menu = gtk.Menu()
# Меню <Подключиться>
item_up = gtk.ImageMenuItem(gtk.STOCK_CONNECT)
item_up.show()
menu.append(item_up)
item_up.connect('activate', self.run_vpn_up)
# Меню <Отключиться>
item_down = gtk.ImageMenuItem(gtk.STOCK_DISCONNECT)
item_down.show()
menu.append(item_down)
item_down.connect('activate', self.run_vpn_down)
# Включаем/отключаем доступность пункта меню
if self.vpn_state == "up":
item_up.set_sensitive(False)
item_down.set_sensitive(True)
else:
item_up.set_sensitive(True)
item_down.set_sensitive(False)
# Меню <Обновить>
item_refresh = gtk.ImageMenuItem(gtk.STOCK_REFRESH)
item_refresh.show()
menu.append(item_refresh)
item_refresh.connect('activate', self.refresh_info)
# Меню <О программе>
item_about = gtk.MenuItem("О программе")
item_about.show()
menu.append(item_about)
item_about.connect('activate', self.show_about_dialog)
# Меню <Выход>
item_quit = gtk.ImageMenuItem(gtk.STOCK_QUIT)
item_quit.show()
menu.append(item_quit)
item_quit.connect('activate', gtk.main_quit)
menu.popup(None, None, gtk.status_icon_position_menu,
event_button, event_time, self.tray)
def run_vpn_up(self, widget):
# Подключение
os.system('wg-quick up ' + self.VPN_INTERFACE_NAME)
self.get_info()
def run_vpn_down(self, widget):
# Отключение
os.system('wg-quick down ' + self.VPN_INTERFACE_NAME)
self.get_info()
def refresh_info(self, widget):
self.get_info()
def show_about_dialog(self, widget):
about_dialog = gtk.AboutDialog()
about_dialog.set_destroy_with_parent(True)
about_dialog.set_icon_name("VPNWidget")
about_dialog.set_name('VPNWidget')
about_dialog.set_version("1.0")
about_dialog.set_copyright("(C) 2020 Денис Ткаченко")
about_dialog.set_comments(("Программа для управления VPN (WireGuard)"))
about_dialog.set_authors(['Денис Ткаченко <d.tkachenko88@yandex.ru>'])
about_dialog.run()
about_dialog.destroy()
if __name__ == "__main__":
VPNWidget()
gtk.main()
Просто, не знаю когда руки дойдут, чего добру пропадать, верно? :) Кстати, на ЛОР-е не хватает руководства по настройке этой замечательной штуки (WireGuard).
P.S. Используя мой скрипт, естественно, не запускайте WireGuard на клиенте в качестве сервиса. Он работает с командами wg-quick up/down, иконка программы помещается в трей, все действия с контекстного меню. Неделю пользуюсь - полет нормальный. Всем добра!
P.P.S. [АВТОЗАПУСК] Т.к. wg-quick требует прав root, то я для себя по простому закинул скрипт в автозагрузку и дал только ему права в sudoers. Есть, конечно, и другие варианты автозапуска, озвучил самый простой.