Ejemplo n.º 1
0
def handle_domain_proxy(sock, host, port, client_address, left_buf=""):
    if not isinstance(sock, SocketWrap):
        sock = SocketWrap(sock, client_address[0], client_address[1])

    sock.target = "%s:%d" % (host, port)
    rule = g.user_rules.check_host(host, port)
    if not rule:
        if host == "www.twitter.com":
            rule = "gae"
        elif utils.check_ip_valid(host) and utils.is_private_ip(host):
            rule = "direct"

    if rule:
        return try_loop("domain user", [rule], sock, host, port, client_address, left_buf)

    record = g.domain_cache.get(host)
    if record:
        rule = record["r"]
        if rule == "gae":
            rule_list = ["gae", "socks", "redirect_https", "direct"]
        else:
            rule_list = ["direct", "gae", "socks", "redirect_https"]

        if not g.domain_cache.accept_gae(host):
            rule_list.remove("gae")
    elif g.gfwlist.check(host):
        rule_list = ["gae", "socks", "redirect_https", "direct"]
    else:
        rule_list = ["direct", "gae", "socks", "redirect_https"]

    try_loop("domain", rule_list, sock, host, port, client_address, left_buf)
Ejemplo n.º 2
0
    def create_connect(self, queue, host, ip, port, timeout=5):
        if int(g.config.PROXY_ENABLE):
            sock = socks.socksocket(socket.AF_INET if ':' not in
                                    ip else socket.AF_INET6)
        else:
            sock = socket.socket(socket.AF_INET if ':' not in
                                 ip else socket.AF_INET6)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # set struct linger{l_onoff=1,l_linger=0} to avoid 10048 socket error
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
                        struct.pack('ii', 1, 0))
        # resize socket recv buffer 8K->32K to improve browser releated application performance
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 32 * 1024)
        sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
        sock.settimeout(timeout)

        start_time = time.time()
        try:
            sock.connect((ip, port))
            time_cost = (time.time() - start_time) * 1000
            # xlog.debug("connect %s %s:%d time:%d", host, ip, port, time_cost)
            g.ip_cache.update_connect_time(ip, port, time_cost)
            s = SocketWrap(sock, ip, port, host)
            host_port = "%s:%d" % (host, port)
            self.add_sock(host_port, s)
            queue.put(True)
        except Exception as e:
            # xlog.debug("connect %s %s:%d fail:%r", host, ip, port, e)
            g.ip_cache.report_connect_fail(ip, port)
            queue.put(False)
Ejemplo n.º 3
0
def handle_ip_proxy(sock, ip, port, client_address):
    if not isinstance(sock, SocketWrap):
        sock = SocketWrap(sock, client_address[0], client_address[1])

    rule = g.user_rules.check_host(ip, port)
    if not rule:
        if utils.is_private_ip(ip):
            rule = "direct"

    if rule:
        return try_loop("ip user", [rule], sock, ip, port, client_address)

    try:
        host = get_sni(sock)
        return handle_domain_proxy(sock, host, port, client_address)
    except SniNotExist as e:
        xlog.debug("ip:%s:%d get sni fail", ip, port)

    record = g.ip_cache.get(ip)
    if record and record["r"] == "socks":
        rule_list = ["socks"]
    else:
        rule_list = ["direct", "socks"]

    try_loop("ip", rule_list, sock, ip, port, client_address)
Ejemplo n.º 4
0
def handle_ip_proxy(sock, ip, port, client_address):
    sock = SocketWrap(sock, client_address[0], client_address[1])
    rule = g.user_rules.check_host(ip, port)
    if not rule:
        if utils.is_private_ip(ip):
            rule = "direct"

    if rule:
        if rule == "direct":
            try:
                do_direct(sock, ip, [ip], port, client_address)
                xlog.info("host:%s:%d user direct", ip, port)
            except ConnectFail:
                xlog.warn("ip:%s:%d user rule:%s connect fail", ip, port, rule)
                sock.close()
            return
        elif rule == "socks":
            do_socks(sock, ip, port, client_address)
            xlog.info("host:%s:%d user socks", ip, port)
            return
        elif rule == "black":
            xlog.info("ip:%s:%d user rule:%s", ip, port, rule)
            sock.close()
            return
        else:
            xlog.error("get rule:%s unknown", rule)
            sock.close()
            return

    try:
        host = get_sni(sock)
        return handle_domain_proxy(sock, host, port, client_address)
    except SniNotExist as e:
        xlog.debug("ip:%s:%d get sni fail", ip, port)

    record = g.ip_cache.get(ip)
    if record:
        rule = record["r"]
    else:
        rule = "direct"

    if rule == "direct":
        try:
            do_direct(sock, ip, [ip], port, client_address)
            xlog.info("host:%s:%d direct", ip, port)
            return
        except ConnectFail:
            xlog.debug("%s:%d try direct fail", ip, port)
            rule = "socks"
            g.ip_cache.update_rule(ip, port, "socks")
    if rule == "socks":
        do_socks(sock, ip, port, client_address)
        xlog.info("host:%s:%d socks", ip, port)
        return

    xlog.error("get rule:%s unknown", rule)
    sock.close()
    return
