我希望创建一个“切换按钮”放入我的 Unity Launcher 中,以启动或停止我的 OpenVPN 设置。
基本上我正在寻找一个可以
sudo /etc/init.d/openvpn start
或者
sudo /etc/init.d/openvpn stop
(通过选择一个选项或另一个选项,或者通过单击它进行切换)。
我已经使用了十年 Mac,现在正准备迁移到 Linux,请保持简单,因为我的大脑可能已经烂掉了。我知道这是可能的,因为我在前同事的机器上看到了这一点。
当我没有通过 VPN 连接时,路由的输出:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 192.168.111.1 0.0.0.0 UG 0 0 0 wlan0
192.168.111.0 * 255.255.255.0 U 9 0 0 wlan0
当我通过 VPN 连接时的输出
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 10.8.0.101 128.0.0.0 UG 0 0 0 tun0
default 192.168.111.1 0.0.0.0 UG 0 0 0 wlan0
10.8.0.1 10.8.0.101 255.255.255.255 UGH 0 0 0 tun0
10.8.0.101 * 255.255.255.255 UH 0 0 0 tun0
<OpenVPNserver>.net 192.168.111.1 255.255.255.255 UGH 0 0 0 wlan0
128.0.0.0 10.8.0.101 128.0.0.0 UG 0 0 0 tun0
192.168.111.0 * 255.255.255.0 U 9 0 0 wlan0
答案1
这里有一个切换脚本、一个设置说明、两个桌面文件及其对应的图标。虽然答案有点冗长,但设置起来很简单。
怎么运行的
如果您单击启动器中的图标,脚本将查找 VPN 连接是打开还是关闭。无论哪种情况,它都会切换到另一个选项,并且启动器中的图标将相应地替换。10 秒后,脚本将检查连接是否实际建立。如果没有,它会将图标改回正确的图标。您可以在脚本的头部部分 ( wait = 10
) 更改此“超时”设置。(不要触碰其他定义,除非您知道自己在做什么)
几点说明:
- 首先也是最重要的一点:从本地目录运行需要管理员权限的脚本,从定义上讲是一种潜在的安全风险。每次运行脚本时,您都不会检查其代码,如果怀有恶意的人能够更改代码,那么任何事情都可能发生。如果您对谁在您的计算机上做什么有疑问(或应该有疑问),我建议您从安全位置运行脚本。
- 为了使其界面更加流畅,我在您提供的命令中使用了 gksu,而不是 sudo。默认情况下未安装 gksu,您必须安装它。
- 该脚本会查看 shell 在命令“route”上返回的内容。我使用 作为一个标识符,
<OpenVPNserver>
因为这是最简单、最明显的字符串。如果设置用于其他类型的连接,它将不够用。 - 为了根据连接状态替换启动器中的图标,脚本会读取当前启动器的内容。如果您使用 13.10 或 14.04,应该没问题,但 gsettings -“call” 的结果在较旧的 Ubuntu 版本上看起来有点不同,并且无法正常工作。
- 在脚本更改启动器之前,会创建当前启动器的备份(脚本)
/.restore_currentlauncher.sh
。虽然在我使用它的这些年里,我从来没有需要过它,但有它总是好的。
如何使用:
图标:
右键单击下面的图标并将其保存为toggle_officon.png
(白色)和toggle_onicon.png
(绿色)。
剧本:复制以下(全部)文本,将其粘贴到一个空文件中,并将其保存为toggle_vpn.py
#!/usr/bin/python3
import subprocess
import getpass
import time
# time to wait, to check if connection was established (set correct icon)
wait = 10
# identifying difference on route command
running_id = "<OpenVPNserver>"
# location of the launcher restore script
backup_copy = "/home/"+getpass.getuser()+"/.restore_currentlauncher.sh"
# name of the desktop file if connection is down
mention_ifdown = 'application://VPN_off.desktop'
# name of the desktop file if connection is down
mention_ifup = 'application://VPN_on.desktop'
def check_ifrunning():
# check if connection is up or down
get_routeinfo = subprocess.Popen(["route"], stdout=subprocess.PIPE)
output = (get_routeinfo.communicate()[0].decode("utf-8"))
if running_id in output:
return "running"
else:
return "not_running"
def read_currentlauncher():
# read the current launcher contents
get_launcheritems = subprocess.Popen([
"gsettings",
"get",
"com.canonical.Unity.Launcher",
"favorites"
], stdout=subprocess.PIPE)
return eval((get_launcheritems.communicate()[0].decode("utf-8")))
def set_current_launcher(current_launcher):
# before editing the launcher, create restore script
backup_data = read_currentlauncher()
with open(backup_copy, "wt") as create_backup:
create_backup.write(
"#!/bin/sh\n\n"\
"gsettings set com.canonical.Unity.Launcher favorites "+\
'"'+str(backup_data)+'"'
)
# preparing subprocess command string
current_launcher = str(current_launcher).replace(", ", ",")
subprocess.Popen([
"gsettings",
"set",
"com.canonical.Unity.Launcher",
"favorites",
current_launcher,
])
def set_icon(change_mode):
# defines the appropriate icon in the launcher
state = check_ifrunning()
if state == "running":
if change_mode == "set_current":
iconset = [mention_ifup, mention_ifdown]
else:
iconset = [mention_ifdown, mention_ifup]
elif state == "not_running":
if change_mode == "set_current":
iconset = [mention_ifdown, mention_ifup]
else:
iconset = [mention_ifup, mention_ifdown]
# set the defined icon
current_launcher = read_currentlauncher()
if iconset[0] in current_launcher:
pass
else:
index = current_launcher.index(iconset[1])
current_launcher.pop(index)
set_current_launcher(current_launcher)
time.sleep(1)
current_launcher.insert(index, iconset[0])
set_current_launcher(current_launcher)
def toggle_connection():
set_icon("set_alter")
runcheck = check_ifrunning()
if runcheck == "not_running":
subprocess.call(["gksu", "/etc/init.d/openvpn", "start"])
else:
subprocess.call(["gksu", "/etc/init.d/openvpn", "stop"])
time.sleep(wait)
set_icon("set_current")
toggle_connection()
桌面文件
VPN_off 桌面文件:复制以下文本,输入图标和脚本的适当路径,将其保存为 VPN_off.desktop~/.local/share/applications
[Desktop Entry]
Name=VPN_off
Exec=python3 /path_to_script/toggle_vpn.py
Icon=/path_to_icon/toggle_officon.png
Terminal=false
Type=Application
NoDisplay=true
VPN_on 桌面文件:复制以下文本,输入图标和脚本的适当路径,将其保存为 VPN_on.desktop~/.local/share/applications
[Desktop Entry]
Name=VPN_on
Exec=python3 /path_to_script/toggle_vpn.py
Icon=/path_to_icon/toggle_onicon.png
Terminal=false
Type=Application
NoDisplay=true
如果您执行了上述操作,请将其中一个桌面文件拖到启动器上(您可能需要注销并重新登录),它应该可以正常工作!如果您将“错误的”桌面文件拖到启动器上,它将在第一次使用时得到纠正。
如果您需要更多具体的详细信息,请发表评论。