46 comments

[ 4.9 ms ] story [ 94.9 ms ] thread
I love this. But also why.
Instead of building a OTP gateway into each connection, you can just connect to the constantly rotating IP and go from there. Seems useful!
This is absolutely brilliant and amazing and also completely and utterly useless. I love it.
Cool.

That is a pretty bad idea in practice though, the issue(s) being: IP addresses are public (especially to anyone in the middle of your connection) and it's trivially brute-forceable.

Definitely a cool project. And I agree this is a bad idea in practice for many reasons.

But I wasn't aware that TOTP was brute-forcable. What is the mechanism to achieve this (given only a set of IP address and their timestamps)?

TOTP implemented this way is brute-forceable because you can just connect to all of the IP addresses (or pick however many connections you can practically make in 60 seconds and hit those).

There's no way to lock out after N failures or even to rate limit attempts.

A /80 prefix is equivalent to 65536 ipv4 Internets. Not so brute-forceble.
The random part is six digits. I'd say pretty brute-forceable.
The TOTP spec (rfc6238) allows up to 10 digits or 10 billion unique values, a bit bigger than IPv4's space.

Running anything like fail2ban on IP address misses would stop brute forcing in its tracks.

Both good ideas.

None of this fixes even a passive mitm attack, but it's still better.

> There's no way to lock out after N failures or even to rate limit attempts.

Given it’s a single machine with a /80, couldn’t the machine rate limit attempts to any IP in the /80? Ie rate limit by source, and separately rate limit by destination. Cover both bases.

The way I understood it, only the correct IP address would even be connected to anything, the rest would just fail. You probably could do something like that, yeah.
Putting the IP block over WireGuard fixes both issues.
If you're using wireguard don't you already have a secured connection and don't even need any of this?
If the computer is stolen or compromised, but the TOTP device remains secure, then access will be blocked.

Actually, occurs to me now, the brute force approach could still be used then, so that does have to be mitigated separately (which is possible).

I don't think the idea was suggesting that TOTP would be the _only_ method to get in. In fact the code just decides to accept or reject the incoming connection. The normal SSH auth flow would still need to be completed.

So you would need to brute force SSH (which is already decently hard) AND brute force the IP every 30 seconds.

This would stop the constant and relentless failed auth logs. (Yes there are other methods, but this one is novel and good as well)

I love that the submitter fit the entire idea into the title. Understood it without even clicking. Brevity is the soul of wit.

Clever idea, wouldn't have thought of it on my own.

Aidan is one of the most brilliant engineering person I have known. I share a slack workspace with him and his posts are always enlightening.

Glad to see him on HN front-page.

This is like port knocking except using the low 48 bits of the IP address instead of the port. Personally I'm not into port knocking but some people are.
Add a local DNS server that rotates the AAAA record in tandem, and voila!
Risky - both because browsers use DoH more and more, and otherwise DNS cache will be out of sync.
Amazing. But why “ghost ship”?
A ghost ship mysteriously appears and disappears in a number of seemingly random locations, presumably leading mariners to follow it to nowhere chasing ghosts.
I know that even with /80 prefixes on everything we will not run out of IPv6 addresses but why do they provide such large blocks to individual instances, servers etc?

Is there any practical reason? Like easier routing? Just curious.

That individual instance might host hundreds of LAMP vhosts, each could have its own IP now
That individual instance can host 300 trillion vhosts with individual IPs with a /80 block. It has more publicly adressable IP addresses than the entire ipv4 address space.

That is exactly my question, is there a technical / practical reason for this? Or is it simply an arbitrary prefix?

IPv6 networks, by specification, are (almost) always /64 - that is, your subnetwork can have 2^64 nodes on it - which means that any EUI-64 device (A device with a 64 Bit MAC address - Ethernet Devices with 48 bits commonly extend to 64 bits by stuffing 16 bits (FF:FE) in the middle) can automatically determine its own IPv6 address by just concatenating the Network + MAC address. No Stateful DHCP server required.

