puppet のクライアント/サーバ間通信は https + XMLRPC で、認証は SSLv3 の証明書認証が利用されています。
通常、SSLv3 で証明書認証とかいうと、CA とか、自己署名証明書とか、色々めんどくさかったりしますが、puppet はこの辺りはほとんど自動で処理してくれるので、とても楽です。
例えば、puppet サーバ側では、puppetmasterd をはじめて起動した時に、CA 関連ファイルや自己署名証明書などを、/etc/puppet/ssl 以下に勝手に作ってくれます。
$ ls -R /etc/puppet/ssl /etc/puppet/ssl: ca/ certs/ csr_kenny.southpark.pem private/ private_keys/ public_keys/ /etc/puppet/ssl/ca: ca_crl.pem ca_key.pem inventory.txt requests/ signed/ ca_crt.pem ca_pub.pem private/ serial /etc/puppet/ssl/ca/private: ca.pass /etc/puppet/ssl/ca/requests: /etc/puppet/ssl/ca/signed: kenny.southpark.pem /etc/puppet/ssl/certs: ca.pem kenny.southpark.pem /etc/puppet/ssl/private: /etc/puppet/ssl/private_keys: kenny.southpark.pem /etc/puppet/ssl/public_keys: kenny.southpark.pem
あれ、CA 証明書っぽいものが二つある、と思ったら、ca/ca_crt.pem と certs/ca.pem はまったく同じものでした。
また、CA 証明書とは別に、kenny.southpark.pem というものができていますが、これはおそらく、自身が puppet クライアントになる時に利用するものと思われます。
CA 証明書の中身を覗いてみるとこんな感じ。
$ sudo openssl x509 -text -in /etc/puppet/ssl/ca/ca_crt.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 0 (0x0)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=kenny.southpark
Validity
Not Before: Mar 20 14:29:16 2007 GMT
Not After : Mar 18 14:29:16 2012 GMT
Subject: CN=kenny.southpark
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:ea:83:02:5a:83:08:02:c8:bc:cd:d0:26:07:e7:
44:f7:a0:0e:0f:26:23:82:ba:e4:ed:d7:c8:88:c6:
43:b7:0a:5d:16:39:a2:6a:48:f9:8f:a5:9d:35:2f:
24:1e:ec:38:6b:73:0f:23:17:84:70:7e:08:08:96:
bd:e6:51:53:f2:fe:1d:ec:2f:d0:9a:5b:3d:ea:92:
8a:39:f5:ff:02:ff:6b:e4:d2:ef:9f:d2:c3:d6:35:
d8:5c:51:42:d9:16:59:62:c5:da:9a:9d:cd:f7:91:
a7:06:0b:28:8e:7f:4a:52:bc:5f:c3:5c:cb:b3:e3:
81:d0:1b:ca:b6:7f:73:b2:3f
Exponent: 65537 (0x10001)
X509v3 extensions:
Netscape Comment:
Puppet Ruby/OpenSSL Generated Certificate
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
82:0D:36:AD:29:30:30:2D:CC:2D:EB:EA:F9:32:07:44:80:11:D3:E6
X509v3 Key Usage:
Certificate Sign, CRL Sign
Signature Algorithm: sha1WithRSAEncryption
e0:0b:a7:28:39:8e:09:cc:91:85:ce:13:19:c1:9b:ba:21:c3:
d8:09:c2:ee:93:ac:8d:76:91:18:7a:31:01:fc:55:8b:84:e6:
69:3f:f5:a3:62:ce:cc:af:87:21:42:d4:0d:ab:02:62:26:4f:
c2:f4:a2:22:4f:52:a5:06:bd:88:4c:65:89:9e:98:4c:cb:82:
ce:09:50:e0:4b:67:59:1e:d7:26:75:2f:6f:3d:d3:d4:92:55:
79:06:5e:56:39:2b:15:b0:67:d9:00:79:09:37:86:1a:a1:30:
e0:ce:e8:2b:0a:16:92:73:a3:b8:1f:16:c8:60:f7:7d:c5:24:
09:66
-----BEGIN CERTIFICATE-----
MIICIzCCAYygAwIBAgIBADANBgkqhkiG9w0BAQUFADAaMRgwFgYDVQQDDA9rZW5u
eS5zb3V0aHBhcmswHhcNMDcwMzIwMTQyOTE2WhcNMTIwMzE4MTQyOTE2WjAaMRgw
FgYDVQQDDA9rZW5ueS5zb3V0aHBhcmswgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
AoGBAOqDAlqDCALIvM3QJgfnRPegDg8mI4K65O3XyIjGQ7cKXRY5ompI+Y+lnTUv
JB7sOGtzDyMXhHB+CAiWveZRU/L+Hewv0JpbPeqSijn1/wL/a+TS75/Sw9Y12FxR
QtkWWWLF2pqdzfeRpwYLKI5/SlK8X8Ncy7PjgdAbyrZ/c7I/AgMBAAGjeTB3MDgG
CWCGSAGG+EIBDQQrFilQdXBwZXQgUnVieS9PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0
aWZpY2F0ZTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSCDTatKTAwLcwt6+r5
MgdEgBHT5jALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEFBQADgYEA4AunKDmOCcyR
hc4TGcGbuiHD2AnC7pOsjXaRGHoxAfxVi4TmaT/1o2LOzK+HIULUDasCYiZPwvSi
Ik9SpQa9iExliZ6YTMuCzglQ4EtnWR7XJnUvbz3T1JJVeQZeVjkrFbBn2QB5CTeG
GqEw4M7oKwoWknOjuB8WyGD3fcUkCWY=
-----END CERTIFICATE-----
次にクライアント側ですが、こちらもはじめて puppetd(クライアント側で起動するデーモン)を実行した時に、秘密鍵、公開鍵、CSR を自動的に作成し、サーバに対して CSR への署名を求めることが、起動時のメッセージから読み取れます。
$ sudo /usr/sbin/puppetd --server mizzy.org --test err: No certificate; running with reduced functionality. info: Creating a new SSL key at /var/lib/puppet/ssl/private_keys/cartman.southpark.pem info: Creating a new certificate request for cartman.southpark info: Requesting certificate warning: peer certificate won't be verified in this SSL session notice: Did not receive certificate
サーバ側では、証明書リクエストが来ていることを、次のようなコマンドで確認できます。
$ sudo puppetca --list cartman.southpark
これに署名するには、
$ sudo puppetca --sign cartman.southpark
と実行するだけです。これで puppet クライアント/サーバ間で無事通信できるようになります。
セキュアな通信が割りと簡単に実現できていい感じ。