[HN Gopher] How to make "localhost" slightly less local
___________________________________________________________________
How to make "localhost" slightly less local
Author : brycewray
Score : 39 points
Date : 2022-04-02 16:53 UTC (6 hours ago)
(HTM) web link (www.brycewray.com)
(TXT) w3m dump (www.brycewray.com)
| aussieguy1234 wrote:
| You can follow these steps and learn about network interfaces and
| IP addresses or you can use my app (https://expose.sh) and get a
| public URL for your service in a single command.
|
| Note: This won't only make your localhost service slightly less
| local, but also publicly accessible.
|
| Example: `expose 80`
| jeroenhd wrote:
| ...and then you'll find out that all kinds of fancy JS features
| don't work any more because of something called a "secure
| origin"! Soon after you end up in a rabbit hole of acronyms like
| CORS, XHR, CSP, TLS, HSTS, (m)DNS, WSS and HTTPS, and soon enough
| you'll be copy/pasting a hundred of lines of configuration just
| to make your website work like it did on localhost.
|
| I enjoy the ease of use that the special privileges localhost was
| given in browsers, but I'm 100% sure it's a pitfall for starting
| developers. It's still confusing to me that someone capable of
| developing a website needs an explainer on how basic computer
| networking works, but I guess other people learn about computers
| top-down rather than bottom-up. I have no idea what all of these
| servers are (most of them seem Javascript based?) but I'd expect
| someone knowing how to deal with a piece of complex server
| software like that to at least know where to find their machine's
| IP address!
| devmor wrote:
| Or you can just bridge the connection and use mDNS?
| tedunangst wrote:
| Back in the day, you used to be able to connect to services bound
| to 127.1 on host A from host B by deleting 127.1 on host B, then
| adding a manual route to host A's public IP. Host B stack sees
| packet for 127.1, says not me, routes it to host A, host A gets
| packet, looks at its IPs, sees 127.1, says oh this must be for
| me. Most systems are probably better about configuring host A to
| not let this happen now.
| svnpenn wrote:
| Is it possible to access the local site from another network?
| Like run a local server, that I can access from my phone outside
| of the house? I looked into this before, but I could never find a
| simple solution.
| mhitza wrote:
| Use something like ngrok (or manual ssh tunnels), just be sure
| to have some authentication in place.
| skinnymuch wrote:
| Tailscale as others have said. ZeroTier if not Tailscale. Both
| are top notch
| johnny35 wrote:
| Look into Tailscale. Ridiculously easy to set up and free for
| your use case.
| newaccount74 wrote:
| +1 on Tailscale. It took me time to accept using a closed
| source free product, but it's just such a nice product --
| they focussed on the essentials and it works really well.
| skinnymuch wrote:
| It seems like they have gone past essentials now. Like
| being able to use any connected device as an endpoint? I
| haven't used Tailscale yet past as a mesh network but
| regardless. It is so well done.
| jeroenhd wrote:
| With IPv6: yes, if you open the port in your firewall.
|
| With IPv4 you can do it with a port forward, but the IP listed
| isn't the same as the IP you'll actually receive the connection
| on. You can get your external IP relatively easily with `curl
| ifconfig.co`.
|
| If firewalls or port forwards aren't available to you, pick any
| of the popular port forwarding methods (here's a list:
| https://github.com/anderspitman/awesome-tunneling). I'm a big
| fan of just SSH-ing into an internet connected machine myself
| (`ssh -R 0.0.0.0:3000:127.0.0.1:3000 server.on.the.inter.net`
| will expose localhost:3000 on server.on.the.inter.net:3000 and
| encrypt the traffic between you and the server as an added
| bonus!) but there are plenty of paid and sketchy alternatives
| if you don't have a server to SSH into.
| svnpenn wrote:
| > If firewalls or port forwards aren't available to you
|
| I don't know if they are or not. I am just a regular person
| with a home computer. I know how to set up a run a basic
| localhost server, but I don't really know about the other
| stuff you're talking about.
| mhitza wrote:
| Not sure how mDNS service (Bonjour I think) is setup on macOS,
| but you should be able to reach it by some domain name as well
| (hostname.local format), once you expose your service on the
| public IP address.
|
| On Linux I have my VMs run avahi (the Linux mDNS service), and I
| access my VMs using vmname.local instead of using hardcoded IP
| addresses.
| zdragnar wrote:
| Android doesn't support mDNS at the OS level, so it is possible
| to bake it into an app, but i.e. chrome won't connect. It is a
| long standing issue that I don't think Google cares to
| prioritize:
|
| https://issuetracker.google.com/issues/140786115?pli=1
|
| I would have sworn I saw that the latest pixel / android
| versions could, but now I'm not finding one way or the other.
| Given the issue above is still open, I am assuming not.
| avip wrote:
| I've always had issues using mDNS on a mixed os network. I
| assume both bonjour and avahi and whatever windows uses comply
| with some standard. But in (my) reality, it doesn't work.
| maliker wrote:
| I just use ngrok.com. Makes specific localhost ports accessible
| regardless of network.
| pricci wrote:
| I prefer Cloudflare Tunnels.
|
| Just install cloudflared.
| [deleted]
| janjones wrote:
| Localtunnel[1] is also great, you don't even have to sign up.
|
| [1] https://theboroer.github.io/localtunnel-www/
| danielvaughn wrote:
| I love ngrok outside of two pain points - (1) the urls are kind
| of difficult to type into a phone, and (2) the latency can be
| pretty terrible at times.
| stuartd wrote:
| The basic paid plan is pretty cheap and lets you use
| your_subdomain_name.ngrok.com as the address.
| paskozdilar wrote:
| In my opinion, (2) is a feature, not a bug. You never know
| what kind of connection your users have. Ngrok forces you to
| consider the "bad connection" factor early on in development,
| which can avoid many pitfalls that occur when network
| software assumes that latency is zero and bandwidth is
| unlimited.
| skinnymuch wrote:
| It's not a feature imo when there are other ways to force a
| "bad connection". However with ngrok if latency is bad. You
| can't ever change fhat.
| paskozdilar wrote:
| That's a fair point.
|
| I suppose latency is important if you use ngrok for
| something other than development. I use ngrok exclusively
| for development, so that's where my comment comes from.
| skinnymuch wrote:
| I have switched over to using Tailscale. But that only works
| if the devices are mine before the friction of someone else's
| device being set up happens
| pdpi wrote:
| Your computer has multiple network interfaces, and it has routing
| tables that tell it which interface to use for each IP it tries
| to talk to. E.g. your home router basically has one interface
| talking to the outside world and another talking to your local
| network, and its whole job is patching together connections
| through each of those interfaces.
|
| Your personal computer will have ethernet and/or wifi, and those
| are entirely separate network interfaces, but it will also have a
| loopback interface (which is a dummy software-only interface that
| just connects back to your computer). The "localhost" hostname
| points at 127.0.0.1, and that IP is bound to the loopback
| interface, so all connections through localhost won't even hit
| the network, they'll just be looped back in (hence the name).
|
| What all those -H/--host/--bind options do is tell your service
| which of those network interfaces to bind to. Instead of
| specifying an IP (and, therefore, an interface) to bind on, you
| can use 0.0.0.0 as a catch-all "meta-IP" that will tell your
| service to listen on all interfaces.
|
| My personal preference (though it does require a bit more setup
| ahead of time) is to keep all these (HTTP) services listening on
| localhost, and then configure one single NGINX instance that
| binds on the external interface and proxies each individual
| service.
| 1vuio0pswjnm7 wrote:
| "The "localhost" hostname points at 127.0.0.1, but it will also
| have a loopback interface (which is a dummy software-only
| interface that just connects back to your computer)."
|
| AFAIK, 127.0.0.1 localhost as a HOSTS file entry is merely a
| convention. For example, the name "localhost" can point to any
| address in the 127.x.x.x address space or any address in
| general. Similarly, a loopback interface can be assigned any
| 127.x.x.x address. The convention is to assign 127.0.0.1.
|
| One of the nice things about NetBSD (IMO) is that when
| compiling one's own system, a loopback is not necessarily
| automatically created. It may be left up to the user to create
| one and assign it with an address. This can teach the user what
| software depends on the presence of a loopback interface that
| is assigned "127.0.0.1".
| pdpi wrote:
| Yeah, and you can also have multiple loopback interfaces in
| the 127.0.0.0/8 range if you want, no reason why you can only
| have one. That said, enough stuff out there assumes localhost
| = 127.0.0.1 = loopback interface that I wouldn't want to make
| my life complicated by breaking the convention.
|
| Also, that comment was already a bit muc, and I opted to
| simplify a bit.
| brycewray wrote:
| I hope you'll find this helpful whenever you're web-dev'ing and
| just can't remember that string of commands/flags/etc. for seeing
| "localhost" from your other devices.
|
| EDIT: post is now available also on dev.to[0].
|
| [0]: https://dev.to/brycewray/let-all-your-devices-see-your-
| site-...
| [deleted]
| mac-chaffee wrote:
| I lost a lot of the blind faith I had in people who make http
| servers when I realized some network configurations just can't be
| expressed.
|
| Like next.js's "Production Server"[1] uses Node's builtin server,
| which doesn't natively let you listen on more than one IP. And
| because next.js hardcodes 0.0.0.0, it doesn't also listen on the
| IPv6 equivalent if available, which breaks some clients when
| using "localhost" as the hostname (BusyBox wget as a notable
| example I found).
|
| [1]: https://nextjs.org/docs/api-reference/cli#production
| fuzzy2 wrote:
| But then Busybox wget is simply broken, sorry. It's still
| entirely normal for a hostname to resolve to both IPv4 and IPv6
| addresses, yet have some services not listening on both. Good
| TCP clients implement a fallback mechanism that could be so
| fast the user doesn't even notice.
| Dylan16807 wrote:
| That fallback is a workaround. Requiring it is simply broken.
| mac-chaffee wrote:
| If BusyBox did implement that kind of fallback, they'd need
| to set a default timeout. So the whole thing would still be
| broken because every other request would be delayed by the
| timeout.
| jeroenhd wrote:
| I've encountered a similar failure, when some old process
| still claimed [::]:80 when I restarted the web server,
| probably a lingering socket or something like that, which
| made the new process only bind to 0.0.0.0:80. It took me a
| while to find out why my changes weren't being reflected when
| I could see the binding _right there_ in `ss -tlpn`!
|
| Honestly, I don't think it's too unreasonable to argue that
| if a client has IPv6 connectivity and a hostname has a valid
| AAAA record, the connection should be established over IPv6.
| Browsers tend to have fallbacks to IPv4, but outside browsers
| you'll be surprised how little actual system software cares
| about DNS fallback.
|
| Reading the BusyBox source code (https://elixir.bootlin.com/b
| usybox/latest/source/libbb/xconn...) it seems like it will
| pass AF_UNSPEC to str2sockaddr, which is packed into
| `addrinfo hint` and then passed on to getaddrinfo(). Only
| when IPv6 support is disabled or
| ENABLE_FEATURE_PREFER_IPV4_ADDRESS is enabled will busybox
| shuffle around the DNS results to return an IPv4 address.
|
| If your service isn't available on IPv6 yet your hostname has
| a valid IPv6 record, it's your task to indicate this to the
| software (using the -4 flag, for example) or to configure it
| to retry.
| ajsnigrutin wrote:
| > On Linux, you have multiple choices (wouldn't you know?), but
| the easiest is to enter this in your terminal app:
|
| > hostname -I $ hostname -I hostname:
| invalid option -- 'I' Usage: hostname [-v] {hostname|-F
| file} set hostname (from file) domainname [-v]
| {nisdomain|-F file} set NIS domainname (from file)
| hostname [-v] [-d|-f|-s|-a|-i|-y|-n] display formatted name
| hostname [-v] display hostname
| brycewray wrote:
| Interesting. I used an alternate source[0] to check this and it
| says the same thing I had in the article.
|
| [0]: https://www.tecmint.com/hostname-command-examples-for-
| linux/
| rascul wrote:
| Debian's hostname has -I. Turns out that's the hostname I have
| here on openSUSE.
|
| https://tracker.debian.org/pkg/hostname
| Hello71 wrote:
| there are at least four common implementations of "hostname"
| on Linux: debian, coreutils, net-tools, busybox, and arguably
| toybox. there are also at least four implementations of su
| (util-linux, shadow, busybox, toybox) and five
| implementations of kill (coreutils, procps(-ng), util-linux,
| busybox, toybox).
| ajsnigrutin wrote:
| Yep, net-tools doesn't have the "-I" option
___________________________________________________________________
(page generated 2022-04-02 23:01 UTC)