Amazon EC2でJenkinsをインストールして443ポートで立ち上げようとした際に嵌った話


![jenkins_logo.png](https://qiita-image-store.s3.amazonaws.com/0/36837/472f1bd1-41e7-a87a-a896-1d2b95af644b.png)

EC2でJenkinsをインストールして443ポートで立ち上げようとして嵌ったけどなんとかなった話です。
同じ症状で嵌っている人の参考になれば幸いです。

# EC2起動・ログイン
とりあえず t2.micro あたりを起動。
起動の設定の際に、

「Step 3: Configure Instance Details」

で
「Auto-assign Public IP」
項目を
Enable
にしておくとPublic IPがふられる。

起動し終わったら、振られたPublic IPを確認して

```
ssh -i {登録した秘密鍵}.pem ec2-user@{Public IP}
```

などでログイン。Windowsの場合はPuttyなどが便利。

# Jenkinsインストール

Jenkinsのリポジトリをダウンロードして、yumコマンドでインストール

```
mkdir temp
cd temp
sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
sudo yum -y install jenkins
```

自動起動ON

```
sudo chkconfig jenkins on
```

# 設定変更して起動

HTTPポートははずして、HTTPSポートを443にする。
あとついでに、Jenkinsのアクセス用URLを /jenkins/ というようにプレフィックスをつける。(お好みで)

/etc/sysconfig/jenkins にある設定ファイルを修正する。

```
sudo vi /etc/sysconfig/jenkins
```

```/etc/sysconfig/jenkins
JENKINS_PORT=""

JENKINS_HTTPS_PORT="443"

JENKINS_ARGS="--prefix=/jenkins"
```

# 嵌った話

さて、ここからが嵌った話。
上記の設定後、とりあえずはJenkinsに内蔵されているJettyサーバーでJenkinsを実行しようとして、
インストールされていた起動スクリプトを

```
sudo /etc/init.d/jenkins start
```

と実行してJenkinsを起動し、試しにcurlでアクセスしようとすると、

```
curl --insecure https://localhost/jenkins/
```

```
curl: (7) Failed to connect to localhost port 443: 接続を拒否されました
```

・・・ん？

なにこれ。なんで？

とりあえずログチェック。

```
sudo tail -fn 100 /var/log/jenkins/jenkins.log
```

```
重大: Container startup failed
java.io.IOException: Failed to start Jetty
	at winstone.Launcher.<init>(Launcher.java:156)
	at winstone.Launcher.main(Launcher.java:354)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at Main._main(Main.java:293)
	at Main.main(Main.java:98)
Caused by: java.net.SocketException: 許可がありません
	at sun.nio.ch.Net.bind0(Native Method)
	at sun.nio.ch.Net.bind(Net.java:444)
	at sun.nio.ch.Net.bind(Net.java:436)
	at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
	at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
	at org.eclipse.jetty.server.nio.SelectChannelConnector.open(SelectChannelConnector.java:187)
	at org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:316)
	at org.eclipse.jetty.server.nio.SelectChannelConnector.doStart(SelectChannelConnector.java:265)
	at org.eclipse.jetty.server.ssl.SslSelectChannelConnector.doStart(SslSelectChannelConnector.java:631)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
	at org.eclipse.jetty.server.Server.doStart(Server.java:293)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
	at winstone.Launcher.<init>(Launcher.java:154)
	... 7 more
```

・・・なんかエラーでてる。
さっきの

```
JENKINS_HTTPS_PORT="443"
```

のところを、8443とかにして

```
sudo /etc/init.d/jenkins restart
```

```
curl --insecure https://localhost/jenkins/
```

とかするとちゃんと表示が出る。

起動したてのEC2なので当然443ポートは使われていないのに、何のエラーなのかと
大分悩んだ挙句、以下の記事を見つけた。

http://roguer.info/2012/07/23/5727/

どうにも1024ポート以下は、Linuxでは特殊な権限を持つユーザーじゃないと起動できないらしい。
そして上記の
/etc/init.d/jenkins
のスクリプトは、Jenkinsユーザーで実行するらしいが、そのJenkinsユーザーには1024以下のポートで動かす権限がないらしい。

インフラよく触っている人には常識なんでしょうけど全く知らなかった・・・。

# 回避方法

回避方法としては、以下のようなやり方が考えられるかと思います。

- 権限を与える(ケーパビリティとかいう機能？)
- rootユーザーで実行するようにJenkinsの起動スクリプトを作る
- Jenkinsサーバー自体は1024より大きいポートで動かし、Apache、iptablesなどで443ポートをJenkinsのポートにリダイレクトする。
- Tomcatなどのサーバー上にJenkinsのwarを配置し、Tomcatをsudoなどで動かす

今回は3つ目の方法をApacheで試してみた。


# Apacheで443ポートをJenkinsポートにフォワードする。

Apacheを443ポートで起動し、Apacheのプロキシ機能を使って443ポートのアクセスをJenkinsの8443ポートに転送します。

まずはApacheインストール

```
sudo yum install httpd
```

自動起動ON

```
sudo chkconfig httpd on
```

SSL接続するため、mod_sslのインストール

```
sudo yum -y install mod_ssl
```

設定変更

```
sudo vi /etc/httpd/conf.d/ssl.conf
```

で、最後の\</VirtualHost\>の前あたりに

```
<IfModule mod_proxy.c>
	SSLProxyEngine on
	
	ProxyPass /jenkins/ https://localhost:8443/jenkins/
	ProxyPassReverse /jenkins/ https://localhost:8443/jenkins/
</IfModule>
```

と記載する。この設定で、Apacheの443にきた /jenkins/ 以下のアクセスを、8443ポートの /jenkins/ に
プロキシしてくれるようになる。

そしてApache起動。

```
sudo service httpd start
```

```
curl --insecure https://localhost/jenkins/
```

でちゃんとアクセスできる。


確認終わったらEC2ちゃんと落としておきましょう。


# 参考

参考にさせて頂いた記事

http://treeapps.hatenablog.com/entry/2014/06/11/233027
http://d.hatena.ne.jp/nosa1/20120225/1330154608
http://blog.neet-shikakugets.com/archives/1007/