def cgroup_vpn(self): self.kill_dnsmasq() if self.tun_bypass is not None: dev_bypass = self.tun_bypass bypass.create_cgroup(self.net["user"], self.net["group"], dev_bypass, default_int=self.interface) if self.tun is not None: interface = self.tun else: interface = self.interface interface_bypass = self.tun_bypass dns_manager.set_dns("127.0.0.1") dns_manager.dnsmasq(interface, "53", self.dns, self.dns_2, "") else: dev_bypass = self.interface dns_manager.set_dns(self.dns, self.dns_2) if self.config["bypass"] == 1: dns_manager.dnsmasq(dev_bypass, "5354", self.dns_bypass, self.dns_2_bypass, "_bypass") bypass.create_cgroup(self.net["user"], self.net["group"], dev_bypass, gw=self.gw, gw_6=self.gw_6, default_int=self.interface)
def cgroup_vpn(self): self.kill_dnsmasq() no_dnsmasq = config.settings["no_dnsmasq"] if self.tun_bypass is not None: dev_bypass = self.tun_bypass bypass.create_cgroup( self.net["user"], self.net["group"], dev_bypass, default_int=self.interface, no_dnsmasq=no_dnsmasq ) if self.tun is not None: interface = self.tun else: interface = self.interface interface_bypass = self.tun_bypass if config.settings["dns_off"] == 0: dns_manager.set_dns("127.0.0.1") if no_dnsmasq == 0: dns_manager.dnsmasq( interface, "53", self.dns, self.dns_2, "" ) else: dev_bypass = self.interface if config.settings["dns_off"] == 0: dns_manager.set_dns(self.dns, self.dns_2) if config.settings["bypass"] == 1: if no_dnsmasq == 0: dns_manager.dnsmasq( dev_bypass, "5354", self.dns_bypass, self.dns_2_bypass, "_bypass" ) bypass.create_cgroup( self.net["user"], self.net["group"], dev_bypass, gw=self.gw, gw_6=self.gw_6, default_int=self.interface, no_dnsmasq=no_dnsmasq )
def ovpn(self, ovpn_file, h, cwd_ovpn): self.log.emit(("info", "Establishing new OpenVPN tunnel")) name = self.server_dict["name"] last_ip = self.server_dict["ip"] add = "" if "bypass" not in self.server_dict and h != 1: exe_custom_scripts("pre", self.server_dict["provider"], self.config) #if doublehop is selected additional arguments are needed for OpenVPN if h == "1": add = "_hop" name = self.hop_dict["name"] self.log.emit(("info", "Establishing connection to {} - first hop".format(name))) last_ip = self.hop_dict["ip"] cmd_ovpn = ['openvpn', '--config', '{}'.format(ovpn_file), '--route-nopull', '--script-security', '2', '--up', '{}/scripts/hop.sh -f {} {}'.format( ROOTDIR, self.hop_dict["ip"], self.server_dict["ip"] ), '--down', '{}/scripts/hop_down.sh {}'.format(ROOTDIR, self.hop_dict["ip"]) ] elif h == "2": self.log.emit(("info", "Establishing connection to {} - second hop".format(name))) cmd_ovpn = ['openvpn', '--config', '{}'.format(ovpn_file), '--route-nopull', '--script-security', '2', '--up', '{}/hop.sh -s'.format(ROOTDIR) ] else: self.log.emit(("info", "Establishing connection to {}".format(name))) cmd_ovpn = ['openvpn', '{}'.format(ovpn_file)] if "bypass" in self.server_dict: add = "_bypass" self.dns_bypass = self.config["alt_dns1"] self.dns_2_bypass = self.config["alt_dns2"] else: self.dns = self.config["alt_dns1"] self.dns_2 = self.config["alt_dns2"] ovpn_exe = Popen(cmd_ovpn, stdout=PIPE, stderr=STDOUT, cwd=cwd_ovpn, bufsize=1, universal_newlines=True ) self.log.emit(("debug", "OpenVPN pid: {}".format(ovpn_exe.pid))) self.pid.emit((ovpn_exe.pid, "OpenVPN{}".format(add))) line = ovpn_exe.stdout.readline() self.status.emit("starting_timer{}".format(add)) #keep this thread as long as openvpn process has not been terminated #disconnection from gui will kill the openvpn process and break the loop while line.find("SIGTERM[hard,] received, process exiting") == -1: time_measure = time.time() line_format = ("OpenVPN:" + line.replace('{}'.format(time.asctime()), '').replace('\n', '')) self.log.emit(("info", line_format)) #signals that tunnel has been successfully established if line.find("Initialization Sequence Completed") != -1: if "bypass" not in self.server_dict and h != 1: exe_custom_scripts("up", self.server_dict["provider"], self.config) self.connect_status = 1 self.bypass.emit() self.status.emit("connection_established{}".format(add)) self.log.emit(("info", "Successfully connected to {}".format(name))) elif line.find('TUN/TAP device') != -1: setattr(self, "tun{}".format(add), line_format.split(" ")[3]) self.dev.emit(("tun{}".format(add), getattr(self, "tun{}".format(add)))) #read dns servers pushed by OpenVPN server #if not found: fallback to alternatives ones from config file elif line.find('PUSH: Received control message:') != -1: dns_option_1 = line_format.find('dhcp-option') if dns_option_1 != -1 and self.config["alt_dns"] == 0: option = line_format[dns_option_1:].split(",")[0] setattr(self, "dns{}".format(add), option.split(" ")[2]) dns_option_2 = line_format.find('dhcp-option', dns_option_1+20) if dns_option_2 != -1: option = line_format[dns_option_2:].split(",")[0] setattr(self, "dns_2{}".format(add), option.split(" ")[2]) else: setattr(self, "dns_2{}".format(add), None) dns_manager.set_dns(getattr(self, "dns{}".format(add)), getattr(self, "dns_2{}".format(add))) self.dnsserver.emit((add, getattr(self, "dns{}".format(add)), getattr(self, "dns_2{}".format(add)))) #might be redundant as gui checks for timeout anyway elif line.find("Restart pause, 10 second(s)") != -1: self.status.emit("conn_attempt_failed{}".format(add)) self.log.emit(("info" ,"Connection attempt failed")) elif line.find('SIGTERM[soft,auth-failure]') != -1: self.status.emit("conn_attempt_failed{}".format(add)) self.log.emit(("info", "Authentication error while trying to connect")) #bugfix for double-hop #sometimes whitelisting servers via iptables fails so we retry #need to investigate further elif line.find('write UDP: Operation not permitted') != -1: ips = [] try: hop_ip = self.hop_dict["ip"] ips.append(hop_ip) except: pass remote_ip = self.server_dict["ip"] ips.append(remote_ip) for ip in ips: firewall.allow_dest_ip(ip, "-I") elif line.find("Exiting due to fatal error") != -1: self.status.emit("conn_attempt_failed{}".format(add)) self.log.emit(("info", "Connection attempt failed due to fatal error")) #break if openvpn emits empty lines to avoid clogging log elif line == '': break line = ovpn_exe.stdout.readline() if "bypass" not in self.server_dict and h != 1: exe_custom_scripts("down", self.server_dict["provider"], self.config) self.log.emit(("info", "OpenVPN:" + line.replace('{}'.format(time.asctime()), '').replace('\n', ''))) ovpn_exe.stdout.close() self.status.emit("tunnel_terminated{}".format(add)) self.log.emit(("info", "OpenVPN - process killed")) #delete outbound rule for this server firewall.allow_dest_ip(last_ip, "-D") #reset bypass so it can work without second OpenVPN tunnel if add == "_bypass": setattr(self, "dns{}".format(add), self.config["alt_dns1"]) setattr(self, "dns{}_2".format(add), self.config["alt_dns2"]) setattr(self, "tun{}".format(add), None) self.dnsserver.emit((add, self.config["alt_dns1"], self.config["alt_dns2"])) self.dev.emit(("tun{}".format(add), getattr(self, "tun{}".format(add)))) self.bypass.emit() else: setattr(self, "tun{}".format(add), None) self.dev.emit(("tun{}".format(add), getattr(self, "tun{}".format(add))))
def wg(self, wg_file): exe_custom_scripts("pre", self.server_dict["provider"], self.config) name = self.server_dict["name"] self.log.emit(("info", "Establishing connection to {}".format(name))) #allow traffic via wg interface wg_rules = [["-I", "INPUT", "2", "-i", "wg_qomui", "-j", "ACCEPT"], ["-I", "OUTPUT", "2", "-o", "wg_qomui", "-j", "ACCEPT"] ] firewall.batch_rule_6(wg_rules) firewall.batch_rule(wg_rules) time.sleep(1) try: self.dev.emit(("tun", "wg_qomui")) cmd_wg = Popen(['wg-quick', 'up', '{}'.format(wg_file)], stdout=PIPE, stderr=STDOUT) for line in cmd_wg.stdout: self.log.emit(("info", "WireGuard: " + line.decode("utf-8").replace("\n", ""))) with open("{}/wg_qomui.conf".format(ROOTDIR), "r") as dns_check: lines = dns_check.readlines() for line in lines: if line.startswith("DNS ="): dns_servers = line.split("=")[1].replace(" ", "").split(",") self.dns = dns_servers[0].split("\n")[0] try: self.dns_2 = dns_servers[1].split("\n")[0] except IndexError: self.dns_2 = None dns_manager.set_dns(self.dns, self.dns_2) self.dnsserver.emit(("", self.dns, self.dns_2)) #Necessary, otherwise bypass mode breaks - need to investigate if self.config["bypass"] == 1: try: check_call(["ip", "rule", "del", "fwmark", "11", "table", "bypass_qomui"]) check_call(["ip", "-6", "rule", "del", "fwmark", "11", "table", "bypass_qomui"]) except CalledProcessError: pass try: check_call(["ip", "rule", "add", "fwmark", "11", "table", "bypass_qomui"]) check_call(["ip", "-6", "rule", "add", "fwmark", "11", "table", "bypass_qomui"]) self.log.emit(("debug", "Packet classification for bypass table reset")) except CalledProcessError: self.log.emit(("warning", "Could not reset packet classification for bypass table")) self.bypass.emit() #we can't be sure of that exe_custom_scripts("up", self.server_dict["provider"], self.config) self.status.emit("connection_established") except (CalledProcessError, FileNotFoundError): self.status.emit("fail")