Ejemplo n.º 5
0
def handle_domain_proxy(sock, host, port, client_address, left_buf=""):
    global fake_host
    if not fake_host and g.gae_proxy:
        fake_host = g.gae_proxy.web_control.get_fake_host()

    if not isinstance(sock, SocketWrap):
        sock = SocketWrap(sock, client_address[0], client_address[1])

    sock.target = "%s:%d" % (host, port)
    rule = g.user_rules.check_host(host, port)
    if not rule:
        if host == fake_host:
            rule = "gae"
        elif utils.check_ip_valid(host) and utils.is_private_ip(host):
            rule = "direct"

    if rule:
        return try_loop("domain user", [rule], sock, host, port,
                        client_address, left_buf)

    record = g.domain_cache.get(host)
    ips = g.dns_srv.query(host)

    if check_local_network.IPv6.is_ok() and have_ipv6(ips):
        rule_list = ["direct", "gae", "socks", "redirect_https"]
    elif record:
        rule = record["r"]
        if rule == "gae" or not g.ip_region.check_ips(record["ip"]):
            rule_list = ["gae", "socks", "redirect_https", "direct"]
        else:
            rule_list = ["direct", "gae", "socks", "redirect_https"]

        if not g.domain_cache.accept_gae(host):
            rule_list.remove("gae")
    elif g.gfwlist.check(host):
        rule_list = ["gae", "socks", "redirect_https", "direct"]
    else:
        ips = g.dns_srv.query(host)
        if g.ip_region.check_ips(ips):
            rule_list = ["direct", "gae", "socks", "redirect_https"]
        else:
            rule_list = ["gae", "socks", "redirect_https", "direct"]

    if not g.config.auto_direct and "direct" in rule_list:
        try:
            rule_list.remove("direct")
            rule_list.remove("redirect_https")
        except:
            pass

    if not g.config.auto_gae and "gae" in rule_list:
        try:
            rule_list.remove("gae")
        except:
            pass

    try_loop("domain", rule_list, sock, host, port, client_address, left_buf)
Ejemplo n.º 6
0
def handle_domain_proxy(sock, host, port, client_address, left_buf=""):
    global fake_host
    if not fake_host and g.gae_proxy:
        fake_host = g.gae_proxy.web_control.get_fake_host()

    if not isinstance(sock, SocketWrap):
        sock = SocketWrap(sock, client_address[0], client_address[1])

    sock.target = "%s:%d" % (host, port)
    rule = g.user_rules.check_host(host, port)
    if not rule:
        if host == fake_host:
            rule = "gae"
        elif utils.check_ip_valid(host) and utils.is_private_ip(host):
            rule = "direct"

    if rule:
        return try_loop("domain user", [rule], sock, host, port,
                        client_address, left_buf)

    if g.config.block_advertisement and g.gfwlist.is_advertisement(host):
        xlog.info("block advertisement %s:%d", host, port)
        sock.close()
        return

    #ips = g.dns_srv.query(host)
    #if check_local_network.IPv6.is_ok() and have_ipv6(ips) and port == 443:
    #    rule_list = ["direct", "gae", "socks", "redirect_https"]
    # gae is more faster then direct.

    record = g.domain_cache.get(host)
    if record and record["r"] != "unknown":
        rule = record["r"]
        if rule == "gae":
            rule_list = ["gae", "socks", "redirect_https", "direct"]
        elif rule == "socks":
            rule_list = ["socks", "gae", "redirect_https", "direct"]
        else:
            rule_list = ["direct", "gae", "socks", "redirect_https"]

        if not g.domain_cache.accept_gae(host):
            rule_list.remove("gae")
    elif g.gfwlist.is_white(host):
        rule_list = ["direct", "gae", "socks", "redirect_https"]
    elif g.gfwlist.check(host):
        rule_list = ["gae", "socks", "redirect_https", "direct"]
    else:
        ips = g.dns_srv.query(host)
        if g.ip_region.check_ips(ips):
            rule_list = ["direct", "socks", "redirect_https"]
        else:
            rule_list = ["direct", "gae", "socks", "redirect_https"]

    try_loop("domain", rule_list, sock, host, port, client_address, left_buf)
