GCE インスタンスの sshd_config
にはこんなのが書かれていることがある。
(以下、適当にUbuntuインスタンスで検証)
#### Google OS Login control. Do not edit this section. ####
AuthorizedKeysCommand /usr/bin/google_authorized_keys
AuthorizedKeysCommandUser root
#### End Google OS Login control section. ####
なんぞこれ、というお話。
OS Login
ご存知のようにGCEインスタンスには OS Login なるものが存在する。
このおかげでインスタンス毎にわざわざアカウントと鍵を登録する必要がないわけだが、sshd
的には鍵を取る方法が必要なので何らかの細工がしてある。
それに使ってるのが AuthorizedKeysCommand
項目に指定されてある google_authorized_keys
というツール。
AuthorizedKeysCommand
Specifies a program to be used to look up the user's public keys. The program must be owned by root, not writable by group or others and specified by an absolute path. Arguments to AuthorizedKeysCommand accept the tokens described in the TOKENS section. If no arguments are specified then the username of the target user is used.
The program should produce on standard output zero or more lines of authorized_keys output (see AUTHORIZED_KEYS in sshd(8)). AuthorizedKeysCommand is tried after the usual AuthorizedKeysFile files and will not be executed if a matching key is found there. By default, no AuthorizedKeysCommand is run.
このコマンド、トラブルシューティングでも使われている。
/usr/bin/google_authorized_keys USERNAME
をインスタンス上で実行すると、鍵が返ってくる。
google_authorized_keys
のやってること
これは普通にGitHubの GoogleCloudPlatform/guest-oslogin
にある。
Authorized Keys Command
The google_authorized_keys binary is designed to be used with the sshd AuthorizedKeysCommand option in sshd_config(5). It does the following:
- Reads the user's profile information from the metadata server:
http://metadata.google.internal/computeMetadata/v1/oslogin/users?username=<username>
- Checks to make sure that the user is authorized to log in:
http://metadata.google.internal/computeMetadata/v1/oslogin/authorize?email=<user_email>&policy=login
- If the check is successful, returns the SSH keys associated with the user for use by sshd. Otherwise, exits with an error code.
ということで、GCEインスタンスから metadata.google.internal
にアクセスすれば普通に鍵が取れる仕様になっている。
これを見る限り、公開鍵認証前提なんだろうなという印象を受ける。
ちなみにコードはこの辺
std::stringstream url;
url << kMetadataServerUrl << "users?username=" << UrlEncode(argv[1]);
string user_response;
long http_code = 0;
if (!HttpGet(url.str(), &user_response, &http_code) ||
user_response.empty() || http_code != 200) {
if (http_code == 404) {
// Return 0 if the user is not an oslogin user. If we returned a failure
// code, we would populate auth.log with useless error messages.
// This exits successfully but prints no keys.
return 0;
}
return 1;
}
url.str("");
url << kMetadataServerUrl << "authorize?email=" << UrlEncode(email)
<< "&policy=login";
string auth_response;
if (!HttpGet(url.str(), &auth_response, &http_code) || http_code != 200 ||
auth_response.empty()) {
return 1;
}
if (!ParseJsonToSuccess(auth_response)) {
return 1;
}
oslogin_utils::kMetadataServerUrl
は今のverだと http://169.254.169.254/computeMetadata/v1/oslogin/
らしい。
// Metadata server URL.
static const char kMetadataServerUrl[] =
"http://169.254.169.254/computeMetadata/v1/oslogin/";