ポートをバインドするときに permission denied エラーが表示される
プラットフォームについて: Server および Data Center のみ。この記事は、Server および Data Center プラットフォームのアトラシアン製品にのみ適用されます。
Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.
*Fisheye および Crucible は除く
問題
Linux 環境でポートをバインドしようとしていて、 "Permission denied" エラーが表示される。一般に、これはポート 80 または 443 です。
catalina.out
に次のメッセージが出力される。
Jun 7, 2012 4:58:57 PM org.apache.coyote.http11.Http11Protocol init
SEVERE: Error initializing endpoint
java.net.BindException: Permission denied <null>:80
at org.apache.tomcat.util.net.JIoEndpoint.init(JIoEndpoint.java:549)
at org.apache.coyote.http11.Http11Protocol.init(Http11Protocol.java:176)
at org.apache.catalina.connector.Connector.initialize(Connector.java:1022)
at org.apache.catalina.core.StandardService.initialize(StandardService.java:703)
at org.apache.catalina.core.StandardServer.initialize(StandardServer.java:838)
at org.apache.catalina.startup.Catalina.load(Catalina.java:538)
at org.apache.catalina.startup.Catalina.load(Catalina.java:562)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:261)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: java.net.BindException: Permission denied
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:383)
at java.net.ServerSocket.bind(ServerSocket.java:328)
at java.net.ServerSocket.<init>(ServerSocket.java:194)
at java.net.ServerSocket.<init>(ServerSocket.java:150)
at org.apache.tomcat.util.net.DefaultServerSocketFactory.createSocket(DefaultServerSocketFactory.java:50)
at org.apache.tomcat.util.net.JIoEndpoint.init(JIoEndpoint.java:538)
... 12 more
Jun 7, 2012 4:58:57 PM org.apache.catalina.core.StandardService initialize
SEVERE: Failed to initialize connector [Connector[HTTP/1.1-80]]
LifecycleException: Protocol handler initialization failed: java.net.BindException: Permission denied <null>:80
at org.apache.catalina.connector.Connector.initialize(Connector.java:1024)
at org.apache.catalina.core.StandardService.initialize(StandardService.java:703)
at org.apache.catalina.core.StandardServer.initialize(StandardServer.java:838)
at org.apache.catalina.startup.Catalina.load(Catalina.java:538)
at org.apache.catalina.startup.Catalina.load(Catalina.java:562)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:261)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
原因
1024 よりも小さいポートは予約済みのポートと呼ばれ、 Linux (およびほとんどの UNIX フレーバーや UNIX 様のシステム) では、非 root ユーザーがオープンすることができません。これは元々は、悪意のあるユーザーが既知のサービス ポートで悪意のあるサービスをセットアップすることを防ぐための方法として実装されたセキュリティ機能です。
ソリューション
回避策として複数のソリューションが考えられます。
- リバース プロキシ サーバーとして Apache または nginx をインストールおよび構成します。これらを root として開始してポートをオープンし、その後権限を標準のユーザーに戻します。
iptables
または代替手段を使用してサーバー上にファイアウォールをセットアップし、小さいポート番号を Confluence がリッスンしている大きいポート番号に内部で転送するようにします。- ポートを root としてオープン可能な jsvc を使用し、その後権限をダウングレードします。
- authbind を使用し、非 root ユーザーに予約済みのポートをオープンする権限を付与します。
Linux 2.6.24 以降を使用している場合、java の実行ファイルでファイル機能をセットアップし、予約済みポートのオープンのみを許可して他のスーパーユーザー権限は付与しない昇格権限を付与します。
# setcap cap_net_bind_service+ep /path/to/bin/java
これを設定したあとに Java を開始すると、次のようなエラーが表示される場合があります。
$ java -version /path/to/bin/java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory
これは、ライブラリが信頼される Id.so パスではなく動的なパスからインポートされていることを示します。詳細については http://bugs.sun.com/view_bug.do?bug_id=7157699 をご確認ください。これを修正するには、ライブラリを見つけ、そのパスを Id.so 構成に追加する必要があります。以降は 1 つの例であり、Linux ディストリビューションに応じて異なる可能性があります。JAVA_HOME を適切なロケーションで置き換えます。
$ find JAVA_HOME -name 'libjli.so' JAVA_HOME/lib/amd64/jli/libjli.so # echo "JAVA_HOME/lib/amd64/jli" > /etc/ld.so.conf.d/java-libjli.conf # ldconfig -v
これらすべてをセットアップしたら、Confluence がシンボリック リンク経由ではなく直接バイナリ パスで java を開始することを確認します。シンボリック リンク経由の場合、機能が取り込まれません。
これをセットアップすると、あらゆるユーザーが Java を使用して予約済みポートをオープンできるようになります。このようなユーザーには管理者が承諾したユーザーも、承諾していないユーザーも含まれる可能性があります。
Confluence を root として実行することは、動作する可能性はありますが、推奨されません。攻撃者が実行ユーザーとして任意のコードを実行できるようなセキュリティ脆弱性があった場合に、攻撃者が root アクセスを取得してしまいます。