セッションマネージャを利用したEC2インスタンスへのssh接続

EIPを利用しないEC2インスタンスsshでアクセスする際にパブリックIPをいちいち確認する事が面倒だったので、不変なインスタンスIDを利用したアクセスによってssh接続の設定を簡単にする。 この際にセッションマネージャを利用することでEC2インスタンスのセキュリティ向上にもつながったので、理解した範囲でセキュリティについても紹介する。 最後にvscodeを利用したインスタンスへのリモートアクセスについて記載する。 ここではあくまでも備忘録のため、セキュリティグループのインバウンドルールがなにかなどの話はしない。

概要

  • 経緯
  • EC2インスタンスへのアクセス方法

  • ポートを開ける危険性

  • セッションマネージャを経由したssh接続
  • vscodeからのアクセス

経緯

Elastic IPを利用していないのでssh接続をする際に毎回EC2のマネージメントコンソールからパブリックipをコピペして接続するという作業が面倒になっていた。特にvscodeのremote-sshを利用していたので、インスタンスを立ち上げてIPが変わるたびにssh configを書き換えるのは無駄な作業で頻繁にやらないと忘れてしまいそうだった。

そこで何らかの不変なidを利用してvscodeからssh接続できないかが目標となった。今回は

EC2インスタンスへのアクセス方法

EC2へのアクセスは主に2つの方法がある。*1

  • ローカルsshクライアント EC2インスタンス作成時の公開鍵を利用してインスタンスに接続する。22番ポートを開ける必要がある。
  • セッションマネージャ 公開鍵や22番ポートを開ける必要がない。 ただしユーザーがec2-userでなかったり、シェルがshだったりする。

今までは前者の方法でターミナル上からアクセスしていたが、sshアクセスの際にパブリックipが必要となり、これがインスタンス起動のたびに変化するのが面倒だった。

そこでセッションマネージャを通じてssh接続をすることで、不変なインスタンスidのみが必要であることがわかった。またセッションマネージャを経由することにより、22番ポートを開ける必要がない事がわかった。これが実際にはセキュリティ向上に貢献する事がわかった。こちらに関して次に記述する。

 ポートを開ける危険性

ssh接続をする際にはセキュリティグループのインバウンドルールにおいて22番ポートを開ける必要がある。*2 22番ポートを常に開けてしまっていると、このインスタンスのセキュリティはすべて公開鍵方式に頼ってしまっていることになる。万が一秘密鍵が流出した際には直ぐに他者にアクセスされてしまい、EC2上で何らかのウイルスなどを配置されてしまうかもしれない。 セッションマネージャを利用すれば、そもそも扉は存在しないので、他人がアクセスすることはできない。 そのため可能であれば、22番ポートは閉じて置きたいということらしい。

セッションマネージャを経由したssh接続

それでは本題のセッションマネージャを通じてssh接続する方法について記述する。この方法はEC2インスタンスとクライアント(ローカル)のそれぞれについて設定が必要になる。

  • EC2インスタンスに対する設定

    • EC2インスタンスに対して何らかのロールをアタッチしていると思うが、そのロールに対してAmazonSSMManagedInstanceCoreというポリシーをアタッチする。これによりEC2インスタンスAWS Systems Managerとやり取りできるようになる。
    • EC2インスタンスにアクセスして、SSM Agentをインストールする。*3 Amazon Linux2を利用している場合はこの手順はスキップできるかもしれないが、脚注の手順に従ってインストール推奨。またAgentを立ち上げる事を忘れずに。
  • クライアント(ローカル)に対する設定

    • Session Manager Pluginのインストール。*4
    • ~/.ssh/configに以下の設定を記入。 profileのところは自分のAssume roleを利用する。

    # SSH over Session Manager host i-* mi-* ProxyCommand sh -c "aws --profile hogefuga ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

以上で、ssh -i {path/to/key} ec2-user@{instance ID}とすることで、ターミナルからインスタンスにアクセスすることができる。 この時注意したいのはEC2インスタンスのregionとprofileのregionが一致している方が都合がよい。regionが異なる場合はssh接続の際にregionを引数に入れる必要がある。これで私は6時間溶かしました。

