예제 #1
0
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

    firewall.batch_rule(cgroup_iptables_del)
    firewall.batch_rule_6(cgroup_iptables_del)

    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")
예제 #2
0
    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(config.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"]
                    ]
                firewall.batch_rule_6(wg_rules)
                firewall.batch_rule(wg_rules)
                tunnel.exe_custom_scripts("down", self.wg_provider, config.settings)
                self.wg_connect = 0

        elif env == "bypass":
            for i in self.pid_list:
                if i[1] == "OpenVPN_bypass":
                    self.kill_pid(i)
예제 #3
0
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"
                  ]]

    firewall.batch_rule(postroutes)
    firewall.batch_rule_6(postroutes)
예제 #4
0
def create_cgroup(user,
                  group,
                  interface,
                  gw=None,
                  gw_6=None,
                  default_int=None,
                  no_dnsmasq=0):
    print("nodnsmasq={}".format(no_dnsmasq))
    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"
                       ]]

    if no_dnsmasq == 0:
        cgroup_iptables.append([
            "-t", "nat", "-A", "OUTPUT", "-m", "cgroup", "--cgroup",
            "0x00110011", "-p", "tcp", "--dport", "53", "-j", "REDIRECT",
            "--to-ports", "5354"
        ])
        cgroup_iptables.append([
            "-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")

    firewall.batch_rule(cgroup_iptables)
    if gw_6 != "None" and default_int == interface:
        firewall.batch_rule_6(cgroup_iptables)

    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"
        ])
        firewall.batch_rule_6(cgroup_iptables)

    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")

    try:
        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))
    except FileNotFoundError:
        logging.error("Failed to disable 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?")
예제 #5
0
    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")