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): = 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:
def close(self):
for port in self.closeseq:
def knock(self, port):
skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
skt.connect( (, port) );
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();[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.port, args.openseq, args.closeseq);
if not args.onlyclose and args.doopen and not knocker.is_open():
print "\033[92m -> opening ports...",;
print "done\033[0m"
# run command
if not args.onlyopen and not args.onlyclose:
print " \033[92m-> starting command...\033[0m", shell=True);
print " \033[92m-> command done\033[0m"
if not args.onlyopen and args.doclose:
print " \033[92m-> closing ports...",
print "done\033[0m"