vscodeからのアクセス

以下はregionが一致していることを前提。

  • vscodeにremote-sshをインストールする。
  • サイドパネルにremote-sshが出てくるので、歯車をクリックし、~/.ssh/configをクリック。
  • configに以下を記入。instance nameは識別しやすい適当な名前、 instance idはEC2インスタンスのinstance id, identityfileにはssh接続する際のpemファイルを入れる。

    # SSH over each instance using Session Manager Host instance name ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'" User ec2-user HostName instance id IdentityFile path to your key

  • インスタンスを起動後、ssh targetsの中から対応するインスタンスをクリックすると、vscodeの新しいウィンドウが開いてEC2インスタンスにアクセスできる。

まとめ

EC2インスタンスにアクセスする際の手順で詰まりやすい部分について記載した。詳細については以下の参考資料を参照されたい。

参考資料

ステップ 8: (オプション) Session Manager を通して SSH 接続を有効にする - AWS Systems Manager

ssm経由でVSCodeをリモートSSHで使った話 - Qiita

*1:もう一つEC2 Instance Connectという方法もあるが、使っていないので詳細はわからない。基本的には鍵の管理が簡単になったローカルと同じ方法に見える。

*2:ポートはサーバーの扉のようなものらしい。

*3:https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/sysman-manual-agent-install.html こちらを参照。

*4:こちらを参照。 https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html

非エンジニアのクラウドと環境構築勉強方法

最近、プログラミング自体ではなくて, Linuxやインフラに関する知識が不足していると感じていて少し苦労しました。色々と勉強しましたが遠回りもしていたなと思うので、各位に同じ轍を踏まないように

  • どのようなプロセスでクラウドサービスや環境構築の必要性を感じたか
  • 必要性を感じたときにどうやって勉強すればいいのか

の2点についてまとめておきたいと思います。

想定読者

  • 僕と同じような経済学出身(いわゆる文系?)の人間の多くは、必要に迫られてプログラミングを始めた人。
  • 非エンジニアで環境構築に苦しめられる人

つまり僕のようなアマチュアを対象としています。あくまでこれは僕の学習プロセスの振り返りの面もあるので、更に良い方法があるなどは適宜教えて下さい。僕も勉強していきたいです。

プログラミングにおけるステップ

プログラミングの必要に迫られていたタイプの僕は次のようなプロセスで新しい課題にぶつかってきました。

  • プログラミング何もわからん。

    とりあえずプログラミング言語勉強するしかない… pythonだとみんなのpython(入門)とかpython実践入門(中級ぐらい)が結構良かったです。

  • コードがあっちこっち行ってしまう。

    バージョン管理の出番です。どれが最新版なのかわからなくなるようなコード管理をやめて、gitを勉強しましょう。 僕もそんなにうまく使えているわけではないですが、GitHub実践入門が良かった記憶があります。

  • 重たい計算がしたくなる。(本題)

    研究あるあるですね。最近だとディープラーニングGPUが使いたいなどのニーズがあるかと思います。ここでクラウドサービスの出番です。 クラウドを利用すれば、自分のPCよりもよいスペックのサーバーをすぐに用意出来るので、研究プロセスを高速化することが出来ます。さあ!クラウドを使ってみましょう!

ここに落とし穴がありました…

クラウド利用時における落とし穴

クラウドサービスに登録して色々やってみようと思った時に次のような落とし穴にハマりました。(現在もハマり中です。)

  • クラウドの使い方よくわからん IAMってなに?EC2?ってなに?セキュリティどうすればいいの? 今までローカルでしか研究開発をしていなかった人間にはクラウドの世界は摩訶不思議です。クラウドサービス自体を把握する必要があります。 クラウドサービスは疎結合なので非常に良いといいますが、結局色々やりたい時には多くのサービスについて知らないといけないし、それぞれで詰まります。

  • EC2インスタンスLinuxだしCUIやんけ!

    僕のような人間はGUIが大好きです。UNIXコマンドも代表的なものしか知りません。 クラウドを利用する際には多少なりともLinuxコマンドラインと親しんでいたほうがいいこともあります。

  • EC2インスタンスの環境がローカルと違う!

    今までは自分のPC上でライブラリなどを用意すればよかったのですが、それを再度EC2インスタンス上でもやる必要があります。このときにローカルのライブラリとEC2上で バージョンが違って、無駄なエラーが出る場合があります。 この時間は完全に無駄なので、どうにかしてローカルとクラウド上で同じ環境を使って分析がしたくなります。ここでdockerの存在を知ります。

