はじめましておひさしぶりですこんばんわ。
リベロエンジニアで社員として働きながら、藤波製作所で個人事業主(代表)という活躍の機会をいただいているドラゴン藤波です。
今回はAWSで構築するサーバ等にアクセスする方法のうち、クラウドっぽいなぁと思った手段を紹介する記事です。
AWSのVPC内リソースに接続する方法あれやこれ
AWS使ってますか。いいですよね。AWS。マニュアルが読みやすくて。
AWSにはVPC(Amazon VPC)という、ネットワーク的に独立した仮想データセンター的なものを構築できるサービスがあります。
LinuxやWindowsサーバ、コンテナの類はVPCの中に構築・実行できます。
詳細:https://aws.amazon.com/jp/vpc/
自宅の環境ならLAN線を引いて、(L2L3レベルの設定間違ってなければ)対象マシンや仮想基盤上に構築したOSとはHelloWorldできるので、まぁカンタンです。
しかしAWSと自宅(自社)を接続する経路は、アカウント開設時点ではインターネット経由しかありません。
インターネットは万人が使えるため、自分だけが使えるように設定を追加したり、ちょっと気を使ってアクセスする必要があります。
ビギナー/入門向けで見かける手法
よくある手法は下記の通りかな?
- パブリックサブネット(インターネットゲートウェイと同じサブネットグループ)にEC2を構築する。
- 鍵を払い出してダウンロードする。
- IP確認くん等を使って、自分のグローバルIPアドレスをセキュリティグループに追加し、RDPまたはSSHポートを解放する。
- 鍵を使用して対象にログインする。
あら不思議、AWSに構築したサーバにログインできました。
世の中には乗り込み方ががいろいろあるのだ。
お客様のセキュリティ要件や運用設計上の構成により、VPC上に構築したリソースへのアクセス方法は多数あります。
そしてVPCは、PublicSubnetやPrivateSubnetと呼ばれるサブネット空間を用意することがベターです。
これがまた乗り込み方法のバリエーションを生んでいるのですが、
まぁ大別すると次の通りかなと
- PublicSubnetに踏み台用のサーバを構築する
- SessionManagerを使用して対象サーバに乗りこむ
上記どちらかのパターンが多いです。
乗り込み方法を意識するようになるのは、企業がセキュリティに対して意識がある傾向の現れだと思います。
良いことです。
クローズドなネットワーク環境の経験が多い。
ドラゴン藤波が主に経験する環境は、AWSとお客様拠点がDirectConnectで接続されており、
専用PCからOSユーザのID/PWでログインすることをジャスティスとするパターンが多めです。
そして当たり前のようにIAMユーザに鍵払い出しは絶対NGです。
あ、開発環境or本番環境問わず、PCとかVPCがインターネット接続何それおいしいのって環境は実在しますよ。念のため。
あと本記事ではClosed なVPCにおける設計、開発運用における留意事項については触れません。すげぇ長くなるから。
Private Subnetへのアクセスは手法が限られる。
インターネット経由からアクセスする場合、リソースはPublic Subnetに置く必要があります。
Private Subnetに置いてある場合、踏み台を経由するかSessionManagerのどちらかを使用する必要があります。
Private Subnet内のEC2に踏み台なしでRDP/SSHするゾ!
さて本題です。踏み台なしでPrivateSubnetのEC2サーバにRDP/SSHする方法は、必然的にSessionManagerになります。
Linuxはまぁいいでしょう。どうにでもなるでしょう。
しかしWindowsはAWSマネジメントコンソールからSessionManagerを実行した場合、Powershellがブラウザに表示されます。そりゃそうだ。
そのあたりを回避して、わざわざブラウザを立ち上げなくてもCLIだけで完結する方法です。
※あとこれはMFA設定済みが前提です。ROOTユーザIAMユーザ問わず、絶対にMFA設定してくださいね。
MFA有効化されてないIAMユーザは何もできないようにしちゃうゾ❤️
①CLIでログインする準備を整える
Pythonのライブラリであるaws-mfaを使用します。
使い方はこちら:https://qiita.com/ogady/items/c17ffe8f7c8e15b15f77
これで、あなたのコマンドプロンプトはAWSのマネジメントコンソールに早変わりです。
②SessionManagerを実行する。
WindowsにRDP接続したいときは下記コマンドを実行します。
aws ssm start-session --target i-xxxxxxxxxx --document-name AWS-StartPortForwardingSession --parameters "portNumber=3389, localPortNumber=13899"
③リモートデスクトップ接続する
127.0.0.1:13889
にリモートデスクトップ接続する。
これだけ。aws-mfa便利~~~~~~↑↑↑↑↑↑
スイッチロール必須の環境でも
- aws-mfaでログインする
- スイッチロールする(後述)
- SessionManagerを実行する
- 接続する。
これだけ。簡単~~~~~~~~~~~↑↑↑↑↑
スイッチロールのコマンドは下記を参考ください。
※リストの中にコードブロックって入れられないのかな。。。RedmineとかBacklogの感覚で書きたい。。。
### Powershell
$credentials = aws sts assume-role --role-arn arn:aws:iam::1919114514:role/RoleName --role-session-name test --query "Credentials" | jq -r ".AccessKeyId, .SecretAccessKey, .SessionToken"
$env:AWS_ACCESS_KEY_ID, $env:AWS_SECRET_ACCESS_KEY, $env:AWS_SESSION_TOKEN = $credentials -split '\r?\n'
コマンドプロンプトの場合はどうだろうか。
ちょっと教えてちょ
PowerShellで記述されたAWS CLIのスイッチロールコマンドをコマンドプロンプトで実行するには、いくつかの変更が必要です。具体的には、環境変数を設定する方法が異なります。以下はその一例です。
@echo off
for /f "tokens=*" %i in ('aws sts assume-role --role-arn arn:aws:iam::1919114514:role/RoleName --role-session-name test --query "Credentials" ^| jq -r ".AccessKeyId, .SecretAccessKey, .SessionToken"') do set "credentials=%i"
for /f "tokens=1,2 delims= " %a in ("%credentials%") do (
if "%a"=="AccessKeyId" set "AWS_ACCESS_KEY_ID=%b"
if "%a"=="SecretAccessKey" set "AWS_SECRET_ACCESS_KEY=%b"
if "%a"=="SessionToken" set "AWS_SESSION_TOKEN=%b"
)
このコマンドは、jq を使用してJSONから必要な値を抽出し、それらを一時変数に格納します。次に、その変数から個々のキーに対応する値を抽出し、対応する環境変数に設定します。この方法は、JSONの構造に依存するため、JSON形式が変更されると適切に機能しなくなる可能性がありますが、コマンドの複雑さを減らすことができます。
さすが生成AIだぜ。。。動作確認してないから使う場合は途中結果確認して気を付けて実行してくれよな。。。
得られるメリット
こうすることで
クロスアカウントでスイッチロール必須な環境だろうが、
PrivateSubnet内のリソースに無邪気にSessionManagerでお邪魔することができるようになります。
踏み台EC2がいらなくなる。というのがメリットですね。
そしてLocalPortからRemotePortをマッピングしているので、LocalPortにお好みのターミナルで接続すれば
いつも通りTeratermで仕事できるわけです。
あくまでコンピュータリソース向け
注意事項として、RDSとかRedshift、ElasticacheみたいなDBインスタンスにはお邪魔できないので、
あくまでEC2向けという点に留意してください。
Provisiond EMRで起動してくるEC2にはお邪魔できるはず。
※頑張ればECS/Fargateにお邪魔できますけど、手間ばっかり増えてダルい運用を呼ぶので紹介しません。
導入する前に考慮すべきデメリット
IAMユーザの鍵を払い出す必要があります。最大のデメリットです。
どういうことかというと
踏み台アカウントを用意したり、
踏み台アカウントを利用するときにMFA認証しないと使えないようにしたり、
鍵を定期的に入れ替える運用機能を用意したり、
不正に利用されていないかどうかを監査するとか
そういう仕組みを実装して安全性を高める必要が発生します。
ウチは小規模だから、狙われないよ。そこまでしなくていいよ
そう思う方もいるでしょう。
そんなふうに考えていた時期が
俺にもありました。
穴だらけのEC2サーバが乗り込まれて、広告をクリックされまくったり
AWSアカウントが乗っ取られて、仮想通貨掘りまくってたり
セキュリティ事故が起きてから慌てるのが世の常です。
なぜこんなことが起こるかというと
行儀の悪いひとは、無防備なAWSアカウントを無作為に探してグルグルとお散歩しています。
つまり無防備な環境に規模の大小関係ないのです。
ご利用は計画的に!ヨシ!
最後はセキュリティの話になってしまいましたが、
PrivateSubnetのリソースに置いてあろうが、
コマンドプロンプトからSessionManagerで接続してPortをマッピングしてあげれば
踏み台不要でセキュアに乗り込めるようになりました。鍵の問題さえなければなぁ
皆様の参考になれば幸いです。
余談)IAMユーザの鍵問題を回避するには
公式には該当する手法がないので、気合で回避するしかないんですが
「ブラウザからマネジメントコンソールにログインする相当の挙動をコマンドプロンプトから実行する」必要があるかなって
🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