From e266f43d359a03ee5ac9ad072ba474f959dc8739 Mon Sep 17 00:00:00 2001 From: mantaohuang Date: Thu, 9 Apr 2020 15:21:48 -0400 Subject: [PATCH] some improvement and readme --- README.md | 10 ++++++++++ o_manager.py | 26 ++++++++++++-------------- openvpn.py | 24 +++++++++++++++--------- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index e69de29..99cec33 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,10 @@ +Multiple Openvpn Manager +========= + +Supervise multiple openvpn client connections and provide socks5 proxy with load balancing to achieve bandwidth aggregation from multiple connections. The link isolation is by iptables and ip rules using group id as the identifier. One socks5 server is started for each openvpn connection, and an additional load balancing socks5 server listens for external requests. + +The program also provides link quality monitoring (ping time and speed). The load balancing proxy has the option to dynamically change the rule for load balancing based on the link quality. + +The program has builtin web ui to monitor and control the openvpn connections and load balancing rules. + +The program needs to run as root. diff --git a/o_manager.py b/o_manager.py index 45112f7..8e90618 100644 --- a/o_manager.py +++ b/o_manager.py @@ -10,27 +10,27 @@ class OManager: self.base_folder = base_folder self.base_port = base_port self.ops = [] - self.idx = 0 + self.new_idx = 0 self.running_idx = [] self.run_task = [] - self.PID = None + self.PID = None if loop: self.loop = loop else: self.loop = asyncio.get_event_loop() def new_op(self, cfg_fp, name=None, additional_cfg={}): - folder_path = os.path.join(self.base_folder, f"session{self.idx}") + folder_path = os.path.join(self.base_folder, f"session{self.new_idx}") if not os.path.isdir(folder_path): os.makedirs(folder_path) if not name: - name = f"openvpn-{self.idx}" - os.system(f"groupadd vpn{self.idx}") - op = Openvpn(cfg_fp, self.idx, folder_path, - f"{self.base_port + self.idx}", "script.sh.template", "3proxy.cfg.template", name=name, + name = f"openvpn-{self.new_idx}" + os.system(f"groupadd vpn{self.new_idx}") + op = Openvpn(cfg_fp, self.new_idx, folder_path, + f"{self.base_port + self.new_idx}", "script.sh.template", "3proxy.cfg.template", name=name, additional_cfg=additional_cfg) self.ops.append(op) - self.idx += 1 + self.new_idx += 1 return op def generate_lb_cfg(self): @@ -40,8 +40,7 @@ class OManager: buf = template_f.read() template = Template(buf) items = { - "running_idx": self.running_idx, - "port": f"{1080 + self.idx}" + "running_idx": self.running_idx } lb_cfg = template.generate(**items) with open(lb_cfg_fp, "wb") as lb_cfg_f: @@ -72,9 +71,8 @@ class OManager: self.reset_lb() def stop_all(self): - loop = self.loop for op in self.ops: - loop.create_task(op.stop()) + op.stop() self.running_idx = [] self.reset_lb() @@ -91,7 +89,7 @@ class OManager: lb_cfg_fp = self.generate_lb_cfg() if len(self.running_idx): lb_cmd = ["go-socks-lb/go-socks-lb", "-config", - lb_cfg_fp, "-bind", "0.0.0.0:7000"] + lb_cfg_fp, "-bind", "0.0.0.0:7000"] print("lb_cmd", lb_cmd) self.run_task.append(self.loop.create_task( self.run_cmd(lb_cmd))) @@ -100,7 +98,7 @@ class OManager: while True: print("Manager trying to start go") proc = await asyncio.create_subprocess_exec( - cmd[0], *cmd[1:], + cmd[0], *cmd[1:], stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) print("Manager started", cmd) diff --git a/openvpn.py b/openvpn.py index eecd1e6..dfa9042 100644 --- a/openvpn.py +++ b/openvpn.py @@ -13,6 +13,7 @@ from datetime import datetime import humanize from tornado.template import Template import stat +import shutil def generate_config(in_fp, cfg): @@ -149,10 +150,17 @@ class Openvpn: except: return "" - def clear_log(self): - os.remove(self.log_fp) + def clear_folder(self): + try: + # removing all files in folder path, not removing folders + dirpath = self.folder_path + for filename in os.listdir(dirpath): + filepath = os.path.join(dirpath, filename) + os.remove(filepath) + except Exception as err: + print("cannot remove log file, error:", err) - async def stop(self): + def stop(self, clear_folder=True): if self.status == RUNNING: for pid in self.pids: try: @@ -164,13 +172,11 @@ class Openvpn: task.cancel() self.pids = [] self.run_task = [] - try: - os.remove(self.log_fp) - except Exception as err: - print("cannot remove log file, error:", err) + if clear_folder: + self.clear_folder() - async def restart(self): - await self.stop() + def restart(self): + self.stop() self.start() def get_io_stat(self):