| udp-holepunch - Python script for UDP holepunching using a webserver. With an example of SSH using this and sctp-echo. |
ssh_holepunch_client.py (2657B) - raw
1 #!/usr/bin/env python3 2 3 import argparse as ap 4 import subprocess as subp 5 import sys 6 7 from udp_holepunch import udp_holepunch_client 8 9 if __name__ == "__main__": 10 parser = ap.ArgumentParser( 11 description="Run SSH through UDP with holepunching (client)" 12 ) 13 14 parser.add_argument( 15 "-l", "--local-port", 16 type=int, 17 default=0, 18 help="Fixed internal UDP port for us to use (defaults to 0 = auto-assigned by system)" 19 ) 20 parser.add_argument( 21 "-p", "--server-port", 22 type=int, 23 default=0, 24 help="Fixed UDP port to use to start holepunching (defaults to 0 to use our external UDP port number)" 25 ) 26 parser.add_argument( 27 "-s", "--skip-ack", 28 action="store_true", 29 default=False, 30 help="Skip hello packet acknowledgement to finalize holepunching (a couple of the first packets down the line may get lost)", 31 ) 32 parser.add_argument( 33 "-e", "--sctp-echo", 34 default="sctp_echo", 35 help="Path to invoke sctp_echo" 36 ) 37 parser.add_argument( 38 "-k", "--signing-key", 39 type=str, 40 default=None, 41 help="Path to the SSH key used to sign postings on the webserver (can be different from the login key" 42 ) 43 parser.add_argument( 44 "--ack-timeout", 45 type=int, 46 default=60, 47 help="Timeout when waiting for holepunching to be established", 48 ) 49 50 parser.add_argument( 51 "server_name", 52 help="Name of the intermediate server (for SSH)" 53 ) 54 parser.add_argument( 55 "server_path", 56 help="Path of file to write on the intermediate server (e.g. /var/www/inter)" 57 ) 58 parser.add_argument( 59 "ssh_name", 60 help="Name of SSH server to connect to (%%h if in ProxyCommand)", 61 ) 62 63 args = parser.parse_args() 64 65 ## 1. Holepunch 66 local_port, remote_ip, remote_port = udp_holepunch_client( 67 args.local_port, 68 args.server_name, 69 args.server_port, 70 args.server_path, 71 no_ack=args.skip_ack, 72 key_path=args.signing_key, 73 timeout=args.ack_timeout, 74 ) 75 76 ## 2. Run the client 77 client = subp.Popen( 78 [ 79 args.sctp_echo, 80 "-c", 81 "0.0.0.0", ## Local IP 82 str(local_port), ## Local UDP 83 str(local_port), ## Local SCTP = UDP 84 remote_ip, ## Remote IP 85 str(remote_port), ## Remote UDP port 86 str(remote_port), ## Remote SCTP port = UDP 87 ], 88 stdout=sys.stdout.buffer.raw, ## Must use raw or e.g. vi will crash it 89 stdin=sys.stdin.buffer.raw, 90 ) 91 client.wait()