-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathforward.py
68 lines (56 loc) · 1.84 KB
/
forward.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import select
import threading
import socket
import paramiko
import os
from paramiko import SSHClient
# SSH server configuration
ssh_host = os.getenv('SSH_HOST')
ssh_port = int(os.getenv('SSH_PORT'))
ssh_password = os.getenv('SSH_PASSWORD')
# Port forwarding configuration
local_port = int(os.getenv('LOCAL_PORT'))
remote_host = os.getenv('REMOTE_HOST')
remote_port = int(os.getenv('REMOTE_PORT'))
# Enable verbose logging (mimics -v)
paramiko.util.log_to_file("ssh.log")
def reverse_forward_tunnel(local_port, remote_host, remote_port, transport):
transport.request_port_forward(address=remote_host, port=remote_port)
while True:
chan = transport.accept(1000)
if chan is None:
continue
thr = threading.Thread(target=handler, args=(chan, local_port))
thr.setDaemon(True)
thr.start()
def handler(chan, port):
sock = socket.socket()
try:
sock.connect(('localhost', port))
except Exception as e:
print(f'Forwarding request to localhost:{port} failed: {e}')
return
while True:
r, w, x = select.select([sock, chan], [], [])
if sock in r:
data = sock.recv(1024)
if len(data) == 0:
break
chan.send(data)
if chan in r:
data = chan.recv(1024)
if len(data) == 0:
break
sock.send(data)
chan.close()
sock.close()
def forward_port():
client = SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print("Connecting to SSH server")
client.connect(hostname=ssh_host, port=ssh_port, password=ssh_password)
print("Setting up remote port forwarding")
reverse_forward_tunnel(local_port, remote_host, remote_port, client.get_transport())
client.close()
if __name__ == '__main__':
forward_port()