EC2 に ping ができなくてつまづいた話

# はじめに
本記事は、[Elastic Stack Advent Calendar](https://qiita.com/advent-calendar/2020/elasticsearch) 20日目の記事です。
Elasticsearch 初学者ですが、枠が空いていたため投稿させていただきます。

**最初に、一点謝ります。**
当初、Elasticsearch のトラブルシューティング記事を執筆する予定でしたが、
推敲をしているうちに **Elasticsearch との関係性が低い記事になってしまいました。**
Elastic ネタを楽しみにされていた方、本当にすみません。
（記事の後半に Elasticsearch に関連する内容も記載してはいます。）
直前で投稿を辞退するのもご迷惑かと思ったので、このまま投稿いたします。

# 本記事のサマリー：EC2 に ping を通す方法
先日、AWS 上の EC2 インスタンスへの ping 疎通でつまづいたので、どなたかの役に立てばと思い記事にします。
結論から言うと、**EC2 に ping をしたい時は、セキュリティーグループの設定から ICMPプロトコルを追加する**必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/d9f50404-d0fc-e7a7-fe10-cdbdb78f7512.png)

# 発生した問題
以下のようなEC2インスタンスがあります。（AMI は Amazon Linux 2 を利用）
ポイントは以下2点

1. パブリックIPv4アドレスが付与されている　→ インターネットからアクセスできる状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/026a2d3e-092a-af70-ba05-6c12d511b96b.png)

2. セキュリティーグループにて、HTTPの80番ポート、SSHの22番ポート、両方空いている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/b9f75531-f807-8a96-b756-56730b876e9b.png)


上記２つの設定により、この EC2 には ローカルマシンから SSH 経由でアクセスすることができます。
（写真では Tera Term からログインできています）
<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/160034ee-e738-e36f-2555-61198aae3a47.png">


また、インスタンスに以下のコマンドを流して Apache をインストールすると、ブラウザから Apache の初期ページを表示することもできます。

```shell
$ sudo yum -y install httpd
$ sudo systemctl start httpd.service
```

<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/0e6ae6be-8291-fdc2-4ba3-bacbcffcbc1c.png">


しかし、ここで謎なことが。
ローカルPCのコマンドプロンプト（ターミナル）を開いて、EC2 インスタンスに ping してみると…
あれ、ping が疎通しない…　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/b0529956-c833-39ed-951a-d511d486b210.png)
疎通確認のための ping なのに…
WEB ページ見れているのに、なぜ？？

セキュリティーグループにて、ポートをフルオープンにしてもだめでした…うーん？？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/36261894-f1ae-3cfc-6b22-83460bdc917a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/8126ceaf-9bb4-4a58-c211-64508efc44b8.png)

# 原因と解決策
**ping は、TCP/IPプロトコルではなく、ICMPプロトコルを使用しています。**
そのため、ping の疎通をするためには、EC2のセキュリティーグループ設定にて、ICMPプロトコルを許可する設定が必要になります。
※ HTTP, SSH, POP3, FTP など、身近なものは全てTCP/IPプロトコルなので、てっきりTCPポートを全てあければ大丈夫だろうと思っていました。

「セキュリティーグループを編集」の画面から、インバウンドルールにて「すべてのICMP - IPv4」を追加して保存します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/1795ea82-b766-1b07-f2ec-33fafc7af318.png)

すると、無事にpingが疎通しました、良かった良かった！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/50137aae-7e73-da30-4319-f7d7b34c4eea.png)



# 補足：Elasticsearch でのトラブルシューティングの話
「Elastic Stack Advent Calendar なのに Elasticseach ネタじゃない！」と怒られそうなので、この記事の執筆理由となった Elasticsearch のトラブルについても記載しておきます。かなり初心者的な設定ミスです。

## 発生したトラブルの内容
個人学習としてEC2を立て、そこにApacheとElasticseachをインストールしました。
セキュリティーグループにて、HTTP(80)とElasticsearch(9200,9300)のポートをあけたものの、
ローカルPCからは、HTTPリクエストしか通らない現象がありました。（Elasticsearch のAPIが叩けない...）

