9 ms·
Show HN: Ruroco – like port knocking, but better
Hey there HN!
ruroco (RUn RemOte COmmand) is a tool that lets you execute commands on a server by sending UDP packets (instead of knocking on ports).
the tool consist of 3 binaries:
- client -> runs on your notebook/computer and sends the UDP packets
- server -> receives the UDP packets and makes sure that they are valid
- commander -> runs the command encoded by the data of the UDP packet if it's valid
The commands are configured on the server side, so the client does not define what is going to be executed, it only picks from existing commands.
I use this tool to open up the SSH port on my server via ufw, but only for the IP address from where I'm connecting, so the SSH port appears closed for everyone else, except me.
This is my very first "real" rust project, so any feedback is highly appreciated :)
Enjoy!
- bell-cot 2y agoFrom a quick skim, it sounds like you're using the current time (encrypted) to prevent replay attacks. Good, simple...but I'd note that higher up in your description. And at least think about a Plan B, for when things really go sideways, and system clocks get out of sync. Or intruders have a foothold your network infrastructure.
- mschempp 2y agoThanks for the feedback! Will definitely put some thought into it.
- opem 2y agosuper complicated github description! hn desc. is rather better. great work tho :)
- mschempp 2y agoI'm not good at describing things easily. I will put the hn description on top of the git repo :) Thanks for the feedback!
- deleted 2y ago[deleted]
- Tepix 2y agoThe example shows you opening port 80 (HTTP standard port), the comment next to it mentions SSH (default port 22). That's confusing. Also your headline claims that your system is "better", but it fails to explain why. Modern port knocking also incorporates secure cryptographic hashes.
- rmholt 2y agoI believe the author is comparing their method against just the naive port knocking approach
- mschempp 2y agoyes thats correct. Should have stated that in the headline
- mschempp 2y ago"The example shows you opening port 80 (HTTP standard port)" that's because I run my ssh on port 80, but that's not standard, so I agree that it's confusing. Thanks for pointing it out. I will fix it :)
- mschempp 2y ago"Modern port knocking also incorporates secure cryptographic hashes." Are you referring to fwknop? Thats not "port knocking" but Single Packet Authorization. That is very different from port knocking. How can one incorporate secure cryptographic hashes with simple port knocking?
- Daril 2y agoVery useful! I think it is a great idea !
- cius 2y agoYour docs say: client uses private key to encrypt -> server uses public key to decrypt. Do you mean: client uses private key to sign -> server uses public key to verify? My understanding is private keys decrypt/sign and public keys encrypt/verify. Either your usage, your docs, or my understanding seem to be wrong. I think I'll stick with fwknop for now.
- jagged-chisel 2y agoEncrypting with the private key has the name “signing” because it’s convenient. Both are technically correct.
- cius 2y agoIt sounds like my misunderstanding. So is this just a nomenclature mix up? I'll have to do more research, because I am under the impression there is something special about the private key other than the fact it was designated as such at generation time. I have many holes to fill in my knowledge around this.
- wongarsu 2y agoThe special thing about the private key is that if you have the private key you can also derive the public key from it. Meanwhile if you only have the public key you can't derive the private key. Hence you always use the private key for decrypting or for signing. But other than switching which key to use signing and encrypting are the same thing
- cius 2y agoI think some of this is starting to come into focus. It appears the way these keys are commonly stored necessitates careful treatment after generation. For instance, if this reference is accurate, an RSA private key in PKCS#1 includes the p and q prime factors on which the whole security of the key pairs depends, so you certainly would not want to mix up the files: https://crypto.stackexchange.com/a/79606 https://crypto.stackexchange.com/a/79606
- Tepix 2y agoThe security section fails to explain how the service prevents an attacker from intercepting a packet, then sending it again himself with a new sender IP address to whitelist SSH access his IP address. The original (authorized) sender would then think something went wrong (packet loss), send a new packet and be none the wiser.
- cies 2y agoI agree with your observation, but this is merely put fwd as an alternative to port knocking. Port knocking is IMHO just to keep your sshd logs clean from huge lists of failed attempts, that prevent me from actually finding interesting information in them.
- mschempp 2y agoI used port knocking in the description, because anyone here probably knows what port knocking is and ruroco is kind of similar to that. Ruroco can be used for more than just keeping sshd logs clean, for example I could also enable a service other than ssh, for example a private file server that I want to get access to when I'm on my phone (although I haven't implemented an android version yet, it should be doable).
- Thorrez 2y agoEven if that was protected against (by putting the source IP inside the payload), I'm not sure it's really much more secure. An attacker who can intercept the packet can likely also spoof the source IP, so the attacker could wait for you to open it with your IP, and then use your IP using spoofing.
- beagle3 2y agoSpoofing UDP is easy. Spoofing TCP is useless - you actually need to receive all the packets sent to the original TCP, which means either you are already on the receiving path, or managed to put yourself on it e.g. through a BGP route advertisement - either way, it leaves some trail and much harder to carry out. (And even so, the attacker still has to go through SSH authentication or an SSH vulnerability)
- mr_mitm 2y agoPretty cool. Have you seen considerations regarding port knocking by Moxie Marlinspike? I think he raises some valid points: https://github.com/moxie0/knockknock https://github.com/moxie0/knockknock Instead of using UDP he reads the firewall log. Also he prevents replay attacks (even though his implementation is apparently not secure in this regard). Unfortunately his code is ancient and in Python 2, so a rust implementation would be awesome.
- thrwaway1985882 2y ago> Instead of using UDP he reads the firewall log. Hah! I'd never seen this before, but in a fit of pique driven by ssh scanning one day I did a similar pattern on my OpenBSD router: I added a block in log to a high port in pf.conf, wired up a little shell script that did tcpdump on pflog0 and watched for a packet to come in, then added the IP to the allow port 22 table. I knocked on the door three times, two of which were testing, and ended up throwing it all out in favor of wireguard & making SSH no longer listen on em0, which seems infinitely less silly.
- bongobingo1 2y agoI know its very minor, but are there ergonomic improvements possible to this setup besides shell aliases/functions around pairing `wg-up host && ssh host && wg-down host`? I agree that ultimately, with wg in the kernel, this is a much simpler setup.
- thrwaway1985882 2y agoFrom the OpenBSD perspective, I just populate /etc/hostname.wg0 on my laptop with my wg configuration ... and I can immediately `ssh router` at home or on the road :-) IOW, why ever down the connection? Why not start your tunnel immediately when the network comes up and leave it running until the network goes down?
- bongobingo1 2y agoI was thinking about doing this to multiple different servers and thought they could all share the same vpn network address for simpler configuration but now that I think about it doing that might run into constant server-key-changed warnings from SSH.
- praptak 2y agoIf your use case is "remotely trigger execution of a very small set of fixed commands, securely" then there's Ostiary: https://openwrt.org/docs/guide-user/services/remote_control/ostiary.server https://openwrt.org/docs/guide-user/services/remote_control/... Its value is in the simplicity of the crypto protocol used for this - basically "hash a password with a one time pad".
- mschempp 2y agoThanks for the link. Looks interesting!
- jbstack 2y agoWhat would be the reasons to choose this over fwknop?
- orev 2y agoWhile I wish that fwknop would have displaced the whole idea of port knocking by now, this adds the element of triggering command execution based on the packet, instead of the single fixed action of just opening a port.
- deleted 2y ago[deleted]
- password4321 2y agoI documented the snippets I needed when setting up Caddy + fastcgi to run shell scripts remotely with self-signed HTTPS Basic Auth on an internal server a couple years ago: https://hn-notes.pages.dev/20221128 https://hn-notes.pages.dev/20221128 Although far more heavyweight and barely relevant to this discussion since it's not hidden, sometimes it's useful to be able to do things remotely in an emergency without a private key.
- Thorrez 2y agoWhat type of encryption is used?
- mschempp 2y agoRSA
- rmholt 2y agoSeems really cool! It seems pertinent to remember however that it isn't security as much it is obfuscation.
- hiatus 2y agoSending encrypted messages is obfuscation? Can you elaborate?
- mschempp 2y agoI think what rmholt means is that ruroco does not improve security in the sense, that it has stronger and safer encryption/algorithms/... but that it merely "hides" existing services. I would argue that it does improve security in the way that it reduces the attack surface of potential vulnerable services, because they are simply not accessible for adversaries. On the other hand, having another tool running increases the attack surface, but imho that's very small.
- rmholt 2y agoYup that's what I meant! And I am worried that a replay attack would be able to bypass ruroco. Thus ruruco is not a replacement for good SSH security, which you have to do anyway. But like I wanna stress that I like ruroco and I might end up using it to decrease the internet noise on my home lab, but I'm just worried that someone might end up relying on ruroco instead of proper SSH security
- mschempp 2y agoa replay attack won't work, because every UDP packet data has deadline in nanoseconds. Once this UDP packet reaches the server the deadline will be added to the blocklist. If an attacker sends the same packet again, the server will check its blocklist for the deadline. It does not matter if the deadline has been reached or not. once the packet reaches the server, the deadline of that packet will be added to the blocklist.
- throwaway984393 2y ago[dead]
- mariocesar 2y agoI know a guy who works as an IT consultant for a local telecom company. This is what he does: He calls up the data center and says he needs to connect to a server. The support staff there physically walks into the server room grabs an UTP cable and connects a router directly to the blade server. The router then assigns an IP with all ports wide open—no firewall, no nothing. An hour or so later, the support guy calls back to see if the work is done and then unplugs the cable. And that's their whole security protocol
- electric_mayhem 2y agoHow does this distinguish itself from fwknop? https://github.com/mrash/fwknop https://github.com/mrash/fwknop And what have you got to protest against DoS attacks on your packet inspection mechanism?
- mschempp 2y agoDid not know fwknop, but since it came up multiple times in this thread, I'll look into it. I have no protection against DoS attacks, but I'm working on it (there is also a WIP in the README about that :) )
- gz5 2y agoNice. The deadline argument concept is smart and not in many other implementations. It seems there are two sides of the spectrum for secure SSH access: + Relatively infrequent access by limited # of people to servers which are not top targets for attacks. Solutions like the one above are great for this. + More frequent, more users, more sensitive servers. Close all the inbound ports, permanently. Example: https://github.com/openziti-test-kitchen/zssh https://github.com/openziti-test-kitchen/zssh (or with an integrated OIDC like KeyCloak - https://youtu.be/NZJtzSoS_g0?si=Qg6p6Hdkaq1ahefg https://youtu.be/NZJtzSoS_g0?si=Qg6p6Hdkaq1ahefg)
- mrbluecoat 2y agoI agree. Instead of closing port 22 only to open a different port, it seems more secure to close all ports like the zssh example above or Tailscale SSH [1] or SSH No Ports [2]. [1] https://tailscale.com/tailscale-ssh https://tailscale.com/tailscale-ssh [2] https://atsign.com/resources/articles/close-port-22-forever-with-ssh-no-ports/ https://atsign.com/resources/articles/close-port-22-forever-...
- 0cf8612b2e1e 2y agoSSH on something other than port 22 is not more secure, but it does massively reduce the amount of log noise. Which I find invaluable since I do not have a security team monitoring my machines.
- mschempp 2y ago"+ Relatively infrequent access by limited # of people to servers which are not top targets for attacks. Solutions like the one above are great for this." Thats exactly what I'm using it for - I'm the only one on my server :)
- tptacek 2y agoHow does this compare to just running WireGuard?
- Jnr 2y agoIMHO Wireguard + SSH is a better (more robust, widely supported and more secure) approach. Maybe the OP simply hasn't yet heard about or used Wireguard.
- mschempp 2y ago"Maybe the OP simply hasn't yet heard about or used Wireguard." I have, but I do not want to run a VPN solution on my private sever, for which I barely have any need. Also Wireguard, although VERY secure is still not "simple" software. In addition there are usecases where Wireguard would not help, for example when I want to open up an http service for the current network that Im in.
- throwitaway1123 2y agoWireGuard is honestly very easy to set up. All of the commands feel very straightforward: https://www.procustodibus.com/blog/2020/11/wireguard-point-to-point-config/ https://www.procustodibus.com/blog/2020/11/wireguard-point-t... You can definitely run an HTTP server behind WireGuard. WireGuard just adds a network interface that your server can listen on (e.g. your server would listen on a private address like 10.0.0.1).
- Jnr 2y agoOP's example was a great one. For example, let's say you visit your friends and you want to watch some content together that is accessible on your server. Using this approach you can open access to that without setting up Wireguard on friend's smart TV. And Wireguard does use quite a bit of CPU if you are using a lot of network bandwidth. Small servers don't have that much compute power, so utilizing the port knocking somewhat removes that issue.
- joshuaheard 2y agoIs is pronounced "Ruh-Roh" like Scooby Doo?
- mschempp 2y agoFunny. Haven't thought of that, probably because I'm german. The way I pronounce it is with long vowels. So in an extreme way it would be ruuurooocooo :)
- mannyv 2y agoUgh, I need to enable port knocking on my mikrotik one day.
- saghm 2y ago> The commands are configured on the server side, so the client does not define what is going to be executed, it only picks from existing commands Super interesting! From looking at the readme, it looks like the configuration isn't specific to ssh either; I assume you could use it for any service that exposes a port.
- mschempp 2y agothat is correct. The configuration is not even ufw specific, you could run any command that you like. This means you could also, for example, disable or enable certain nginx configurations.
- damezumari 2y agoI think this does what ostiary does except worse. It has replay protection. Of course, that project is long abandoned although I use it. The only difference is, knocking is via tcp as it makes unique challenges instead of this repeatable udp packet.
- mschempp 2y agoThanks for the feedback and pointing out ostiary. Fixing replay attacks is on my todo list, maybe I can learn some things from how ostiary does it. Kind advice from my PoV: Your comment could be read as "your project is shit, there is ostiary which has replay protection and yours doesn't". I'm sure you didn't intend for you comment to not come across that way, and I also did not read it that way, but others could have. Also keep in mind that ruroco is a very young project and is by no means finished. I was thinking about using one-time-pads or other encryption algorithms as well. I also posted this here to get feedback to improve my project. So hopefully when I release version 1.0.0 all the issues that this project has atpit are resolved ;)
- praptak 2y agoOstiary prevents replay by salting. Client's reply is only valid for the unique salt that the server has generated and only for a short time and obviously only once. A replay attack can only make the server do whatever the legit client intended it to do, just up to [timeout] seconds later.
- mschempp 2y agohmmm just validated my implementation the deadline that is sent from the client is being added to the blocklist after the command was executed, so sending the same packet again will not work, because the deadline (which is in nanoseconds) is already on the blocklist and therefore the command will not be executed again. This effectively means that replaying a packet is not possible, because the server will deny it.
- KaiserPro 2y agoif you are old like me, you might remember https://en.wikipedia.org/wiki/Xinetd https://en.wikipedia.org/wiki/Xinetd which did this kinda thing.