sudo apt-get install libxml-parser-perl
cd /usr/sbin && cat > /tmp/write_py3_ws.sh <<'BASH'
#!/bin/bash
set -e
write_proxy() {
file="$1"
port="$2"
defhost="$3"
cp -n "$file" "$file.py2.bak" 2>/dev/null || true
cat > "$file" <<PY
#!/usr/bin/env python3
import socket
import threading
import select
import sys
import time
import getopt
LISTENING_ADDR = '0.0.0.0'
LISTENING_PORT = $port
PASS = ''
BUFLEN = 4096 * 4
TIMEOUT = 60
DEFAULT_HOST = '$defhost'
RESPONSE = b'HTTP/1.1 101 Switching Protocols\\r\\n\\r\\n'
class Server(threading.Thread):
def __init__(self, host, port):
super().__init__()
self.running = False
self.host = host
self.port = port
self.threads = []
self.threadsLock = threading.Lock()
self.logLock = threading.Lock()
def run(self):
self.soc = socket.socket(socket.AF_INET)
self.soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.soc.settimeout(2)
self.soc.bind((self.host, self.port))
self.soc.listen(200)
self.running = True
try:
while self.running:
try:
c, addr = self.soc.accept()
c.setblocking(True)
except socket.timeout:
continue
conn = ConnectionHandler(c, self, addr)
conn.daemon = True
conn.start()
self.addConn(conn)
finally:
self.running = False
self.soc.close()
def printLog(self, log):
with self.logLock:
print(log)
def addConn(self, conn):
with self.threadsLock:
if self.running:
self.threads.append(conn)
def removeConn(self, conn):
with self.threadsLock:
if conn in self.threads:
self.threads.remove(conn)
def close(self):
self.running = False
with self.threadsLock:
for c in list(self.threads):
c.close()
class ConnectionHandler(threading.Thread):
def __init__(self, socClient, server, addr):
super().__init__()
self.clientClosed = False
self.targetClosed = True
self.client = socClient
self.client_buffer = b''
self.server = server
self.log = 'Connection: ' + str(addr)
def close(self):
try:
if not self.clientClosed:
self.client.shutdown(socket.SHUT_RDWR)
self.client.close()
except Exception:
pass
self.clientClosed = True
try:
if not self.targetClosed:
self.target.shutdown(socket.SHUT_RDWR)
self.target.close()
except Exception:
pass
self.targetClosed = True
def run(self):
try:
self.client_buffer = self.client.recv(BUFLEN)
hostPort = self.findHeader(self.client_buffer, 'X-Real-Host') or DEFAULT_HOST
split = self.findHeader(self.client_buffer, 'X-Split')
if split:
self.client.recv(BUFLEN)
passwd = self.findHeader(self.client_buffer, 'X-Pass')
if len(PASS) != 0 and passwd == PASS:
self.method_CONNECT(hostPort)
elif len(PASS) != 0 and passwd != PASS:
self.client.sendall(b'HTTP/1.1 400 WrongPass!\\r\\n\\r\\n')
elif hostPort.startswith('127.0.0.1') or hostPort.startswith('localhost'):
self.method_CONNECT(hostPort)
else:
self.client.sendall(b'HTTP/1.1 403 Forbidden!\\r\\n\\r\\n')
except Exception as e:
self.log += ' - error: ' + str(e)
self.server.printLog(self.log)
finally:
self.close()
self.server.removeConn(self)
def findHeader(self, head, header):
if isinstance(head, bytes):
head = head.decode('latin-1', 'ignore')
aux = head.find(header + ': ')
if aux == -1:
return ''
aux = head.find(':', aux)
head = head[aux + 2:]
aux = head.find('\\r\\n')
if aux == -1:
return ''
return head[:aux]
def connect_target(self, host):
i = host.find(':')
if i != -1:
port = int(host[i + 1:])
host = host[:i]
else:
port = 80
soc_family, soc_type, proto, _, address = socket.getaddrinfo(host, port)[0]
self.target = socket.socket(soc_family, soc_type, proto)
self.targetClosed = False
self.target.connect(address)
def method_CONNECT(self, path):
self.log += ' - CONNECT ' + path
self.connect_target(path)
self.client.sendall(RESPONSE)
self.client_buffer = b''
self.server.printLog(self.log)
self.doCONNECT()
def doCONNECT(self):
socs = [self.client, self.target]
count = 0
while True:
count += 1
recv, _, err = select.select(socs, [], socs, 3)
if err:
break
if recv:
for in_ in recv:
try:
data = in_.recv(BUFLEN)
if not data:
return
if in_ is self.target:
self.client.sendall(data)
else:
self.target.sendall(data)
count = 0
except Exception:
return
if count >= TIMEOUT:
break
def print_usage():
print('Usage: $file -p <port>')
print(' $file -b <bindAddr> -p <port>')
def parse_args(argv):
global LISTENING_ADDR
global LISTENING_PORT
try:
opts, args = getopt.getopt(argv, 'hb:p:', ['bind=', 'port='])
except getopt.GetoptError:
print_usage()
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print_usage()
sys.exit()
elif opt in ('-b', '--bind'):
LISTENING_ADDR = arg
elif opt in ('-p', '--port'):
LISTENING_PORT = int(arg)
def main():
print('\\n:-------Python3Proxy-------:\\n')
print('Listening addr: ' + LISTENING_ADDR)
print('Listening port: ' + str(LISTENING_PORT) + '\\n')
print(':--------------------------:\\n')
server = Server(LISTENING_ADDR, LISTENING_PORT)
server.daemon = True
server.start()
while True:
try:
time.sleep(2)
except KeyboardInterrupt:
print('Stopping...')
server.close()
break
if __name__ == '__main__':
parse_args(sys.argv[1:])
main()
PY
chmod +x "$file"
}
write_proxy PDirect.py 80 127.0.0.1:550
write_proxy Proxy.py 8181 127.0.0.1:22
write_proxy PStunnel.py 8080 127.0.0.1:550
write_proxy POpenvpn.py 8880 127.0.0.1:110
sed -i 's/nohup python /nohup python3 /g' /usr/sbin/sshws.sh /usr/sbin/sslws.sh /usr/sbin/ovpnws.sh
python3 -m py_compile PDirect.py Proxy.py PStunnel.py POpenvpn.py
pkill -f 'python.*\(PDirect\|Proxy\|PStunnel\|POpenvpn\)\.py' 2>/dev/null || true
systemctl daemon-reload
systemctl restart sshws sslws ovpnws
BASH
bash /tmp/write_py3_ws.sh
grep -R "nohup python" -n /usr/sbin/sshws.sh /usr/sbin/sslws.sh /usr/sbin/ovpnws.sh; python3 -m py_compile /usr/sbin/PDirect.py /usr/sbin/Proxy.py /usr/sbin/PStunnel.py /usr/sbin/POpenvpn.py; ss -lntp | grep -E ':80|:8181|:8080|:8880'