x,exclude= exclude this subnet (can be used more than once) X,exclude-from= exclude the subnets in a file (whitespace separated) v,verbose increase debug message verbosity e,ssh-cmd= the command to use to connect to the remote [ssh] seed-hosts= with -H, use these hostnames for initial scan (comma-separated) no-latency-control sacrifice latency to improve bandwidth benchmarks wrap= restart counting channel numbers after this number (for testing) D,daemon run in the background as a daemon s,subnets= file where the subnets are stored, instead of on the command line syslog send log messages to syslog (default if you use --daemon) pidfile= pidfile name (only if using --daemon) [./sshuttle.pid] server (internal use only) firewall (internal use only) hostwatch (internal use only) """ o = options.Options(optspec) (opt, flags, extra) = o.parse(sys.argv[1:]) if opt.daemon: opt.syslog = 1 if opt.wrap: import sshuttle.ssnet as ssnet ssnet.MAX_CHANNEL = int(opt.wrap) helpers.verbose = opt.verbose try: if opt.firewall: if len(extra) != 0: o.fatal('exactly zero arguments expected') result = firewall.main(opt.method, opt.syslog) sys.exit(result)
def main(): o = options.Options(optspec) (opt, flags, extra) = o.parse(sys.argv[1:]) if opt.version: from sshuttle.version import version print(version) return 0 if opt.daemon: opt.syslog = 1 if opt.wrap: import sshuttle.ssnet as ssnet ssnet.MAX_CHANNEL = int(opt.wrap) helpers.verbose = opt.verbose or 0 try: if opt.firewall: if len(extra) != 0: o.fatal('exactly zero arguments expected') return firewall.main(opt.method, opt.syslog) elif opt.hostwatch: return hostwatch.hw_main(extra) else: if len(extra) < 1 and not opt.auto_nets and not opt.subnets: o.fatal('at least one subnet, subnet file, or -N expected') includes = extra excludes = ['127.0.0.0/8'] for k, v in flags: if k in ('-x', '--exclude'): excludes.append(v) if k in ('-X', '--exclude-from'): excludes += open(v).read().split() remotename = opt.remote if remotename == '' or remotename == '-': remotename = None nslist = [family_ip_tuple(ns) for ns in parse_list(opt.ns_hosts)] if opt.seed_hosts and not opt.auto_hosts: o.fatal('--seed-hosts only works if you also use -H') if opt.seed_hosts: sh = re.split(r'[\s,]+', (opt.seed_hosts or "").strip()) elif opt.auto_hosts: sh = [] else: sh = None if opt.subnets: includes = parse_subnet_file(opt.subnets) if not opt.method: method_name = "auto" elif opt.method in ["auto", "nat", "tproxy", "pf"]: method_name = opt.method else: o.fatal("method_name %s not supported" % opt.method) if opt.listen: ipport_v6 = None ipport_v4 = None list = opt.listen.split(",") for ip in list: if '[' in ip and ']' in ip: ipport_v6 = parse_ipport6(ip) else: ipport_v4 = parse_ipport4(ip) else: # parse_ipport4('127.0.0.1:0') ipport_v4 = "auto" # parse_ipport6('[::1]:0') ipport_v6 = "auto" if not opt.disable_ipv6 else None if opt.syslog: ssyslog.start_syslog() ssyslog.stderr_to_syslog() return_code = client.main(ipport_v6, ipport_v4, opt.ssh_cmd, remotename, opt.python, opt.latency_control, opt.dns, nslist, method_name, sh, opt.auto_nets, parse_subnets(includes), parse_subnets(excludes), opt.daemon, opt.pidfile) if return_code == 0: log('Normal exit code, exiting...') else: log('Abnormal exit code detected, failing...' % return_code) return return_code except Fatal as e: log('fatal: %s\n' % e) return 99 except KeyboardInterrupt: log('\n') log('Keyboard interrupt: exiting.\n') return 1