Public AccessのRDSへIAM認証に失敗する
- 評価
- クリップ 0
- VIEW 1,986
前提・実現したいこと
こちらの記事を参考に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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+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
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
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);
}
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.31%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
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
https://github.com/mysqljs/mysql#ssl-options
ssl : {
ca : fs.readFileSync(__dirname + '/mysql-ca.crt')
}
2017/06/16 16:23
わたしも最初は
ssl : {
ca : fs.readFileSync(__dirname + '/rds-combined-ca-bundle.pem')
}
と記述していたのですが、
mysqlクライアントのソースを眺めていて
ssl: "Amazon RDS"
と等価ということがわかりこのようなソースになっています。
2017/06/16 16:26
mysqlクライアントのソース該当部分: https://goo.gl/tzWzwH