Ejemplo n.º 7
0
def do_unwrap_socks(sock, host, port, client_address, req, left_buf=""):
    if not g.x_tunnel:
        return

    try:
        remote_sock = socks.create_connection((host, port),
                                              proxy_type="socks5h",
                                              proxy_addr="127.0.0.1",
                                              proxy_port=g.x_tunnel_socks_port,
                                              timeout=15)
    except Exception as e:
        xlog.warn("do_unwrap_socks connect to x-tunnel for %s:%d proxy fail.",
                  host, port)
        return

    if isinstance(req.connection, ssl.SSLSocket):
        try:
            # TODO: send SNI
            remote_ssl_sock = ssl.wrap_socket(remote_sock)
        except:
            xlog.warn("do_unwrap_socks ssl_wrap for %s:%d proxy fail.", host,
                      port)
            return
    else:
        remote_ssl_sock = remote_sock

    # avoid close by req.__del__
    req.rfile._close = False
    req.wfile._close = False
    req.connection = None

    if not isinstance(sock, SocketWrap):
        sock = SocketWrap(sock, client_address[0], client_address[1])

    xlog.info("host:%s:%d do_unwrap_socks", host, port)

    remote_ssl_sock.send(left_buf)
    sw = SocketWrap(remote_ssl_sock, "x-tunnel", port, host)
    sock.recved_times = 3
    g.pipe_socks.add_socks(sock, sw)
Ejemplo n.º 8
0
def do_unwrap_socks(sock, host, port, client_address, req, left_buf=""):
    # TODO: bug exist

    sock.close()
    return

    if not g.x_tunnel:
        return

    try:
        remote_sock = socks.create_connection(
            (host, port),
            proxy_type="socks5", proxy_addr="127.0.0.1", proxy_port=1080, timeout=15
        )
    except Exception as e:
        xlog.warn("do_unwrap_socks connect to x-tunnel for %s:%d proxy fail.", host, port)
        return

    if req.path.startswith("https"):
        try:
            ssl_sock = ssl.wrap_socket(remote_sock)
        except:
            xlog.warn("do_unwrap_socks ssl_wrap for %s:%d proxy fail.", host, port)
            return
    else:
        ssl_sock = remote_sock

    if not isinstance(sock, SocketWrap):
        sock = SocketWrap(sock, "x-tunnel", port, host)

    xlog.info("host:%s:%d do_unwrap_socks", host, port)

    ssl_sock.send(left_buf)
    sw = SocketWrap(ssl_sock, client_address[0], client_address[1])
    sock.recved_times = 3
    g.pipe_socks.add_socks(sock, sw)
Ejemplo n.º 9
0
def handle_ip_proxy(sock, ip, port, client_address):
    if not isinstance(sock, SocketWrap):
        sock = SocketWrap(sock, client_address[0], client_address[1])

    rule = g.user_rules.check_host(ip, port)
    if not rule:
        if utils.is_private_ip(ip):
            rule = "direct"

    if rule:
        return try_loop("ip user", [rule], sock, ip, port, client_address)

    if g.config.auto_direct and g.ip_region.check_ip(ip):
        rule_list = ["direct", "gae", "socks", "redirect_https"]
    else:
        if g.config.auto_direct or g.config.auto_gae:
            try:
                host = get_sni(sock)
                if host:
                    return handle_domain_proxy(sock, host, port,
                                               client_address)
            except SniNotExist as e:
                xlog.debug("ip:%s:%d get sni fail", ip, port)

        if not g.config.auto_direct:
            rule_list = ["socks"]
        else:
            record = g.ip_cache.get(ip)
            if record and record["r"] == "socks":
                rule_list = ["socks"]
            else:
                rule_list = ["direct", "socks"]

    if not g.config.auto_direct and "direct" in rule_list:
        try:
            rule_list.remove("direct")
            rule_list.remove("redirect_https")
        except:
            pass

    if not g.config.auto_gae and "gae" in rule_list:
        try:
            rule_list.remove("gae")
        except:
            pass

    try_loop("ip", rule_list, sock, ip, port, client_address)
