Go で 1024 以下のポートを Listen するアプリを作る

Go はネットワークアプリケーションを手軽に書ける言語ですが、例えば 80 番ポートなど、 root でしか bind できないアドレスを Listen するアプリケーションを、 root でないユーザーで動かすのは地味に面倒です。

普通はソケットを bind してから setuid/setgid するのですが、 Linux では setuid が呼び出したスレッドしか適用されないという問題があり、 Go との相性が悪いからです。 参考

対処方法として、

  1. Linux では capabilities を使って非 root ユーザーでも 1024 番以下を bind できるようにし、 Mac OS X などでは bind してから setuid するようにする。

  2. 先に root で bind したソケットを Go のプログラムに渡す。

2番めの方法を使うサンプルプログラムを書いておきます.

$ sudo bind_and_setuser.py :80 username ./echo_server '-fd=$FD'
このブログに乗せているコードは引用を除き CC0 1.0 で提供します。