Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 110 lines (85 sloc) 3.53 KB
#!/usr/bin/env python2
import argparse, ConfigParser, os, socket, subprocess, time
class Knocker:
def __init__(self, host, target_port, openseq, closeseq):
self.host = host;
self.target_port = target_port;
self.openseq = openseq;
self.closeseq = closeseq;
def is_open(self):
return self.knock(self.target_port);
def open(self):
for port in self.openseq:
self.knock(port);
def close(self):
for port in self.closeseq:
self.knock(port);
def knock(self, port):
skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
try:
skt.connect( (self.host, port) );
skt.shutdown(2);
return True;
except socket.error:
return False;
if __name__ == "__main__":
cfg = {
'host': 'localhost',
'port': 22,
'command': 'ssh localhost',
'openseq': [1234, 5678, 9123],
'closeseq': [2345, 6789, 1234]
};
# configure from config file
cp = ConfigParser.SafeConfigParser();
cp.read([os.path.expanduser("~/.knocker")]);
if cp.has_section('config'):
for op in cfg.keys():
if cp.has_option('config', op):
if op in ['host', 'command']:
cfg[op] = cp.get('config', op);
elif op == 'port':
cfg[op] = cp.getint('config', op);
elif op in ['openseq', 'closeseq']:
_ = cp.get('config', op);
_ = _.replace(' ', '');
_ = _.split(',');
cfg[op] = [ int(__) for __ in _ ];
# configure from command line
p = argparse.ArgumentParser(description="Port Knocker");
p.add_argument('-H', '--host', action='store', type=str,
dest='host', default=cfg['host'], help="host");
p.add_argument('-p', '--target-port', action='store', type=int,
dest='port', default=cfg['port'], help="target port to open");
p.add_argument('-r', '--command', action='store', type=str,
dest='command', default=cfg['command'], help="command to run");
for oc in ('open', 'close'):
p.add_argument("-%s" %oc[0], "--only-%s" %oc,
action='store_true', default=False,
dest="only%s" %oc,
help="only %s the port, nothing else" %oc);
p.add_argument("-%s" %oc[0].upper(), "--no-%s" %oc,
action='store_false', default=True,
dest="do%s" %oc,
help="don't try to %s the port" %oc);
p.add_argument("-%s" %{'open':'s', 'close':'e'}[oc], '--%s-seq' %oc,
action='store', type=int, nargs='+',
dest="%sseq" %oc,
default=cfg["%sseq" %oc],
help="open sequence");
args = p.parse_args();
# start knocking
knocker = Knocker(args.host, args.port, args.openseq, args.closeseq);
if not args.onlyclose and args.doopen and not knocker.is_open():
print "\033[92m -> opening ports...",
knocker.open();
print "done\033[0m"
# run command
if not args.onlyopen and not args.onlyclose:
print " \033[92m-> starting command...\033[0m"
subprocess.call(args.command, shell=True);
print " \033[92m-> command done\033[0m"
if not args.onlyopen and args.doclose:
print " \033[92m-> closing ports...",
knocker.close();
print "done\033[0m"