{"id":13557791,"url":"https://github.com/moxie0/knockknock","last_synced_at":"2025-04-03T12:31:08.967Z","repository":{"id":1669159,"uuid":"2395956","full_name":"moxie0/knockknock","owner":"moxie0","description":"A simple, secure, and stealthy port knocking implementation that does not use libpcap or bind to a socket interface.","archived":false,"fork":false,"pushed_at":"2018-10-19T21:58:32.000Z","size":223,"stargazers_count":651,"open_issues_count":7,"forks_count":105,"subscribers_count":36,"default_branch":"master","last_synced_at":"2024-11-04T08:36:19.270Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://www.thoughtcrime.org/software/knockknock/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/moxie0.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-09-15T22:51:44.000Z","updated_at":"2024-11-03T12:40:05.000Z","dependencies_parsed_at":"2022-09-14T12:01:58.496Z","dependency_job_id":null,"html_url":"https://github.com/moxie0/knockknock","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxie0%2Fknockknock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxie0%2Fknockknock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxie0%2Fknockknock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxie0%2Fknockknock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moxie0","download_url":"https://codeload.github.com/moxie0/knockknock/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247002227,"owners_count":20867431,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T12:04:32.998Z","updated_at":"2025-04-03T12:31:08.511Z","avatar_url":"https://github.com/moxie0.png","language":"Python","funding_links":[],"categories":["Python","\u003ca id=\"295e14c39bf33cd5136be8ced9383746\"\u003e\u003c/a\u003e工具","others"],"sub_categories":["\u003ca id=\"07f06751f1de7ddd1f6a95323f0191c8\"\u003e\u003c/a\u003ePortKnocking"],"readme":"Some History:\n\n    The port knockingconcept has been around for a while, and there\n    are many different port knocking implementations.  The core idea\n    is that you send a sequence of innocuous looking packets to a\n    server, which have the effect of adjusting the firewall rules to\n    allow you to connect through on a port that was previously\n    firewalled off.\n  \n    Originally, this was simply conceived as a series of connection\n    attempts to closed ports in a specific order.  The \"knock\" would\n    be something like trying to connect to ports 12, 23, 18, 66, or\n    whatever, in that order, over a specific period of time.\n  \n    The problem with the original concept was that if your port\n    sequence was observed by passive eavesdropping, it was easily\n    replayable.  The obvious solution was to develop a port knocking\n    system that did not allow for replay attacks.  Such a solution\n    suggests the use of cryptography.\n  \n    And this is where the insanity begins.  People started\n    implementing all kinds of stuff to achieve this goal, and along\n    the way lost sight of the original intent behind port knocking.\n  \n    Let me tell you what I /don't/ want from a port knocking\n    implementation:\n    \n      * I don't want something written in an an unsafe language.  This\n        should be a very small application, and the performance\n        requirements should be minimal.  \n      * I don't want something that runs /in the kernel/.  \n      * I don't want an entirely new service that binds to a port.  \n      * I don't want something that uses libpcap and inspects /every/ \n        packet.  \n      * I don't want something that uses UDP.  \n      * I don't want something that generates obvious port-knock \n        requests and leaves an observer knowing exactly what port is \n        about to open up.  \n      * I don't want something which requires that more than one\n        packet move over the network.  \n      * I don't want something that uses half-baked cryptography and\n        isn't provably IND-CCA secure.\n    \n  \n    But from what I can tell, this is exactly what people have\n    implemented.  Despite the fact that the main thrust of this is to\n    have less services running, the direction that this has been going\n    is to have whole servers written in C that bind to sockets and\n    exchange UDP packets.  The entire /point/ of port-knocking was for\n    it to be stealthy, simple, and secure.  The goal was to eliminate\n    network services, not create more of them.  We can use\n    cryptography to /simplify/ the initial port knocking concept,\n    rather than making it more complex.\n  \nknockknock Overview:\n\n    So here's how knockknock works:\n    \n      * Servers run the python app 'knockknock-daemon', and clients\n        open ports on those servers by running the python app\n        'knockknock'\n\n      * 'knockknock-daemon' simply tails kern.log.  It doesn't bind to\n        any sockets, load libpcap and inspect every packet, or send\n        anything onto the network at all.\n\n      * When you want to open a port from a client, you run\n        'knockknock', which sends a /single/ SYN packet to the server.\n        The packet's IP and TCP headers are encoded to represent an\n        IND-CCA secure encrypted request to open a specified port from\n        the source IP address.\n\n      * Fields from this packet are logged to kern.log and processed\n        by 'knockknock-daemon', which validates them.\n\n      * You connect from the client to the now-open port on the\n        server.\n\n      * The port closes behind you and doesn't allow any new\n        connections.\n    \n  \n    That's it.  Written in python, simple, single-packet, secure.\n  \n    The request is encrypted using AES in CTR mode, with an HMAC-SHA1\n    using the authenticate-then-encrypt paradigm.  It protects against\n    evesdropping, replay attacks, and all known forms of cryptanalysis\n    against IND-CCA secure schemes.\n  \nWhy Is knockknock Secure?\n  \n    * The knockknock-daemon code is very simple, and is written in\n      python (a 'safe' language).  The code is concise enough to be\n      easily audited, and doesn't make use of any crazy libraries like\n      libpcap.\n\n    * While knockknock-daemon needs root priviledges to adjust\n      iptables rules, it employs privilege separation to isolate the\n      code that actually runs as root to ~15 lines.  So even though\n      the entire code base is very small and very simple, the only\n      part of the code actually running with root privilges is even\n      smaller and even simpler.  When you run knockknock-daemon, it\n      will fork out the privileged code and drop privilges everywhere\n      else before processing knockknock requests.\n\n    * The communication protocol is a simple IND-CCA secure encryption\n      scheme that uses standard, contemporary, cryptographic\n      constructions.  An observer watching packets is not given any\n      indication that the SYN packet transmitted by 'knockknock' is a\n      port knocking request, but even if they knew, there would be no\n      way for them to determine which port was requested to open.\n      Replaying the knock request later does them no good, and in fact\n      does not provide any information that might be useful in\n      determining the contents of future requets.\n  \n  \nWhy Is This Even Necessary?  \n\n    /You are running network services with security vulnerabilities in\n    them./ Again, /you are running network services with security\n    vulnerabilities in them/.  If you're running a server, this is\n    almost universally true.  Most software is complex.  It changes\n    rapidly, and innovation tends to make it more complex.  It is\n    going to be, forever, hopelessly, insecure.  Even projects like\n    OpenSSH that were designed from the ground-up with security in\n    mind, where every single line of code is written with security as\n    a top priority, where countless people audit the changes that are\n    made every day -- even projects like this have suffered from\n    remotely exploitable vulnerabilities.  If this is true, what hope\n    do the network services that are written with different priorities\n    have?\n  \n    The name of the game is to isolate, compartmentalize, and /expose\n    running services as little as possible/.  That's where knockknock\n    comes in.  Given that your network services are insecure, you want\n    to expose as few of them to the world as possible.  I offer\n    knockknock as a possible solution to minimizing exposure.\n  \n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoxie0%2Fknockknock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoxie0%2Fknockknock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoxie0%2Fknockknock/lists"}