[SadServers] 解説 "Lisbon": etcd SSL cert troubles
"Lisbon": etcd SSL cert troubles
SadServersの "Lisbon": etcd SSL cert troubles の解説です。
SadServers って何? って人は、 SadServers解説 を見てください。
一言でいうと、LeetCode (コーディング問題集) の Linuxサーバ設定版のようなものです。
問題
問題を見ていきます。 >
の箇所は DeepLでの翻訳です。
Scenario: "Lisbon": etcd SSL cert troubles
Level: Medium
Description: There's an etcd server running on https://localhost:2379 , get the value for the key "foo", ie etcdctl get foo or curl https://localhost:2379/v2/keys/foo
> https://localhost:2379 で etcd サーバーが動いているので、キー "foo" の値を取得します。etcdctl get foo または curl https://localhost:2379/v2/keys/foo です。
Test: etcdctl get foo returns bar.
Time to Solve: 20 minutes.
OS: Debian 11
etcd
は 'etcd とは'を読むと、Key Value Store の サーバのようです。
etcdctl
がetcd
専用のクライアントのようです。が、curl
でも叩けるので、HTTPサーバということがわかります。
解説
早速、etcdctl
を実行します。
admin@ip-10-0-0-138:/$ etcdctl get foo
Error: client: etcd cluster is unavailable or misconfigured; error #0: x509: certificate has expired or is not yet valid: current time 2024-02-05T14:12:40Z is after 2023-01-30T00:02:48Z
error #0: x509: certificate has expired or is not yet valid: current time 2024-02-05T14:12:40Z is after 2023-01-30T00:02:48Z
error #0: x509: certificate has expired or is not yet valid: current time 2024-02-05T14:12:40Z is after 2023-01-30T00:02:48Z
エラー内容と見ると、SSL証明書の有効期限が2023-01-30T00:02:48Z
ですが、現在時刻が2024-02-05T14:12:40Z
のため、SSL証明書の有効期限切れ(expired)です。
date
コマンドで、システムの現在日時を確認します。
admin@ip-10-0-0-138:/$ date
Mon Feb 5 14:12:52 UTC 2024
たしかに、Feb 5 2024
となっているので、SSL証明書の有効期限2023-01-30
を満たすように、date -s
コマンドで日時を2023-01-01
に変更します。
(実際に実施した日時は、2023 Feb 5
なので、どうやらこのVMの日時は一年後になっているようです。)
admin@ip-10-0-0-138:/$ sudo date -s "01/01 13:00 2023"
Sun Jan 1 13:00:00 UTC 2023
その後、再度 ectctl
を実施します。
admin@ip-10-0-0-138:/$ etcdctl get foo
Error: client: response is invalid json. The endpoint is probably not valid etcd cluster endpoint.
エラー内容が変わりました。不正なJSONを返しているとエラーは言っています。
ちょっと、わからないので、curl
も実行してみます。
admin@ip-10-0-0-138:/$ curl -v https://localhost:2379/v2/keys/foo
* Trying 127.0.0.1:2379...
* Connected to localhost (127.0.0.1) port 2379 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=AU; ST=Some-State; O=Internet Widgits Pty Ltd; CN=localhost
* start date: Dec 31 00:02:48 2022 GMT
* expire date: Jan 30 00:02:48 2023 GMT
* common name: localhost (matched)
* issuer: C=AU; ST=Some-State; O=Internet Widgits Pty Ltd; CN=localhost
* SSL certificate verify ok.
> GET /v2/keys/foo HTTP/1.1
> Host: localhost:2379
> User-Agent: curl/7.74.0
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
< Server: nginx/1.18.0
< Date: Sun, 01 Jan 2023 13:00:25 GMT
< Content-Type: text/html
< Content-Length: 153
< Connection: keep-alive
<
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
* Connection #0 to host localhost left intact
404
が返ってきています。また、レスポンスヘッダーから、
< Server: nginx/1.18.0
と、etcd
ではなく nginx
がレスポンスを変えているようです。 これはどういうことでしょうか??
lsof
で、port 2379を使っているプロセスを調べます。 が、残念ながらlsof
は入っていません。
admin@ip-10-0-0-138:/$ lsof -i:2379
bash: lsof: command not found
systemctl status etcd
で、ectd
の状態を確認します。
admin@ip-10-0-0-138:/$ systemctl status etcd
● etcd.service - etcd - highly-available key value store
Loaded: loaded (/lib/systemd/system/etcd.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2023-02-05 14:22:39 UTC; 1 months 4 days left
Docs: https://etcd.io/docs
man:etcd
Main PID: 580 (etcd)
Tasks: 8 (limit: 521)
Memory: 25.5M
CPU: 1.022s
CGroup: /system.slice/etcd.service
└─580 /usr/bin/etcd --cert-file /etc/ssl/certs/localhost.crt --key-file /etc/ssl/certs/loca>
Feb 05 14:22:38 ip-10-0-0-138 etcd[580]: ClientTLS: cert = /etc/ssl/certs/localhost.crt, key = /etc/ssl/>
Feb 05 14:22:39 ip-10-0-0-138 etcd[580]: 8e9e05c52164694d is starting a new election at term 18
Feb 05 14:22:39 ip-10-0-0-138 etcd[580]: 8e9e05c52164694d became candidate at term 19
Feb 05 14:22:39 ip-10-0-0-138 etcd[580]: 8e9e05c52164694d received MsgVoteResp from 8e9e05c52164694d at >
Feb 05 14:22:39 ip-10-0-0-138 etcd[580]: 8e9e05c52164694d became leader at term 19
Feb 05 14:22:39 ip-10-0-0-138 etcd[580]: raft.node: 8e9e05c52164694d elected leader 8e9e05c52164694d at >
Feb 05 14:22:39 ip-10-0-0-138 etcd[580]: ready to serve client requests
Feb 05 14:22:39 ip-10-0-0-138 systemd[1]: Started etcd - highly-available key value store.
Feb 05 14:22:39 ip-10-0-0-138 etcd[580]: published {Name:ip-10-0-0-138 ClientURLs:[https://localhost:237>
Feb 05 14:22:39 ip-10-0-0-138 etcd[580]: serving client requests on 127.0.0.1:2379
Feb 05 14:22:39 ip-10-0-0-138 etcd[580]: serving client requests on 127.0.0.1:2379
etcd
が、port 2379
で待っていることは確認できます。
admin@ip-10-0-0-138:/$ sudo /usr/sbin/iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
REDIRECT tcp -- anywhere anywhere tcp dpt:2379 redir ports 443
DOCKER all -- anywhere !ip-127-0-0-0.us-east-2.compute.internal/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- ip-172-17-0-0.us-east-2.compute.internal/16 anywhere
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- anywhere anywhere
REDIRECT tcp -- anywhere anywhere tcp dpt:2379 redir ports 443
port 2379が、 port 443にリダイレクトされています。 そのため、nginx
が返答していたのです。
iptables -t nat -F
で、設定をリセットします。
admin@ip-10-0-0-138:/$ sudo /usr/sbin/iptables -t nat -F
# リセット後確認
admin@ip-10-0-0-138:/$ sudo /usr/sbin/iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
Chain DOCKER (0 references)
target prot opt source destination
で、再度、 etcdctl
を実施します。
admin@ip-10-0-0-138:/$ etcdctl get foo
bar
正しく動きました。
Discussion