python-proxy是一个使用Python编写的代理服务器,可以用于在爬虫和其他类似的应用程序中轻松地启用代理。它还提供了许多其他功能,如HTTPS代理支持,自动切换代理等。
```
轻量级单线程异步IO。
纯Python,无需额外的库。
TCP / UDP代理客户端/服务器。
在远程服务器之间进行调度(负载平衡)。
自动检测进入的流量。
支持隧道/跳跃/向后跳转。
Unix域套接字支持。
HTTP v2,HTTP v3(QUIC)。
用户/密码身份验证支持。
使用正则表达式模式过滤/阻止主机名。
SSL / TLS客户端/服务器支持。
Shadowsocks OTA(一次性身份验证),SSR插件。
按带宽和流量统计。
支持PAC用于JavaScript配置。
Iptables / Pf NAT重定向数据包隧道。
系统代理自动设置支持。
提供客户端/服务器API。
```
从github上python-proxy的发展和更新历史来看,这个项目的质量相对较高。然而,跟绝大多数开源项项目一样,更新频率可能比较低,所以您需要小心地评估使用Python-Proxy项目适不适合您的需求。 最好查看一下项目的许可证、社区维护,最近的活动等等因素,以及查看其他用户的反馈和建议,同时也可以自己尝试使用和测试,以决定是否安全和可靠地使用这个项目。
[1] @halomaster • 03 Mar 2023, 07:00 GMT
# 什么是 socks5代理,它有什么优势?
socks5代理是一种网络协议,它可以在客户端和服务器之间建立一个中间层,使得客户端可以通过中间层来访问任何目标服务器,而不需要直接连接。socks5代理的全称是 Socket Secure version 5,它是 socks 协议的第五个版本,也是目前最新和最完善的版本。
socks5代理有以下几个优势:
- 支持多种认证方式。socks5代理可以根据客户端和服务器的协商,选择合适的认证方式,如无需认证、用户名密码认证、GSS-API 认证等。这样可以提高安全性和灵活性。
- 支持多种地址类型。socks5代理可以处理 IPv4、IPv6、域名和其他任意格式的地址,而不需要进行 DNS 解析。这样可以提高效率和兼容性。
- 支持多种数据传输模式。socks5代理可以支持 TCP 和 UDP 两种数据传输模式,以及 BIND 和 ASSOCIATE 两种连接模式。这样可以满足不同的应用场景和需求。
- 支持透明代理。socks5代理可以在不修改客户端或服务器的情况下,实现透明地转发数据包。这样可以保持原始的网络结构和功能。
## 如何使用 socks5代理?
要使用 socks5代理,你需要以下几个条件:
- 一个可用的 socks5代理服务器。你可以自己搭建一个 socks5代理服务器,或者使用第三方提供的服务。
- 一个支持 socks5协议的客户端软件。你可以使用浏览器、邮件客户端、即时通讯软件等任何支持 socks5协议的软件。
- 一个正确的配置方法。你需要根据你的具体情况,配置好你的客户端软件和 socks5代理服务器之间的连接参数。
具体的配置方法可能因为不同的软件而有所差异,但一般来说,你需要设置以下几个参数:
- 代理类型:选择 SOCKS 或 SOCKS v.5
- 代理地址:输入你的 socks5代理服务器的 IP 地址或域名
- 代理端口:输入你的 socks5代理服务器监听的端口号
- 认证方式:选择你和你的 socks5代理服务器协商好的认证方式,并输入相应的用户名和密码(如果有)
完成以上设置后,你就可以通过 socks5代理来访问任何目标网站了。
## 总结
socks5代理是一种强大而灵活的网络协议,它可以帮助我们实现匿名上网、突破网络封锁、加速网络访问等功能。
[2] @halomaster • 04 Mar 2023, 08:57 GMT
pycryptodome是一个可选库,可以启用更快(C版本)的密码学lib。pproxy有许多内置的纯Python密码学功能,它们是稳定的轻量级库,但速度比C版本慢。使用PyPy进行加速后,纯Python密码学模块的性能可以达到与C版本类似的水平。如果性能很重要且不使用PyPy,请安装pycryptodome替代纯Python模块。
asyncssh是一个可选库,可以启用SSH隧道客户端支持。
[3] @halomaster • 05 Mar 2023, 02:55 GMT
``` python
class WindowsSetting(object):
KEY = r'Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections'
SUBKEY = 'DefaultConnectionSettings'
def __init__(self, args):
self.listen = None
for option in args.listen:
protos = [x.name for x in option.protos]
if option.unix or 'ssl' in protos or 'secure' in protos:
continue
if 'http' in protos:
self.listen = option
break
if self.listen is None:
print('No server listen on localhost by http')
import winreg
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, self.KEY, 0, winreg.KEY_ALL_ACCESS)
value, regtype = winreg.QueryValueEx(key, self.SUBKEY)
assert regtype == winreg.REG_BINARY
server = f'localhost:{self.listen.port}'.encode()
bypass = '<local>'.encode()
counter = int.from_bytes(value[4:8], 'little') + 1
value = value[:4] + struct.pack('<III', counter, 3, len(server)) + server + struct.pack('<I', len(bypass)) + bypass + b'\x00'*36
winreg.SetValueEx(key, self.SUBKEY, None, regtype, value)
winreg.CloseKey(key)
def clear(self):
if self.listen is None:
return
import winreg
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, self.KEY, 0, winreg.KEY_ALL_ACCESS)
value, regtype = winreg.QueryValueEx(key, self.SUBKEY)
assert regtype == winreg.REG_BINARY
counter = int.from_bytes(value[4:8], 'little') + 1
value = value[:4] + struct.pack('<II', counter, 1) + b'\x00'*44
winreg.SetValueEx(key, self.SUBKEY, None, regtype, value)
winreg.CloseKey(key)
```
用于设置或清除 Windows 系统代理设置,代理一个监听 HTTP 协议的本地主机。
该类有一个常量 KEY,用于保存 Windows 网络设置的注册表键路径,以及一个常量 SUBKEY,用于存储系统代理设置的注册表子键名称。这些常量用于构造函数 __init__ 和方法 clear 中来访问和修改 Windows 注册表。
构造函数需要一个 args 参数,该参数预计是一个具有 listen 属性的对象。listen 属性是一个包含 port、protos 和 unix 属性的对象,用于确定一个监听 HTTP 的 localhost 服务器的配置。如果没有找到这样的服务器,则构造函数会打印一条消息。
在构造函数中,打开注册表键,并读取当前值的 SUBKEY 子键。该值预计是一个二进制值,其中包含若干特定格式的字段。修改该值以将 localhost 服务器添加到代理设置中,并将修改后的值写回注册表。
clear 方法重新打开注册表键,读取 SUBKEY 子键的当前值,修改值以从代理设置中删除 localhost 服务器,并将修改后的值写回注册表。
[4] @halomaster • 05 Mar 2023, 02:56 GMT
``` python3
async def test_url(url, rserver):
url = urllib.parse.urlparse(url)
assert url.scheme in ('http', 'https'), f'Unknown scheme {url.scheme}'
host_name, port = proto.netloc_split(url.netloc, default_port = 80 if url.scheme=='http' else 443)
initbuf = f'GET {url.path or "/"} HTTP/1.1\r\nHost: {host_name}\r\nUser-Agent: pproxy-{__version__}\r\nAccept: */*\r\nConnection: close\r\n\r\n'.encode()
for roption in rserver:
print(f'============ {roption.bind} ============')
try:
reader, writer = await roption.open_connection(host_name, port, None, None)
except asyncio.TimeoutError:
raise Exception(f'Connection timeout {rserver}')
try:
reader, writer = await roption.prepare_connection(reader, writer, host_name, port)
except Exception:
writer.close()
raise Exception('Unknown remote protocol')
if url.scheme == 'https':
import ssl
sslclient = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
sslclient.check_hostname = False
sslclient.verify_mode = ssl.CERT_NONE
reader, writer = proto.sslwrap(reader, writer, sslclient, False, host_name)
writer.write(initbuf)
headers = await reader.read_until(b'\r\n\r\n')
print(headers.decode()[:-4])
print(f'--------------------------------')
body = bytearray()
while not reader.at_eof():
s = await reader.read(65536)
if not s:
break
body.extend(s)
print(body.decode('utf8', 'ignore'))
print(f'============ success ============')
```
这是一个异步函数 test_url,用于测试一个 URL 是否能够被代理到指定的远程服务端。
该函数接受两个参数,一个是要测试的 URL,一个是代理服务器列表 rserver。函数首先会解析 URL,并检查 URL 的方案是否为 http 或 https。然后构造一个 HTTP GET 请求,发送到 URL 的主机上。
函数会遍历 rserver 中的每个代理服务器,尝试连接代理服务器,并向代理服务器发送 HTTP 请求。代理服务器的连接方法和准备方法由 roption 对象提供,这个对象预计有 open_connection 和 prepare_connection 两个方法,用于连接和准备代理服务器连接。
如果 URL 的方案为 https,则会使用 SSL 包装,连接到代理服务器。最后,读取代理服务器的响应,并将响应头和响应体打印出来。
当函数成功测试 URL 时,将打印 success 消息。
[5] @halomaster • 05 Mar 2023, 02:58 GMT
``` python3
def proxy_by_uri(uri, jump):
scheme, _, uri = uri.partition('://')
url = urllib.parse.urlparse('s://'+uri)
rawprotos = [i.lower() for i in scheme.split('+')]
err_str, protos = proto.get_protos(rawprotos)
protonames = [i.name for i in protos]
if err_str:
raise argparse.ArgumentTypeError(err_str)
if 'ssl' in rawprotos or 'secure' in rawprotos:
import ssl
sslserver = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
sslclient = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
if 'ssl' in rawprotos:
sslclient.check_hostname = False
sslclient.verify_mode = ssl.CERT_NONE
sslcontexts.append(sslserver)
sslcontexts.append(sslclient)
else:
sslserver = sslclient = None
if 'quic' in rawprotos or 'h3' in protonames:
try:
import ssl, aioquic.quic.configuration
except Exception:
raise Exception('Missing library: "pip3 install aioquic"')
quicserver = aioquic.quic.configuration.QuicConfiguration(is_client=False, max_stream_data=2**60, max_data=2**60, idle_timeout=SOCKET_TIMEOUT)
quicclient = aioquic.quic.configuration.QuicConfiguration(max_stream_data=2**60, max_data=2**60, idle_timeout=SOCKET_TIMEOUT*5)
quicclient.verify_mode = ssl.CERT_NONE
sslcontexts.append(quicserver)
sslcontexts.append(quicclient)
if 'h2' in rawprotos:
try:
import h2
except Exception:
raise Exception('Missing library: "pip3 install h2"')
urlpath, _, plugins = url.path.partition(',')
urlpath, _, lbind = urlpath.partition('@')
plugins = plugins.split(',') if plugins else None
cipher, _, loc = url.netloc.rpartition('@')
if cipher:
from .cipher import get_cipher
if ':' not in cipher:
try:
cipher = base64.b64decode(cipher).decode()
except Exception:
pass
if ':' not in cipher:
raise argparse.ArgumentTypeError('userinfo must be "cipher:key"')
err_str, cipher = get_cipher(cipher)
if err_str:
raise argparse.ArgumentTypeError(err_str)
if plugins:
from .plugin import get_plugin
for name in plugins:
if not name: continue
err_str, plugin = get_plugin(name)
if err_str:
raise argparse.ArgumentTypeError(err_str)
cipher.plugins.append(plugin)
if loc:
host_name, port = proto.netloc_split(loc, default_port=22 if 'ssh' in rawprotos else 8080)
else:
host_name = port = None
if url.fragment.startswith('#'):
with open(url.fragment[1:]) as f:
auth = f.read().rstrip().encode()
else:
auth = url.fragment.encode()
users = [i.rstrip() for i in auth.split(b'\n')] if auth else None
if 'direct' in protonames:
return ProxyDirect(lbind=lbind)
else:
params = dict(jump=jump, protos=protos, cipher=cipher, users=users, rule=url.query, bind=loc or urlpath,
host_name=host_name, port=port, unix=not loc, lbind=lbind, sslclient=sslclient, sslserver=sslserver)
if 'quic' in rawprotos:
proxy = ProxyQUIC(quicserver, quicclient, **params)
elif 'h3' in protonames:
proxy = ProxyH3(quicserver, quicclient, **params)
elif 'h2' in protonames:
proxy = ProxyH2(**params)
elif 'ssh' in protonames:
proxy = ProxySSH(**params)
else:
proxy = ProxySimple(**params)
if 'in' in rawprotos:
proxy = ProxyBackward(proxy, rawprotos.count('in'), **params)
return proxy
```
这是一个函数proxy_by_uri,用于根据一个URI字符串创建不同类型的代理服务器对象,并返回给调用者。
该函数接受两个参数,一个是URI字符串uri,一个是代理跳板列表jump。函数首先按照:分割,将scheme(通常指代使用的传输协议)和uri获取。然后使用urllib.parse.urlparse解析uri,并得到scheme, path, netloc,fragment等信息。
接下来根据解析得到的scheme,使用proto.get_protos获取对应协议处理插件列表。如果是ssl或secure,代表使用SSL协议,函数将创建一个sslclient和sslserver对象。如果是quic或h3,代表使用QUIC或HTTP/3协议,函数将引入aioquic.quic.configuration模块,并创建对应的quicserver和quicclient对象。如果是h2,代表使用HTTP/2协议,函数将引入h2模块。如果插件列表不为空,函数将根据插件列表创建插件对象,并将其添加到cipher中。
接下来函数将解析uri中的各个字段,如path,lbind,netloc,fragment等,并根据这些字段构造代理对象的基本属性。
最后,根据scheme以及各个字段构造的代理对象属性,使用不同的代理对象类型来创建最终的代理对象。
[6] @halomaster • 05 Mar 2023, 03:51 GMT
``` python3
class AuthTable(object):
_auth = {}
_user = {}
def __init__(self, remote_ip, authtime):
self.remote_ip = remote_ip
self.authtime = authtime
def authed(self):
if time.time() - self._auth.get(self.remote_ip, 0) <= self.authtime:
return self._user[self.remote_ip]
def set_authed(self, user):
self._auth[self.remote_ip] = time.time()
self._user[self.remote_ip] = user
```
这是一个用于跟踪已验证用户的IP地址的表的类定义。它包括两个类变量“_auth”和“_user”,它们是字典,将远程IP地址映射到`身份验证时间`和`已验证的用户`。
init()方法使用远程IP地址和身份验证时间初始化类。authed()方法检查用户是否已经进行身份验证,它通过查找远程IP在_auth字典中,并检查身份验证时间是否已经过期。如果用户已经通过身份验证,则返回_auth字典中存储的用户。
set_authed() 方法在_auth和_user字典中为当前的远程IP地址设置身份验证时间和用户。
[7] @halomaster • 13 Mar 2023, 02:20 GMT
Socks是一种网络传输协议,允许客户端向代理服务器发送请求,让代理服务器代表客户端完成某些操作。Socks4和Socks5是其中两种版本。
Socks4和Socks5的主要区别包括:
1. Socks5支持IPv6地址,而Socks4只支持IPv4地址。
2. Socks5支持UDP数据包的发送和接收,Socks4只支持TCP数据包。
3. Socks5使用更加安全的GSS API机制进行认证,可以使用用户名和密码来进行身份验证,而Socks4只支持单向身份验证。
4. Socks5支持代理链,可以将多个代理服务器串连起来使用,而Socks4不支持代理链。
5. Socks5支持多种认证方式,包括用户名/密码、常见的各种认证方式(如NTLM、Kerberos等),而Socks4只支持基本的用户名/密码认证方式。
Socks5比Socks4更加功能强大和安全,但Socks4简单易用,比较适合一些简单的应用场景。
[8] @halomaster • 24 Mar 2023, 10:56 GMT
dnscrypt-proxy 是一种开源工具,用于加密 DNS 查询流量并保护用户的隐私。它可以将 DNS 查询流量从计算机或移动设备转发到加密的 DNS 服务器,以保护用户免受 DNS 劫持和窥视者的攻击。更妙的是由于DNS解析被缓存和加速,用户可以明显感觉到外网网页打开的速度变快了。
https://github.com/DNSCrypt/dnscrypt-proxy
1 of 1 pages 8 replies