この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
MAD事業部@大阪の岩田です。
本エントリは クラスメソッド Google Cloud Advent Calendar 2021 の 2日目 の記事です。
個人的にマネージドサービスの裏側を想像するのが好きなので、FaaS実行環境でOSコマンドを実行して出力を見ながらニヤニヤするアレをやってみました。
やってみる
ということで早速やっていきます。
- トリガーはHTTP
- ランタイムはNode.js14
を指定して以下のソースコードを準備します。
const execSync = require('child_process').execSync;
exports.helloWorld = (req, res) => {
const cmd = 'ここに実行したいOSコマンドを設定'
const result = execSync(cmd).toString();
res.status(200).send(result);
};
あとは変数cmd
の中身に実行したいOSコマンドを設定して実行、出力を確認していきます。実行したいコマンドをクエリストリングで渡そうかとも思ったのですが、検証とはいえOSコマンドインジェクションバリバリな実装をするのはどうかと思い留まりました。
実行するOSコマンドについては既に先人がパスの通っているコマンド一覧を調査されていたので、こちらを参考にさせて頂きました。
では諸々のコマンドの実行結果を見ていきましょう。
pwd
/workspace
/workspaceなんてディレクトがあるんですね
ls -al /
total 0
drwxr-xr-x 2 root root 0 Nov 30 13:55 .
drwxr-xr-x 2 root root 0 Nov 30 13:55 ..
drwxr-xr-x 2 root root 0 Oct 21 03:26 bin
drwxr-xr-x 2 root root 0 Jan 1 2000 boot
dr-xr-xr-x 2 www-data www-data 0 Nov 30 13:56 cloudsql
drwxr-xr-x 2 root root 0 Jan 1 1980 cnb
dr-xr-xr-x 1 root root 0 Nov 30 13:56 dev
drwxr-xr-x 2 root root 0 Nov 25 05:26 etc
lrwxrwxrwx 1 root root 0 Oct 21 03:28 home -> /tmp
drwxr-xr-x 2 www-data www-data 0 Jan 1 1980 layers
drwxr-xr-x 2 root root 0 Oct 21 03:27 lib
drwxr-xr-x 2 root root 0 Jan 1 2000 lib64
drwxr-xr-x 2 root root 0 Jan 1 2000 media
drwxr-xr-x 2 root root 0 Jan 1 2000 mnt
drwxr-xr-x 2 root root 0 Jan 1 2000 opt
dr-xr-xr-x 2 root root 0 Nov 30 13:56 proc
lrwxrwxrwx 1 root root 0 Oct 21 03:28 root -> /tmp
lrwxrwxrwx 1 root root 0 Oct 21 03:28 run -> /tmp/run
drwxr-xr-x 2 root root 0 Oct 21 03:26 sbin
lrwxrwxrwx 1 root root 0 Oct 21 03:28 serve -> /usr/bin/serve
lrwxrwxrwx 1 root root 0 Nov 10 05:57 srv -> /workspace
drwxr-xr-x 2 root root 0 Nov 10 05:54 staging
lrwxrwxrwx 1 root root 0 Oct 21 03:28 start -> /usr/bin/start
dr-xr-xr-x 1 root root 0 Nov 30 13:56 sys
drwxrwxrwt 1 www-data www-data 0 Nov 30 13:56 tmp
drwxr-xr-x 2 root root 0 Jan 1 2000 usr
drwxr-xr-x 2 root root 0 Nov 28 15:42 var
drwxr-xr-x 2 www-data www-data 0 Jan 1 1980 workspace
drwxr-xr-x 2 www-data www-data 0 Nov 10 05:57 www-data-home
pwdより先にこっちを実行しとけば良かったですね。/homeや/rootが/tmpにリンクしてるのが面白いところです。
ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
www-data 1 2.0 3.0 644488 63476 ? Ssl 13:10 0:03 node /layers/google.nodejs.functions-framework/functions-framework/node_modules/.bin/functions-framework
www-data 15 0.0 0.1 12688 3520 ? S 13:13 0:00 /bin/sh -c ps aux
www-data 16 0.0 0.1 42464 3748 ? R 13:13 0:00 ps aux
ナルホドPID:1の /layers/google.nodejs.functions-framework/functions-framework/node_modules/.bin/functions-framework
が関数のプロセスなんですね
uname -a
Linux localhost 4.4.0 #1 SMP Sun Jan 10 15:06:54 PST 2016 x86_64 x86_64 x86_64 GNU/Linux
カーネルは4.4を使っているようです
whoami
www-data
これはHTTPトリガーを指定したからユーザーがwww-data
なのかな?と思い、GCSバケットからトリガーする関数でも試してみましたが、ユーザーは変わらずwww-data
でした
node -v
v14.17.6
2021/11/30時点のNode.jsのランタイムはv14.17.6が動作しているようです
printenv
GCF_BLOCK_RUNTIME_nodejs6=410
S2A_ACCESS_TOKEN=なにかのトークンらしき文字列
NO_UPDATE_NOTIFIER=true
K_REVISION=15
SHLVL=1
HOME=/root
PORT=8080
NODE_OPTIONS=--max-old-space-size=192
FUNCTION_SIGNATURE_TYPE=http
GCF_BLOCK_RUNTIME_go112=410
_=/layers/google.nodejs.functions-framework/functions-framework/node_modules/.bin/functions-framework
PATH=/workspace/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
FUNCTION_TARGET=helloWorld
DEBIAN_FRONTEND=noninteractive
NODE_PATH=/workspace/node_modules
K_SERVICE=os-cmd
PWD=/workspace
GAE_RUNTIME=nodejs14
NODE_ENV=production
S2A_ACCESS_TOKEN
が何者なのか気になりますね。S2AはSecure Session Agentの略でしょうかね?
https://github.com/google/s2a-core
df -h
Filesystem Size Used Avail Use% Mounted on
none 8.0E 0 8.0E 0% /tmp
Availableが8.0E?!こんなの初めて見ました
lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Vendor ID: GenuineIntel
CPU family: 6
Model: 85
Model name: unknown
Stepping: unknown
CPU MHz: 2679.843
BogoMIPS: 2679.84
Virtualization: VT-x
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm mpx rdt_a avx512f avx512dq rdseed adx smap clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves pku
安定のIntel製
lsblk
Error: function terminated. Recommended action: inspect logs for termination reason. Additional troubleshooting documentation can be found at https://cloud.google.com/functions/docs/troubleshooting#logging Details:
Command failed: lsblk
lsblk: failed to access sysfs directory: /sys/dev/block: No such file or directory
ダメでした!
findmnt
TARGET SOURCE FSTYPE OPTIONS
/ none overlayfs rw
|-/dev none overlayfs rw
| `-/dev/shm none tmpfs rw
|-/proc none proc rw
|-/sys none sysfs rw
|-/tmp none tmpfs rw
|-/cloudsql none 9p rw
`-/var/log none overlayfs rw
注目したいのは/cloudsql none 9p rw
の部分です。9p filesystemなんてのがあるんですね。恥ずかしながら初めて知りました。
dmesg
[ 0.000000] Starting gVisor...
[ 0.384209] Letting the watchdogs out...
[ 0.720865] Consulting tar man page...
[ 0.868943] Checking naughty and nice process list...
[ 1.279663] Creating process schedule...
[ 1.535912] Daemonizing children...
[ 1.683496] Searching for socket adapter...
[ 2.025663] Adversarially training Redcode AI...
[ 2.468126] Conjuring /dev/null black hole...
[ 2.827750] Segmenting fault lines...
[ 2.832743] Granting licence to kill(2)...
[ 2.939954] Ready!
おお、gVisorの出力が!Cloud FunctionsはgVisor上で動いていると聞いていましたが、こうやってログから確認できるとナルホドとなりますね
まとめ
Cloud Functionsの実行環境について少し詳しくなれました。やはりマネージド・サービスの裏側を想像するのは楽しいですね!
明日12/3は小倉功一 さんです。よろしくお願いします!