[HN Gopher] SSH has no Host header
___________________________________________________________________
SSH has no Host header
Author : apitman
Score : 145 points
Date : 2026-03-18 05:18 UTC (17 hours ago)
(HTM) web link (blog.exe.dev)
(TXT) w3m dump (blog.exe.dev)
| Eikon wrote:
| I am not sure to understand what this is this achieving compared
| to just assigning a ip + port per vm?
| otterley wrote:
| Not needing a different port. Middleboxes sometimes block ssh
| on nonstandard ports. Also, to preserve the alignment between
| the SSH hostname and the web service hostname, as though the
| user was accessing a single host at a single public address.
| Usability is key for them.
| Charon77 wrote:
| They don't want each vm to have different public IP
| gsich wrote:
| Middleboxes are not relevant in this scenario.
| otterley wrote:
| Uh, why not? Unless your SSH client is on the same network
| as theirs, there are going to be middleboxes somewhere in
| the path.
| gsich wrote:
| Because your ISP should (and most do not) alter traffic.
| Dylan16807 wrote:
| Why would anyone configure it to do that?
|
| Like, I understand the really restrictive ones that only
| allow web browsing. But why allow outgoing ssh to port 22 but
| not other ports? Especially when port 22 is arguably the
| least secure option. At that point let people connect to any
| port except for a small blacklist.
| otterley wrote:
| I'm not a network security expert, so I don't know the
| threat model. I just know that this is a thing companies do
| sometimes.
| josephcsible wrote:
| Middlebox operators aren't known for making reasonable or
| logical decisions.
| 9dev wrote:
| Asking back, when I limit the outgoing connections from a
| network, why would I account for any nonstandard port and
| make the ruleset unwieldy, just in case someone wanted to
| do something clever?
| Dylan16807 wrote:
| A simple ruleset would only block a couple dangerous
| ports and leave everything else connectable. Whitelisting
| outgoing destination ports is more complicated and more
| annoying to deal with for no benefit. The only place you
| should be whitelisting destination ports is when you're
| looking at incoming connections.
| 9dev wrote:
| I definitely block outgoing ports on all our servers by
| default; Established connections, HTTP(S), DNS, NTP, plus
| infra-specific rules. There is really no legitimate
| reason to connect to anything else. The benefit is
| defence against exfiltration.
| CGamesPlay wrote:
| Using nonstandard ports would break the `ssh foo.exe.dev`
| pattern.
|
| This could also have been solved by requiring users to
| customize their SSH config (coder does this once per machine,
| and it applies to all workspaces), but I guess the exe.dev guys
| are going for a "zero-config, works anywhere" experience.
| w-ll wrote:
| -p ?
| hrmtst93837 wrote:
| Zero-config usually means the complexity got shoved somewhere
| less visible. An SSH config is fine for one box, but with a
| pile of ephemeral workspaces it turns into stale cruft fast
| and half the entries is for hosts you forgot existed.
|
| The port issue is also boringly practical. A lot of corp envs
| treat 22 as blessed and anything else as a ticket, so baking
| the routing into the name is ugly but I can see why they
| picked it, even if the protocool should have had a target
| name from day one.
| CGamesPlay wrote:
| SSH configs support wildcards, so if you couple it with a
| ProxyCommand you can an arbitrary level of dynamism for a
| host pattern (like *.exe.dev).
|
| But yeah, everything is a trade-off.
| KomoD wrote:
| Too bad most SSH clients don't seem to support SRV records,
| they would've been perfect for this: ;;
| Domain: mydomain.com. ;; SSH running on port 2999
| at host 1.2.3.4 ;; A Record
| vm1928.mydomain.com. 1 IN A 1.2.3.4 ;; SRV Record
| _ssh._tcp.vm1928.mydomain.com. 1 IN SRV 0 0 2999
| vm1928.mydomain.com.
|
| If supported it would result in just being able to do "ssh
| vm1928.mydomain.com" without having to add "-p 1928"
| dlenski wrote:
| SSH is an incredibly versatile and useful tool, but many things
| about the protocol are _poorly designed_ , including its
| essentially made-up-as-you-go-along wire formats for
| authentication negotiation, key exchange, etc.
|
| In 2024-2025, I did a survey of millions of public keys on the
| Internet, gathered from SSH servers and users in addition to TLS
| hosts, and discovered--among other problems--that it's incredibly
| easy to misuse SSH keys in large part because they're stored
| "bare" rather than encapsulated into a certificate format that
| can provide some guidance as to _how_ they should be used and
| _for what purposes_ they should be trusted:
|
| https://cryptographycaffe.sandboxaq.com/posts/survey-public-....
| Charon77 wrote:
| What good does certificate format do? Certainly won't make
| people not reuse it the same way.
|
| > where the affected users might be surprised or alarmed to
| learn that it is possible to link these real-world identities.
|
| I feel like it's obvious that ssh public keys publically
| identifies me, and if I don't want that, I can make different
| keys for different sites.
| bauruine wrote:
| ssh by default sends all your public keys to a server. Yes
| you can limit some keys to specific hosts but it's very easy
| to dox yourself.
| ulrikrasmussen wrote:
| I had never thought about that. Seems like an easy problem
| to fix by sending salted hashes instead.
| unsnap_biceps wrote:
| The server matches your purposed public key with one in
| the authorized keys file. If you don't want to expose
| your raw public key to the server, you'll need to
| generate and send the hashed key format into the
| authorized keys file, which at that point is the same as
| just generating a new purpose built key, no? Am I missing
| something?
| grey-area wrote:
| Doesn't it try one key at a time rather than send all?
| unsnap_biceps wrote:
| It does, and there's typically a maximum number of
| attempts (MaxAuthTries defaults to 6 IIRC) before the
| server just rejects the connection attempt.
| 84634E1A607A wrote:
| Yep, but this is server-side setting. Were I a sniffer, I
| would set this to 10000 and now I can correlate keys.
| bauruine wrote:
| True but a server that wants to "deanonymize" you can
| just reject each key till he has all the default keys and
| the ones you added to your ssh agent.
|
| You can try it yourself [0] returns all the keys you send
| and even shows you your github username if one of the
| keys is used there.
|
| [0] ssh whoami.filippo.io
| grey-area wrote:
| Nice, tried it out. This wording is incorrect though:
|
| "Did you know that ssh sends all your public keys to any
| server it tries to authenticate to?"
|
| It should be _may_ send, because in the majority of cases
| it does not in fact send all your public keys.
| rwmj wrote:
| Modern sshd limits the number of retries. I have 5 or 6
| keys and end up DoSing myself sometimes.
| grepfru_it wrote:
| This thread made me realize why fail2ban keeps banning me
| after one failed password entry :lightbulb:
| est wrote:
| so it's good practice to store key in non-default location
| and use ~/.ssh/config to point the path for each host?
| geocar wrote:
| Specifically to use a different key for each host.
| 9dev wrote:
| What a great case of "you're holding it wrong!" I need to
| add individual configuration to every host I ever want to
| connect to before connecting to avoid exposing all public
| keys on my device? What if I mistype and contact a server
| not my own by accident?
|
| This is just an awfully designed feature, is all.
| est wrote:
| > add individual configuration to every host I ever want
| to connect
|
| Are you AI?
|
| You can wildcard match hosts in ssh config. You generally
| have less than a dozen of keys and it's not that
| difficult to manage.
| kemotep wrote:
| I have over a dozen ssh keys (one for each service and
| duplicates for each yubikey) and other than the 1 time I
| setup .ssh/config it just works.
|
| I have the setting to only send that specific host's
| identity configured or else I DoS myself with this many
| keys trying to sign into a computer sitting next to me on
| my desk through ssh.
|
| Like I can't imagine complaining about adding 5 lines to
| a config file whenever you set up a new service to ssh
| onto. And you can effectively copy and paste 90% of those
| 5 short lines, just needing to edit the hostname and key
| file locations.
| wasmitnetzen wrote:
| I would say it's best practice to use a key agent backed
| by a password manager.
| dlenski wrote:
| > > where the affected users might be surprised or alarmed to
| learn that it is possible to link these real-world
| identities.
|
| > I feel like it's obvious that ssh public keys publically
| identifies me, and if I don't want that, I can make different
| keys for different sites.
|
| You're probably not the only one for whom it's obvious, but
| it appears to be _not at all obvious_ to large numbers of
| users.
| dotwaffle wrote:
| That's the point, though. An SSH key gives authentication, not
| authorization. Generally a certificate is a key signed by some
| other mutually trusted authority, which SSH explicitly tried to
| avoid.
| simonjgreen wrote:
| SSH does support certificate based auth, and it's a great
| upgrade to grant yourself if you are responsible for a multi
| human single user system. It grants revocation, short
| lifetime, and identity metadata for auditing, all with
| vanilla tooling that doesn't impose things on the target
| system.
| waynesonfire wrote:
| > multi human single user system
|
| A rather niche use-case to promote certificate auth... I'd
| add the killer-app feature is not having to manage
| authorized_keys.
| _bernd wrote:
| You can also sign ssh host keys with an ssh ca.
|
| See ssh_config and ssh-keygen man-pages...
| dlenski wrote:
| Agreed, this makes sense in principle.
|
| But what I found, empirically, is that a substantial number
| of observable SSH public keys are (re)used in way that allows
| a likely-unintended and unwanted determination of the owner's
| identities.
|
| This consequence was likely not foreseen when SSH pubkey
| authentication was first developed 20-30 years ago.
| Certainly, the use and observability of a massive number of
| SSH keys on just a single servers (ssh git@github.com) wasn't
| foreseen.
| arcfour wrote:
| SSH does have a certificate format that can place restrictions
| on what the user can do when connecting with that key. I'm not
| so sure about the hostkey side of things though.
|
| For example: https://smallstep.com/blog/ssh-
| vs-x509-certificates/#certifi... you can see here that X11
| forwarding is permitted for this certificate, among other
| things.
| 3r7j6qzi9jvnve wrote:
| I wonder if it's something like https://github.com/cea-
| hpc/sshproxy that sits in the middle (with decryption and
| everything) or if they could do this without setting up a session
| directly with the client.
|
| Well, we're implicitly trusting the host when running a VM anyway
| (most of the time), but it's something I'd want to check before
| buying into the service.
|
| EDIT: Ah, it's probably https://github.com/boldsoftware/sshpiper
|
| will try to remember to look later.
| kro wrote:
| Almost certainly it does, as public key auth takes place after
| setting up the session encryption
| otterley wrote:
| This is a clever trick, but I can't help but wonder where it
| breaks. There seems to be an invariant that the number of
| backends a public key is mapped to cannot exceed the number of
| proxy IPs available. The scheme probably works fine if most
| people are only using a small number of instances, though. I
| assume this is in fact the case.
|
| Another thing that just crossed my mind is that the proxy IP
| cannot be reassigned without the client popping up a warning.
| That may alarm security-conscious users and impact usability.
| cortesoft wrote:
| They just need to set the limit on the number of VMs per user
| to be less than or equal to the number of public IPs they have
| available. As long as two users don't try to share a key, you
| are good... which should be easy, just don't let them upload a
| key that another user has already uploaded.
| ulrikrasmussen wrote:
| I also wonder what happens if you want to grant access to your
| VM to additional public keys and one of those public keys
| happen to already be routed to a different VM on the same IP.
| dwedge wrote:
| Github has a similar system and just refuses to let you
| addthe key if it already exists. It's hacky but it's also
| obviously massively widespread.
| otterley wrote:
| I just encountered this the other day, in fact. You cannot
| utilize a single SSH key with multiple GitHub accounts.
| krautsauer wrote:
| SSH waits for the server key before it presents the client keys,
| right? Does this mean that different VMs from different users
| have the same key? (Or rather, all VMs have the same key? A quick
| look shows s00{1,2,3}.exe.xyz all having the same key.) So this
| is full MitM?
| cortesoft wrote:
| I mean, anytime you use the cloud for anything, you are giving
| MITM capabilities to the hosting provider. It is their
| hardware, their hypervisors... they can access anything inside
| the VMs
| yaur wrote:
| This approach doesn't give access from the hypervisor to your
| private keys it gives access to other tenants to your private
| keys.
| TZubiri wrote:
| I think the vulnerability would be that not only the host can
| now MITM, but other co-tenants would have the capability to
| bypass that MiTM protection.
| rwmj wrote:
| Not if it's using Confidential Computing. Then you're
| trusting "only" the CPU vendor (plus probably the government
| of the country where that vendor is located), but you're
| trusting the CPU already.
| unsnap_biceps wrote:
| You are correct, but I expect they instruct their users to run
| with a host key validation disabled ( StrictHostKeyChecking=no
| UserKnownHostsFile=/dev/null) , as they expect these are
| ephemeral instances.
| morpheuskafka wrote:
| They are saying they want to directly SSH into a VM/container
| based on the web hostname it serves. But that's not how the HTTP
| traffic flows either. With only one routable IP for the host, all
| traffic on a port shared by VMs has to go to a server on the host
| first (unless you route based on port or source IP with iptnbles,
| but that is not hostname based).
|
| The HTTP traffic goes to a server (a reverse proxy, say nginx) on
| the host, which then reads it and proxies it to the correct VM.
| The client can't ever send TCP packets directly to the VM, HTTP
| or otherwise. That doesn't just magically happen because HTTP has
| a Host header, only because nginx is on the host.
|
| What they want is a reverse proxy for SSH, and doesn't SSH
| already have that via jump/bastion hosts? I feel like this could
| be implement with a shell alias, so that:
|
| ssh user@vm1.box1.tld becomes: ssh -j jumpusr@box1.tld user@vm1
|
| And just make jumpusr have no host permissions and shell set to
| only allow ssh.
| Dylan16807 wrote:
| If jump host shell aliases were a valid option, then setting a
| port would be a much easier valid option.
| lmm wrote:
| The point is that they want the simple UX of "ssh vm1.box1.tld"
| takes you to the same machine that browsing to vm1.box1.tld
| takes you to, without requiring their users to set any
| additional configuration.
| bfivyvysj wrote:
| You can have that already? It's just dns. Are you saying
| different vms share the same box1 ip? Well then yeah, you
| want a reverse proxy on some shared ip.
| dwedge wrote:
| > Well then yeah, you want a reverse proxy on some shared
| ip.
|
| At that point you run into the problem that SSH doesn't
| have a host header and write this blog post.
| bfivyvysj wrote:
| Yeah, ftp has the same issue depending on implementation.
| dwedge wrote:
| Most host/port services have the same issue, even https
| used to have it and it's the reason SNI was introduced.
| But if by implementation you mean sftp, then of course -
| it uses Ssh
| bombcar wrote:
| I wonder if SSH supports SRV records and if it would help.
| TZubiri wrote:
| >They are saying they want to directly SSH into a VM/container
| based on the web hostname it serves. But that's not how the
| HTTP traffic flows either.
|
| > Proceeds to explain how the HTTP traffic flows based on the
| hostname.
|
| If you wanted to flex on your knowledge of the subject you
| could have just lead the whole explanation with
|
| >"I know all about this, here's how it works."
|
| Also
|
| >"What they want is a reverse proxy for SSH"
|
| They already did this, I'm much more impressed by the original
| article that actually implemented it than by your comment
| "correcting them" and suggesting a solution.
| geocar wrote:
| > The HTTP traffic goes to a server (a reverse proxy, say
| nginx) on the host, which then reads it and proxies it to the
| correct VM.
|
| That's one implementation. Another implementation is the proxy
| looks at the SNI information in the ClientHello and can choose
| the correct backend using that information _without_ decrypting
| anything.
|
| Encrypted SNI and ECH requires some coordination, but still
| doesn't require decryption/trust by the proxy/jumpbox which
| might be really important if you have a large number of
| otherwise independent services behind the single address.
| miyuru wrote:
| > We cannot issue an IPv4 address to each machine without blowing
| out the cost of the subscription. We cannot use IPv6-only as that
| means some of the internet cannot reach the VM over the web. That
| means we have to share IPv4 addresses between VMs.
|
| Give a user a option for use IPv6 only, and if the user need
| legacy IP add it as a additional cost and move on.
|
| Trying to keep v4 at the same cost level as v6 is not a thing we
| can solve. If it was we wouldn't need v6.
| YesThatTom2 wrote:
| This is the way.
| TZubiri wrote:
| Op solved a problem and your comment is "I wouldn't have solved
| the problem".
|
| >legacy IP
|
| lol
| 9dev wrote:
| It's a nice solution for sure, but a problem by choice. You
| could just have an AAAA record for the domain in addition to
| the A record, and as GP pointed out, resolve SSH sessions via
| the IPv6. If the user _wants_ SSH to work with IPv4 for
| whatever reason--I see the point that there may be some web
| visitors without IPv6 still, but devs?--they could pay a
| small extra for a dedicated IPv4 address.
| lifthrasiir wrote:
| They could buy a dedicated IPv4 address, but that address
| still has to be tunneled through [EDIT:] IPv6 networks if
| that dev has no access to [EDIT:] IPv4 networks. Thus DX
| still suffers. [ADDENDUM: I mistakenly swapped "IPv4" and
| "IPv6" there. See comments.]
| 9dev wrote:
| I'm not sure I understand your point; if exe.dev operates
| a dedicated IP solely so a specific mythical IPv6-less
| developer can connect to a specific server, then there's
| no tunnelling involved at all.
| lifthrasiir wrote:
| Oops, I think I mixed up two sentences in the middle. A
| fixed comment is available. But I also probably
| misinterpreted what you were saying:
|
| > they could pay a small extra for a dedicated IPv4
| address.
|
| Did you mean that the dedicated IPv4 address _to connect
| via SSH_? Then my objection doesn 't apply.
| michaelt wrote:
| Products targeted at developers like to get a foothold in
| large corporations "by stealth" - let the developers
| experience what a great product it is first, _before_ they
| have to do the approval paperwork.
|
| With this IPv4 trick, if your employer or university only
| provides IPv4 you can use the product anyway.
| asmor wrote:
| This is great if you have IPv6 support from your ISP. Not so
| great if you don't.
|
| Before someone mentions tunnels: Last time I tried to set up a
| tunnel Happy Eyeballs didn't work for me at all; almost
| everything went through the tunnel anyway and I had to deal
| with non-residential IP space issues and way too much traffic.
| miyuru wrote:
| I complained as a yearly tradition for couple of years to get
| v6 enabled in my ISP. They had the core network enabled on
| World IPv6 Launch in 2012, but not deployed to end customers.
|
| One simple way to check if your ISP have some kind of IPv6
| netowork is to see if CDN domains given by YouTube and
| Facebook have AAAA records.
|
| We shouldn't have to ask for ISPs to add IPv6 support but
| here we are.
| jeroenhd wrote:
| ISPs won't bother with IPv6 until they've either run out of
| IPv4 space or the internet starts to use IPv6's advantages.
|
| Discussions about IPv6 quickly end with "we have enough v4
| space and there are no services that require v6 anyway". As
| long as the extra cruft for v4 support remains free or even
| supported, large ISPs won't care. We're at the point where
| people need to deal with things like peer to peer
| connectivity with two sides behind CGNAT which require
| dedicated effort to even work.
|
| I know it sucks if none of the ISPs in your area support IPv6
| and you're left with suboptimal solutions like tunnels from
| HE, but I think it's only reasonable all this extra cost or
| effort becomes visible at some point. Half the world is on
| v6, legacy v4-only connections are becoming the minority now.
| rjsw wrote:
| I have has native IPv6 since 2010, from two different ISPs.
|
| It is also available for one of my phone contracts but not
| tried enabling it yet.
| ralferoo wrote:
| Conversely, I had IPv6 for about 5 years from an ISP and
| when I switched providers, the new ISP was IPv4 only. A
| few years later and they now support IPv6, but my
| firewall setup is now IPv4 only, so I've not bothered to
| update it.
| mrjay42 wrote:
| Well, you're very lucky (genuinely).
|
| In 2025, I tried to access my services using IPv6 with 4G
| phones and different subscriptions (different ISPs), fact
| is, many (most?) of them did not support IPv6 at all :(
|
| I had to revert to IPv4. And really I have nothing
| against IPv6, but yeah, as a simple user, self hosting a
| bunch of services for friends and family: it was simply
| just not possible to use only IPv6 :(
|
| (for context, the 4G providers are French, in
| metropolitan France)
| rjsw wrote:
| My phone contract that does offer IPv6 is with Free, I
| could not work out whether it would disable IPv4 if I
| enabled IPv6 so have not tried changing it.
| crawshaw wrote:
| (exe.dev co-founder here)
|
| We are not running out of IPv4 space because NAT works. The
| price of IPv4 addresses has been dropping for the last
| year.
|
| I know this because I just bought another /22 for exe.dev
| for the exact thing described in this blog post: to get our
| business customers another 1012 VMs.
| apitman wrote:
| Yep. As sad as it is for p2p, NAT handles most uses cases
| for users, and SNI routing (or creative hacks like OP)
| handles most use cases for providers.
|
| I was surprised how low IPv4 prices have gotten. Lowest
| since at least 2019.
| crawshaw wrote:
| Amazingly even most p2p works with NAT, see (and I am
| biased here) Tailscale.
|
| I certainly wish we simply had more addresses. But v4
| works.
| apitman wrote:
| Your NAT traversal article is amazing, but sadly the long
| tail (ha) means any production quality solution has to
| have relays, which is a huge complexity jump for people
| who just want to run some p2p app on their laptop.
|
| And it's not clear it will ever be better than it is now
| with CGNAT on the rise.
|
| Would love to hear I'm wrong about this.
| rwmj wrote:
| Are there really ISPs that don't support IPv6? I've had IPv6
| from various ISPs since around 2010, and even my phone gets
| an IPv6 address from the cellular network.
| TobTobXX wrote:
| Yes and it's ANNOYING. In Switzerland there is literally
| not one cellular network that issues IPv6 addresses. Also
| my workplace network (a school using some sort of Microslop
| solution) doesn't issue IPv6es.
|
| I have a IPv6-only VPN with some personal services.
| Theoretically, the data can be transported via IPv4, but
| Android doesn't even query AAAA records if it doesn't have
| a route for [::]/0. So when I'm not home, I can't reach my
| VPN servers, because there is supposedly no address.
|
| (I fix it by routing all IPv6 traffic through my VPN. Just
| routing connectivitycheck may suffice though).
| p_l wrote:
| Anything Microsoft lacking V6 is configuration issue -
| ever since Vista, Windows networking (in corporate)
| treats v4-only as somewhat "degraded" configuration (some
| time ago there was even a funny news post about how
| Microsoft was forced to keep guest WiFi with enabled v4,
| having switched everything else to V6 only)
| johannes1234321 wrote:
| They could have done that in addition (and maybe they do), but
| for some of their customers it then may not work, for reasons
| hard to understand as a customer. Especially when changing
| locations frequently it may sometimes work and sometimes not
| ... not good for keeping customers
| jcgl wrote:
| You could also provide a dual stack jump host. Then v4-only
| clients just set the ProxyJump option to get to all the v6-only
| hosts via the jump host.
| crawshaw wrote:
| (exe.dev co-founder here)
|
| IPv6 does not work on the only ISP in my neighborhood that
| provides gigabit links. I will not build a product I cannot
| use.
|
| Even when IPv6 is rolled out, it is only tested for consumer
| links by Happy Eyeballs. Links between DCs are entirely IPv4
| even when dual stacked. We just discovered 20 of our machines
| in an LAX DC have broken IPv6 (because we tried to use
| Tailscale to move data to them, which defaults to happy
| eyeballs). Apparently the upstream switch configuration has
| been broken for months for hundreds of machines and we are the
| first to notice.
|
| I am a big believer in: first make it work. On the internet
| today, you first make it work with IPv4. Then you have the
| luxury of playing with IPv6.
| c45y wrote:
| I would love it if more systems just understood SRV records,
| hostname.xyz = 10.1.1.1:2222
|
| So far it feels like only LDAP really makes use of it, at least
| with the tech I interact with
| iwontberude wrote:
| I love that kubernetes does this for cluster service domain
| names
| jiehong wrote:
| It's also similar with mDNS on local networks. It's actually
| nice!
|
| Overall, DNS features are not always well implemented on most
| software stack.
|
| A basic example is the fact that DNS resolution actually
| returns a list of IPs, and the client should be trying them
| sequentially or in parallel, so that one can be down without
| impact and annoying TTL propagation issues. Yet, many languages
| have a std lib giving you back a single IP, or a http client
| assuming only one, the first.
| geocar wrote:
| This has history: https://egopoly.com/2008/02/ssh-slow-on-
| leopard.html
|
| I also know of https://github.com/Crosse/sshsrv and other
| tricks
|
| I agree more SRV records would have helped with a tremendous
| number of unnecessary proxies and wasted heat energy from
| unnecessary computing, but in this day and age, I think
| ECH/ESNI-type functions should be considered for _every_ new
| protocol.
| ComputerGuru wrote:
| SRV is essentially a simple layer of abstraction that
| provides (via one approach) the required end result
| (reachability + UX) that is easy to add to any $PROTO client
| without. Supporting ESNI would complicate the actual
| lib/protocol, increase the amount of dev and maintenance work
| required all around, significantly increase complexity, and
| require more infrastructure and invasive integration than any
| DNS-enabled service already uses.
| otterley wrote:
| Even with SRV records, there's still the problem of middleboxes
| restricting protocol traffic to certain ports. (There's another
| comment thread in which we discuss this.) In practice, SRV
| records work much better inside network borders than on the
| larger Internet.
| XorNot wrote:
| The solution to this is TLS SNI redirecting.
|
| You can front a TLS server on port 443 and then redirect _without
| decrypting_ the connection based on the SNI name to your final
| destination host.
| J-Kuhn wrote:
| But... this doesn't work for SSH, which is the problem here?
| XorNot wrote:
| SSH has ProxyCommand which accepts the %h template.
|
| Provided your users will configure something a little - or
| you provide a wrapping command - you can setup the tunneling
| for them.
| miladyincontrol wrote:
| Im not saying its the solution I would implement but caddy's L4
| module does let you do this, essentially using TLS as a tunnel
| and openssl in the proxy command to terminate it client side.
| binarin wrote:
| In kinda the same situation, I was using username for host
| routing. And real user was determined by the principal in SSH
| certificate - so the proxy didn't even need to know the concrete
| certificates for users; it was even easier than keeping track of
| user SSH keys.
|
| Certificate signing was done by a separate SSH service, which you
| connected too with enabled SSH agent forwarding, pass 2FA
| challenge, and get a signed cert injected into your agent.
| unsnap_biceps wrote:
| Can you expand on your solution a little bit? AFAIK principals
| don't impact the user that is logged in at all. A principal in
| the cert and in the authorized list just allows the user to log
| in as any user they want, which is why you have to write a
| script that validates the username before listing principals to
| accept.
|
| I'd love to learn more about how you solved it and what I may
| be mistaken about.
| binarin wrote:
| What I had is roughly the following: users connects via SFTP
| to external.website.com@my.proxy.com. Proxy server (which
| handles SSH protocol itself) authenticates the user using the
| principal, then checks whether this principal is allowed to
| access an external web-site and what exactly it can do here.
| Then proxy connects to the external website using its own
| secret credentials. In the end, it solved the problem of
| having a shared google doc with a bunch of passwords in there
| which everyone had access to.
| charcircuit wrote:
| You don't need SSH. Installing an SSH server to such a VM is a
| hold over from how UNIX servers worked. It puts you in the
| mindset of treating your server as a pet and doing things for a
| single vm instead of having proper server management in place. I
| would reconsider if offering ssh is an actual requirement here or
| if it could be better served by offering users a proper control
| panel to manage and monitor the vms.
| mystifyingpoi wrote:
| Could you suggest an alternative then? Something that is
| feature complete with SSH server, and also free.
| charcircuit wrote:
| I have not worked in the server management in many years, but
| with how cheap code is with AI rolling your own dashboard may
| not be such a bad idea.
|
| >with SSH server
|
| My comment was about how you do not need an ssh server. The
| idea of a server exposing a command line that allows
| potentially anything to be done is not necessary in order to
| manage and monitor a server.
| sirl1on wrote:
| Treating your server as pet may perfectly fine. Not everything
| has to be fully automated cloud cluster cattle.
| charcircuit wrote:
| Even as a pet I think a proper interface for managing the
| server would be better and more secure than ssh.
| dspillett wrote:
| Often those proper interfaces are wrappers around what you
| would run via SSH and add their own security holes, so I
| would argue against "more secure than SSH".
| zeratax wrote:
| what control panel is perfect for literally every type of
| project and has no edge cases
| ComputerGuru wrote:
| Plenty of (cattle or pet) tooling essentially devolves to SSH
| under those layers of abstraction.
| thaumaturgy wrote:
| Yeah, I ran into this problem too. I tried a few different hacky
| solutions and then settled on using port knocking to sort inbound
| ssh connections into their intended destinations. Works great.
|
| I have an architecture with a single IP hosting multiple LXC
| containers. I wanted users to be able to ssh into their
| containers as you would for any other environment. There's an
| option in sshd that allows you to run a script during a
| connection request so you can _almost_ juggle connections
| according to the username -- if I remember right, it 's been
| several years since I tried that -- but it's terribly fragile and
| tends to not pass TTYs properly and basically everything hates
| it.
|
| But, set up knockd, and then generate a random knock sequence for
| each individual user and automatically update your knockd config
| with that, and each knock sequence then (temporarily) adds a nat
| rule that connects the user to their destination container.
|
| When adding ssh users, I also provide them with a client config
| file that includes the ProxyCommand incantation that makes it
| work on their end.
|
| Been using this for a few years and no problems so far.
| dwedge wrote:
| Doesn't this require configuration at the end user, so you
| could just as easily ProxyJump or use a different port?
|
| It's a nice solution but I've been looking for something more
| transparent (getting them to configure an SSH key is already
| difficult for them). A reverse proxy that selects backend based
| solely on the SSH key fingerprint would be ideal
| thaumaturgy wrote:
| That's all true, but juggling connections based on key
| fingerprints would also require users to have different keys
| for different containers -- which is good practice, but I've
| found that it's equally difficult for users unfamiliar with
| ssh to set up and properly manage more than one key, and it's
| equally easy for users familiar with ssh to manage multiple
| client configs.
|
| That and ProxyJump both also require the container-host to
| negotiate ssh connections, which is... fine, I guess? But the
| port knocking approach means that the only thing the
| container-host is doing is port forwarding, which gives it
| like half an extra point in my calculus.
| snvzz wrote:
| The solution is ipv6.
| TZubiri wrote:
| It's hard to think of a clearer example for the concept of
| Developer Experience.
|
| One similar example of SSH related UX design is Github. We mostly
| take the git clone git@github.com/author/repo for granted, as if
| it were a standard git thing that existed before. But if you ever
| go broke and have to implement GitHub from scratch, you'll notice
| the beauty in its design.
| ulrikrasmussen wrote:
| Wouldn't a much simpler approach be to have everyone log in to a
| common server which sits on a VPN with all the VMs? It introduces
| an extra hop, but this is a pretty minor inconvenience and can be
| scripted away.
| duckerduck wrote:
| They kind of already have a central point with 'ssh exe.dev',
| which hosts the interface for provisioning new VMs. But yeah,
| still one extra step for the user.
| YooLc wrote:
| Why not include header in the username field :)
|
| Take a look at this repo: https://github.com/mrhaoxx/OpenNG
|
| It allows you to connect multiple hosts using the same IP, for
| example:
|
| ssh alice+hostA@example.com -> hostA
|
| ssh alice+hostB@example.com -> hostB
| jeroenhd wrote:
| I think that would work just fine for most use cases, though
| you may run into people trying to set up weird usernames on
| their VMs that conflict with the host split config.
|
| Still, this is the best zero-config solution in my opinion,
| much simpler than the solution they decided to go with.
| est wrote:
| jump servers, it's a thing and a good security measure.
| szszrk wrote:
| And it's easy to create a clean 3 lines of ssh client config
| for the user to later just do
|
| `ssh name`
|
| Even less things to remember + you have documented your
| hostnames in the process.
| hamandcheese wrote:
| This would be a great use case of SSH over HTTP/3[0]. Sadly it
| doesn't seem to have gained traction.
|
| [0]: https://www.ietf.org/archive/id/draft-michel-ssh3-00.html
| geocar wrote:
| Initial thoughts are it's a meh protocol that does not look
| well thought-out, has fewer features than SSH, to the point I'm
| not sure it deserves to be called SSH3 and not telnet-over-
| websockets. Also, there's already an SSH3
| https://marc.info/?l=openssh-unix-dev&m=99840513407690&w=2 so I
| _really_ think the thing you're thinking of is just some
| namesquatter assuming it has any connection to openssh or ssh.
|
| I also know how to use SRV records so this is a non-issue for
| me and everyone I work with.
| thomashabets2 wrote:
| While not transparent to users, I'd just use SSH ProxyCommand
| like I did in https://github.com/ThomasHabets/huproxy
|
| Not exactly what i built in for, but it'll do the job here too,
| and able to connect to private addresses on the server side.
| fcpk wrote:
| I mean it works... but it's really ghetto. You have to handle
| username collisions(or enforce unique usernames). IPv4 should be
| non free, and that'd cover the costs...
| ksk23 wrote:
| Once hooked into PAM to have a central ,,ssh box" mount remote
| boxes filesystems on user connect. Just need to have a lookup
| table: which username belongs to wich customer(s server). Ezpz.
| gorgoiler wrote:
| Hosting DNS on the same machine as your application opens up all
| sorts of nice hacks. For example, you can add domain names to
| nf_conntrack by noticing the client resolving example.com to
| 10.0.0.1, then making a connection to 10.0.0.1 tcp/443. This was
| how I made my own "little snitch" like tool.
| dwedge wrote:
| This is a problem I've come up against a few times. Enforcing a
| different key per server would also help solve it in their case,
| but really I just want a haproxy plugin that allows selecting a
| backend based on the public key
| loktarogar wrote:
| I'm building something that has to share a pool of phone numbers
| for SMS between many businesses with many clients and the
| architecture I had planned out looks a lot like this - client
| gets assigned a phone number from the pool for all its
| interactions with a certain business.
|
| Good write up of a tricky problem, and glad to real-world
| validate the solution I was considering.
| elric wrote:
| Two options I use:
|
| 1. Client side: ProxyJump, by far the easiest
|
| 2. Server side: use ForceCommand, either from within sshd_config
| or .ssh/authorized_keys, based on username or group, and forward
| the connection that way. I wrote a blogpost about this back in
| 2012 and I assume this still mostly works, but it probably has
| some escaping issues that need to be addressed:
| https://blog.melnib.one/2012/06/12/ssh-gateway-shenanigans/
| niobe wrote:
| I had to reread the first paragraph several times before I
| understood - the author was misuing a term.
|
| > unexpected-behaviour.exe.dev
|
| That is not a URL, that's a fully qualified domain name (FQDN),
| often referred to as just 'hostname'.
| spwa4 wrote:
| True, BUT you can use proxycommand in sshconfig, along with
| wildcard matches to make this sort of thing very practical, at
| the cost of a single config change.
| dspillett wrote:
| The workaround I use for my own stuff is to have a single jump-
| host that listens on the public IPv4 address and from there
| connect to the others. I can still just ssh username@namedhost
| (which could be username@www.websitehostedonthevm.tld, though I
| usually give short aliases in .ssh/config) without extra command-
| line options with the on-time config of adding a host entry in
| .ssh/config listing the required jump host and internal IP
| address. Connecting this way (rather than alternatives like
| manual multi-hop) means all my private keys stay local rather
| than needing to be on the jump host, without needing to muck
| around with a key agent.
|
| I even do this despite having a small range of routable IPv4s
| pointing at home, so I don't really need to most of the time. And
| as an obscurity measure the jump/bastion host can only be
| contacted by certain external hosts too, though this does still
| leave my laptop as a potential single point of security failure
| (and of course adds latency) and one or any bot trying to get in
| needs to jump through a few hoops to do so.
| jamesvzb wrote:
| surprised this isn't talked about more
| Shorel wrote:
| We all should do our part to move to IPv6, the sooner, the
| better.
| hnarn wrote:
| There are about 60k ports you can choose from for each IP, so I
| don't understand why you can't just give one user 1.2.3.4:1001
| and the other 1.2.3.4:1002 and route that.
|
| Setting it up like this where you just assume:
|
| > The public key tells us the user, and the {user, IP} tuple
| uniquely identifies the VM they are connecting to.
|
| Seems like begging for future architectural problems.
| bombcar wrote:
| Something like getting SSH to support SRV records would allow
| that to be transparent to the user:
| https://github.com/Crosse/sshsrv
| GoblinSlayer wrote:
| Host header is poorly designed builtin socks5 protocol. Use
| proper socks5 protocol. Its intended purpose is proxy access to
| inner networks, which became ubiquitous with this
| docker/kube/microservice thing.
| kazinator wrote:
| > _SSH, on the other hand, has no equivalent of a Host header._
|
| SSH cannot multiplex to different servers on the same host:port.
| But you can use multiple ports and forwarding.
|
| You could give each machine a port number instead of a host name:
| ssh-proxy:10001 ssh-proxy:10002
|
| When you ssh to "ssh-proxy:10002" ("ssh -p 10002 ssh-proxy" wth
| your OpenSSH client that doesn't take host:port, sigh), it
| forwards that to wherever the 10002 machine currently is.
|
| It would be interesting to know why they rejected the port number
| solution, but the only hit for "port" in the article is in the
| middle of the word "important" in the sentence:
|
| _But uniform, predictable domain name behavior is important to
| us, so we took the time to build this for exe.dev._
|
| You can have uniform, predictable domain + port behavior. Then
| you don't need a smart proxy which routes connections based on
| identities like public keys. Just manipulation of standard port
| forwarding (e.g. iptables).
| mritzmann wrote:
| Why not "ssh undefined-behavior@exe.xyz" (naming based on the
| example in the blog)? That way, you would have the "Host header"
| as username.
___________________________________________________________________
(page generated 2026-03-18 23:00 UTC)