Skip to content

Commit

Permalink
进一步优化了域名过滤和流量分流控制逻辑.
Browse files Browse the repository at this point in the history
Signed-off-by: Sadam·Sadik <[email protected]>
  • Loading branch information
Haoke98 committed May 17, 2024
1 parent 5a242de commit 59eeff3
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 24 deletions.
2 changes: 1 addition & 1 deletion PFlowC/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
def get_version():
return '2.3.0'
return '2.3.1'
39 changes: 22 additions & 17 deletions PFlowC/geo_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,31 @@
import os
import socket

import geoip2.database
from mitmproxy import http

from PFlowC.proxy_helper import set_bypass_domains
from PFlowC.utils.net import is_domestic2, geoip_db

from PFlowC.utils.net import is_domestic2

# 本地区域的国家代码,例如'CN'为中国
LOCAL_REGION_CODE = 'CN'
DEFAULT_BYPASS_DOMAINS = [
# LOCAL Address
"127.0.0.1",
"192.168.0.0/16",
"172.16.0.0/16",
"10.0.0.0/8",
# DNS
'223.5.5.5',
'119.29.29.29',
'doh.pub',
'dns.alidns.com',
"218.31.113.0/24"
]
AGENT_DOMAINS = {
DOMAINS = {
"CN": [
# TODO:不要用记下IP地址, 因为GeoIP就能够分辨IP地址的区域划分.
"218.31.113.0/24"
],
"US": [
"github.com",
"api.github.com"
]
Expand All @@ -42,14 +45,14 @@
bypass_domains_fp = os.path.join(home_dir, "bypass_domains.json")
bypass_domains = set()
if not os.path.isfile(bypass_domains_fp):
logging.warning("bypass domains cache file[{}] does not exist.".format(bypass_domains_fp))
print("bypass domains cache file[{}] does not exist.".format(bypass_domains_fp))
else:
try:
bypass_domains = set(json.load(open(bypass_domains_fp)))
# TODO: 加载时对在PROXY规则里, 但是由于时间关系, 之前被加入到DIRECT里的域名都要提取出来
# TODO: 用户个人的BypassDomains列表也要进行汇入.
except json.decoder.JSONDecodeError as e:
logging.warning("BypassDomains缓存列表解析异常")
print("BypassDomains缓存列表解析异常")


def save_bypass_domains():
Expand All @@ -59,15 +62,17 @@ def save_bypass_domains():

for item in DEFAULT_BYPASS_DOMAINS:
bypass_domains.add(item)
set_bypass_domains(bypass_domains)
for domain in DOMAINS[LOCAL_REGION_CODE]:
bypass_domains.add(domain)
set_bypass_domains(bypass_domains)


def is_local_region(ip):
try:
response = geoip_db.country(ip)
return response.country.iso_code == LOCAL_REGION_CODE
except geoip2.errors.AddressNotFoundError:
return False
def is_exact_other_region(host):
for country_code, domains in DOMAINS.items():
if country_code != LOCAL_REGION_CODE:
if host in domains:
return True
return False


def request(flow: http.HTTPFlow) -> None:
Expand All @@ -76,16 +81,16 @@ def request(flow: http.HTTPFlow) -> None:
# 判断是否属于本地区域
ip = socket.gethostbyname(flow.request.pretty_host)
_type = "PROXY"
if flow.request.pretty_host in AGENT_DOMAINS[LOCAL_REGION_CODE]:
if is_exact_other_region(flow.request.pretty_host):
_type = "PROXY"
else:
# 直接访问,不走上游代理
_type = "DIRECT"
if is_domestic2(flow.request.pretty_host, target_country_code=LOCAL_REGION_CODE):
_type = "PROXY =2=> DIRECT"
# 需要更新一下bypass_domains列表
# TODO: 部分特殊域名要存在于官网规则中, 对他们进行过滤单独分离出来
bypass_domains.add(flow.request.pretty_host)
set_bypass_domains(bypass_domains)
save_bypass_domains()
# TODO: 收集到中央服务方便以后成为按地区分布代理流量控制缓存.
print(f"[{flow.timestamp_start}][{flow.type}][mode:{flow.mode}][{_type}][{ip} - {flow.request.pretty_host}]")
logging.info(f"[{flow.timestamp_start}][{flow.type}][mode:{flow.mode}][{_type}][{ip} - {flow.request.pretty_host}]")
5 changes: 3 additions & 2 deletions PFlowC/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import logging
import os
import subprocess
import sys
from pathlib import Path

import click

from PFlowC import get_version
Expand Down Expand Up @@ -154,7 +154,8 @@ def server():
logging.info("Server is now on!")
# 循环读取输出并打印
for line in iter(p.stdout.readline, b''):
print(line.decode(), end='')
sys.stdout.write(line.decode())
sys.stdout.flush() # 刷新缓冲区以立即显示内容
except subprocess.CalledProcessError as e:
logging.error("CallSubprocessFailed:%s" % e.stderr)

Expand Down
3 changes: 2 additions & 1 deletion PFlowC/utils/net.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
raise ImportError("无法加载资源文件 'Country.mmdb'")

# 确保GEOIP_DB_PATH有有效的值后再使用
if GEOIP_DB_PATH:
if not GEOIP_DB_PATH:
raise FileNotFoundError("未能找到或创建GeoIP数据库文件的路径")

# 继续使用GEOIP_DB_PATH
Expand Down Expand Up @@ -81,6 +81,7 @@ def is_domestic(domain_name: str, max_try=10, target_country_code: str = "CN") -


def is_domestic2(domain_name: str, max_try=10, target_country_code: str = "CN"):
# FIXME:区分是否是IP地址
for i in range(max_try):
answers = resolver.resolve(domain_name, 'A')
for rdata in answers:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ A net flow pilot in order to handle some proxy configuration automatically.
╚═╝ ╚═╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝ ╚═════╝

Command line interface for Proxy Flow Controller with basic auto configurations.
Version: 2.3.0 By: BlackHaoke<[email protected]>
Version: 2.3.1 By: BlackHaoke<[email protected]>
Usage: pflow-cli [OPTIONS] COMMAND [ARGS]...

Options:
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Usage ::
╚═╝ ╚═╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝ ╚═════╝

Command line interface for Proxy Flow Controller with basic auto configurations.
Version: 2.3.0 By: BlackHaoke<[email protected]>
Version: 2.3.1 By: BlackHaoke<[email protected]>
Usage: pflow-cli [OPTIONS] COMMAND [ARGS]...

Options:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

setup(
name='PFlowC',
version='2.3.0',
version='2.3.1',
url='https://github.com/Haoke98/FlowPilot',
author='Haoke98',
author_email='BlackHaoke<[email protected]>',
Expand Down

0 comments on commit 59eeff3

Please sign in to comment.