simple-proxy 0.0.28__tar.gz → 0.0.30__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {simple_proxy-0.0.28/simple_proxy.egg-info → simple_proxy-0.0.30}/PKG-INFO +25 -40
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/README.md +23 -38
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/pyproject.toml +2 -2
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/__main__.py +7 -4
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/handler/proxy_channel_handler.py +3 -1
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/handler/shell_channel_handler.py +0 -16
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/run.py +5 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/utils/stringutils.py +4 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30/simple_proxy.egg-info}/PKG-INFO +25 -40
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy.egg-info/SOURCES.txt +12 -11
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy.egg-info/requires.txt +1 -1
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy.egg-info/top_level.txt +1 -0
- simple_proxy-0.0.30/tests/handler/test_echo_channel_handler.py +42 -0
- simple_proxy-0.0.30/tests/handler/test_http_proxy_channel_handler.py +258 -0
- simple_proxy-0.0.30/tests/handler/test_proxy_channel_handler.py +306 -0
- simple_proxy-0.0.30/tests/handler/test_shell_channel_handler.py +202 -0
- simple_proxy-0.0.30/tests/handler/test_socks5_proxy_channel_handler.py +361 -0
- simple_proxy-0.0.30/tests/test_clients.py +155 -0
- simple_proxy-0.0.30/tests/utils/test_certutils.py +25 -0
- simple_proxy-0.0.30/tests/utils/test_logutils.py +55 -0
- simple_proxy-0.0.30/tests/utils/test_netutils.py +59 -0
- {simple_proxy-0.0.28/tests → simple_proxy-0.0.30/tests/utils}/test_osutils.py +0 -7
- simple_proxy-0.0.30/tests/utils/test_proxyutils.py +128 -0
- {simple_proxy-0.0.28/tests → simple_proxy-0.0.30/tests/utils}/test_stringutils.py +8 -1
- simple_proxy-0.0.28/tests/test_certutils.py +0 -23
- simple_proxy-0.0.28/tests/test_clients.py +0 -138
- simple_proxy-0.0.28/tests/test_echo_channel_handler.py +0 -46
- simple_proxy-0.0.28/tests/test_http_proxy_channel_handler.py +0 -255
- simple_proxy-0.0.28/tests/test_logutils.py +0 -53
- simple_proxy-0.0.28/tests/test_netutils.py +0 -60
- simple_proxy-0.0.28/tests/test_proxy_channel_handler.py +0 -308
- simple_proxy-0.0.28/tests/test_proxyutils.py +0 -132
- simple_proxy-0.0.28/tests/test_socks5_proxy_channel_handler.py +0 -391
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/LICENSE +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/setup.cfg +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/__init__.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/clients.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/handler/__init__.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/handler/echo_channel_handler.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/handler/http_proxy_channel_handler.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/handler/socks5_proxy_channel_handler.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/utils/__init__.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/utils/certutils.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/utils/logutils.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/utils/netutils.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/utils/osutils.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/utils/proxyutils.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/utils/tlsutils.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy/version.py +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy.egg-info/dependency_links.txt +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/simple_proxy.egg-info/entry_points.txt +0 -0
- {simple_proxy-0.0.28 → simple_proxy-0.0.30}/tests/test_run.py +0 -0
- {simple_proxy-0.0.28/tests → simple_proxy-0.0.30/tests/utils}/test_tlsutils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simple_proxy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.30
|
|
4
4
|
Summary: A simple NIO proxy tool
|
|
5
5
|
Home-page: https://github.com/ruanhao/simple-proxy
|
|
6
6
|
Author-email: Hao Ruan <ruanhao1116@gmail.com>
|
|
@@ -26,7 +26,7 @@ Requires-Python: <4,>=3.7
|
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
28
|
Requires-Dist: click-option-group
|
|
29
|
-
Requires-Dist: py-netty>=1.0.
|
|
29
|
+
Requires-Dist: py-netty>=1.0.8
|
|
30
30
|
Requires-Dist: cryptography>=42.0.0
|
|
31
31
|
Requires-Dist: attrs>=22.1.0
|
|
32
32
|
Provides-Extra: dev
|
|
@@ -43,6 +43,7 @@ Dynamic: license-file
|
|
|
43
43
|
|
|
44
44
|
[](https://github.com/ruanhao/simple-proxy/actions/workflows/ci.yml)
|
|
45
45
|
[](https://codecov.io/github/ruanhao/simple-proxy)
|
|
46
|
+

|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
|
|
@@ -69,69 +70,53 @@ pip install simple-proxy -U
|
|
|
69
70
|
Usage: simple-proxy [OPTIONS]
|
|
70
71
|
|
|
71
72
|
Options:
|
|
72
|
-
Common configuration: Configuration for local/remote
|
|
73
|
-
|
|
74
|
-
-l, --listening-host TEXT Listening server address
|
|
75
|
-
[default: localhost]
|
|
73
|
+
Common configuration: Configuration for local/remote endpoints
|
|
74
|
+
-l, --listening-host TEXT Listening server address [default: localhost]
|
|
76
75
|
-lp, --listening-port INTEGER
|
|
77
76
|
Listening port [default: 8080]
|
|
78
77
|
-g, --global Listening on all interfaces
|
|
79
78
|
-r, --remote-host TEXT Remote host [default: localhost]
|
|
80
79
|
-rp, --remote-port INTEGER Remote port [default: 80]
|
|
81
|
-
-s, --tls Denote remote is listening on
|
|
82
|
-
secure port
|
|
80
|
+
-s, --tls Denote remote is listening on secure port
|
|
83
81
|
-ss Listening on secure port
|
|
84
82
|
TCP proxy configuration: Configuration for TCP proxy mode
|
|
85
83
|
--read-delay-millis INTEGER Read delay(ms) [default: 0]
|
|
86
84
|
--write-delay-millis INTEGER Write delay(ms) [default: 0]
|
|
85
|
+
-sni, --server-name-indication TEXT
|
|
86
|
+
Server Name Indication(SNI) for TLS connection to remote server
|
|
87
87
|
Thread configuration: Configuration for thread
|
|
88
|
-
--workers INTEGER Number of worker threads
|
|
89
|
-
|
|
90
|
-
--proxy-workers INTEGER Number of proxy threads [default:
|
|
91
|
-
1]
|
|
88
|
+
--workers INTEGER Number of worker threads [default: 1]
|
|
89
|
+
--proxy-workers INTEGER Number of proxy threads [default: 1]
|
|
92
90
|
Traffic dump configuration: Configuration for traffic dump
|
|
93
91
|
-c, --tcp-flow Dump tcp flow on to console
|
|
94
92
|
-f, --save-tcp-flow Save tcp flow to file
|
|
95
|
-
TLS certificate configuration:
|
|
93
|
+
TLS certificate configuration:
|
|
96
94
|
Configuration for TLS certificate
|
|
97
95
|
-kf, --key-file PATH Key file for local server
|
|
98
96
|
-cf, --cert-file PATH Certificate file for local server
|
|
99
|
-
--alpn Set ALPN protocol as [h2,
|
|
100
|
-
|
|
101
|
-
Traffic monitor configuration:
|
|
97
|
+
--alpn Set ALPN protocol as [h2, http/1.1]
|
|
98
|
+
Traffic monitor configuration:
|
|
102
99
|
Configuration for traffic monitor
|
|
103
|
-
-m, --monitor Print speed info to console for
|
|
104
|
-
established connection
|
|
100
|
+
-m, --monitor Print speed info to console for established connection
|
|
105
101
|
-mi, --monitor-interval INTEGER
|
|
106
|
-
Speed monitor interval(seconds)
|
|
107
|
-
|
|
108
|
-
TLS Disguise configuration: Configuration for protection
|
|
109
|
-
against unwanted inspection
|
|
102
|
+
Speed monitor interval(seconds) [default: 3]
|
|
103
|
+
TLS Disguise configuration: Configuration for protection against unwanted inspection
|
|
110
104
|
-dti, --disguise-tls-ip TEXT Disguised upstream TLS IP
|
|
111
105
|
-dtp, --disguise-tls-port INTEGER
|
|
112
|
-
Disguised upstream TLS port
|
|
113
|
-
|
|
114
|
-
--
|
|
115
|
-
|
|
116
|
-
-wl, --white-list TEXT IP White list for legal incoming
|
|
117
|
-
TLS connections (comma separated)
|
|
118
|
-
Proxy configuration: Configuration for application
|
|
119
|
-
proxies
|
|
106
|
+
Disguised upstream TLS port [default: 443]
|
|
107
|
+
--run-disguise-tls-server Run builtin disguise TLS server without specifying external one
|
|
108
|
+
-wl, --white-list TEXT IP White list for legal incoming TLS connections (comma separated)
|
|
109
|
+
Proxy configuration: Configuration for application proxies
|
|
120
110
|
-e, --echo-proxy Run as Echo server
|
|
121
111
|
--shell-proxy Run as shell proxy server
|
|
122
112
|
--http-proxy Run as HTTP proxy server
|
|
123
113
|
--socks5-proxy Run as SOCKS5 proxy server
|
|
124
|
-
--proxy-username TEXT Proxy username for HTTP/SOCKS5
|
|
125
|
-
|
|
126
|
-
--proxy-password TEXT Proxy password for HTTP/SOCKS5
|
|
127
|
-
proxy
|
|
114
|
+
--proxy-username TEXT Proxy username for HTTP/SOCKS5 proxy
|
|
115
|
+
--proxy-password TEXT Proxy password for HTTP/SOCKS5 proxy
|
|
128
116
|
-t, --proxy-transform <TEXT INTEGER TEXT INTEGER>...
|
|
129
|
-
List of target
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
transformed_port) for HTTP/SOCKS5
|
|
133
|
-
proxy
|
|
134
|
-
Misc configuration:
|
|
117
|
+
List of target transformations(origin_host, origin_port, transformed_host,
|
|
118
|
+
transformed_port) for HTTP/SOCKS5 proxy
|
|
119
|
+
Misc configuration:
|
|
135
120
|
-v, --verbose
|
|
136
121
|
--log-file PATH Log file
|
|
137
122
|
--version Show the version and exit.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/ruanhao/simple-proxy/actions/workflows/ci.yml)
|
|
4
4
|
[](https://codecov.io/github/ruanhao/simple-proxy)
|
|
5
|
+

|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
|
|
@@ -28,69 +29,53 @@ pip install simple-proxy -U
|
|
|
28
29
|
Usage: simple-proxy [OPTIONS]
|
|
29
30
|
|
|
30
31
|
Options:
|
|
31
|
-
Common configuration: Configuration for local/remote
|
|
32
|
-
|
|
33
|
-
-l, --listening-host TEXT Listening server address
|
|
34
|
-
[default: localhost]
|
|
32
|
+
Common configuration: Configuration for local/remote endpoints
|
|
33
|
+
-l, --listening-host TEXT Listening server address [default: localhost]
|
|
35
34
|
-lp, --listening-port INTEGER
|
|
36
35
|
Listening port [default: 8080]
|
|
37
36
|
-g, --global Listening on all interfaces
|
|
38
37
|
-r, --remote-host TEXT Remote host [default: localhost]
|
|
39
38
|
-rp, --remote-port INTEGER Remote port [default: 80]
|
|
40
|
-
-s, --tls Denote remote is listening on
|
|
41
|
-
secure port
|
|
39
|
+
-s, --tls Denote remote is listening on secure port
|
|
42
40
|
-ss Listening on secure port
|
|
43
41
|
TCP proxy configuration: Configuration for TCP proxy mode
|
|
44
42
|
--read-delay-millis INTEGER Read delay(ms) [default: 0]
|
|
45
43
|
--write-delay-millis INTEGER Write delay(ms) [default: 0]
|
|
44
|
+
-sni, --server-name-indication TEXT
|
|
45
|
+
Server Name Indication(SNI) for TLS connection to remote server
|
|
46
46
|
Thread configuration: Configuration for thread
|
|
47
|
-
--workers INTEGER Number of worker threads
|
|
48
|
-
|
|
49
|
-
--proxy-workers INTEGER Number of proxy threads [default:
|
|
50
|
-
1]
|
|
47
|
+
--workers INTEGER Number of worker threads [default: 1]
|
|
48
|
+
--proxy-workers INTEGER Number of proxy threads [default: 1]
|
|
51
49
|
Traffic dump configuration: Configuration for traffic dump
|
|
52
50
|
-c, --tcp-flow Dump tcp flow on to console
|
|
53
51
|
-f, --save-tcp-flow Save tcp flow to file
|
|
54
|
-
TLS certificate configuration:
|
|
52
|
+
TLS certificate configuration:
|
|
55
53
|
Configuration for TLS certificate
|
|
56
54
|
-kf, --key-file PATH Key file for local server
|
|
57
55
|
-cf, --cert-file PATH Certificate file for local server
|
|
58
|
-
--alpn Set ALPN protocol as [h2,
|
|
59
|
-
|
|
60
|
-
Traffic monitor configuration:
|
|
56
|
+
--alpn Set ALPN protocol as [h2, http/1.1]
|
|
57
|
+
Traffic monitor configuration:
|
|
61
58
|
Configuration for traffic monitor
|
|
62
|
-
-m, --monitor Print speed info to console for
|
|
63
|
-
established connection
|
|
59
|
+
-m, --monitor Print speed info to console for established connection
|
|
64
60
|
-mi, --monitor-interval INTEGER
|
|
65
|
-
Speed monitor interval(seconds)
|
|
66
|
-
|
|
67
|
-
TLS Disguise configuration: Configuration for protection
|
|
68
|
-
against unwanted inspection
|
|
61
|
+
Speed monitor interval(seconds) [default: 3]
|
|
62
|
+
TLS Disguise configuration: Configuration for protection against unwanted inspection
|
|
69
63
|
-dti, --disguise-tls-ip TEXT Disguised upstream TLS IP
|
|
70
64
|
-dtp, --disguise-tls-port INTEGER
|
|
71
|
-
Disguised upstream TLS port
|
|
72
|
-
|
|
73
|
-
--
|
|
74
|
-
|
|
75
|
-
-wl, --white-list TEXT IP White list for legal incoming
|
|
76
|
-
TLS connections (comma separated)
|
|
77
|
-
Proxy configuration: Configuration for application
|
|
78
|
-
proxies
|
|
65
|
+
Disguised upstream TLS port [default: 443]
|
|
66
|
+
--run-disguise-tls-server Run builtin disguise TLS server without specifying external one
|
|
67
|
+
-wl, --white-list TEXT IP White list for legal incoming TLS connections (comma separated)
|
|
68
|
+
Proxy configuration: Configuration for application proxies
|
|
79
69
|
-e, --echo-proxy Run as Echo server
|
|
80
70
|
--shell-proxy Run as shell proxy server
|
|
81
71
|
--http-proxy Run as HTTP proxy server
|
|
82
72
|
--socks5-proxy Run as SOCKS5 proxy server
|
|
83
|
-
--proxy-username TEXT Proxy username for HTTP/SOCKS5
|
|
84
|
-
|
|
85
|
-
--proxy-password TEXT Proxy password for HTTP/SOCKS5
|
|
86
|
-
proxy
|
|
73
|
+
--proxy-username TEXT Proxy username for HTTP/SOCKS5 proxy
|
|
74
|
+
--proxy-password TEXT Proxy password for HTTP/SOCKS5 proxy
|
|
87
75
|
-t, --proxy-transform <TEXT INTEGER TEXT INTEGER>...
|
|
88
|
-
List of target
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
transformed_port) for HTTP/SOCKS5
|
|
92
|
-
proxy
|
|
93
|
-
Misc configuration:
|
|
76
|
+
List of target transformations(origin_host, origin_port, transformed_host,
|
|
77
|
+
transformed_port) for HTTP/SOCKS5 proxy
|
|
78
|
+
Misc configuration:
|
|
94
79
|
-v, --verbose
|
|
95
80
|
--log-file PATH Log file
|
|
96
81
|
--version Show the version and exit.
|
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "simple_proxy"
|
|
8
|
-
version = "0.0.
|
|
8
|
+
version = "0.0.30"
|
|
9
9
|
description = "A simple NIO proxy tool"
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
requires-python = ">=3.7, <4"
|
|
@@ -17,7 +17,7 @@ keywords = ["network", "tcp", "non-blocking", "proxy"]
|
|
|
17
17
|
|
|
18
18
|
dependencies = [
|
|
19
19
|
"click-option-group",
|
|
20
|
-
"py-netty>=1.0.
|
|
20
|
+
"py-netty>=1.0.8",
|
|
21
21
|
"cryptography>=42.0.0",
|
|
22
22
|
"attrs>=22.1.0",
|
|
23
23
|
]
|
|
@@ -16,7 +16,7 @@ logger = logging.getLogger(__name__)
|
|
|
16
16
|
))
|
|
17
17
|
@optgroup.group('Common configuration', help='Configuration for local/remote endpoints')
|
|
18
18
|
@optgroup.option('--listening-host', '-l', 'local_server', default='localhost', help='Listening server address', show_default=True)
|
|
19
|
-
@optgroup.option('--listening-port', '-lp', 'local_port', type=int, default=8080, help='Listening port', show_default=True)
|
|
19
|
+
@optgroup.option('--listening-port', '-lp', '-p', 'local_port', type=int, default=8080, help='Listening port', show_default=True)
|
|
20
20
|
@optgroup.option('--global', '-g', 'using_global', is_flag=True, help='Listening on all interfaces')
|
|
21
21
|
@optgroup.option('--remote-host', '-r', 'remote_server', default='localhost', help='Remote host', show_default=True)
|
|
22
22
|
@optgroup.option('--remote-port', '-rp', type=int, default=80, help='Remote port', show_default=True)
|
|
@@ -25,6 +25,7 @@ logger = logging.getLogger(__name__)
|
|
|
25
25
|
@optgroup.group('TCP proxy configuration', help='Configuration for TCP proxy mode')
|
|
26
26
|
@optgroup.option('--read-delay-millis', type=int, help='Read delay(ms)', default=0, show_default=True)
|
|
27
27
|
@optgroup.option('--write-delay-millis', type=int, help='Write delay(ms)', default=0, show_default=True)
|
|
28
|
+
@optgroup.option('--server-name-indication', '-sni', help='Server Name Indication(SNI) for TLS connection to remote server')
|
|
28
29
|
#
|
|
29
30
|
@optgroup.group('Thread configuration', help='Configuration for thread')
|
|
30
31
|
@optgroup.option('--workers', type=int, default=1, help='Number of worker threads', show_default=True)
|
|
@@ -64,9 +65,11 @@ logger = logging.getLogger(__name__)
|
|
|
64
65
|
@click.version_option(prog_name='Simple Proxy', version=__version__)
|
|
65
66
|
def _cli(verbose, log_file: click.Path, **kwargs):
|
|
66
67
|
setup_logging(log_file, logging.INFO if verbose == 0 else logging.DEBUG)
|
|
67
|
-
if verbose:
|
|
68
|
-
logger.setLevel(logging.
|
|
69
|
-
|
|
68
|
+
if verbose < 2:
|
|
69
|
+
logger.setLevel(logging.WARNING)
|
|
70
|
+
for name in ("py_netty", "simple_proxy.utils"):
|
|
71
|
+
logging.getLogger(name).setLevel(logging.WARNING)
|
|
72
|
+
|
|
70
73
|
run_proxy(**kwargs)
|
|
71
74
|
|
|
72
75
|
|
|
@@ -24,6 +24,7 @@ class ProxyChannelHandler(LoggingChannelHandler):
|
|
|
24
24
|
alpn: bool = False,
|
|
25
25
|
read_delay_millis: int = 0,
|
|
26
26
|
write_delay_millis: int = 0,
|
|
27
|
+
sni: str | None = None,
|
|
27
28
|
):
|
|
28
29
|
self._remote_host = remote_host
|
|
29
30
|
self._remote_port = remote_port
|
|
@@ -42,6 +43,7 @@ class ProxyChannelHandler(LoggingChannelHandler):
|
|
|
42
43
|
self._write_delay_millis = write_delay_millis
|
|
43
44
|
self._unwritable_seconds: float = None # noqa
|
|
44
45
|
self.raddr: tuple[str, int] = None # noqa
|
|
46
|
+
self.sni = sni
|
|
45
47
|
|
|
46
48
|
def _client_channel(self, ctx0, ip, port):
|
|
47
49
|
|
|
@@ -77,7 +79,7 @@ class ProxyChannelHandler(LoggingChannelHandler):
|
|
|
77
79
|
tls=self._tls,
|
|
78
80
|
verify=False,
|
|
79
81
|
ssl_context_cb=alpn_ssl_context_cb if self._alpn else None,
|
|
80
|
-
).connect(ip, port, True).sync().channel()
|
|
82
|
+
).connect(ip, port, True, self.sni).sync().channel()
|
|
81
83
|
set_keepalive(self._client.socket())
|
|
82
84
|
return self._client
|
|
83
85
|
|
|
@@ -77,22 +77,6 @@ class ShellChannelHandler(LoggingChannelHandler):
|
|
|
77
77
|
self._shell_stdin_fd = master_fd
|
|
78
78
|
submit_daemon_thread(self.handle_read_output, ctx, master_fd)
|
|
79
79
|
|
|
80
|
-
def _setup_linux_shell0(self, ctx):
|
|
81
|
-
my_env = os.environ.copy()
|
|
82
|
-
i_r, i_w = os.pipe()
|
|
83
|
-
o_r, o_w = os.pipe()
|
|
84
|
-
self._process = subprocess.Popen(
|
|
85
|
-
[shutil.which('bash'), '-li'],
|
|
86
|
-
stdin=i_r,
|
|
87
|
-
stdout=o_w,
|
|
88
|
-
stderr=o_w,
|
|
89
|
-
bufsize=-1,
|
|
90
|
-
start_new_session=True,
|
|
91
|
-
env=my_env
|
|
92
|
-
)
|
|
93
|
-
self._shell_stdin_fd = i_w
|
|
94
|
-
submit_daemon_thread(self.handle_read_output, ctx, o_r)
|
|
95
|
-
|
|
96
80
|
def channel_active(self, ctx):
|
|
97
81
|
super().channel_active(ctx)
|
|
98
82
|
local_socket = ctx.channel().socket()
|
|
@@ -20,6 +20,7 @@ from .utils import (
|
|
|
20
20
|
alpn_ssl_context_cb,
|
|
21
21
|
random_sentence,
|
|
22
22
|
)
|
|
23
|
+
from .utils.stringutils import is_ip_address
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
class MyHttpHandler(http.server.BaseHTTPRequestHandler):
|
|
@@ -52,6 +53,7 @@ def run_proxy(
|
|
|
52
53
|
proxy_username=None, proxy_password=None,
|
|
53
54
|
shell_proxy=False,
|
|
54
55
|
read_delay_millis=0, write_delay_millis=0,
|
|
56
|
+
server_name_indication: str | None = None,
|
|
55
57
|
workers=1, proxy_workers=1,
|
|
56
58
|
as_echo_server=False,
|
|
57
59
|
):
|
|
@@ -168,6 +170,7 @@ def run_proxy(
|
|
|
168
170
|
alpn=alpn,
|
|
169
171
|
read_delay_millis=read_delay_millis,
|
|
170
172
|
write_delay_millis=write_delay_millis,
|
|
173
|
+
sni=server_name_indication,
|
|
171
174
|
),
|
|
172
175
|
certfile=cf,
|
|
173
176
|
keyfile=kf,
|
|
@@ -176,6 +179,8 @@ def run_proxy(
|
|
|
176
179
|
disguise = f"https://{disguise_tls_ip}:{disguise_tls_port}" if disguise_tls_ip else 'n/a'
|
|
177
180
|
pstderr(f"Proxy server started listening: {local_server}:{local_port}{'(TLS)' if ss else ''} => {remote_server}:{remote_port}{'(TLS)' if tls else ''} ...")
|
|
178
181
|
pstderr(f"console:{content}, file:{to_file}, disguise:{disguise}, whitelist:{white_list0 or '*'}")
|
|
182
|
+
if is_ip_address(remote_server) and tls and not server_name_indication:
|
|
183
|
+
pstderr("[WARN] Direct IP address is used as remote TLS server, it's recommended to specify SNI using '--server-name-indication' option!")
|
|
179
184
|
|
|
180
185
|
if monitor:
|
|
181
186
|
spawn_clients_monitor(monitor_interval)
|
|
@@ -66,3 +66,7 @@ def check_ip_patterns(patterns: list[str], s: str) -> bool:
|
|
|
66
66
|
_get_logger().debug(f"pattern {pattern} matched {s}")
|
|
67
67
|
return True
|
|
68
68
|
return False
|
|
69
|
+
|
|
70
|
+
def is_ip_address(s: str) -> bool:
|
|
71
|
+
ip_pattern = re.compile(r'^(\d{1,3}\.){3}\d{1,3}$')
|
|
72
|
+
return bool(ip_pattern.match(s))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simple_proxy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.30
|
|
4
4
|
Summary: A simple NIO proxy tool
|
|
5
5
|
Home-page: https://github.com/ruanhao/simple-proxy
|
|
6
6
|
Author-email: Hao Ruan <ruanhao1116@gmail.com>
|
|
@@ -26,7 +26,7 @@ Requires-Python: <4,>=3.7
|
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
28
|
Requires-Dist: click-option-group
|
|
29
|
-
Requires-Dist: py-netty>=1.0.
|
|
29
|
+
Requires-Dist: py-netty>=1.0.8
|
|
30
30
|
Requires-Dist: cryptography>=42.0.0
|
|
31
31
|
Requires-Dist: attrs>=22.1.0
|
|
32
32
|
Provides-Extra: dev
|
|
@@ -43,6 +43,7 @@ Dynamic: license-file
|
|
|
43
43
|
|
|
44
44
|
[](https://github.com/ruanhao/simple-proxy/actions/workflows/ci.yml)
|
|
45
45
|
[](https://codecov.io/github/ruanhao/simple-proxy)
|
|
46
|
+

|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
|
|
@@ -69,69 +70,53 @@ pip install simple-proxy -U
|
|
|
69
70
|
Usage: simple-proxy [OPTIONS]
|
|
70
71
|
|
|
71
72
|
Options:
|
|
72
|
-
Common configuration: Configuration for local/remote
|
|
73
|
-
|
|
74
|
-
-l, --listening-host TEXT Listening server address
|
|
75
|
-
[default: localhost]
|
|
73
|
+
Common configuration: Configuration for local/remote endpoints
|
|
74
|
+
-l, --listening-host TEXT Listening server address [default: localhost]
|
|
76
75
|
-lp, --listening-port INTEGER
|
|
77
76
|
Listening port [default: 8080]
|
|
78
77
|
-g, --global Listening on all interfaces
|
|
79
78
|
-r, --remote-host TEXT Remote host [default: localhost]
|
|
80
79
|
-rp, --remote-port INTEGER Remote port [default: 80]
|
|
81
|
-
-s, --tls Denote remote is listening on
|
|
82
|
-
secure port
|
|
80
|
+
-s, --tls Denote remote is listening on secure port
|
|
83
81
|
-ss Listening on secure port
|
|
84
82
|
TCP proxy configuration: Configuration for TCP proxy mode
|
|
85
83
|
--read-delay-millis INTEGER Read delay(ms) [default: 0]
|
|
86
84
|
--write-delay-millis INTEGER Write delay(ms) [default: 0]
|
|
85
|
+
-sni, --server-name-indication TEXT
|
|
86
|
+
Server Name Indication(SNI) for TLS connection to remote server
|
|
87
87
|
Thread configuration: Configuration for thread
|
|
88
|
-
--workers INTEGER Number of worker threads
|
|
89
|
-
|
|
90
|
-
--proxy-workers INTEGER Number of proxy threads [default:
|
|
91
|
-
1]
|
|
88
|
+
--workers INTEGER Number of worker threads [default: 1]
|
|
89
|
+
--proxy-workers INTEGER Number of proxy threads [default: 1]
|
|
92
90
|
Traffic dump configuration: Configuration for traffic dump
|
|
93
91
|
-c, --tcp-flow Dump tcp flow on to console
|
|
94
92
|
-f, --save-tcp-flow Save tcp flow to file
|
|
95
|
-
TLS certificate configuration:
|
|
93
|
+
TLS certificate configuration:
|
|
96
94
|
Configuration for TLS certificate
|
|
97
95
|
-kf, --key-file PATH Key file for local server
|
|
98
96
|
-cf, --cert-file PATH Certificate file for local server
|
|
99
|
-
--alpn Set ALPN protocol as [h2,
|
|
100
|
-
|
|
101
|
-
Traffic monitor configuration:
|
|
97
|
+
--alpn Set ALPN protocol as [h2, http/1.1]
|
|
98
|
+
Traffic monitor configuration:
|
|
102
99
|
Configuration for traffic monitor
|
|
103
|
-
-m, --monitor Print speed info to console for
|
|
104
|
-
established connection
|
|
100
|
+
-m, --monitor Print speed info to console for established connection
|
|
105
101
|
-mi, --monitor-interval INTEGER
|
|
106
|
-
Speed monitor interval(seconds)
|
|
107
|
-
|
|
108
|
-
TLS Disguise configuration: Configuration for protection
|
|
109
|
-
against unwanted inspection
|
|
102
|
+
Speed monitor interval(seconds) [default: 3]
|
|
103
|
+
TLS Disguise configuration: Configuration for protection against unwanted inspection
|
|
110
104
|
-dti, --disguise-tls-ip TEXT Disguised upstream TLS IP
|
|
111
105
|
-dtp, --disguise-tls-port INTEGER
|
|
112
|
-
Disguised upstream TLS port
|
|
113
|
-
|
|
114
|
-
--
|
|
115
|
-
|
|
116
|
-
-wl, --white-list TEXT IP White list for legal incoming
|
|
117
|
-
TLS connections (comma separated)
|
|
118
|
-
Proxy configuration: Configuration for application
|
|
119
|
-
proxies
|
|
106
|
+
Disguised upstream TLS port [default: 443]
|
|
107
|
+
--run-disguise-tls-server Run builtin disguise TLS server without specifying external one
|
|
108
|
+
-wl, --white-list TEXT IP White list for legal incoming TLS connections (comma separated)
|
|
109
|
+
Proxy configuration: Configuration for application proxies
|
|
120
110
|
-e, --echo-proxy Run as Echo server
|
|
121
111
|
--shell-proxy Run as shell proxy server
|
|
122
112
|
--http-proxy Run as HTTP proxy server
|
|
123
113
|
--socks5-proxy Run as SOCKS5 proxy server
|
|
124
|
-
--proxy-username TEXT Proxy username for HTTP/SOCKS5
|
|
125
|
-
|
|
126
|
-
--proxy-password TEXT Proxy password for HTTP/SOCKS5
|
|
127
|
-
proxy
|
|
114
|
+
--proxy-username TEXT Proxy username for HTTP/SOCKS5 proxy
|
|
115
|
+
--proxy-password TEXT Proxy password for HTTP/SOCKS5 proxy
|
|
128
116
|
-t, --proxy-transform <TEXT INTEGER TEXT INTEGER>...
|
|
129
|
-
List of target
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
transformed_port) for HTTP/SOCKS5
|
|
133
|
-
proxy
|
|
134
|
-
Misc configuration:
|
|
117
|
+
List of target transformations(origin_host, origin_port, transformed_host,
|
|
118
|
+
transformed_port) for HTTP/SOCKS5 proxy
|
|
119
|
+
Misc configuration:
|
|
135
120
|
-v, --verbose
|
|
136
121
|
--log-file PATH Log file
|
|
137
122
|
--version Show the version and exit.
|
|
@@ -27,16 +27,17 @@ simple_proxy/utils/osutils.py
|
|
|
27
27
|
simple_proxy/utils/proxyutils.py
|
|
28
28
|
simple_proxy/utils/stringutils.py
|
|
29
29
|
simple_proxy/utils/tlsutils.py
|
|
30
|
-
tests/test_certutils.py
|
|
31
30
|
tests/test_clients.py
|
|
32
|
-
tests/test_echo_channel_handler.py
|
|
33
|
-
tests/test_http_proxy_channel_handler.py
|
|
34
|
-
tests/test_logutils.py
|
|
35
|
-
tests/test_netutils.py
|
|
36
|
-
tests/test_osutils.py
|
|
37
|
-
tests/test_proxy_channel_handler.py
|
|
38
|
-
tests/test_proxyutils.py
|
|
39
31
|
tests/test_run.py
|
|
40
|
-
tests/
|
|
41
|
-
tests/
|
|
42
|
-
tests/
|
|
32
|
+
tests/handler/test_echo_channel_handler.py
|
|
33
|
+
tests/handler/test_http_proxy_channel_handler.py
|
|
34
|
+
tests/handler/test_proxy_channel_handler.py
|
|
35
|
+
tests/handler/test_shell_channel_handler.py
|
|
36
|
+
tests/handler/test_socks5_proxy_channel_handler.py
|
|
37
|
+
tests/utils/test_certutils.py
|
|
38
|
+
tests/utils/test_logutils.py
|
|
39
|
+
tests/utils/test_netutils.py
|
|
40
|
+
tests/utils/test_osutils.py
|
|
41
|
+
tests/utils/test_proxyutils.py
|
|
42
|
+
tests/utils/test_stringutils.py
|
|
43
|
+
tests/utils/test_tlsutils.py
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from simple_proxy.handler.echo_channel_handler import EchoChannelHandler
|
|
2
|
+
from py_netty import EventLoopGroup
|
|
3
|
+
from simple_proxy.clients import get_clients
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@pytest.fixture(scope='function', autouse=False)
|
|
8
|
+
def ctx_mocker(mocker):
|
|
9
|
+
return mocker.MagicMock()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TestChannelRead:
|
|
13
|
+
|
|
14
|
+
def test_with_client(self, mocker, ctx_mocker):
|
|
15
|
+
raddr = ('127.0.0.1', 8080)
|
|
16
|
+
ctx_mocker.channel.return_value.channelinfo.return_value.peername = raddr
|
|
17
|
+
handler = EchoChannelHandler(EventLoopGroup(), tls=False)
|
|
18
|
+
|
|
19
|
+
client_mocker = mocker.MagicMock()
|
|
20
|
+
get_clients()[raddr] = client_mocker
|
|
21
|
+
handler.channel_read(ctx_mocker, b'123')
|
|
22
|
+
ctx_mocker.channel().write.assert_called_once_with(b'123')
|
|
23
|
+
client_mocker.read.assert_called_once_with(3)
|
|
24
|
+
client_mocker.write.assert_called_once_with(3)
|
|
25
|
+
|
|
26
|
+
def test_without_client(self, ctx_mocker):
|
|
27
|
+
raddr = ('127.0.0.1', 8080)
|
|
28
|
+
ctx_mocker.channel.return_value.channelinfo.return_value.peername = raddr
|
|
29
|
+
handler = EchoChannelHandler(EventLoopGroup(), tls=False)
|
|
30
|
+
|
|
31
|
+
get_clients().clear()
|
|
32
|
+
handler.channel_read(ctx_mocker, b'123')
|
|
33
|
+
assert ctx_mocker.channel.called
|
|
34
|
+
ctx_mocker.channel().write.assert_called_once_with(b'123')
|
|
35
|
+
|
|
36
|
+
def test_empty(self, ctx_mocker):
|
|
37
|
+
raddr = ('127.0.0.1', 8080)
|
|
38
|
+
ctx_mocker.channel.return_value.channelinfo.return_value.peername = raddr
|
|
39
|
+
|
|
40
|
+
handler = EchoChannelHandler(EventLoopGroup(), tls=False)
|
|
41
|
+
handler.channel_read(ctx_mocker, b'')
|
|
42
|
+
assert not ctx_mocker.channel.called
|