###  期待していたこと
ローカルPCから Elasticsearch の REST API で検索クエリを投げて、検索結果が受信できる。

```shell
$ curl -XGET 'http://＜パブリックIPアドレス＞:9200/my_index/my_index/1'
{"_index":"my_index","_type":"my_index","_id":"1","_version":2,"_seq_no":1,"_primary_term":1,"found":true,"_source":
{
user_name : "John Smith",
date : "2017-10-15T15:09:45",
message : "Hello Elasticsearch world."
}
```

### 実際の現象
API を呼び出すと、Connection refused になる。

```shell
$ curl -XGET 'http://＜パブリックIPアドレス＞:9200/my_index/my_index/1'
curl: (7) Failed to connect to ＜パブリックIPアドレス＞ port 9200: Connection refused
```

### 確認したこと1
HTTP アクセスは問題ない模様（Apacheは動いている）　→　セキュリティーグループの設定にミスは無さそう。

```shell
$ curl ＜パブリックIPアドレス＞:80
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd%22%3E
...（以下略）

※ブラウザからもapacheの画面は表示される。
http://＜パブリックIPアドレス＞/
```

### 確認したこと2
ping が通らない　→　えっ!? じゃあなぜ HTTP は通ったの？

```sh

$ ping ＜パブリックIPアドレス＞
Request timeout for icmp_seq 0
...（以下略）
```

### 確認したこと3
ローカルPCのファイアウォール設定はオープンにしたが変わらない。

### 確認したこと4
インスタンス上のシェルから、Elasticsearch サービスが起動していることも確認済み。

```sh
$ sudo lsof -i -n -P
java     3203 elasticsearch  189u  IPv6  21148      0t0  TCP [::1]:9300 (LISTEN)
java     3203 elasticsearch  190u  IPv6  21155      0t0  TCP 127.0.0.1:9300 (LISTEN)
java     3203 elasticsearch  191u  IPv6  21196      0t0  TCP 127.0.0.1:9200 (LISTEN)
java     3203 elasticsearch  198u  IPv6  21195      0t0  TCP [::1]:9200 (LISTEN)
```

### 確認したこと5
インスタンス上で Elasticsearch の API を叩くと、期待通りのレスポンスが正常に表示される。
　→　ローカルPCからのみ API が叩けない。

## 原因と解決策
私は当初、上記の問題が EC2 上の設定ミスだと思っていました。
ですが、時間をかけて調べた結果、２つの問題が組み合わさっていたことがわかりました。

### ping が疎通しない点
これは本記事で記載したとおり、ping が ICMP プロトコルであり、セキュリティーグループの設定でつぶされていたためでした。

### ローカルマシンから Elasticsearch API を呼び出せなかった点
**Elasticsearch はデフォルトでインターネットからのAPIアクセスを閉じている**という理由でした。
[https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html)
上記ドキュメントの通り、`network.host` の項目を変更することで、インターネット経由でもアクセスできるようになります。

具体的には、インスタンスに対して、以下のコマンド操作と yml ファイルを編集したことで、
ローカルPCからでも API を操作できるようになりました。

```shell
$ sudo systemctl stop elasticsearch.service
$ sudo vim /etc/elasticsearch/elasticsearch.yml
　ここで、network.host: 0.0.0.0 に変更
$ sudo systemctl start elasticsearch.service
```


Elasticsearch の有識者の方には当たり前すぎる初期設定なのでしょうが、初学者の私はかなり苦労したトラブルでした。
（日曜日が丸々つぶれました :cry:）
他の学習者の方の参考になればと思い、ここに解決メモとして残させていただきます。
もう少し器用にトラブルシューティングをしていかねばとつくづく思います。。 頑張ります。


# 注意事項

- 本記事では、EC2のセキュリティーグループや`network.host`のソースを`0.0.0.0/0`で設定していますが、<br> 実際には適切な IP 制限をかけてセキュリティーを担保しましょう。