When outside our company firewall, I use a script to tunnel via SSH and expose our internal wiki to my OSX machine. Is there a command to temporarily tell OSX to resolve to my local port when the tunnel is set up?

The sequence I'm hoping to use is:

  1. open the tunnel ssh -f external-proxy.example -L 8001:internal-wiki.example:8000 -N

  3. typing the URL internal-wiki.example:8000 in my browser causes it to transparently view localhost:8001

Other details:

  • I could edit /etc/hosts but that would be a persistent change. I want to use this only when outside
  • We're not using SSL or certs.
  • I can think of a solution involving a tun device which would work on Linux. Does Mac OS X have a tun device that can be used in a similar way?
    – kasperd
    Sep 20, 2017 at 16:53
  • Check my answer as it meets everything you've asked for without any extra steps on creating tun devices, fifo nor proxies.
    – Marcel
    Sep 25, 2017 at 14:32
  • @marcel yes it is a good answer. It's the same as the first option I gave, wrapped in a bash script. I do like the use of trap, btw.
    – virullius
    Sep 26, 2017 at 15:30

5 Answers 5


I have a solution for you, wrap your ssh command into a bash script:


function control_c {
    echo -en "\n## Caught SIGINT; Clean up /etc/hosts and Exit \n"
    sed -i '' "/internal-wiki/d" /etc/hosts
    exit $?

trap control_c SIGINT
trap control_c SIGTERM

(sleep 5; open http://internal-wiki.example:8001 &)&
echo ' internal-wiki.example' >> /etc/hosts
ssh -L8001:internal-wiki.example:8000 -f external-proxy.example -N


  1. function that executes the cleanup on Control-C when issued
  2. trap Control-C and shutdown
  3. sleep, tell osx to open your site, get out of the way (the ampersand)
  4. adds the entry to /etc/hosts
  5. create the tunnel
  6. when you ctrl-c, the functions kicks in and cleans up /etc/hosts with the transient entry
  • Oh, you'll have to sudo script.bash in order to be able to edit /etc/hosts
    – Marcel
    Sep 22, 2017 at 14:36

My apologies if this is not sufficient for an answer, I don't have enough rep to comment here.

I think /etc/hosts is possibly the best option. I don't know what your teardown process is, but you could add removing the /etc/hosts entry as part of it.
Also I think the port change won't work with a /etc/hosts solution. Can you map localhost:8000 to internal-wiki.example:8000?

Then you could add something like internal-wiki.example to /etc/hosts and remove the line when you stop the tunnel like so: sed -i '' '/ internal-wiki.example/d' (be sure to test that before running live of course).

This should allow you to use http(s)://internal-wiki.example:8000 in your browser.

It's not a perfect solution, but anything better (such as port mapping) I think would require an http proxy running locally.

For what it's worth, adding and removing host entries is how Parallels makes VMs addressable by hostname. This is added to my /etc/hosts while my xu17 VM is running: xu17.shared xu17 #prl_hostonly shared

Of course running an nginx proxy would handle this nicely, but it might be a bit more setup than you're looking for?
A simpler option with netcat might work depending on the web application.

# make fifo for second nc to transfer response back to first nc
mkfifo /tmp/proxy.pipe
nc -lk 8001 < /tmp/proxy.pipe | nc internal-wiki.example 8000 > /tmp/proxy.pipe

Then when you close the tunnel, you can kill the nc process and delete /tmp/proxy.pipe


Create temporary hosts entry:

rm /tmp/hosts
cp /etc/hosts /tmp/hosts
echo " example.com" >> /tmp/hosts
mount --bind /tmp/hosts /etc/hosts

Remove temporary hosts entry (and return persistent hosts file):

umount -f /etc/hosts

or reboot or shutdown.


Run a load balancing web server on your Mac balancing between the localhost forwarding and the real address of the wiki configured to prefer the localhost forwarding address.

When the ssh connection is down the load balancer will notice and direct your connections to the regular wiki address.

Configure your web browser to proxy connections for the wiki via the load balancer.

Somewhat of a sledgehammer to crack a nut though.


Name services (DNS, ldap, /etc/hosts) do not "resolve ports" they resolve hostnames. This statement is not entirely true but a proper explanation at this point is irrelevant and time consuming.

Since OSX uses a BSD kernel, I guess it may also "borrow" a lot of other code from there. The files ns resolver defaults to reading from /etc/hosts but this can be overridden on Linux and BSD by setting the HOSTALIASES environment variable (in the shell you start the browser from) but this only works if there is no '.' in the name. If you can use urls without a . in the name this will solve your problem.

Alternatively, you could run a script to configure port redirection to reroute packets addressed to xxx.xxx.xxx.xxx:8000 to and conversely on incoming packets. But this is rather a kludgy solution.

Alternatively you could install squid and use a custom url redirector to rewrite the requests (also possible if you start using https -but tricky).

A much cleaner option would be to run a proper tunnelled connection across the ssh. I believe this is not supported by osx out of the box but there are openvpn compliant add ons for osx

If it were me I would just set up scripts to swap around the hosts file, keeping all the traffic on one port and making sure that the default config is swapped in at boot time and when the ssh connection ends.

  • Not true, check this out: A Service record (SRV record) is a specification of data in the Domain Name System defining the location, i.e., the hostname and port number, of servers for specified services. It is defined in RFC 2782, and its type code is 33.
    – Marcel
    Aug 20, 2020 at 13:23
  • Sort of true - but only in DNS and I've yet to see something actually implementing this to resolve a port number.
    – symcbean
    Aug 20, 2020 at 14:47
  • Well, not for browsers or any service with already predefined ports. But if you need to use non standard sockets, then you could build your system to search for the pertinent SRV record to figure out where to bind to. It's there in the specification, it's not mandatory for the web, but still, there are ways.
    – Marcel
    Aug 21, 2020 at 13:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .