Initial commit.
This commit is contained in:
parent
5d3d6a0247
commit
0dffc6bdd8
31
Makefile
Normal file
31
Makefile
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
BIN = ./.venv/bin/
|
||||||
|
PYTHON = ./.venv/bin/python
|
||||||
|
PIP = ./.venv/bin/pip
|
||||||
|
|
||||||
|
APP_NAME=shadowssh
|
||||||
|
|
||||||
|
all: install build
|
||||||
|
|
||||||
|
ensure_repo:
|
||||||
|
-@git init
|
||||||
|
|
||||||
|
ensure_env: ensure_repo
|
||||||
|
-@python3 -m venv .venv
|
||||||
|
|
||||||
|
install:
|
||||||
|
$(PIP) install -e .
|
||||||
|
|
||||||
|
format:
|
||||||
|
$(PIP) install shed
|
||||||
|
. $(BIN)/activate && shed
|
||||||
|
|
||||||
|
build: install format
|
||||||
|
$(PIP) install build
|
||||||
|
$(PYTHON) -m build
|
||||||
|
|
||||||
|
serve:
|
||||||
|
$(BIN)$(APP_NAME).serve --host=0.0.0.0 --port=443
|
||||||
|
|
||||||
|
run: serve
|
||||||
|
|
||||||
|
|
3
pyproject.toml
Normal file
3
pyproject.toml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools", "wheel"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
25
setup.cfg
Normal file
25
setup.cfg
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
[metadata]
|
||||||
|
name = shadowssh
|
||||||
|
version = 1.0.0
|
||||||
|
description = Run ssh on other service port!
|
||||||
|
author = retoor
|
||||||
|
author_email = retoor@molodetz.nl
|
||||||
|
license = MIT
|
||||||
|
long_description = file: README.md
|
||||||
|
long_description_content_type = text/markdown
|
||||||
|
|
||||||
|
[options]
|
||||||
|
packages = find:
|
||||||
|
package_dir =
|
||||||
|
= src
|
||||||
|
python_requires = >=3.7
|
||||||
|
install_requires =
|
||||||
|
app @ git+https://retoor.molodetz.nl/retoor/app.git
|
||||||
|
mololog @git+https://retoor.molodetz.nl/retoor/mololog.git
|
||||||
|
|
||||||
|
[options.packages.find]
|
||||||
|
where = src
|
||||||
|
|
||||||
|
[options.entry_points]
|
||||||
|
console_scripts =
|
||||||
|
shadowssh.serve = shadowssh.__main__:serve
|
9
src/shadowssh/__init__.py
Normal file
9
src/shadowssh/__init__.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import logging
|
||||||
|
from mololog.client import patch
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
level = logging.INFO
|
||||||
|
)
|
||||||
|
|
||||||
|
log = logging.getLogger()
|
||||||
|
patch("https://mololog.molodetz.nl/")
|
25
src/shadowssh/__main__.py
Normal file
25
src/shadowssh/__main__.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
from shadowssh.app import Application
|
||||||
|
import asyncio
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
parser = argparse.ArgumentParser(description="Shadowssh")
|
||||||
|
|
||||||
|
parser.add_argument("--host",type=str,required=False,default="0.0.0.0")
|
||||||
|
parser.add_argument("--port",type=int,required=False,default=443)
|
||||||
|
parser.add_argument("--host-service",type=str,required=False,default="127.0.0.1")
|
||||||
|
parser.add_argument("--port-service",type=int,required=False,default=4433)
|
||||||
|
parser.add_argument("--host-ssh", type=str,required=False,default="127.0.0.1")
|
||||||
|
parser.add_argument("--port-ssh", type=int,required=False,default=22)
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def serve():
|
||||||
|
args = parse_args()
|
||||||
|
app = Application()
|
||||||
|
asyncio.run(app.serve(args.host,args.port,args.host_service,args.port_service,args.host_ssh,args.port_ssh))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
78
src/shadowssh/app.py
Normal file
78
src/shadowssh/app.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import asyncio
|
||||||
|
from app.app import Application as BaseApplication
|
||||||
|
from shadowssh import log
|
||||||
|
|
||||||
|
class Application(BaseApplication):
|
||||||
|
|
||||||
|
def __init__(self, host_forward_service=None, port_forward_service=None, host_forward_ssh=None, port_forward_ssh=None, *args,**kwargs):
|
||||||
|
self.host_forward_service = host_forward_service
|
||||||
|
self.port_forward_service = port_forward_service
|
||||||
|
self.host_forward_ssh = host_forward_ssh
|
||||||
|
self.port_forward_ssh = port_forward_ssh
|
||||||
|
super().__init__(*args,**kwargs)
|
||||||
|
|
||||||
|
async def connect(self, host, port):
|
||||||
|
log.info("Connected to {}:{}.".format(host,port))
|
||||||
|
reader, writer = await asyncio.open_connection(host, port)
|
||||||
|
return reader,writer
|
||||||
|
|
||||||
|
async def stream(self, reader, writer,port):
|
||||||
|
while True:
|
||||||
|
chunk = await reader.read(4096)
|
||||||
|
if not chunk:
|
||||||
|
writer.close()
|
||||||
|
log.info("Forward connection closed.")
|
||||||
|
return
|
||||||
|
writer.write(chunk)
|
||||||
|
await writer.drain()
|
||||||
|
|
||||||
|
async def forward(self, reader, writer):
|
||||||
|
|
||||||
|
|
||||||
|
data = await reader.read(10)
|
||||||
|
if not data:
|
||||||
|
return
|
||||||
|
port = None
|
||||||
|
host = None
|
||||||
|
if b'SSH-2.0' in data:
|
||||||
|
port = self.port_forward_ssh
|
||||||
|
host = self.host_forward_ssh
|
||||||
|
else:
|
||||||
|
port = self.port_forward_service
|
||||||
|
host = self.host_forward_service
|
||||||
|
|
||||||
|
log.info("Streaming to port: {}.".format(port))
|
||||||
|
upstream_reader, upstream_writer = await self.connect(host, port)
|
||||||
|
upstream_writer.write(data)
|
||||||
|
tasks = []
|
||||||
|
tasks.append(asyncio.create_task(self.stream(reader, upstream_writer,port)))
|
||||||
|
tasks.append(asyncio.create_task(self.stream(upstream_reader, writer,port)))
|
||||||
|
await asyncio.gather(*tasks)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def route(self, host, port):
|
||||||
|
|
||||||
|
async def handle_client(reader, writer):
|
||||||
|
await self.forward(reader, writer)
|
||||||
|
|
||||||
|
server = await asyncio.start_server(handle_client, host, port)
|
||||||
|
addr = server.sockets[0].getsockname()
|
||||||
|
log.info(f'Serving on {addr}')
|
||||||
|
|
||||||
|
async with server:
|
||||||
|
await server.serve_forever()
|
||||||
|
|
||||||
|
async def serve(self, host,port,host_forward_service, port_forward_service, host_forward_ssh, port_forward_ssh):
|
||||||
|
self.host_forward_service = host_forward_service
|
||||||
|
self.port_forward_service = port_forward_service
|
||||||
|
self.host_forward_ssh = host_forward_ssh
|
||||||
|
self.port_forward_ssh = port_forward_ssh
|
||||||
|
tasks = [
|
||||||
|
self.route(host,port)
|
||||||
|
]
|
||||||
|
await asyncio.gather(*tasks)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user