Lambdaの実行環境で使用できるシェルコマンドについて調査しました

2023.10.24

はじめに

Lambdaでnslookupコマンドを実行する処理を実装したところ、「nslookup: command not found」(※そんなコマンドないよ)と怒られてしまいました。 そこでLambda環境からどのようなシェルコマンドを利用できるのか調査した内容とその後の対応についてブログにすることにしました。

前提

  • Lambdaを使用し、とあるドメインからIPアドレスを取得したい。
  • Lambdaのランタイムは「Node.js 18.x」を使用する。

利用可能なコマンドの調査

「/usr/bin」の中身を見て、Lambdaの実行環境に入っているコマンドをログに出してみました。

2023-10-18T07:30:56.235Z	580c4349-8de4-4b4c-bd99-c17ad34aae1b	INFO total 9428
dr-xr-xr-x  2 root root   4096 Jun 19 17:29 .
drwxr-xr-x 13 root root   4096 Jul 11 13:33 ..
-rwxr-xr-x  1 root root  37256 Jan 23  2020 [
-rwxr-xr-x  1 root root     29 Jul 15  2020 alias
-rwxr-xr-x  1 root root  28864 Jan 23  2020 arch
lrwxrwxrwx  1 root root      4 Jun 19 17:29 awk -> gawk
-rwxr-xr-x  1 root root  37248 Jan 23  2020 base64
-rwxr-xr-x  1 root root  28920 Jan 23  2020 basename
-rwxr-xr-x  1 root root 935976 Jul 15  2020 bash
lrwxrwxrwx  1 root root     10 Jun 19 17:29 bashbug -> bashbug-64
-rwxr-xr-x  1 root root   6959 Jul 15  2020 bashbug-64
-rwxr-xr-x  1 root root     26 Jul 15  2020 bg
-rwxr-xr-x  1 root root   1638 Apr 17  2023 ca-legacy
lrwxrwxrwx  1 root root      3 Jun 19 17:29 captoinfo -> tic
-rwxr-xr-x  1 root root  49888 Jan 23  2020 cat
-rwxr-xr-x  1 root root   3283 Apr 11  2023 catchsegv
-rwxr-xr-x  1 root root     26 Jul 15  2020 cd
-rwxr-xr-x  1 root root  62848 Jan 23  2020 chcon
-rwxr-xr-x  1 root root  58576 Jan 23  2020 chgrp
-rwxr-xr-x  1 root root  54384 Jan 23  2020 chmod
-rwxr-xr-x  1 root root  62736 Jan 23  2020 chown
-rwxr-xr-x  1 root root  33032 Jan 23  2020 cksum
-rwxr-xr-x  1 root root  11360 Nov 22  2022 clear
-rwxr-xr-x  1 root root  33192 Jan 23  2020 comm
-rwxr-xr-x  1 root root     31 Jul 15  2020 command
-rwxr-xr-x  1 root root 146880 Jan 23  2020 cp
-rwxr-xr-x  1 root root  45744 Jan 23  2020 csplit
-rwxr-xr-x  1 root root  41472 Jan 23  2020 cut
-rwxr-xr-x  1 root root  62064 Jan 23  2020 date
-rwxr-xr-x  1 root root  70688 Jan 23  2020 dd
-rwxr-xr-x  1 root root 100856 Jan 23  2020 df
-rwxr-xr-x  1 root root 513944 Jul 31  2018 dgawk
-rwxr-xr-x  1 root root 109288 Jan 23  2020 dir
-rwxr-xr-x  1 root root  37192 Jan 23  2020 dircolors
-rwxr-xr-x  1 root root  28872 Jan 23  2020 dirname
-rwxr-xr-x  1 root root 108784 Jan 23  2020 du
-rwxr-xr-x  1 root root  28848 Jan 23  2020 echo
-rwxr-xr-x  1 root root    290 Jul 31  2018 egrep
-rwxr-xr-x  1 root root  28872 Jan 23  2020 env
-rwxr-xr-x  1 root root  33152 Jan 23  2020 expand
-rwxr-xr-x  1 root root  37288 Jan 23  2020 expr
-rwxr-xr-x  1 root root  95432 Jan 23  2020 factor
-rwxr-xr-x  1 root root  28800 Jan 23  2020 false
-rwxr-xr-x  1 root root     26 Jul 15  2020 fc
-rwxr-xr-x  1 root root    132 Sep 25  2019 fc-cache
-rwxr-xr-x  1 root root  15664 Sep 25  2019 fc-cache-64
-rwxr-xr-x  1 root root  15592 Sep 25  2019 fc-cat
-rwxr-xr-x  1 root root  11288 Sep 25  2019 fc-conflist
-rwxr-xr-x  1 root root  11360 Sep 25  2019 fc-list
-rwxr-xr-x  1 root root  11424 Sep 25  2019 fc-match
-rwxr-xr-x  1 root root  11352 Sep 25  2019 fc-pattern
-rwxr-xr-x  1 root root  11304 Sep 25  2019 fc-query
-rwxr-xr-x  1 root root  11360 Sep 25  2019 fc-scan
-rwxr-xr-x  1 root root  11368 Sep 25  2019 fc-validate
-rwxr-xr-x  1 root root     26 Jul 15  2020 fg
-rwxr-xr-x  1 root root    290 Jul 31  2018 fgrep
-rwxr-xr-x  1 root root  37264 Jan 23  2020 fmt
-rwxr-xr-x  1 root root  33120 Jan 23  2020 fold
-rwxr-xr-x  1 root root 432504 Jul 31  2018 gawk
-rwxr-xr-x  1 root root  28144 Apr 11  2023 gencat
-rwxr-xr-x  1 root root  26024 Apr 11  2023 getconf
-rwxr-xr-x  1 root root  32112 Apr 11  2023 getent
-rwxr-xr-x  1 root root     31 Jul 15  2020 getopts
-rwxr-xr-x  1 root root 158864 Jul 31  2018 grep
-rwxr-xr-x  1 root root  28968 Jan 23  2020 groups
-rwxr-xr-x  1 root root  37272 Jan 23  2020 head
-rwxr-xr-x  1 root root  28864 Jan 23  2020 hostid
-rwxr-xr-x  1 root root  65904 Apr 11  2023 iconv
-rwxr-xr-x  1 root root  37272 Jan 23  2020 id
-rwxr-xr-x  1 root root   3188 Jul 31  2018 igawk
-rwxr-xr-x  1 root root 271528 Jul 27  2018 info
-rwxr-xr-x  1 root root  57264 Nov 22  2022 infocmp
-rwxr-xr-x  1 root root  21880 Jul 27  2018 infokey
lrwxrwxrwx  1 root root      3 Jun 19 17:29 infotocap -> tic
-rwxr-xr-x  1 root root 138704 Jan 23  2020 install
-rwxr-xr-x  1 root root     28 Jul 15  2020 jobs
-rwxr-xr-x  1 root root  45728 Jan 23  2020 join
-rwxr-xr-x  1 root root   5441 Apr 11  2023 ldd
-rwxr-xr-x  1 root root  28856 Jan 23  2020 link
-rwxr-xr-x  1 root root  54360 Jan 23  2020 ln
-rwxr-xr-x  1 root root  46512 Apr 11  2023 locale
-rwxr-xr-x  1 root root 317104 Apr 11  2023 localedef
-rwxr-xr-x  1 root root  28856 Jan 23  2020 logname
-rwxr-xr-x  1 root root 109288 Jan 23  2020 ls
-rwxr-xr-x  1 root root  25128 Apr 11  2023 makedb
-rwxr-xr-x  1 root root  41416 Jan 23  2020 md5sum
-rwxr-xr-x  1 root root  79696 Jan 23  2020 mkdir
-rwxr-xr-x  1 root root  58872 Jan 23  2020 mkfifo
-rwxr-xr-x  1 root root  62968 Jan 23  2020 mknod
-rwxr-xr-x  1 root root  37408 Jan 23  2020 mktemp
-rwxr-xr-x  1 root root 126144 Jan 23  2020 mv
-rwxr-xr-x  1 root root  32968 Jan 23  2020 nice
-rwxr-xr-x  1 root root  37344 Jan 23  2020 nl
-rwxr-xr-x  1 root root  33104 Jan 23  2020 nohup
-rwxr-xr-x  1 root root  28920 Jan 23  2020 nproc
-rwxr-xr-x  1 root root  66192 Jan 23  2020 numfmt
-rwxr-xr-x  1 root root  66272 Jan 23  2020 od
-rwxr-xr-x  1 root root  32896 Dec 18  2020 p11-kit
-rwxr-xr-x  1 root root  33016 Jan 23  2020 paste
-rwxr-xr-x  1 root root  28872 Jan 23  2020 pathchk
-rwxr-xr-x  1 root root 432536 Jul 31  2018 pgawk
-rwxr-xr-x  1 root root  37352 Jan 23  2020 pinky
-rwxr-xr-x  1 root root  19368 Apr 11  2023 pldd
-rwxr-xr-x  1 root root  66584 Jan 23  2020 pr
-rwxr-xr-x  1 root root  28848 Jan 23  2020 printenv
-rwxr-xr-x  1 root root  49640 Jan 23  2020 printf
-rwxr-xr-x  1 root root  66544 Jan 23  2020 ptx
-rwxr-xr-x  1 root root  33120 Jan 23  2020 pwd
-rwxr-xr-x  1 root root     28 Jul 15  2020 read
-rwxr-xr-x  1 root root  41704 Jan 23  2020 readlink
-rwxr-xr-x  1 root root  58504 Jan 23  2020 realpath
lrwxrwxrwx  1 root root      4 Jun 19 17:29 reset -> tset
-rwxr-xr-x  1 root root  58664 Jan 23  2020 rm
-rwxr-xr-x  1 root root  41320 Jan 23  2020 rmdir
-rwxr-xr-x  1 root root  95216 Apr 11  2023 rpcgen
-rwxr-xr-x  1 root root  33120 Jan 23  2020 runcon
-rwxr-xr-x  1 root root  75960 Aug  1  2018 sed
-rwxr-xr-x  1 root root  45456 Jan 23  2020 seq
lrwxrwxrwx  1 root root      4 Jun 19 17:29 sh -> bash
-rwxr-xr-x  1 root root  37360 Jan 23  2020 sha1sum
-rwxr-xr-x  1 root root  37416 Jan 23  2020 sha224sum
-rwxr-xr-x  1 root root  37416 Jan 23  2020 sha256sum
-rwxr-xr-x  1 root root  37392 Jan 23  2020 sha384sum
-rwxr-xr-x  1 root root  37392 Jan 23  2020 sha512sum
-rwxr-xr-x  1 root root  54104 Jan 23  2020 shred
-rwxr-xr-x  1 root root  50224 Jan 23  2020 shuf
-rwxr-xr-x  1 root root  28960 Jan 23  2020 sleep
-rwxr-xr-x  1 root root 113464 Jan 23  2020 sort
-rwxr-xr-x  1 root root   4281 Apr 11  2023 sotruss
-rwxr-xr-x  1 root root  66960 Jan 23  2020 split
-rwxr-xr-x  1 root root  28720 Apr 11  2023 sprof
-rwxr-xr-x  1 root root  74840 Jan 23  2020 stat
-rwxr-xr-x  1 root root  62256 Jan 23  2020 stdbuf
-rwxr-xr-x  1 root root  66080 Jan 23  2020 stty
-rwxr-xr-x  1 root root  37328 Jan 23  2020 sum
-rwxr-xr-x  1 root root  28864 Jan 23  2020 sync
-rwxr-xr-x  1 root root  15632 Nov 22  2022 tabs
-rwxr-xr-x  1 root root  33136 Jan 23  2020 tac
-rwxr-xr-x  1 root root  62560 Jan 23  2020 tail
-rwxr-xr-x  1 root root  28976 Jan 23  2020 tee
-rwxr-xr-x  1 root root  37200 Jan 23  2020 test
-rwxr-xr-x  1 root root  78192 Nov 22  2022 tic
-rwxr-xr-x  1 root root  54504 Jan 23  2020 timeout
-rwxr-xr-x  1 root root  15696 Nov 22  2022 toe
-rwxr-xr-x  1 root root  58264 Jan 23  2020 touch
-rwxr-xr-x  1 root root  20064 Nov 22  2022 tput
-rwxr-xr-x  1 root root  45560 Jan 23  2020 tr
-rwxr-xr-x  1 root root  28808 Jan 23  2020 true
-rwxr-xr-x  1 root root  49744 Jan 23  2020 truncate
-rwxr-xr-x  1 root root 175112 Dec 18  2020 trust
-rwxr-xr-x  1 root root  24192 Nov 22  2022 tset
-rwxr-xr-x  1 root root  33144 Jan 23  2020 tsort
-rwxr-xr-x  1 root root  28880 Jan 23  2020 tty
-rwxr-xr-x  1 root root  15370 Apr 11  2023 tzselect
-rwxr-xr-x  1 root root     29 Jul 15  2020 umask
-rwxr-xr-x  1 root root     31 Jul 15  2020 unalias
-rwxr-xr-x  1 root root  28864 Jan 23  2020 uname
-rwxr-xr-x  1 root root  33128 Jan 23  2020 unexpand
-rwxr-xr-x  1 root root  41552 Jan 23  2020 uniq
-rwxr-xr-x  1 root root  28856 Jan 23  2020 unlink
-rwxr-xr-x  1 root root   1054 Apr 17  2023 update-ca-trust
-rwxr-xr-x  1 root root  28976 Jan 23  2020 users
-rwxr-xr-x  1 root root 109296 Jan 23  2020 vdir
-rwxr-xr-x  1 root root     28 Jul 15  2020 wait
-rwxr-xr-x  1 root root  37432 Jan 23  2020 wc
-rwxr-xr-x  1 root root  49744 Jan 23  2020 who
-rwxr-xr-x  1 root root  28904 Jan 23  2020 whoami
-rwxr-xr-x  1 root root  24480 Nov  6  2022 xmlwf
-rwxr-xr-x  1 root root  28848 Jan 23  2020 yes

対応方針について

① nslookupコマンドをLambda Layerに突っ込む

のんピさんが以下の記事で、コマンドやライブラリをLambda Layerに突っ込んでnslookupコマンドを使用できるようにする方法を書いてくださっていました。

② おとなしく使えそうなライブラリを探す

僕は結局こちらの方針で、「dns」というライブラリの「dnsPromises.lookup(hostname[, options])」という機能を採用してnslookupと同等の機能を実装しました。
ちなみに、「dns」はNode.jsの標準モジュールなので、Lambda Layersに突っ込む必要はありません。

実装

以下のようにコーディングしました。

import * as dns from "dns";

~~~~~~~~

  let domainName = "ドメイン名";
  let ip = [];
  
  await dns.promises.lookup(domainName, { all: true }).then((result) => {
    Object.keys(result).forEach((key) => {
      ip.push(result[key].address);
    });
  });

~~~~~

テストでubuntuからnslookupをたたいてみたところ、ドメインに対して複数IPアドレスが返ってきたのでオプションに「all: true」を設定して配列で取得できるように実装しています。
※ このオプションを設定しない場合、最初の一つ目に取得したIPアドレスしか返却されません。

最後に

基本的に、Lambdaでシェルコマンドを使用することは考えない方がよさそうです。

あと、今回Node.jsの18系を初めて使用したのですが、モジュールの取り込み文の書き方等、細かい部分が以前と変わっていて戸惑いました、、、。