-2

On a Raspberry PI I have, whatever I run on, say, http://localhost:8080, is automatically visible to other computers on my local network at http://192.168.0.xxx:8080 or http://pi.local:8080.

This doesn't happen with my Mac. If I'm testing an Angular app which runs on http://localhost:4200, that app will not be seen at http://mymac.local:4200 by other computers on my local network.

All I want to do is expose the localhost port to my LAN, not to the rest of the world. Yet when I look for a solution to this problem, all I turn up is tools like ngrok, which isn't what I want. I'm not trying to have my app visible to the whole world, just my LAN.

My macOS firewall is not turned on, so there is not a problem as far as I know with the particular port being actively blocked.

UPDATE:

A make-shift solution I have found is this:

browser-sync start --proxy "localhost:4200" --no-open --no-ghost-mode --no-notify --no-snippet --no-ui --port 4200

browser-sync, however, is specifically HTTP oriented, and tries to mess around with the contents which are served in many way, hence all of the --no-xxx flags I'm using. I'd like to find a similar, simpler solution that forwards TCP traffic in a purely neutral way.

kshetline
  • 109
  • 1
  • 7
  • Is application running on Mac reachable on `http://mymac.local:4200`? – dexter Nov 12 '22 at 18:58
  • @dexter, no, it isn't, but that's what I want to have happen, while also keeping the app visible on localhost at the same time. – kshetline Nov 12 '22 at 19:04
  • I asked that because port numbers differs, you said Angular runs app on port 4200 and you are trying to reach it on the port 8080. If you don't have some routing I don't see how it can work. Check on which `IP:PORT` app is listening on Mac (`ss` or `netstat`, not sue what is there on Mac ). – dexter Nov 12 '22 at 19:18
  • @dexter, sorry about that! It was merely a typo that I repeated 8080 describing the second case. I want localhost:4200 to also be seen at mymac.local:4200. – kshetline Nov 12 '22 at 19:27
  • According to comments on my answer this is not about Angular, but Elasticsearch in Docker. Can you [edit] your question to reflect your *actual* problem, so it's possible to answer? – vidarlo Nov 12 '22 at 20:16

2 Answers2

1

On a Raspberry PI I have, whatever I run on, say, http://localhost:8080, is automatically visible to other computers on my local network at http://192.168.0.xxx:8080 or http://pi.local:8080.

No, you don't. Linux, like all other modern operating systems, has the concept of where you're listening. This is called interface binding. Windows, Darwin, Linux and all other modern operating systems supports this, and it essentially let's you specify on what interface you want to listen. Maybe you want Apache to listen to 203.0.113.1, and nginx on 203.0.113.2? If so, you can specify this in the config files.

This is commonly used when you want something to only be available locally: you tell it to bind to 127.0.0.1, or ::1, which is the loop back address. This will not be reachable from any other host, as it's bound to the loop back interface only.

There's also a catch all: 0.0.0.0, or :: in IPv6 parlance: bind any available interface. This will listen on all enabled interfaces, including loop back and others.

In short: figure out how the service you're using defines network interface bind, and modify it to fit.

vidarlo
  • 6,654
  • 2
  • 18
  • 31
  • Perhaps there's some magic going on behind the scenes of which I am unaware, but my Raspberry Pi project is a simple Node.js Express app, set up to listen on one particular port via `httpServer.listen(httpPort);` I have certainly made no effort to bind to any particular interface. I simply let Express do its thing. The server is then available on both localhost and the LAN, through no special effort of my own. – kshetline Nov 12 '22 at 18:52
  • If the same config produces different results on different computers, then the implementations differ or there's a firewall. – vidarlo Nov 12 '22 at 18:56
  • it's not the same app I'm trying to do this with now, but the same app on the two different computers has produced the results as described, and my firewall is off. At any rate, I really don't care why the problem exists, I simply want a solution that will create an appropriate tunnel without changing anything about any app -- the particular app I'm trying to expose now being an instance of ElasticSearch running on Docker than I want available on both localhost and the LAN without messing with the ElasticSearch setup. – kshetline Nov 12 '22 at 19:02
  • Then ask why ES hosted in docker on Darwin is NOT working. Don't ask about a node.js app! Show us the docker config or docker-compose files you're using! My answer is perfectly valid for the question you asked, but you asked a question which was *not* related to your problem. And it's not about tunneling. It's about interfaces and binding, and possibly port forwarding in case of docker. – vidarlo Nov 12 '22 at 20:14
  • my question made it perfectly clear what end result I wanted. I can't help it if you got fixated on the example I used to illustrate the final result that I wanted. I'll take it you're the one who down-voted my question for the sin of not expressing my problem to your satisfaction. – kshetline Nov 12 '22 at 20:20
  • I downvoted it, yes. My answer answers what your question was before edits, by explaining how interface binding works. Docker brings network namespaces into the mix, and uses masquerading to hide internal things, thus it's not valid for a docker setup. A good rule is to ask what you're wondering about, which as much detail as possible. Now I spent time writing an answer to something you didn't want answered, and I find that behavior by you rude. – vidarlo Nov 12 '22 at 20:23
  • My question was "macOS: How do I expose a localhost port to the LAN IP on the same computer?", before any edits, not "How do I change this app to bind to my LAN instead of localhost?", which is was you appeared compelled to answer, by rudely insisting that what I said was happening wasn't even happening. I'm not an expert on networking, which is why I asked a question here. You apparently have little or no tolerance for someone who dares ask a question other than the way you think it should be asked. And you accuse me of rudeness? – kshetline Nov 12 '22 at 20:44
  • I explained how interface binding works, as I suspected you were unaware of this. Interface binding is your problem as the question stands, with firewalls disabled. You can continue quarreling, or you can read the relevant documentation for the application you're using to figure out how to bind to 0.0.0.0. Incidentially, the other answer also points to interface binding, and provides a workaround if your application is unable to configure this. In most cases it's better to reconfigure your application than using socat... – vidarlo Nov 12 '22 at 20:49
  • "No, you don't." is not the start of helpful advice. And you were wrong too. What I said was happening was happening -- app visible on localhost and LAN, without any special effort on my part -- even if I was unaware of how it was happening. – kshetline Nov 12 '22 at 20:51
  • Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/140580/discussion-between-vidarlo-and-kshetline). – vidarlo Nov 12 '22 at 20:52
1

If the service running is specifically bound to use loopback as a listen interface, such as hardcoded and you do not control the source. Dynamic straightforward an ssh tunnel for instance.

Use socat https://stackoverflow.com/questions/16808543/install-socat-on-mac

Check out the help documentation, you can choose protocols, interfaces to bind to, etc, and a host of other things.

SOCAT rocks....

socat TCP-LISTEN:8080,fork TCP:127.0.1:8888

Sabre
  • 425
  • 2
  • 15
  • 1
    Thank you for answering my actual question, instead of giving me a hard time for not asking it in exactly the right way. – kshetline Nov 12 '22 at 20:49
  • Quite welcome, if the answer works for your needs. You can accept it as *the* answer. There are many ways to do the same type of relay you are doing, if socat does not work out you could use HAproxy as well since you are using http, with the frontend on your LAN int, the backend being localhost. That would be a more formal "Service" approach, if you want this to be persistent. However wrapping socat up as a service works flawlessly as well, I have used it many times to expose things like a dynamic port forwarding socks proxy over SSH, or MITM another service for analysis. – Sabre Nov 13 '22 at 16:51