コロナ禍で
みなさまリモートワークでお仕事されてる方も多いのではないかと思います。当社も5月末までは原則在宅勤務、それ以降も週2出勤(他在宅)が原則、週1〜週4出勤も選択可能という形態になりました。
リモートワークとはいえ
実は開発サーバーはクラウド上(AWSとかGCPとかAzureとか)にあるから会社と家とで大きく変わらんよ、なんて人もだいぶ増えてきたのではないでしょうか。当社も開発のかなりの部分をクラウド化しております。
前置き、以上
bastionサーバ
AWSのVPC上でマイクロサービス構築するとき、bastionサーバーをおいてそれを踏み台にssh tunnelingで開発サーバーにアクセスして開発する、という形がこれまで多かったと思います。bastionサーバーにIP制限を掛けておけば、社外から不正に侵入される可能性は低くなるわけです。
が、在宅リモートワークではこれが仇となります。家から繋いだらIPなんてプロバイダによってマチマチなわけです。もしIP制限解除したら、実は同じマンションにクラッカーがいてクラッキングされた、なんてことになりかねません。
さあ、どうする??
ssm
そこで登場するのが AWS Systems Managerです(ssmは Amazon SimpleSystemsManager, もしくは Amazon EC2 Systems Managerの略らしい)。
ssm-agentといわれるagentプログラムを、管理したいサーバーにインストールしておけば、bastionサーバーなし、SSH鍵ペアの管理もなしで対象サーバーにログインできてしまうという代物。対象サーバーのセキュリティグループの22番ポートを開けておく必要もないので、堅牢です。
ただし今回のSSH/SCPトンネリングの話ではSSH接続を行うので鍵ペアは管理しておく必要があります
ssm のインストール
あちこちに情報は転がっているので、割愛。
公式はこちら
https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-install-ssm-agent.html
とはいえ、Amazon LinuxやAmazon Linux2のAMIにはデフォルトでインストールされるようになっているので、面倒な手続きなどは必要ありません。(古いAMIを利用している場合には手動でインストールが必要です)
接続
AWSコンソールのEC2のインスタンスリストで接続したいEC2インスタンスを選んで、「接続」ボタンをクリック → 接続方法:「セッションマネージャー」 → 「接続」ボタンをクリック
そうすると、ブラウザで新規タブが開き、ブラウザ上で仮装ターミナルが開きます。
デフォルトではssm-userというユーザーでログインします。
でも、在宅リモートワークでログインする人がみんなssm-userでサーバーにログインするのは、管理上どう考えてもよろしくない。
IAM で SSMSessionRunAs タグ設定
ということで、IAMユーザーにSSMSessionRunAsタグでユーザーIDを紐付けしましょう。(要IAM編集権限)
AWSコンソールにログインし、IAMの各ユーザーの設定画面を開き、タグ編集タブで「タグの追加」をクリックして、「キー」にSSMSessionRunAs
を、「値」にログイン対象のLinuxOSでのユーザーIDを登録します。
Amazon Systems Manager の設定
次にAWS コンソールのAWS Systems Managerを開きます(もちろんSystems Managerの編集権限が必要です)。左の「インスタンスとノード」に「セッションマネージャー」があるのでクリックします。右の「設定」のタブをクリックして、「編集」ボタンをクリックし、「Linux インスタンスの Run As サポートを有効にする」のチェックを入れます。
これで、IAMユーザーごとに別々のユーザーでSSM管理下のEC2インスタンスにログインできるようになりました。
SSM接続の制約
ところが、ブラウザ上の仮想ターミナルによるSSM接続には制約が多いです。
まず初期化プロセスが走りません。日頃SSHログインした時に利用しているユーザーコマンド(bundle
など)が使えません。プロンプトも$
だけでカレントディレクトリなどがわかりにくいです
また、LANG設定もされていないので、vimなどで日本語ファイルを開くと文字化けします。
これらの制約は下記のコマンドを実行することである程度解消できます。
source /etc/profile
source ~/.bash_profile
export LANG=ja_JP.UTF-8
また、大きな問題としてSCPによるファイルのアップロードができません。
ブラウザ上の仮想ターミナルでvimで新規ファイルを開いてエディタからコピーペースト、などと原始的な方法を取らざるをえないのです。
どうすればいいんだろう。ということで本題。
Session ManagerでSSH/SCPをトンネリングしてEC2に接続する
参考資料
前提
AWS CLIがローカルマシンにインストール済み。
対象サーバーにssm-agentがインストール済み。
手順
-
Session Manager Pluginのインストール
下記を参考にローカルマシンにインストールします
-
AWS認証情報の確認
一旦サーバーにssmでログインします。
whoami
コマンドで自分のユーザーであること(ssm-userでないこと)を確認してください。それから次のコマンドを実行してAWSの認証情報を開きますcd ~/.aws vi credentials
[default] aws_access_key_id = AKIA******* aws_secret_access_key = ******
とあるaccess_key_idとsecret_access_keyの両方を安全な場所にメモします。
対象サーバーからはログアウトします -
AWS認証情報をローカルマシンに設定する
ローカルマシンでターミナル(コマンドプロンプト)を立ち上げ、aws configure --profile hogefuga
を実行します。(hogefugaは適当なプロファイル名)
idとsecretを聞かれるので2.でメモした値を入力します -
SSHの設定
https://qiita.com/hayao_k/items/78b5bfe030ad8a053e93 にあるように.ssh/configを編集します。この時、# 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'"
と、awsのすぐ後ろに
--profile hogefuga
をいれることで、先ほど入力したプロファイルでアクセスするようになります -
sshログイン
SSHコマンドでログインします。この時従来のSSHログインで用いていた鍵ペアの秘密鍵が必要ですssh -i {秘密鍵のパス} ${user}@{EC2インスタンスID}
ここで
${user}
はサーバーのログインID、{EC2インスタンスID}
はAWSコンソールのEC2のインスタンス一覧で確認できるiで始まるインスタンスIDです。
SSHログインができれば、SCPもできます。
scp <ローカルファイルパス> {EC2インスタンスID}:{サーバーのファイルのパス} # local -> remote
scp {EC2インスタンスID}:{サーバーのファイルのパス} <ローカルファイルパス> # remote -> local
長かった。
これで、ようやく表題が出てきます(^^;)
Microsoft Visual Studio Code の Remote SSH 拡張機能
sshコマンドで接続できるんなら、Microsoft Visual Studio Code (以下VSCode)の Remote SSH 拡張機能が使えるのではないか?と思って試してみました。
VSCodeのRemote SSH拡張機能を使うと、SSHログインできる環境はローカルでVSCodeで開いて編集することが可能になります。(一部古いサーバー、インターネットに接続されていないサーバーを除く)
「SSHログインできる環境」ということはSessionManagerを経由してSSHログインできるならVSCodeで開けるはず!!
前提
MS VSCodeがローカルにインストール済みである
前段 Session ManagerでSSH/SCPをトンネリングしてEC2に接続する でログイン可能な状態である
手順
-
VSCodeにRemote-SSH拡張機能をインストール
- 左のツールバーの一番下の拡張機能をクリック
- 検索窓に”Remote SSH”と入力、Remote - SSHが表示されるのでクリックして、インストールボタンをクリックする
-
SSH設定ファイルをひらく
- F1キーを押し、"Remote-ssh open config"と入力、”Remote-SSH: Open Configuration File...”が表示されるのでクリックする
- ホームディレクトリ配下のconfigファイルが一覧の中に表示されるはずなので選択する。(Mac0SXの場合、/Users/$user/.ssh/config)
- 下記のように設定を追加する。Host: i-*,m-*より上に追加しないと下の設定が優先されてしまうと思われる
Host i-1x2x3ccccc ProxyCommand sh -c "aws --profile hogefuga ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'" User $user HostName i-1x2x3ccccc IdentityFile ~/.ssh/hoge.pem
ここでi-1x2x3cccccはEC2のインスタンスID
$userはログインユーザーID
hoge.pemはi-1x2x3cccccにログインするのに用いる秘密鍵 -
対象のサーバーを開く
- F1キーを押し、"Remote ssh con"と入力、"Remote-SSH: Connect to Host..."をクリック
- リストに接続可能なホストが出てくるので先ほど追加したi-1x2x3ccccをクリック
- 左のツールバーの一番上の”エクスプローラー”をクリックして、フォルダーを開くで任意の開発フォルダを開く
-
enjoy coding!!