Ejemplo n.º 10
0
def do_redirect_https(sock, host, ips, port, client_address, left_buf=""):
    remote_sock = g.connect_manager.get_conn(host, ips, 443)
    if not remote_sock:
        raise RedirectHttpsFail()

    try:
        ssl_sock = ssl.wrap_socket(remote_sock._sock)
    except Exception as e:
        raise RedirectHttpsFail()

    xlog.debug("host:%s:%d redirect_https connect %s success", host, port, remote_sock.ip)

    if left_buf:
        ssl_sock.send(left_buf)
    sw = SocketWrap(ssl_sock, remote_sock.ip, port, host)
    sock.recved_times = 3
    g.pipe_socks.add_socks(sock, sw)
Ejemplo n.º 11
0
    def http_handler(self):
        req_data = self.conn.recv(65537, socket.MSG_PEEK)
        rp = req_data.split("\r\n")
        req_line = rp[0]

        words = req_line.split()
        if len(words) == 3:
            method, url, http_version = words
        elif len(words) == 2:
            method, url = words
            http_version = "HTTP/1.1"
        else:
            xlog.warn("http req line fail:%s", req_line)
            return

        if url.lower().startswith("http://"):
            o = urlparse.urlparse(url)
            host, port = netloc_to_host_port(o.netloc)

            url_prex_len = url[7:].find("/")
            if url_prex_len >= 0:
                url_prex_len += 7
                path = url[url_prex_len:]
            else:
                url_prex_len = len(url)
                path = "/"
        else:
            # not proxy request, should be PAC
            xlog.debug("PAC %s %s from:%s", method, url, self.client_address)
            handler = pac_server.PacHandler(self.conn, self.client_address,
                                            None, xlog)
            return handler.handle()

        #req_d = self.conn.recv(len(req_line))
        #req_d = req_d.replace(url, path)

        sock = SocketWrap(self.conn, self.client_address[0],
                          self.client_address[1])
        sock.replace_pattern = [url[:url_prex_len], ""]

        xlog.debug("http %r connect to %s:%d %s %s", self.client_address, host,
                   port, method, path)
        handle_domain_proxy(sock, host, port, self.client_address)
Ejemplo n.º 12
0
def handle_ip_proxy(sock, ip, port, client_address):
    if not isinstance(sock, SocketWrap):
        sock = SocketWrap(sock, client_address[0], client_address[1])

    rule = g.user_rules.check_host(ip, port)
    if not rule:
        if utils.is_private_ip(ip):
            rule = "direct"

    if rule:
        return try_loop("ip user", [rule], sock, ip, port, client_address)

    try:
        host = get_sni(sock)
        if host:
            ips = g.dns_srv.query(host)
            if not ips:
                cn = "CN" if g.ip_region.check_ip(ip) else "XX"
                ips.append("%s|%s" % (ip, cn))
                g.domain_cache.set_ips(host, ips)
            return handle_domain_proxy(sock, host, port, client_address)
    except SniNotExist as e:
        xlog.debug("ip:%s:%d get sni fail", ip, port)

    record = g.ip_cache.get(ip)
    if record and record["r"] != "unknown":
        rule = record["r"]
        if rule == "gae":
            rule_list = ["gae", "socks", "direct"]
        elif rule == "socks":
            rule_list = ["socks", "gae", "direct"]
        else:
            rule_list = ["direct", "gae", "socks"]
    elif g.ip_region.check_ip(ip):
        rule_list = ["direct", "socks"]
    else:
        rule_list = ["direct", "gae", "socks"]

    try_loop("ip", rule_list, sock, ip, port, client_address)
