セッションマネージャを利用してオンプレミスサーバにssh接続

2026年6月30日に、AWS Systems Manager (SSM) の「アドバンストインスタンス層 (Advanced-instances tier)」が廃止されました。これまでアドバンストインスタンス層にアップグレードしないと利用できなかったオンプレミスのマネージドインスタンスへセッションマネージャを利用してアクセスが可能になりました。

ブラウザからセッションマネージャでアクセスできるのは便利ですが、さらにコマンドラインからsshやsftp等でアクセスしたいということがあり、そのための設定を行いました。

session-manager-pluginのインストール

まず、aws cliがインストールされていることが前提です。 ここでは、macOSにbrewを使用したpluginのインストール方法を記述します。他のOSについては公式ドキュメント「AWS CLI 用の Session Manager プラグインをインストールする」を参照してください。

brew install --cask session-manager-plugin

.ssh/configへ追記

マネージドノードのIDが mi-0123456789abcef0 の場合は以下のように .ssh/config ファイルに追記します。私の場合はさらにIdentity Centerを使用しているため、profileの指定もしています。

Host           mi-0123456789abcef0
  HostName     mi-0123456789abcef0
  ProxyCommand aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters '{"portNumber":["%p"]}' --region ap-northeast-1 --profile myProfile

この設定をして、必要な認証情報を sso login で取得したら、ssh や sftp コマンドで接続できるようになります。

aws sso login --profile myProfile
ssh user@mi-0123456789abcef0

WSL container

この記事は、WSL containerのインストール方法の備忘録です。

WSL containerとは何か

Windows OS上にインストールしたWindows Subsystem for Linux (WSL) を利用して、コンテナをwslcコマンドで実行できるように拡張されています。 これにより、Docker Desktop等を別途インストールしなくても、あるいはWSLに別途Dockerをインストールしなくても、コンテナを実行できるようになりました。

インストール or アップデート

2026年7月4日現在はまだプレビュー中です。そのため、WSLのインストールやアップデートでは --pre-release を追加する必要があります。

インストールする場合:

wsl --install --pre-release

すでにWSL2がインストールされている場合:

wsl --update --pre-release

インストールまたはアップデートが完了したら、別のPowerShellを起動:

wsl --version

ここでWSL バージョンが 2.9.3.0 以降であれば wslc コマンドがインストールされています。

コンテナを実行してみる

wslc run -it --rm ubuntu

dockerコマンドの代わりに、wslcコマンドでコンテナの実行を試せるようになっています。

OIDCを使用してAWS Systems ManagerのSession Managerに接続

OpenID ConnectのID Token (JWT)を使って、AWSのマネジメントコンソールにアクセスするコードはいろいろなところで紹介されていると思います。

今回そこからAWS Systems ManagerのSession Managerに接続できないか試したところあっさり接続できたので記録したいと思いました。

Session Managerに接続するためのURL: https://<REGION>.console.aws.amazon.com/systems-manager/session-manager/<ec2 instance id>?region=<REGION>

最終的にこのURLにアクセスできればよいわけです。これをNode.jsランタイムを使用したAWS Lambda関数にして実行するようにしています。

サンプルコードは以下のようになります。

JWTがtoken変数に入っている想定のコードサンプルです。

const CONSOLE_URL = process.env.CONSOLE_URL;

async function getCredentials(verified) {
    const email = verified.email;
    const userId = verified.sub;

    const command = new AssumeRoleCommand({
        'RoleArn': ROLE_ARN,
        'RoleSessionName': email,

        'Tags': [
            { Key: "UserId", Value: userId }
        ]
    });
    const response = await client.send(command);
    return response;
}

const getLocation = async (token) => {
    const roleCredentials = await getCredentials(token.payload);
    const credentials = {
        'sessionId': roleCredentials.Credentials.AccessKeyId,
        'sessionKey': roleCredentials.Credentials.SecretAccessKey,
        'sessionToken': roleCredentials.Credentials.SessionToken
    };

    const req = "https://signin.aws.amazon.com/federation" +
        "?Action=getSigninToken" +
        "&Session=" + encodeURIComponent(JSON.stringify(credentials));
    const res = await fetch(req);
    const text = await res.text();
    const signinToken = JSON.parse(text)['SigninToken'];
    const distination = encodeURIComponent(CONSOLE_URL);
    const location = `https://signin.aws.amazon.com/federation?Action=login&Issuer=${domain}&Destination=${distination}&SigninToken=${signinToken}`;
    console.log(location);
    return location;
};

何に役立つか

学習にLinux環境を利用する場合、sshの接続が提供されることが多いと感じています。しかし企業のネットワークの場合、外部サーバのsshへのアクセスが制限されていることが多くあると思われます。ブラウザでアクセス可能な環境を提供することに一定の価値があると考えています。

おわりに

LTI 1.3を使用してLMSから接続するコードは、GitHub Repositoryにあります。

レビュー: OpenID Connect入門

いろいろなWebサービスを利用していると、このサイトのパスワードなんだっけ?わからん、リセットするかみたいなことした経験はないでしょうか。

多くのパスワードを覚えずに1度サインインすれば、各サービスで毎回サインインをしなくてもよくなる機能としてSingle Sign On (SSO) があります。

以前はこのSSOにもいろいろな方式がありましたが、最近ではSAMLとOpenID Connect (OIDC) がよく利用されます。

さて、ここで紹介する「OpenID Connect入門」はOIDCについて書かれた書籍です。

特徴

OpenID ConnectのベースとなるOAuth 2.0から、非常にわかりやすい解説で概要を理解するところから始まります。

そして、OIDCのユースケースや各種フローについて解説されています。SPA、BFF、ネイティブアプリでの利用では、ReactのサンプルコードやJavaで書かれたサンプルコードもあります。

さらに、セキュリティ対策の考慮事項についても整理されています。

付録も充実していて、私にとっては馴染みのなかった「デバイスフロー」がありました。最後には関連する公式ドキュメントについて見やすく整理されています。

何が得られるか

私自身は、GMail認証を利用してさまざまなSNSやサービスを利用しています。またクラウド等の利用でもこうしたIdPのSAML、OIDCと連携して利用しています。

さまざまな環境にOIDCで連携するツール類の開発もよくしています。この本を読むと、これまで仕様書の中を行ったり来たりしながらの実装から、ポイントを抑えて非常に簡潔にまとめられた本書によって効率的に開発を進められます。

  • OpenID Connectに登場する用語
  • OpenID Connectを利用する形態
  • OpenID Connectのユースケース
  • エンドポイントとフローの理解
  • JWTとオパークトークン、OIDCで利用されるトークンの種類
  • Keycloakを使った各種形態 (SPA, BFF, ネイティブアプリ等)の実装例
  • セキュリティの脅威と対応策

まとめ

CI/CDで私はGitHub Actionsを使用することが多いですが、GitHub Actionsに限らず他の例えばGitLab CI/CDなどでもOIDCを活用してクラウドとの連携がプラクティスとして推奨されています。安全に認証情報を連携するための知見としてOIDCは非常に有益だと考えています。仕様書を全て理解しながら読み進めるのは大変ですが、本書のようにコンパクトでありながら、サンプルコード等もあり、非常に理解しやすい構成でとてもおすすめできる書籍です。

IAMロールでAWSマネージメントコンソールにアクセスする

私はAWSマネジメントコンソールへのアクセスにGMailの認証を利用したり、あるいはLMS (Learning Management System) の認証を利用してIAMロールを活用してアクセスしています。 いずれも、使用しているのはOpenID ConnectのID Tokenです。

GMailの場合のIAMロールの信頼関係は次のようにそのまま設定できます。IAMでサポートされていない場合は、IDプロバイダを登録して信頼関係を設定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "accounts.google.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "accounts.google.com:aud": "xxxxxx-xxxxx.apps.googleusercontent.com"
                }
            }
        }
    ]
}

IAMロールの信頼関係があれば、そのIAMロールにAssumeRoleWithWebIdentityによって一時的な認証情報が得られます。次のコードブロックは、Google Apps ScriptでAssumeRoleWithWebIdentityを実行するコードです。

const role_arn = encodeURIComponent(ROLE_ARN);
const role_session_name = encodeURIComponent(EMAIL_ADDRESS);
const token = encodeURIComponent(ID_TOKEN);

const formData = `Action=AssumeRoleWithWebIdentity&RoleSessionName=${role_session_name}&RoleArn=${role_arn}&WebIdentityToken=${token}&DurationSeconds=3600&Version=2011-06-15`;
const res = UrlFetchApp.fetch('https://sts.amazonaws.com/', {
  'method': 'post',
  'payload': formData
});
const xml = XmlService.parse(res.getContentText());
const root = xml.getRootElement();
const ns = root.getNamespace();
const assumeRoleWithWebIdentityResult = root.getChild('AssumeRoleWithWebIdentityResult', ns);
const credentials = assumeRoleWithWebIdentityResult.getChild('Credentials', ns);
const roleCreds = {
  'sessionId': credentials.getChildText('AccessKeyId', ns),
  'sessionKey': credentials.getChildText('SecretAccessKey', ns),
  'sessionToken': credentials.getChildText('SessionToken', ns)
};

AWS STS (Security Token Service) の AssumeRoleWithWebIdentity により取得した認証情報を使って SigninToken を https://signin.aws.amazon.com/federation エンドポイントを使用して取得します。Google Apps Scriptのコード例は次のコードブロックのようになります。

const req = "https://signin.aws.amazon.com/federation" +
    "?Action=getSigninToken" +
    "&SessionDuration=43200" +
    "&Session=" + 
    encodeURIComponent(JSON.stringify(roleCreds));
const res = UrlFetchApp.fetch(req);
const signinToken = JSON.parse(res.getContentText())['SigninToken'];

最後にAWSマネージメントコンソールに遷移すると引き受けたIAMロールでアクセスできます。Google Apps Scriptの例は次のコードブロックのようになります。

  const distination = encodeURIComponent('https://console.aws.amazon.com');
  const redirectUrl = `https://signin.aws.amazon.com/federation?Action=login&Issuer=gmail.com&Destination=${distination}&SigninToken=${signinToken}`;

おわりに

この記事では、Google Apps Scriptを使ったコード例で説明しました。直接 STS の AssumeRoleWithWebIdentity を呼び出した場合は XML でレスポンスが返されました。 LMS から連携される ID_TOKEN を利用して AWSマネジメントコンソール にアクセスするためのコードは AWS SDK を利用しているため、レスポンスが XML であることを意識する必要はありません。

参考までに nakanoshima.dev コミュニティの登壇スライドを共有します。

「TiDB実践入門」レビュー

TiDB実践入門

こんにちは、庄司です。

皆さん、MySQLは知っていますか?ここではNewSQLと呼ばれるMySQL互換のTiDBを解説した本「TiDB実践入門」を紹介します。

NewSQLって何?

ソフトウェアエンジニアにとってRDBMSは長い付き合いだと思います。私はオンプレ時代、長い間OracleDb2(ex. DB2)を使ったシステム構築に関わってきました。やがてクラウドの時代になり、Amazon DynamoDBやMongoDBのようなNoSQLと呼ばれる分散データベースを使うようになりました。これらのNoSQLはそれぞれ独自のAPIでデータベースにアクセスします。つまり記述したコードはそれぞれのデータベースに強く依存したコードとなるのが常でした。

レガシーシステムクラウドに対応させる場合や、違った視点でデータをクエリーしたくなった時にはSQLが使えると楽そうだなと思うこともよくあります。さらにコードにしてもRDBMSの場合、例えばJavaだとJDBCがあるように、他の言語でもRDBMSを使用する場合は標準化されたインターフェースを利用でき、異なるRDBMSを利用する場合でも大きな修正なしで移殖できます。

そこから、よくRDBMSとNoSQLを足した(2では割らないよ)ようなデータベースシステムがあると嬉しいという話をしていたものです。

NewSQLはまさにそのような分散データベースシステムです。

TiDBの特徴

TiDBの特徴は多くありますが、個人的に気に入っている点を3つ列挙します。

  1. クラウドでもオンプレミスでも実行可能
  2. シャーディングが不要
  3. TTLを使用してデータを自動削除できる

まず最初にあげたクラウドでもオンプレミスでも実行可能というのは、個人的に気に入っている点です。一般的にNoSQLはそれぞれのクラウドプロバイダに依存したプロダクトとなっているケースが多いと考えています。機密性の高いデータをオンプレミスで管理する必要がある場合にはNoSQLの採用が困難な時があります。ですが、TiDBはRDBMSの時と同様、どちらでも運用できるため、同じコードをクラウド環境でもオンプレミス環境でも実行することが可能になります。

2点目、大規模なRDBMSを運用した経験のあるエンジニアだとわかると思うのですが、シャーディング(パーティショニングといってもいいかもしれない)をどのように設計するかは非常に難易度が高く高度なスキルが必要です。これが自動化されているのはとても嬉しいことです。

最後にTTLを使用したデータの自動削除。もう死語になったかもしれませんが、BigDataを扱うデータベースには古くなってもう決して使うことのないデータも残されたままとなるケースが多いと過去の経験からも感じています。やがてストレージのキャパシティを超えそうだとなって、慌てて古いデータを削除するプログラムを開発し始めることもありましたが、レガシーシステムで古くなったデータを特定して削除するのは想定する以上にリスクが高く、またプログラムの作成、テスト、実行にかかるコストも増大しがちです。NoSQLではTTLによる削除機能を持ったものが多くあります。当初からこのTTLの利用を設計に取り込んでおけば安全に古いデータをメインのデータベースから削除できます。

おわりに

この本ではRocksDBのようなTiDBが内部で利用している技術も含め解説されています。クラウドやオンプレミス環境へのインストール、運用に関する情報、そしてサーバーレスのTiDBについても書かれています。

NewSQLのTiDBを本番環境に採用しようと検討するときには特にこの本を強くお勧めします。また分散データベースに興味のある方にもお勧めします。

JJUG CCC 2025 Spring参加の記録

こんにちは、庄司です。今回もボランティアスタッフとしてJJUG CCC 2025 Springに参加しました。

【Room E】 JJUGパネルトーク: ローカルJavaコミュニティの底力

私は、関ジャバからパネリストとして参加しました。COVID-19パンデミックが始まった頃の何度かのオンライン開催から、長いお休みがあって、2023年11月から隔月ペースでオフライン開催を継続し、2025年1月からは毎月のペースでの開催を報告しました。今後も他のローカルJavaコミュニティと連携したり、もくもく会の開催をしたいなという話をしました。オフライン開催を継続する中で他のコミュニティ参加者の認知度が少しずつ高まっていることも感じています。

JJUGが、Java30周年の2025年5月23日に時を同じくして設立された「一般社団法人クロスコミュニティカンファレンス協会(略称:CCC協会)」となり、今後より一層Javaコミュニティの活性化につながるのではないかと期待を話しました。関ジャバもより活性化していきたいものです。

【Room C+D】 実践Kafka Streams 〜イベント駆動型アーキテクチャを添えて〜

ボランティアスタッフ業務で、12:00 - 15:00がこのRoom C+Dの部屋担当でした。人気の高いこのセッションを業務で視聴できるのはとても役得でした。

途中、RocksDB の話も出てきます。技術評論社の「TiDB実践入門」によるとTiDBもこのRocksDBを使っているという記述があったので、いろいろなところで使われているのだろうかと思いました。

CQRS+ESに関心のある私にとって、とても興味深いセッションでした。

【Room C+D】 エンジニアリングでビジネスを加速する。モデル駆動開発という選択肢

これもまた、役得セッションでした。セッションの後、イベントストーミングを使ってみるのもいいかもとスタッフを忘れて会話させていただきました。

【Room A+B】 複数アプリケーションを育てていくための共通化戦略

スタッフ業務を一旦終えて、1参加者としての視聴です。セッションが始まる前に何やら外を向いて計算しています。何だろうと思っていたら、なんとスライド 102 ページ もあるではないですか!!でもこれちゃんと時間内に収めるという、そして単に収めるだけでなく、ちゃんとオーディエンスにメッセージが伝わっているのがすごい!!皆さんもそう思いませんか?

おわりに

交流会では、お昼に一度会話していたじゅくちょーが集合写真に間に合うように戻ってきていただけましたし、多くの方と会話することができとても楽しい日を過ごすことができました。

次の秋には私もCfPを出したいと思います。

最後に宣伝、6月16日に関ジャバは「Javaの歴史と未来 / 関ジャバ'25 6月度」を開催します。Javaに興味のある方もない方もぜひ来てください!!