aws cliのMFA(多要素認証)によるAccessDeniedExceptionの対応
どういう状態か
何のコマンドでも以下のようになる。
$ aws lambda list-functions An error occurred (AccessDeniedException) when calling the ListFunctions operation: User: arn:aws:iam::111111111111:mfa/username is not authorized to perform: lambda:ListFunctions on resource: * with an explicit deny
確認したのは
- IAMに権限はある
- ~/.aws/{credentials,config} はある
原因
MFA(多要素認証)エラーだった
調べ方
IAM Policy Simulatorコンソールが公式に用意されているので、こちらで調べる
(iam policyはaws iam simulate-principal-policy
でも通常調べる事もできるが、この場合は同じくAccessDeniedException
になる)
https://policysim.aws.amazon.com/
こんな感じで機能、使いたいポリシーを選択、Run Simulationを押すと詳細な原因が表示されるAccessDeniedExceptionになる)
結果
{ "Sid": "DenyAllExceptListedIfNoMFA", "Effect": "Deny", "NotAction": [ "iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "iam:GetUser", "iam:ListMFADevices", "iam:ListVirtualMFADevices", "iam:ResyncMFADevice", "iam:ChangePassword", "iam:GetAccountPasswordPolicy", "sts:GetSessionToken" ], "Resource": "*", "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } } }
この結果を調べると以下のページから
The DenyAllExceptListedIfNoMFA statement denies access to every action in all AWS services, except a few listed actions, but only if the user is not signed in with MFA.
MFAで認証していないとエラーだとわかる。
対応方法
以下のサイトを参照に一時認証情報を作成する
aws sts get-session-token --serial-number arn:aws:iam::111111111111:mfa/username --token-code 【MFAトークン】
{ "Credentials": { "AccessKeyId": "AAA", "SecretAccessKey": "bbb", "SessionToken": "ccc", "Expiration": "2021-08-03T03:24:32+00:00" } }
これを ~/.aws/credentials
へ設定
[mfa] aws_access_key_id = AAA aws_secret_access_key = bbb
~/.aws/config
側へregionなども設定しておく
そして最初のコマンドを --profile
付きでたたくと結果が表示されるようになる
$ aws lambda list-functions --profile mfa { "Functions": [ ...省略
MFAの設定を簡略化する
この辺の設定をもう少し簡単に、またsessionを自動更新するには以下のツールを使う
詳しくはREADME.mdにあるが簡単にメモしておくと
~/.aws/credentials
の[default]
->[default-long-term]
に変更- コマンドを実行して、あとは支持に従ってmfaコードを入力
$ aws-mfa --duration 1800 arn:aws:iam::111111111111:mfa/username INFO - Validating credentials for profile: default WARNING - Your existing credentials are missing or invalid, obtaining new credentials. Enter AWS MFA code for device [arn:aws:iam::111111111111:mfa/username] (renewing for 1800 seconds): INFO - Fetching Credentials - Profile: default, Duration: 1800 INFO - Success! Your credentials will expire in 1800 seconds at: 2021-08-07 14:13:08+00:00
これで--profile
なしでMFA有りのaws cliを使えるようになり、指定の --duration
で自動でsessionを更新してくれるようになる
gpg: keyserver receive failed: Server indicated a failure
Ubuntu 20.04.2 LTS
gpgが使うhkpプロトコルはport 11371 を使う。
なので
gpg: keyserver receive failed: Server indicated a failure
このエラーは大概portを変えれば解決することが多い(と思う)
# github-cliのpgp鍵取得 # https://github.com/cli/cli/blob/trunk/docs/install_linux.md sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key C99B11DEB97541F0
ちなみにPGPは、Pretty Good Privacy
の略。センスがいい。
Slackのチャネル作成+ユーザー(&グループ)複数をまとめて招待できるコマンドをGAS+typescriptで作った
typescript 4.2.3
Slackで新チャンネルを作るときに、ユーザーもまとめて招待できるコマンドを作成してみた。 チャンネル名はある程度固定で使う事を想定した。
また(だいぶ前から) claspがtypescriptをサポートしていたので書いてみた
・・・が割とコードが膨大になったので、結局webpackしてアップロードするようにしたので、あまりtypescriptのサポートは関係なくなってしまった
最初はペラっと1,2ファイルのつもりだったのをガリガリ拡張したので、ちょっと雑になってしまった
コードはgithubを見てもらうとして、作っている途中に引っかかったところを書いてみる。
Slack
- Q: slash command打ったら
dispatch_failed
と出る- A: commandに設定したURLが200 OKを返してない
- A: curlなどで確認してみる。3xxでもNG
- A: AppsScriptでデプロイを新しく作り直してみる
- Q: slash command打ったら
timeout
が返ってくる- A: 3000ms以上だとそうなる。slack仕様。
- A: ロジックを工夫する。api何度も叩くようなのは非同期実行する
- 今回はユーザーデータ、グループデータはtriggerで別に取得するようにした
- 多分GASだと非同期にしてもrootなメソッド(これだとdoPost)は終わらないぽいので非同期できない
- Q: ユーザーグループ名がリクエストボディからうまく取得できない
- A: グループは
<!subteam^S0AAAAA0A|@usergroup_name>
のようなテキストで入ってくるので、パースする必要がある
- A: グループは
GAS
- Q: clasp createで作ったAppsScriptだとGCPプロジェクトを変更できない事がある
- A: GAS側で新規プロジェクトで作る
- Q: clasp pushでエラーになる
- A: エラーメッセージにある説明にだいたいURL書いていてそこにアクセスすれば解決する
- A: https://script.google.com/home/usersettingsの設定がOFFだと権限で弾かれる
- Q: doPostのログが確認できない
- A: GCPプロジェクトと紐づけて、ロギングを見る必要がある
- A: ロギングはテストのまま使うにはテストユーザーを登録する必要がある
- Q: GASからHTTPリクエストできない
- A: http requestはUrlFetchAppを使う
- scope
https://www.googleapis.com/auth/script.external_request
を許可する必要がある
- scope
- A: webpackすれば他のnpmも使えるかもしれないが未検証
- A: http requestはUrlFetchAppを使う
- Q: GAS実行時の権限設定でエラー表示になる
- A: GCPプロジェクトのOAuth同意画面で公開ステータスが
本番環境
になっている必要がある - A:
テスト
ならテストユーザーに登録する
- A: GCPプロジェクトのOAuth同意画面で公開ステータスが
GAS written with typescript
- Q:
import * as X from './xxx'
エイリアスが読めない- A: GASではすべてのクラスがフラットな状態で存在するので実際の名前を全部指定する必要がある
- A: また同じ名前のexportは競合するので使えない
- A: webpackする
- Q: eslint, tsc, babel, webpack全部通るのにアップロードするとエラーになる
- A: ときどきある。諦めて書きかえる
- ts2gasをきちんと見ればわかるかも
- A: ときどきある。諦めて書きかえる
その他
【Scala】giter8でプロジェクトのテンプレートを作る
環境 Scala 2.13.0
[1] giter8のテンプレートを用意
$ sbt new foundweekends/giter8.g8 [info] Loading settings for project global-plugins from metals.sbt ... [info] Loading global plugins from /home/takafumi/.sbt/1.0/plugins [info] Set current project to a (in build file:/home/takafumi/A/) [info] Set current project to a (in build file:/home/takafumi/A/) Creates a Giter8 project template. name [My Te mplate Project]: scala-template giter8_version [0.12.0-M2]: sbt_version [1.2.8]: 1.3.0 Template applied in /path/to/dir/scala-template
[2] src/main/g8/
の下にテンプレートにしたいプロジェクトを追加
[3] src/main/g8/default.properties
にテンプレートで使えるプロパティを定義できる
// default.properties name=scala-template version=1.0 scala_version=1.3.0 sbt_version=1.2.8
// e.g. build.sbt name = "$name$" scalaVersion := "$scala_version$"
[4] ローカルでテストしたいときは
$ sbt new file:///path/to/dir/scala-template
[5] githubにpushしたら
$ sbt new repository/scala-template
で使えるようになる
【Rust】【Vim】LSPの導入
- 環境
- archlinux 5.0.9-arch1-1-ARCH
- rust 1.34.1
- neovim 0.3.5
rust
rls(Rust Language Server)
https://github.com/rust-lang/rls
rustup component add rls rustup component add rust-analysis rustup component add rust-src
neovim
dein + LanguageClient-neovim
https://github.com/autozimu/LanguageClient-neovim
" " lsp.toml " [[plugins]] repo = 'autozimu/LanguageClient-neovim' rev = 'next' build = 'bash install.sh' hook_add = ''' let g:LanguageClient_autoStart = 1 " LanguageServerを自動起動する " 言語毎のLSPを設定 let g:LanguageClient_serverCommands = { \ 'rust': ['rustup', 'run', 'stable', 'rls'], \ } augroup LanguageClient_config autocmd! autocmd User LanguageClientStarted setlocal signcolumn=yes autocmd User LanguageClientStopped setlocal signcolumn=auto augroup END nnoremap [lsp] <Nop> nmap <Space>l [lsp] nnoremap [lsp]h :call LanguageClient_textDocument_hover()<CR> nnoremap [lsp]d :call LanguageClient_textDocument_definition()<CR> nnoremap [lsp]r :call LanguageClient_textDocument_rename()<CR> nnoremap [lsp]f :call LanguageClient_textDocument_formatting()<CR> '''
init.vimなどで以下のコマンドで読み込ませる
call dein#load_toml(s:toml_dir . '/lsp.toml', {'lazy': 0})
遅延読み込み('lazy':1
)だとLanguageServerが起動ないので注意(大分長い事嵌った)
【Rust】導入覚書
- 環境
- archlinux 5.0.9-arch1-1-ARCH
- rust 1.34.1
- neovim 0.3.5
rust
binary
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh echo 'source $HOME/.cargo/env' >> ~/.zshrc rustc -V rustc 1.34.1 (fc50f328b 2019-04-24) cargo -V cargo 1.34.0 (6789d8a0a 2019-04-01)
source
補完系で必要になる
rustup component add rust-src rustup update echo 'export RUST_SRC_PATH="$(rustc --print sysroot)/lib/rustlib/src/rust/src"' >> ~/.zshrc
component, tool, etc
formatter
https://github.com/rust-lang/rustfmt
rustup component add rustfmt
linter
https://github.com/rust-lang/rust-clippy
rustup component add clippy
watcher
https://github.com/passcod/cargo-watch
cargo install cargo-watch
Cargo.toml editor
https://github.com/killercup/cargo-edit
cargo install cargo-edit
code completion
設定面倒くなければ rls使ったほうが良いかも
https://github.com/racer-rust/racer
## From 2.1, racer needs nightly rust rustup toolchain add nightly cargo +nightly install racer
vim
dein.vimでplugin管理しているならなら以下をtomlファイルに追加し、UpdateRemotePlugins
rust.vim
detection, syntax highlighting, formatting
https://github.com/racer-rust/vim-racer
[[plugins]] repo = 'rust-lang/rust.vim' on_ft = 'rust' hook_source = ''' let g:rustfmt_autosave = 1 '''
vim-racer
vimでracerを使うplugin
https://github.com/racer-rust/vim-racer
repo = 'racer-rust/vim-racer' on_ft = 'rust' hook_source = ''' " racerバイナリ let g:racer_cmd = "~/.cargo/bin/racer" " rustソースコードパス let $RUST_SRC_PATH="~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src" let g:racer_experimental_completer = 1 au FileType rust nmap gd <Plug>(rust-def) au FileType rust nmap gs <Plug>(rust-def-split) au FileType rust nmap gx <Plug>(rust-def-vertical) au FileType rust nmap <leader>gd <Plug>(rust-doc) '''