Ejemplo n.º 13
0
def handle_domain_proxy(sock, host, port, client_address, left_buf=""):
    if not isinstance(sock, SocketWrap):
        sock = SocketWrap(sock, client_address[0], client_address[1])

    sock.target = "%s:%d" % (host, port)
    start_time = time.time()
    rule = g.user_rules.check_host(host, port)
    if not rule:
        if host == "www.twitter.com":
            rule = "gae"
        elif utils.check_ip_valid(host) and utils.is_private_ip(host):
            rule = "direct"

    if rule:
        if rule == "direct":
            ips = g.dns_srv.query(host)

            try:
                do_direct(sock, host, ips, port, client_address, left_buf)
                xlog.info("host:%s:%d user direct", host, port)
            except ConnectFail:
                xlog.warn("host:%s:%d user rule:%s connect fail", host, port,
                          rule)
                sock.close()
            return
        elif rule == "redirect_https":
            ips = g.dns_srv.query(host)

            try:
                do_redirect_https(sock, host, ips, port, client_address,
                                  left_buf)
                xlog.info("host:%s:%d user redirect_https", host, port)
            except RedirectHttpsFail:
                xlog.warn("host:%s:%d user rule:%s connect fail", host, port,
                          rule)
                sock.close()
            return
        elif rule == "gae":
            if not is_gae_workable():
                xlog.debug("host:%s:%d user rule:%s, but gae not work", host,
                           port, rule)
                sock.close()
                return

            try:
                host = get_sni(sock)
                do_gae(sock, host, port, client_address, left_buf)
                xlog.info("host:%s:%d user gae", host, port)
            except ssl.SSLError as e:
                xlog.warn("host:%s:%d user rule gae, GetReqTimeout:%d e:%r",
                          host, port, (time.time() - start_time) * 1000, e)
                sock.close()
            except simple_http_server.GetReqTimeout as e:
                # xlog.warn("host:%s:%d user rule gae, GetReqTimeout:%d e:%r", host, port, (time.time()-start_time)*1000, e)
                sock.close()
            except Exception as e:
                xlog.warn("host:%s:%d user rule:%s except:%r", host, port,
                          rule, e)
                sock.close()
            return
        elif rule == "socks":
            do_socks(sock, host, port, client_address, left_buf)
            xlog.info("host:%s:%d user rule:socks", host, port)
            return
        elif rule == "black":
            xlog.info("host:%s:%d user rule black", host, port)
            sock.close()
            return
        else:
            xlog.error("get rule:%s unknown", rule)
            sock.close()
            return

    record = g.domain_cache.get(host)
    if not record:
        rule = "direct"
    else:
        rule = record["r"]

    if not rule or rule == "direct":
        if g.config.auto_direct:
            ips = g.dns_srv.query(host)

            try:
                if port == 80 and g.gfwlist.check(host):
                    do_redirect_https(sock, host, ips, port, client_address,
                                      left_buf)
                    xlog.info("%s:%d redirect_https", host, port)
                    return
                else:
                    do_direct(sock, host, ips, port, client_address, left_buf)
                    xlog.info("%s:%d direct", host, port)
                    return
            except (ConnectFail, RedirectHttpsFail) as e:
                xlog.debug("%s:%d try direct/redirect fail:%r", host, port, e)
                rule = "gae"
        else:
            rule = "gae"

    if rule == "gae":
        if g.config.auto_gae and is_gae_workable(
        ) and g.domain_cache.accept_gae(host, port):
            try:
                sni_host = get_sni(sock)
                do_gae(sock, host, port, client_address, left_buf)
                xlog.info("%s:%d gae", host, port)
                return
            except SniNotExist:
                xlog.debug("domain:%s get sni fail", host)
                rule = "socks"
            except (SslWrapFail, simple_http_server.ParseReqFail) as e:
                xlog.warn("domain:%s sni:%s fail:%r", host, sni_host, e)
                g.domain_cache.report_gae_deny(host, port)
                sock.close()
                return
            except simple_http_server.GetReqTimeout:
                # Happen sometimes, don't known why.
                # xlog.warn("host:%s:%d try gae, GetReqTimeout:%d", host, port,
                #          (time.time() - start_time) * 1000)
                sock.close()
                return
            except Exception as e:
                xlog.warn("host:%s:%d cache rule:%s except:%r", host, port,
                          rule, e)
                g.domain_cache.report_gae_deny(host, port)
                sock.close()
                return

        else:
            rule = "socks"

    if rule == "socks":
        do_socks(sock, host, port, client_address, left_buf)
        xlog.info("%s:%d socks", host, port)
        return
    else:
        xlog.error("domain:%s get rule:%s unknown", host, rule)
        sock.close()
        return
Ejemplo n.º 14
0
# !/usr/bin/python3
# -*- coding: utf-8 -*-

import logging
from socket_wrap import SocketWrap

logging.basicConfig(filename='/var/log/temperature_errors.log',
                    level=logging.ERROR,
                    format='%(asctime)s - %(message)s',
                    datefmt='%Y.%m.%d %H:%M:%S')

try:
    socketObj = SocketWrap(logging.getLogger(__name__))
    socketObj.send('Hourly update')

except Exception as err:
    logging.error(err)