def wg(self, wg_file): name = self.ovpn_dict["name"] self.logger.info("Establishing connection to %s" % name) wg_rules = [["-I", "INPUT", "1", "-i", "wg_qomui", "-j", "ACCEPT"], ["-I", "OUTPUT", "1", "-o", "wg_qomui", "-j", "ACCEPT"]] for rule in wg_rules: firewall.add_rule_6(rule) firewall.add_rule(rule) time.sleep(1) try: self.tun = "wg_qomui" cmd_wg = Popen(['wg-quick', 'up', '%s' % wg_file], stdout=PIPE, stderr=STDOUT) for line in cmd_wg.stdout: logging.info(line) self.wg_connect = 1 self.reply("success") except (CalledProcessError, FileNotFoundError): self.reply("fail1")
def disconnect(self): self.restore_default_dns() for i in self.pid_list: self.kill_pid(i) if self.wg_connect == 1: try: wg_down = Popen( ["wg-quick", "down", "%s/wg_qomui.conf" % ROOTDIR], stdout=PIPE, stderr=STDOUT) for line in wg_down.stdout: logging.info(line) except CalledProcessError: pass wg_rules = [["-D", "INPUT", "-i", "wg_qomui", "-j", "ACCEPT"], ["-D", "OUTPUT", "-o", "wg_qomui", "-j", "ACCEPT"]] for rule in wg_rules: firewall.add_rule_6(rule) firewall.add_rule(rule) self.wg_connect = 0
def allow_ip(self, ip, rule): try: if len(ip.split(".")) == 4: firewall.add_rule(rule) elif len(ip.split(":")) >= 4: firewall.add_rule_6(rule) except: pass
def delete_cgroup(interface): cgroup_iptables_del = [[ "-t", "mangle", "-D", "OUTPUT", "-m", "cgroup", "--cgroup", "0x00110011", "-j", "MARK", "--set-mark", "11" ], [ "-t", "nat", "-D", "POSTROUTING", "-m", "cgroup", "--cgroup", "0x00110011", "-o", "{}".format(interface), "-j", "MASQUERADE" ], [ "-D", "OUTPUT", "-m", "cgroup", "--cgroup", "0x00110011", "-j", "ACCEPT" ], [ "-D", "INPUT", "-m", "cgroup", "--cgroup", "0x00110011", "-j", "ACCEPT" ], [ "-t", "nat", "-D", "OUTPUT", "-m", "cgroup", "--cgroup", "0x00110011", "-p", "tcp", "--dport", "53", "-j", "REDIRECT", "--to-ports", "5354" ], [ "-t", "nat", "-D", "OUTPUT", "-m", "cgroup", "--cgroup", "0x00110011", "-p", "udp", "--dport", "53", "-j", "REDIRECT", "--to-ports", "5354" ]] try: check_call( ["ip", "rule", "del", "fwmark", "11", "table", "bypass_qomui"]) except CalledProcessError: pass for rule in cgroup_iptables_del: firewall.add_rule(rule) for rule in cgroup_iptables_del: firewall.add_rule_6(rule) try: os.rmdir(cgroup_path) except (OSError, FileNotFoundError): logging.debug( "Bypass: Could not delete {} - resource does not exist or is busy". format(cgroup_path)) logging.info("Deleted cgroup")
def set_bypass_vpn(interface, interface_cmd, tun, tun_cmd): postroutes = [[ "-t", "nat", tun_cmd, "POSTROUTING", "-m", "cgroup", "--cgroup", "0x00110011", "-o", tun, "-j", "MASQUERADE" ], [ "-t", "nat", interface_cmd, "POSTROUTING", "-m", "cgroup", "--cgroup", "0x00110011", "-o", interface, "-j", "MASQUERADE" ]] for rule in postroutes: firewall.add_rule(rule) firewall.add_rule_6(rule)
def dns_request_exception(action, dns_1, dns_2, port): rules = [] protocols = ["udp", "tcp"] if action == "-I": logging.info("iptables: adding exception for DNS requests") elif action == "-D": logging.info("iptables: removing exception for DNS requests") for p in protocols: rules.append( [action, 'OUTPUT', '1', '-p', p, '--dport', port, '-j', 'ACCEPT']) rules.append( [action, 'INPUT', '1', '-p', p, '--sport', port, '-j', 'ACCEPT']) for rule in rules: firewall.add_rule(rule) firewall.add_rule_6(rule)
def disconnect(self, env): if env == "main": self.restore_default_dns() self.tun is None for i in self.pid_list: if i[1] != "OpenVPN_bypass": self.kill_pid(i) if self.wg_connect == 1: try: wg_down = Popen([ "wg-quick", "down", "{}/wg_qomui.conf".format(ROOTDIR) ], stdout=PIPE, stderr=STDOUT) for line in wg_down.stdout: self.logger.info( "WireGuard: " + line.decode("utf-8").replace("\n", "")) except CalledProcessError: pass #as WireGuard is down we can remove those rules wg_rules = [["-D", "INPUT", "-i", "wg_qomui", "-j", "ACCEPT"], ["-D", "OUTPUT", "-o", "wg_qomui", "-j", "ACCEPT"]] for rule in wg_rules: firewall.add_rule_6(rule) firewall.add_rule(rule) tunnel.exe_custom_scripts("down", self.wg_provider, self.config) self.wg_connect = 0 elif env == "bypass": for i in self.pid_list: if i[1] == "OpenVPN_bypass": self.kill_pid(i)
def wg(self, wg_file): 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"]] for rule in wg_rules: firewall.add_rule_6(rule) firewall.add_rule(rule) 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 self.status.emit("connection_established") except (CalledProcessError, FileNotFoundError): self.status.emit("fail")
def create_cgroup(user, group, interface, gw=None, gw_6=None, default_int=None): logging.info("Creating bypass for {}".format(interface)) delete_cgroup(default_int) cgroup_iptables = [[ "-t", "mangle", "-A", "OUTPUT", "-m", "cgroup", "--cgroup", "0x00110011", "-j", "MARK", "--set-mark", "11" ], [ "-t", "nat", "-A", "POSTROUTING", "-m", "cgroup", "--cgroup", "0x00110011", "-o", "{}".format(interface), "-j", "MASQUERADE" ], [ "-I", "OUTPUT", "1", "-m", "cgroup", "--cgroup", "0x00110011", "-j", "ACCEPT" ], [ "-I", "INPUT", "1", "-m", "cgroup", "--cgroup", "0x00110011", "-j", "ACCEPT" ], [ "-t", "nat", "-A", "OUTPUT", "-m", "cgroup", "--cgroup", "0x00110011", "-p", "tcp", "--dport", "53", "-j", "REDIRECT", "--to-ports", "5354" ], [ "-t", "nat", "-A", "OUTPUT", "-m", "cgroup", "--cgroup", "0x00110011", "-p", "udp", "--dport", "53", "-j", "REDIRECT", "--to-ports", "5354" ]] if not os.path.exists(cgroup_path): os.makedirs(cgroup_path) with open("{}/net_cls.classid".format(cgroup_path), 'w') as setcid: setcid.write(cls_id) setcid.close() logging.debug("Bypass: Created cgroup 'net_cls:bypass_qomui'") try: check_call(["ip", "route", "show", "table", "bypass_qomui"]) logging.debug( "Bypass: No routing table added - table bypass_qomui already exists" ) except CalledProcessError: with open("/etc/iproute2/rt_tables", "a") as rt_tables: rt_tables.write("11 bypass_qomui\n") logging.debug("Bypass: Created new routing table") for rule in cgroup_iptables: firewall.add_rule(rule) if gw_6 != "None" and default_int == interface: for rule in cgroup_iptables: firewall.add_rule_6(rule) else: logging.debug("Blocking ipv6 via bypass_qomui") cgroup_iptables.pop(1) cgroup_iptables.insert(1, [ "-t", "nat", "-A", "POSTROUTING", "-m", "cgroup", "--cgroup", "0x00110011", "-o", "{}".format(interface), "-j", "MASQUERADE" ]) cgroup_iptables.pop(2) cgroup_iptables.insert(2, [ "-I", "OUTPUT", "1", "-m", "cgroup", "--cgroup", "0x00110011", "-j", "DROP" ]) cgroup_iptables.pop(3) cgroup_iptables.insert(3, [ "-I", "INPUT", "1", "-m", "cgroup", "--cgroup", "0x00110011", "-j", "DROP" ]) for rule in cgroup_iptables: firewall.add_rule_6(rule) try: check_call( ["ip", "rule", "add", "fwmark", "11", "table", "bypass_qomui"]) if interface == default_int: check_call(["ip", "route", "flush", "table", "bypass_qomui"]) check_call( ["ip", "rule", "add", "fwmark", "11", "table", "bypass_qomui"]) check_call([ "ip", "route", "add", "default", "via", "{}".format(gw), "dev", "{}".format(interface), "table", "bypass_qomui" ]) logging.debug( "Bypass: Set ipv4 route 'default via {} dev {}'".format( gw, interface)) except CalledProcessError: logging.error( "Bypass: Setting ipv4 route 'default via {} dev {}'".format( gw, interface)) try: check_call([ "ip", "-6", "rule", "add", "fwmark", "11", "table", "bypass_qomui" ]) if interface == default_int: check_call(["ip", "-6", "route", "flush", "table", "bypass_qomui"]) check_call([ "ip", "-6", "route", "add", "default", "via", "{}".format(gw_6), "dev", "{}".format(interface), "table", "bypass_qomui" ]) logging.debug( "Bypass: Set ipv6 route 'default via {} dev {}'".format( gw_6, interface)) except CalledProcessError: logging.error( "Bypass: Setting ipv6 route 'default via {} dev {}' failed".format( gw, interface)) with open("/proc/sys/net/ipv4/conf/all/rp_filter", 'w') as rp_edit_all: rp_edit_all.write("2") with open("/proc/sys/net/ipv4/conf/{}/rp_filter".format(interface), 'w') as rp_edit_int: rp_edit_int.write("2") logging.debug( "Disabled reverse path filtering for {}".format(interface)) try: check_call([ "cgcreate", "-t", "{}:{}".format(user, group), "-a" "{}:{}".format(user, group), "-g", "net_cls:bypass_qomui" ]) logging.debug("Bypass: Configured cgroup access for {}".format(user)) logging.info("Successfully created cgroup for {}".format(interface)) except (CalledProcessError, FileNotFoundError) as e: logging.error("Creating cgroup failed - is libcgroup installed?")