もちろんクラウドを利用するのも学習コストが0ではありません。これまでのように適当なレビューのいい本を買って勉強すればいいじゃん!と思いますが、僕のようなアマチュアには実は大変です。

  • 前提知識が違いすぎる

    それぞれの本の著者の想定読者層に比べて残念ながら知識が足りていません。それもそのはずで、有名な本はエンジニア初心者を対象にしていたりします。そのためテクニカルタームがわからないし、本の中身がわかったようでわかりません。そもそもニーズが異なる場合があります。(webサービスを作ることを目的にされても…)

  • 読んでも自分の課題を解決出来ない。

    上に関連しますが、本の内容を消化しきれないケースや、本当に概要しか書いてないケースがあり、実際にやりたいことが自分でできる様になりません。

残念ながらクラウドで計算させたいだけなのに、LinuxとDockerの知識が必要になってしまいました。ここで挫けそうですが、こうしたらいいんじゃないかという勉強方法を見つけました。

暫定的な勉強方法

結論から言いますが、AWSLinuxは同時に学ぶ事ができますが、Dockerは1から勉強してください。ただしDockerを学ぶのに効率的な方法はありそうです。 この部分から先は僕も勉強中です。なので、後々もっとよい方法を見つけるかもしれません。

  • AWSLinux

    AWSではじめるLinux入門ガイドを読みましょう。 AWSのサービスに加え、基本的なLinuxの知識(コマンドラインでの実行方法など)を得ることが出来ます。AWSを利用する際に必要なのに、それほど記載されていることがないaws cliについても記載があるので、非常に良い本だと思っています。

  • Docker

    この部分が一番むずかしいと思います。Docker/Kubernetes 実践コンテナ開発入門という本は評判がよいですが、応用できるような知識が身につきませんでした。恐らく僕が想定読者に含まれないためだと思います。 おすすめとしては若干胡散臭いレビューが多くて申し訳ないのですが、Udemyにある米国AI開発者がゼロから教えるDocker講座が最もよい気配があります。これは勉強中なので、話半分に聞いて貰えれば幸いです。

全体を通しての学習プロセス

まだ学習途中ではありますが、今後の方針について記載したいと思います。以下の図はAWSでマネージドサービスを利用した場合、EC2上でデータベースを作成する場合、オンプレミスで作った場合に、どこまで自分で管理するべきかを示しています。

f:id:tokutokupooh:20201011200923p:plain
Black Belt Online Seminar AWS Amazon RDSより引用

僕のようなアマチュアにとっては、必要に応じて概ね各ブロックの上から下に知識を増やしていく事で効率的に目的を達成するために必要な知識を得ることができるかと思っています。*1なぜかというと、ハードウェアやOSから積み上げる場合だと目的から遠すぎるのと、きちんと学ぶにはあまりにも多くの範囲をカバーする必要があるからです。研究側のほとんどの人にとってLinuxカーネルがハードウェアを動かす仕組み(システムコール)はそこまで必要とする知識ではないと思います。我々の時間は有限なので、効率的に必要な知識を得るべきです。

まとめ

今回の記事ではどのようなステップを踏むとクラウドサービスやdockerによる環境構築を必要とするのか、必要となった場合に何を使って勉強すればいいのかということを紹介しました。 もちろんこの記事は僕がこうしたらいいんじゃないかという中間結果でしかないので人によってはより理解しやすいプロセスがあるかと思いますし、不適切な理解をしている可能性もあります。 しかしこうした0から学習した場合に何が必要なのかということを明確にしている記事は多くないと思いますので、この記事が参考になれば幸いです。

*1:もちろんラックの方法とかを学ぶ必要はないと思いますし、せいぜい必要になるのはOSについての理解までではないでしょうか