はじめに結論
goのサーバ起動のコードを修正すれば出さないようにできます。
他の言語でも同様のやり方で回避できるはずです。
下のMacのファイアウォール設定を修正して出ないよう設定するのはおそらく無理です。
ファイアウォールのオフはやめておいたほうが良いです。
環境
MacOS Mojave 10.14.6
go v1.13.8
gin v1.4.0
原因
0.0.0.0
でサーバを起動していることが原因
例えば、0.0.0.0:8080
で起動すると、
ローカルのすべてのIPv4アドレスに対して 8080
ポートでサーバが待機します。
たいていは、127.0.0.1
と192.168.xx.xx
の2つくらいかと。
参考: https://ja.wikipedia.org/wiki/0.0.0.0
なので、このままだとMacの外部にポート開放しようとしてるけど大丈夫?という意味で
「ネットワーク受信接続を許可しますか?」
とMacのファイアウォールが聞いてきます。
用途もなしにこのまま「許可」すると、セキュリティ上良くないです。
「拒否」しても外部に公開されないだけで、127.0.0.1
には公開されているので、
ローカルからはアクセス可能です。
警告を消す方法
サーバ起動のIPを以下のように指定します(ポートは任意)
127.0.0.1:8080
127.0.0.1
はループバックアドレスと呼ばれていて、localhost
でアクセスできるあれです。
ループバックアドレスにだけサーバを公開すれば警告は止まります。
以下のginのサンプルアプリだと設定ファイルでループバック指定しているので警告が出ません。
https://github.com/eddycjy/go-gin-example/blob/master/conf/app.ini
!注意! 単純に書き換えるとデプロイ先のサーバがアクセスできなくなります(実装はこの後説明)
実装
Macローカルでは 127.0.0.1
、それ以外のサーバでは 0.0.0.0
を環境変数で切り替えられるように実装します。
srv := &http.Server{
Addr: fmt.Sprintf("%s:%d", os.Getenv("HOSTNAME"), os.Getenv("PORT")),
...
}
srv.ListenAndServe()
環境変数の切り替え方法は種々あるので、ここでは省略します。
参考記事
Suppressing Accept Incoming Network Connections warnings on OSX
Firewall blocks Go development server
macでGo echoサーバーを再起動する度にファイアウォールのアラートが出るのを回避する
おまけ
srv.ListenAndServe()のデフォルト値
srv.ListenAndServe() にAddrを渡さないとデフォルト値として、
:http
が使われます。
これは 0.0.0.0:80
の意味になります。
:8080
こういうのをあえて指定しているのをたまに見かけますが、それも上のようにホスト名が解釈されます。
参考:
https://golang.org/pkg/net/http/#Server.ListenAndServe
https://golang.org/pkg/net/#Dial (たぶんここ)
なぜ警告が毎回出るのか
go run
で毎回自動コンパイルしているのが原因かなーと予想しています。
開発時はビルドがかわりまくるので、FWの設定でなんとかするのは厳しそうですね。
調べにくさ
「golang ネットワーク受信接続を許可しますか」
で調べても、ファイアウォールオフにするとか、設定で許可するとか、ハックなことするとか
そういうのしかヒットしないので
「golang mac firewall」
でググる必要がありました。
なので日本語の警告名まんまでヒットしそうな記事を書きました。
chromeの 0.0.0.0 論争
調べてる過程で面白い記事を見つけました。
今まで、 localhost
or 127.0.0.1
でローカルアクセスしてましたが、chromeでは 0.0.0.0
でも良いみたいです。
ただ、wikiには
0.0.0.0は全ビットが0のIPアドレスであり、無効、不明、または適用外の対象を指定するために使用されるルーティング不可のメタアドレスである
https://ja.wikipedia.org/wiki/0.0.0.0
とあり、本来はルーティングしてはいけないものなので、アクセス用途で使うのはやめておいたほうが良さそうです。