# 💃 soxy👯♀️proxy 🕺
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![PyPI](https://img.shields.io/pypi/v/soxyproxy.svg)](https://pypi.python.org/pypi/soxyproxy)
[![PyPI](https://img.shields.io/pypi/dm/soxyproxy.svg)](https://pypi.python.org/pypi/soxyproxy)
Асинхронная socks4/4a/5/5h прокся, написанная от скуки в целях самообучения, ~~без единного гвоздя~~ без использования внешних зависимостей
Проект на этапе активной периодической разработки, и поддерживается по настроению.
Любые пожелания и прочие штуки можно мне писать в Телеграм-аккаунт [@shpaker](https://t.me/shpaker).
## 🛩️ Install
```shell
pip install soxyproxy
```
## 🫶🏼 Пробуем
### 👨💻 Запускаем из кода
```python
import asyncio
import logging
from ipaddress import IPv4Address, IPv4Network
from socket import gethostbyname
import soxy
logging.basicConfig(level=logging.INFO)
def auther(
username: str,
password: str,
) -> bool:
return username == "top" and password == "secret"
def resolver(
domain_name: str,
) -> IPv4Address:
return IPv4Address(gethostbyname(domain_name))
async def main() -> None:
async with soxy.Proxy(
protocol=soxy.Socks5(
auther=auther,
resolver=resolver, # если резолвер не передать, то не будет работать 5h (и 4a в случае Socks4)
),
transport=soxy.TcpTransport(),
ruleset=soxy.Ruleset(
allow_connecting_rules=[
# необходимо хотя бы одно разрешающие правило для соединения
soxy.ConnectingRule(
from_addresses=IPv4Address("127.0.0.1"),
)
],
allow_proxying_rules=[
# необходимо хотя бы одно разрешающие правило для проксирования
soxy.ProxyingRule(
from_addresses=IPv4Address("127.0.0.1"),
to_addresses=IPv4Network("0.0.0.0/0"),
),
],
),
) as app:
await app.serve_forever()
if __name__ == "__main__":
asyncio.run(main())
```
#### Проверить всегда можно курлом
socks5:
```shell
curl -x "socks5://top:secret@127.0.0.1:1080" https://google.ru -v
```
socks5h:
```shell
curl -x "socks5a://top:secret@127.0.0.1:1080" https://google.ru -v
```
### 👟 В качестве инструмента коммандной строки
Но тут все очень просто
#### пишем конфиг следующего вида и сохарняем в `socks5.toml`:
```toml
[proxy]
protocol = "socks5"
transport = "tcp"
clients_from = [
'0.0.0.0/0',
]
[transport]
host = '127.0.0.1'
port = 1080
[[ruleset.connecting.allow]]
from = '127.0.0.1'
[[ruleset.proxying.allow]]
from = "127.0.0.1"
to = "0.0.0.0/0"
```
#### запускаем сервер:
```shell
soxy socks5.toml logs.txt
```
если хочется чтоб логи летели в терминал, то параметр с файлом логов можно не указывать и оставить просто `soxyproxy socks5.toml`
Raw data
{
"_id": null,
"home_page": null,
"name": "soxyproxy",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "proxy, socks, socks4, socks4a, socks5h",
"author": null,
"author_email": "Aleksandr Shpak <shpaker@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/7b/e3/2b3fe7affd1a2a6eeb0395bf3fc37b574eb910b9f6e429bed898e8a2898a/soxyproxy-0.8.0.tar.gz",
"platform": null,
"description": "# \ud83d\udc83 soxy\ud83d\udc6f\u200d\u2640\ufe0fproxy \ud83d\udd7a\n\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n[![PyPI](https://img.shields.io/pypi/v/soxyproxy.svg)](https://pypi.python.org/pypi/soxyproxy)\n[![PyPI](https://img.shields.io/pypi/dm/soxyproxy.svg)](https://pypi.python.org/pypi/soxyproxy)\n\n\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f socks4/4a/5/5h \u043f\u0440\u043e\u043a\u0441\u044f, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u043e\u0442 \u0441\u043a\u0443\u043a\u0438 \u0432 \u0446\u0435\u043b\u044f\u0445 \u0441\u0430\u043c\u043e\u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f, ~~\u0431\u0435\u0437 \u0435\u0434\u0438\u043d\u043d\u043e\u0433\u043e \u0433\u0432\u043e\u0437\u0434\u044f~~ \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439\n\n\u041f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044e.\n\n\u041b\u044e\u0431\u044b\u0435 \u043f\u043e\u0436\u0435\u043b\u0430\u043d\u0438\u044f \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u0448\u0442\u0443\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u043c\u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c-\u0430\u043a\u043a\u0430\u0443\u043d\u0442 [@shpaker](https://t.me/shpaker). \n\n## \ud83d\udee9\ufe0f Install\n\n```shell\npip install soxyproxy\n```\n\n## \ud83e\udef6\ud83c\udffc \u041f\u0440\u043e\u0431\u0443\u0435\u043c\n\n### \ud83d\udc68\u200d\ud83d\udcbb \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438\u0437 \u043a\u043e\u0434\u0430\n\n```python\nimport asyncio\nimport logging\nfrom ipaddress import IPv4Address, IPv4Network\nfrom socket import gethostbyname\n\nimport soxy\n\nlogging.basicConfig(level=logging.INFO)\n\n\ndef auther(\n username: str,\n password: str,\n) -> bool:\n return username == \"top\" and password == \"secret\"\n\n\ndef resolver(\n domain_name: str,\n) -> IPv4Address:\n return IPv4Address(gethostbyname(domain_name))\n\n\nasync def main() -> None:\n async with soxy.Proxy(\n protocol=soxy.Socks5(\n auther=auther,\n resolver=resolver, # \u0435\u0441\u043b\u0438 \u0440\u0435\u0437\u043e\u043b\u0432\u0435\u0440 \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c, \u0442\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c 5h (\u0438 4a \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 Socks4)\n ),\n transport=soxy.TcpTransport(),\n ruleset=soxy.Ruleset(\n allow_connecting_rules=[\n # \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u044e\u0449\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f\n soxy.ConnectingRule(\n from_addresses=IPv4Address(\"127.0.0.1\"),\n )\n ],\n allow_proxying_rules=[\n # \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u044e\u0449\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f\n soxy.ProxyingRule(\n from_addresses=IPv4Address(\"127.0.0.1\"),\n to_addresses=IPv4Network(\"0.0.0.0/0\"),\n ),\n ],\n ),\n ) as app:\n await app.serve_forever()\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\n#### \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043a\u0443\u0440\u043b\u043e\u043c\n\nsocks5:\n\n```shell\ncurl -x \"socks5://top:secret@127.0.0.1:1080\" https://google.ru -v\n```\n\nsocks5h:\n\n```shell\ncurl -x \"socks5a://top:secret@127.0.0.1:1080\" https://google.ru -v\n```\n\n### \ud83d\udc5f \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u043a\u043e\u043c\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438\n\n\u041d\u043e \u0442\u0443\u0442 \u0432\u0441\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\n\n#### \u043f\u0438\u0448\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u0438\u0434\u0430 \u0438 \u0441\u043e\u0445\u0430\u0440\u043d\u044f\u0435\u043c \u0432 `socks5.toml`:\n\n```toml\n[proxy]\nprotocol = \"socks5\"\ntransport = \"tcp\"\nclients_from = [\n '0.0.0.0/0',\n]\n\n[transport]\nhost = '127.0.0.1'\nport = 1080\n\n[[ruleset.connecting.allow]]\nfrom = '127.0.0.1'\n\n[[ruleset.proxying.allow]]\nfrom = \"127.0.0.1\"\nto = \"0.0.0.0/0\"\n```\n\n#### \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440:\n\n```shell\nsoxy socks5.toml logs.txt \n```\n\n\u0435\u0441\u043b\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0447\u0442\u043e\u0431 \u043b\u043e\u0433\u0438 \u043b\u0435\u0442\u0435\u043b\u0438 \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b, \u0442\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0441 \u0444\u0430\u0439\u043b\u043e\u043c \u043b\u043e\u0433\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e `soxyproxy socks5.toml` \n",
"bugtrack_url": null,
"license": "GPL-3.0",
"summary": "Add your description here",
"version": "0.8.0",
"project_urls": {
"Homepage": "https://github.com/shpaker/soxyproxy/"
},
"split_keywords": [
"proxy",
" socks",
" socks4",
" socks4a",
" socks5h"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "226c62c1b2b6e4372f76e92ccedafad9e4bccb77cb45c9ef3c11e36e22512662",
"md5": "2e86995fe2f75973841ea3c11722b5e0",
"sha256": "c17efd1949cee2c162374a602f800cc76e3c34ea8d5512a441dcca7c686d627a"
},
"downloads": -1,
"filename": "soxyproxy-0.8.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2e86995fe2f75973841ea3c11722b5e0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 27114,
"upload_time": "2024-12-04T20:54:00",
"upload_time_iso_8601": "2024-12-04T20:54:00.142046Z",
"url": "https://files.pythonhosted.org/packages/22/6c/62c1b2b6e4372f76e92ccedafad9e4bccb77cb45c9ef3c11e36e22512662/soxyproxy-0.8.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "7be32b3fe7affd1a2a6eeb0395bf3fc37b574eb910b9f6e429bed898e8a2898a",
"md5": "2242b0b70bcf100533ccf9733fbfbe9a",
"sha256": "45e21edda63d0e39eaf6e91b7c91574cdb7fb7391f2c7904b59681366783ae53"
},
"downloads": -1,
"filename": "soxyproxy-0.8.0.tar.gz",
"has_sig": false,
"md5_digest": "2242b0b70bcf100533ccf9733fbfbe9a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 24373,
"upload_time": "2024-12-04T20:54:01",
"upload_time_iso_8601": "2024-12-04T20:54:01.183737Z",
"url": "https://files.pythonhosted.org/packages/7b/e3/2b3fe7affd1a2a6eeb0395bf3fc37b574eb910b9f6e429bed898e8a2898a/soxyproxy-0.8.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-04 20:54:01",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "shpaker",
"github_project": "soxyproxy",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "soxyproxy"
}