I'm more curious as to why the /80. This is the very first time I've seen anything less than a /64. Without digging into the details, I'm guessing(?) that the network is a /64 (almost certainly), and on that network there can be /16 nodes (65536), each of which can have /48 (300 Trillion) vhosts.

And I thought I had left CIDR behind with IPv4... Sigh.

It's more "why not." The mindset that addresses are something that need to be conserved and carefully parceled out simply does not jive with V6. It takes a while for that to really sink in particularly if one is used to having to care a lot.

Who cares if they need 100 or 200 or 500,000. Give them a /64 or /80 and let them use it for whatever they come up with. As to why specifically /64 and /80 it probably makes the internal net magic easier versus something that isn't 4-byte aligned.

Yeah I don't really have a problem with the use of large spaces, was just curious about the prefix selection.

> As to why specifically /64 and /80 it probably makes the internal net magic easier versus something that isn't 4-byte aligned.

Thanks for the insight!

Nibble aligned is usually the norm
/64 is the standardized value for the host part of an IPv6 address. Specifically, it's half the address.
And to me, this is part of the problem with IPV6. This HUGE amount of space that results in "why not" numbering, also means long hexadecimal IP addresses that no one can ever remember. The ship has sailed, but adding an octet to IPV4 and not planning to assign 28912479812 IP addresses to a toaster would have been so much easier.
Remembering ip addresses is like remembering passwords.

Why would you do that, when there are so many good tools you can use to do it for you way better than your feeble grey meat sack can?

I mean sure, I remember 127.0.0.1 and 8.8.8.8 and 9.9.9.9, but decent passwords these days are no more memorable than ipv6 addresses.

You're not supposed to be remembering addresses, that's what DNS and LLNMR et al are for. IPv4 let people depend on bad habits and hard-coded fixups, V6 makes that slightly less practical.

Although frankly the functional part of most V6 addresses isn't that much more. Using ULA, of which there are enough of that organizations need not fear constant overlap like 10/8, the network side of our private internet space is only 6 characters and fixed host addresses are often 2. eg, fde3af::1.

We get cute with 6to4 mappings and some routing games and so they may look more like fde3:af00:12:34::1 but the local subnet is handed out via prefix delegation so end users rarely, if ever, need to care.

> Using ULA … the network side of our private internet space is only 6 characters

How do you fit the fixed 8-bit ULA prefix (fd00::/8) plus the 40 random bits you're supposed to use for the Global ID (per RFC 4193) into six hex characters? It should be at least 12, e.g. fdXX:XXXX:XXXX::/48.

As for remembering addresses, yes, just use (m)DNS. You can even set up an mDNS Discovery Proxy[0][1] so that devices which don't support mDNS themselves can resolve the names via regular unicast DNS.

[0] https://www.rfc-editor.org/rfc/rfc8766.html

[1] https://github.com/mkuron/mdns-discovery-proxy

What few private organizations I've seen working with ULA ... are not using really random global IDs. I'm sure larger scale organizations are following RFC4193 more honestly, but getting V6 going at all versus ever more horrifying NAT contraptions in industrial networks is usually enough of a victory for me.
It says right there in the description:

    “You could use the feature to run 281 trillion containers with their own IPs (which I assume is what AWS intended for the feature), but I wanted to find a more fun use.”
It's actually a pretty small prefix in the IPv6 world. The recommendation for an IPv6 network is to be at least a /64, because features like SLAAC, which mostly replaces DHCP, need a /64 prefix to work properly. If you have multiple networks, it's standard to use a separate /64 prefix per network. My ISP for instance gives every home user a /56 prefix, some ISPs even give out /48 prefixes.
It's a odd size but more for being too stingy - normally in these kinds of setups you get something like a /48 or /56 for routing which lets you still have some bits for routing and then you can hang normal /64 subnets at the end of your routes.

Operating systems don't support non-64 prefixes very well and v6 wasn't designed to work like that.

> Operating systems don’t support non-64 prefixes

Then how do routers work? Docker containers? VMs running on a machine with some part of a /64?

Reminds me of port knocking a little bit lol but it's a cute solution for on the fly obfuscation