Open port on mac for Go program running on VSCode

Tatsuo Nomura
3 min readMay 29, 2024

TLDR; Programs in ~/Desktop and some other ~/* sub directories don’t trigger firewall permission dialog.

Problem & Workaround

Mac by default has firewall rules that block incoming network connections. Usually this isn’t a problem because the OS will pop a up a dialog asking to allow incoming network connections.

For example, the following command will launch a server at port 8000.

# start an HTTP server
python3 -m http.server 8000

The command will trigger the following permission dialog. You can simply click on “Allow” to open up the port.

Same can be done on VSCode as well with the following launch.json

    {
"name": "test server",
"request": "launch",
"module": "http.server",
"type": "debugpy",
"args": [
"8000",
]
}

So far so good, no problema.

Now, let’s try this with a server written in go.

package main

import (
"fmt"
"log"
"net/http"
)

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
})
log.Fatal(http.ListenAndServe(":8000", nil))
}

If we run this from the command line, we get the same dialog

go run .

But, if we try running it on VSCode, for reasons that I don’t know, the dialog doesn’t show up and incoming network connections are blocked by the firewall.

We can solve this using a command line tool called “socat” which can relay packets sent to one port to another. It’s like ssh port forward but from local to local.

# Install socat
brew install socat

# Relay incoming packets to port 8080 to port 8000
socat TCP-LISTEN:8080,fork TCP:localhost:8000

This way the permission dialog will pop up and you can allow it to accept incoming network access.

Mystery Solved (kind of…)

I did a little more digging trying to find out why the dialog doesn’t pop up.

First, I though I must have denied the program before so that the dialog won’t show up again. The allowed/denied programs are saved in /Library/Preferences/com.apple.alf.plist by /usr/libexec/ApplicationFirewall/socketfilterfw command. Although I couldn’t find it in the list, I cleared the list and rebooted just to be sure. It didn’t solve the problem.

Then I looked into the binary. When launched from VSCode, it builds the project as __debug_bin in the project directory. And execute it via LLDB /Library/Developer/CommandLineTools/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/debugserver. This file binary file is only available when the program is launched by VSCode. I tried running this __debug_bin from command line and it indeed did not pop up the dialog.

I then did a bit more experiment. I copied this binary and stopped VSCode and tried to move it to different paths to see if the dialog pops up. The dialog pops up when I move the binary to /Applications, /tmp, ~/, no dialog when I move it to ~/Desktop, ~/Downloads.

Conclusion

It had nothing to do with VSCode or Go after all, it just depended on where I put the damn binary! Remember the first commands that triggered the dialog? They were python and go commands that reside in /usr/local/bin that’s why they worked. So thanks to whatever Apple magic, programs that placed under certain directories such as ~/Desktop won’t trigger firewall permission dialog. What you need to do is to move your project directory outside to somewhere else.

In the end, I moved the project directory to ~/projects and this dialog finally popped up. What a waste of time 😵‍💫

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response