Advertisement
DeaD_EyE

Port-Knocker-Prototype

Jan 25th, 2017
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.16 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. """
  4. Der Prozess öffnet drei Ports und wartet bis ein Client Port
  5. für Port den passenden Text übermittelt.
  6.  
  7. Wenn der Timeout nicht überschritten wird, die Ports in der richtigen
  8. Reihenfolge mit den zugehörigen Schlüsselwörtern übermittelt werden,
  9. wird der Port 22 für eine kurze Zeit geöffnet und dann wieder geschlossen.
  10.  
  11. Bereits bestehende Verbindungen werden dadurch nicht beeinflusst.
  12. """
  13.  
  14. import socket
  15. import subprocess
  16. from shlex import split
  17. import time
  18. import logging
  19.  
  20. FORMAT = '%(asctime)-15s %(message)s'
  21. logging.basicConfig(format=FORMAT)
  22. log = logging.getLogger()
  23. log.setLevel(logging.INFO)
  24.  
  25. def bind(ip, port):
  26.     """
  27.    Erstellt einen TCP-Socket und öffnet ihn auf der jeweiligen IP und Port.
  28.    """
  29.     addr = (ip, port)
  30.     sock = socket.socket()
  31.     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  32.     sock.bind(addr)
  33.     sock.listen(5)
  34.     log.info('Listening: {}:{}'.format(*addr))
  35.     return sock
  36.  
  37. def main(ports, keys):
  38.     lock_ssh() # Neue SSH-Verbindungen abweisen.
  39.     sockets = [bind('0.0.0.0', port) for port in ports] #erstellt die Sockets
  40.     try:
  41.         while True:
  42.             last_client = None
  43.             last_time = None
  44.             for sock, key in zip(sockets, keys):
  45.                 # das muss noch geändert werden
  46.                 client, addr = sock.accept()
  47.                 if not last_client:
  48.                     last_client = addr[0]
  49.                 if not last_client == addr[0]:
  50.                     log.info('Address {} does not fit to {}'.format(addr[0], last_client))
  51.                     break
  52.                 log.info('Client {}{} connected'.format(*addr))
  53.                 data = client.recv(len(key) + 2).strip()
  54.                 client.close()
  55.                 log.info('Received: {}'.format(data))
  56.                 if last_time and (time.time() - last_time) > 0.5:
  57.                     log.info('Time is up')
  58.                     break
  59.                 if not last_time:
  60.                     last_time = time.time()
  61.                 if key != data:
  62.                     break
  63.             else:
  64.                 log.info('Success')
  65.                 log.info('Opening SSH Port')
  66.                 unlock_ssh()
  67.                 time.sleep(0.5)
  68.                 log.info('Closing SSH Port')
  69.                 lock_ssh()
  70.     except KeyboardInterrupt:
  71.         [s.close() for s in sockets]
  72.         unlock_ssh()
  73.  
  74. def lock_ssh():
  75.     """
  76.    Sperrt den Port 22 für neue Verbindungen
  77.    """
  78.     cmd = split('iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j REJECT')
  79.     proc = subprocess.call(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)
  80.  
  81. def unlock_ssh():
  82.     """
  83.    Entfernt die Regel wieder.
  84.    """
  85.     cmd = split('iptables -D INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j REJECT')
  86.     proc = subprocess.call(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)
  87.  
  88. if __name__ == '__main__':
  89.     ports = [1025, 1026, 1027]
  90.     keys = [b'foo', b'bar', b'baz']
  91.     main(ports, keys)
  92.  
  93.  
  94. # Client:
  95. # echo "foo" | nc localhost 1025; echo "bar" | nc localhost 1026; echo "baz" | nc localhost 1027; ssh localhost
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement