質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.40%

  • MySQL

    6379questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • AWS(Amazon Web Services)

    2257questions

    Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

  • Node.js

    2084questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • TypeScript

    394questions

    TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Public AccessのRDSへIAM認証に失敗する

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 908

前提・実現したいこと

こちらの記事を参考にAWS Lambda(Nodejs6.10)でRDS(MySQL5.7.16)へのIAM認証を試みましたが、
コネクション生成時にエラーになってしまっているようです。
私と同じくPython/Javaをnodejsに書き換えようとして上手く出来ていない方いらっしゃいますか?

発生している問題・エラーメッセージ

・AWS Lambdaコンソールでテスト実施時の結果ログ

{
  "errorMessage": "ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client",
  "errorType": "Error",
  "stackTrace": [
    "Handshake.Sequence._packetToError (/var/task/node_modules/mysql/lib/protocol/sequences/Sequence.js:52:14)",
    "Handshake.ErrorPacket (/var/task/node_modules/mysql/lib/protocol/sequences/Handshake.js:103:18)",
    "Protocol._parsePacket (/var/task/node_modules/mysql/lib/protocol/Protocol.js:280:23)",
    "Parser.write (/var/task/node_modules/mysql/lib/protocol/Parser.js:75:12)",
    "Protocol.write (/var/task/node_modules/mysql/lib/protocol/Protocol.js:39:16)",
    "TLSSocket.ondata (_stream_readable.js:555:20)",
    "emitOne (events.js:96:13)",
    "TLSSocket.emit (events.js:188:7)",
    "readableAddChunk (_stream_readable.js:176:18)",
    "TLSSocket.Readable.push (_stream_readable.js:134:10)",
    "    --------------------",
    "Protocol._enqueue (/var/task/node_modules/mysql/lib/protocol/Protocol.js:141:48)",
    "Protocol.handshake (/var/task/node_modules/mysql/lib/protocol/Protocol.js:52:41)",
    "Connection.connect (/var/task/node_modules/mysql/lib/Connection.js:130:18)",
    "/var/task/handler.js:117:32",
    "/var/task/handler.js:115:35",
    "step (/var/task/handler.js:32:23)",
    "Object.next (/var/task/handler.js:13:53)",
    "/var/task/handler.js:7:71",
    "__awaiter (/var/task/handler.js:3:12)",
    "query (/var/task/handler.js:113:12)"
  ]
}

該当のソースコード

import * as _ from 'lodash'
import * as mysql from 'mysql'
import AWS = require('aws-sdk')
import RDS = require('aws-sdk/clients/rds')
import { Context, Callback } from 'aws-lambda'

// ~/hello
export async function hello(event, context: Context, callback: Callback) {
  try {
    const token = await getToken();
    const connection = await connect(token);
    const results = await query(connection);
    callback(null, { statusCode: 200, body: JSON.stringify({ message: results }) });
  } catch (error) {
    callback(error);
  }
}

async function getToken(): Promise<string> {
  return new Promise<string>((resolve, reject) => {
    // パラメータ設定
    const signerOptions: RDS.Signer.SignerOptions = {
      credentials: {
        accessKeyId: "<ACCESS-KEY>",
        secretAccessKey: "<SECRET-ACCESS-KEY>"
      },
      region: "ap-northeast-1",
      hostname: "xxxxx.cts3jwle0qyy.ap-northeast-1.rds.amazonaws.com",
      port: 3306,
      username: "kashihara"
    };
    // トークン発行
    new RDS.Signer(signerOptions).getAuthToken((err: AWS.AWSError, token: string) => {
      if (err) reject(err);
      resolve(token);
    });
  });
}

async function connect(token: string): Promise<mysql.IConnection> {
  return new Promise<mysql.IConnection>((resolve, reject) => {
    const config: mysql.IConnectionConfig = {
      host: 'xxxxx.cts3jwle0qyy.ap-northeast-1.rds.amazonaws.com', //RDSのエンドポイント
      user: 'kashihara', //MySQLのユーザ名
      password: token,
      ssl: 'Amazon RDS'
    };
    const connection = mysql.createConnection(config);
    resolve(connection);
  });
}

async function query(connection: mysql.IConnection): Promise<string> {
  return new Promise<string>((resolve, reject) => {
    // コネクション接続
    connection.connect((err) => { if (err) reject(err) });
    // クエリ発行
    connection.query('select user from mysql.user', (err, results, fields) => {
      if (err) reject(err);
      resolve(JSON.stringify(results));
    });
    // コネクション切断
    connection.end((err) => { if (err) reject(err) });
  });
}

補足情報(言語/FW/ツール等のバージョンなど)

・Nodejs6.10
・TypeScript2.3.4
・MySQL5.7.16
・mysqlクライアント:mysqljs/mysql
・mysqlユーザのAUTH_MODE

mysql> select Host,User,plugin,authentication_string from mysql.user where User='kashihara'\G
*************************** 1. row ***************************
                 Host: %
                 User: kashihara
               plugin: AWSAuthenticationPlugin
authentication_string: RDS
1 row in set (0.01 sec)
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

insecureAuthオプションがデフォルトでfalseになっているせいではないでしょうか。
これをtrueにすればいけませんか?

--以下追記
無理でしたか・・・

RDSで以下対応できるかわかりませんが・・・可能なら試してみてください。

mysql> UPDATE mysql.user SET plugin = 'mysql_old_password'
mysql> WHERE User = 'some_user' AND Host = 'some_host';
mysql> FLUSH PRIVILEGES;
mysql> SET PASSWORD FOR
    -> 'some_user'@'some_host' = OLD_PASSWORD('new_password');

https://dev.mysql.com/doc/refman/5.7/en/old-client.html

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/16 13:21 編集

    ありがとうございます。
    mysql.IConnectionConfigにinsecureAuth: trueを付け足してみましたが同様のエラーログでした・・・

    キャンセル

  • 2017/06/16 13:43

    どうもすみません。
    OLD_PASSWORD()自体がMySQL 5.7.5で削除されているようです。(なんと...

    キャンセル

  • 2017/06/16 16:05

    ソース眺めていて思ったのですが、SSL接続しなければいけないのではないでしょうか?
    https://github.com/mysqljs/mysql#ssl-options
    ssl : {
    ca : fs.readFileSync(__dirname + '/mysql-ca.crt')
    }

    キャンセル

  • 2017/06/16 16:23

    元記事ではrds-combined-ca-bundle.pemをcaとして使用していましたので、
    わたしも最初は
    ssl : {
    ca : fs.readFileSync(__dirname + '/rds-combined-ca-bundle.pem')
    }
    と記述していたのですが、

    mysqlクライアントのソースを眺めていて
    ssl: "Amazon RDS"
    と等価ということがわかりこのようなソースになっています。

    キャンセル

  • 2017/06/16 16:26

    pemファイルのダウンロード先: https://goo.gl/CKXtLY
    mysqlクライアントのソース該当部分: https://goo.gl/tzWzwH

    キャンセル

check解決した方法

0

 解決しました。

① mysql2に変更

import * as mysql from 'mysql2'

②  connectionConfigにmysql_clear_passwordを使用する設定追加(authSwitchHandler:)

const config: mysql.IConnectionConfig = {
      host: 'xxxxx.cts3jwle0qyy.ap-northeast-1.rds.amazonaws.com', //RDSのエンドポイント
      user: 'kashihara',
      database: 'zzzzz',
      ssl: 'Amazon RDS',
      authSwitchHandler: (data, cb) => {
        if (data.pluginName === 'mysql_clear_password') {
          // https://dev.mysql.com/doc/internals/en/clear-text-authentication.html
          var password = token + '\0';
          var buffer = Buffer.from(password);
          cb(null, buffer);
        }
      }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • MySQL

    6379questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • AWS(Amazon Web Services)

    2257questions

    Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

  • Node.js

    2084questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • TypeScript

    394questions

    TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。