Add recipe to set up PostgreSQL replication, rewrite kosmos-postgresql cookbook #163
@@ -1,30 +1,51 @@
|
||||
{
|
||||
"id": "postgresql",
|
||||
"ejabberd_user_password": {
|
||||
"encrypted_data": "egFuX4xov+JZUq/GUbCBEQUnxDKczzxdJiYeRDisNEIVPYLNO/piG701sw==\n",
|
||||
"iv": "G0JpgKtcPnTQ5d6v\n",
|
||||
"auth_tag": "NoNoLmZZT+2qgIuDBEdGKQ==\n",
|
||||
"encrypted_data": "hz0xHS2wl66X6xxqLE5/6apQb8SvIR7r8hCd9ZzEcHf7VaWoFMNLmrmwqw==\n",
|
||||
"iv": "PfEp9Jhqfp0o7Cje\n",
|
||||
"auth_tag": "ckEADxPfymTvSVLLXUxTWA==\n",
|
||||
"version": 3,
|
||||
"cipher": "aes-256-gcm"
|
||||
},
|
||||
"server_password": {
|
||||
"encrypted_data": "vJ3cK8vzUKI97YJVLE11I9Ti/Z3Rits+UQjIDZMZDx4cvTiGN0QX\n",
|
||||
"iv": "ENFE12MnoSta++6j\n",
|
||||
"auth_tag": "JbeVb+zdrkHvj9g9end/2Q==\n",
|
||||
"encrypted_data": "9aV4IykJB3lISayq/crmowTjrQjwSWSrh7+O9LMq0IgZaWZ6Bk6R\n",
|
||||
"iv": "XFeNPuZAh4nCX9NU\n",
|
||||
"auth_tag": "LoAIWrqSAmcuA+r3nyHu2Q==\n",
|
||||
"version": 3,
|
||||
"cipher": "aes-256-gcm"
|
||||
},
|
||||
"mastodon_user_password": {
|
||||
"encrypted_data": "PTCEBIB+qYe+lBoFjgLxendhx2ccJJ4UbUEwnPf8MT39fsF9MFQwFiytvg==\n",
|
||||
"iv": "j59Ndhijtj/YQNp5\n",
|
||||
"auth_tag": "bbdA+OmJvTfjwNHzrF19tg==\n",
|
||||
"encrypted_data": "LGU8N2C9Ax17QvFCWNV9m1rbRpBT9YH1qVn/Cmz0/p+1aUcOUN8rzxb57Q==\n",
|
||||
"iv": "FiYQKLmfJ/CYO50H\n",
|
||||
"auth_tag": "t3NwAMqoGCJ/c/5H2KjQ+Q==\n",
|
||||
"version": 3,
|
||||
"cipher": "aes-256-gcm"
|
||||
},
|
||||
"replication_password": {
|
||||
"encrypted_data": "OFLn4FHP8BbCgBJzlqG+Zo3wjzXtklyKgk3OBKdkcUzzgno=\n",
|
||||
"iv": "xHiYpKX90SF7Blqi\n",
|
||||
"auth_tag": "VO/xnf+N+zX6F3DQ8EdSBQ==\n",
|
||||
"encrypted_data": "6UildEd3UactuYufRp+UjHFlK3zLZ8Vmggfc8URBRNVfWHs=\n",
|
||||
"iv": "e4SpyAt32vXuX4un\n",
|
||||
"auth_tag": "AkCEvuEnb+E5jTC84tC8NA==\n",
|
||||
"version": 3,
|
||||
"cipher": "aes-256-gcm"
|
||||
},
|
||||
"ssl_cert": {
|
||||
"encrypted_data": "loF7NMyOJXr8PfxsuN6zvp86hIqWYoGFiGq+ldirctWnmkeDmaROgzDW1oQp\nAubnEHZNx7IFRn/FGpGhhbX/DGjbL6EK0bSE6x6uzOEhpaFDAqmzzEfMXCMj\nDIsrM5WSmP1WBFd6g+/zk3EAXHeekOlLBEj13zzSJVj4piLFERKZRTgix0eP\nOmH+lGBoxy4hXKfa9ru7c5h4vLVQHSlHjrrsyeKdumbmXWSb3IJWtEsNQRqu\nKu6DZ+IRC8fH+DBs8/32dTbJ6uR29kbKfZrWTrpOKXWJLnT1snuiTMeRbTcO\nVbS1ZSeGcpGMFFayAui4KgPaDK8vT/mXcd2P3+c85GZtmmvIKfloIRmtb4in\nleUx3z70BxPFRg5wYfSiP/xJMpjJrh5/6P+96iMkgmU+wuXT+95yf4Agz7G5\n0gObs/sJCAV9qOoWIXSU3jyNvaYsZMPj8FHXlpnCXojHJ2WnqLCAPeVWYHbd\nvNSEOvmCN07xK1PkGZT9NGfPzRcZxqop5gJ3qP9Km33Z06SNF+28i2d4lpy+\n1oWqg5ow2CBhRrb0Bx8FplQug4EXCV7Sni4mc0jSX90rBv+e65Em+33x0A27\nPrp7lfcv+7ridU5AZXifFZSuIJF6LMXz+ji2zC2JMjS4xQ8/KXBd8E5/fRJH\nI18X+t/xx8gakmaDrz/3+4i8TVt1I8pIpN/SaAXTZqgme1QoISymf6LQzFxW\ns1kQGOwbtgx60+2BG7kF9XRRZJay8P1uxmVgjHWbqyL0KbYTlU2zTLuRs3ez\n+rPEsxB/hNfUeB9guALFLtvlkAob1Fh/Za6aukaFlaVJHbHoXehH/aXBPAVK\n0ld+3fql5Ib/OAD7prWaUCZ/tP357RWwCxz+ECjtJhFdREx8fT1aZGvmJ0yx\nESNhSjrn+b+rVc+HiD4hAytW+QP2yNqfKO9YzxXYfN5BBTxh/fvO2qVtQmSf\n+u9iatEaico44E7MX1ZOYAclTA289dwyu6R9PRa1p0zral5b+vJAOx1iH1uq\nzHUKTiRCRAcWrcciL8PH8MRXdcHSxmfyBSBbcz+dh/MURyQMx/LOQ31gYuYq\nzlgbJNsVl6V9rl9x2SargwJrD1WM863oyQumZc/M42GX0z9PilIhLQbF26MN\n2tUf5IDK7d42Z5A6ATxR+0qKh2/WvDXDbNHy+cuAjRJRX9vTgNqpR5qCOyT5\nIxA55rLvHYxbnqic124I1EdXGtoEXqsxt1YAq3ho9QCQz1t5Z/AP63oUEuLr\np4WIeo44fqZzjprRFEE3KbCGlUDx56xLg4a84JF1rMU0ce11BUtEEtRF2p4X\noecU8Z5vvhvsqXxYko6aFNcAvxO2FdZmC76lilNsHgH9VS02ctjOT7Mvi2XP\n3QEVOg==\n",
|
||||
"iv": "v+wkuXO+2VZHRkOu\n",
|
||||
"auth_tag": "C56+Qe/UNzR8k9HizIFyMA==\n",
|
||||
"version": 3,
|
||||
"cipher": "aes-256-gcm"
|
||||
},
|
||||
"ssl_key": {
|
||||
"encrypted_data": "envd5qBpUVHD5+pFmtRm99y3n+Fi6PtEwjgQl1l1VTn/bRMosMGSbWJ9VmPk\nd1tu/Nr1Z1SZcNyBiUxhAaKI2vU6BsNIpy0lnZN3R0bT4OMH/lPIJyIRqAXU\nPu+73++H41SC47Nt+9UhwRkNifIl3lFo0AhqqeHpJQbhCPVVW6oJf2Q7TGDF\nGhU5y3sat5r7FNSRCNvErv8QX/cIOSTHn76350ktgVG29+31Qp9HDhg01jac\ne8XrAiZXPxzNO7tA6zFlsRr6WVaLJeMd4bTXQpfgy/wcl+UG91n02ODdveqj\n2P+Z+ZnKvgAgmTrWpwHalJ6KkWBjuYPdaawnRPbMVUCm7usPFOurpuvYwX61\ncysFOylwCaw3vCEBWFlQAaV5GJAiaMujI8OFkioQS0FZ8M7slLs9famJzz6c\nR24BJHHb7eJRHsGZptHnEx6JGA4WGQD1e5Z8JtKnUff0WVtiSe9lwEwWNPPx\ntMJX0H8+bXdLC5W+R7pbHQfSWmbk9CP9ehlReJw9Kj1neQfm4W1Vevi42Jz2\n9JkBZ+P0ympsYb+qk0juNUrP5mC8rfW+/RktRihp4sufOW4KcK2nwWka4HeQ\nql2Xh6gHyniB2pe60lFmt2XR/0k47/tz+i6Xim67apfr8vapDzA4vBnJRVNv\nz8OVgBjJ124K5j+V4jJkWem7YfgLVpmzbkOsQp6YAsNitYUeiRwF8ijckkYF\nqEOXq4HTvyCKiPsy+myd6fjyJGCTFz4lFwQa54PFb45BsjApN78SEzWj0fxL\nT/LZF3HxA4vR72zajAFs/Vf6W7Ho5mKG/h21vjw1gDeN7U8FLOzUQX6uSJZh\nDF46Bn9WOilKvUpJrrcFCWcypwtxc6oFvRl05P31Dm0+2R6gNhOlckSsXDjY\nBTOJWI2pN4En8oTN7EF7JkOwG/9O7wUOpGBKrIvn/Z0Ith8O99X8fJnBuqlw\nuz20B2q5KIfNvr2Aw1nALsmPEuQtj+JQ2wj4fxY9P5f6bK31psTymWvLe7Fl\n1t2ec4x6H6cEFBULax1WJaRGHsZJ+U3fxn3SMMVJwkCBvepWM7gM6LdKH0a9\n9qOk2mlLTtFmYjZxMkL5kt457XtAYlK6YZSMLZgIZob5Bfnltrmodv4BpJop\nV7Qffwqmh18E1k8hH4tQrQ7At/gvfMY4IQb/m9H7MCgFODn1NtIAD9+8VFRR\n9Lt3BjAwZpakv6tYBW3q7rr5+17fY5O0kZ7Ns8qnhc7/5ZBjuT38828rJO12\nhLNfp7xFm8oNTlDmQeN2RSmOnt42QYKsDdUG8hzhzOjeHMq/ZzTcKPCHTxlw\nln2F/t7PHV1lvOTzwueDuI8+KAGxhb6OVkQz0Fq60Feq4Bc1/YkX5jHNcPvQ\nL5z9pJJyZ1RhP5/Z9JekzaLn8TDigW3zri2YTKQZedLKHFjzRM9FjkXgn/l6\nETWwN2hK1iryFeoNKDBslRVx89LG96MdABF1x0ZRctZfWLPHmCosqw1rVJs7\nbK3vi1W+i8FVjimu0WH2mPwnP8rMxi+RPul5QJKakHlzUKcGGLfSaTxJ0cKr\nye4u68S8ikAGu9nVmy79NASgkoBETF5EcgjD+r+gH8eYv+Dt3qV+GJAZu5wK\n3ILwGn9HpCJGhwSQCOkj0JqH1fFOZXrGlrnbtCl8QfqILP6IjQvFMO8QvcJX\nDh+kfFKmuKMSAVUwplNHIF65TBpLEr6iFoC9wfTMmha5xdScLxYa9oxFeeQp\n3TdLBFm4X+rXufOp+L1oLgOtKaETvzxHTIi0A0ZPtG2NAgGIxxtmcl6Cl4mZ\nZkWJYAlbsh+suYTAiqtoBSbyl1y8/WayeINOwBWGGl3dvRfuJMH4oQDYhAZ+\ng5UBS5YcSBsIWYairl56w7OeF/1jq702HLqm0+j2qf1gLuefBPG8/Yxo1VSr\nctElIJZwobdtW27uaycczckEuc2rlOc7DSxcTWhz95oBzeWyeB8z8AmOHVsJ\nLKkAINcxyEUfwN0Sq2Z4mQ+vFADR22RPPUWAAM96Udc6cMZyHCWWA6D4nlSl\nLBUDXujfV/ssapX1n3WVR9cc7rsHxTQ0o6ci6YPk0SWUASKP+ITamz31T0HW\nH7urYZleUWKgthcm/7YoEuKUPYBD9RjHz1cIXCO7Xz8zwfVUnMCXaqJzJ7bn\nFUvFb2qmPqc4KxhVoWU7p6NQRQNJC/qtAb27/YwZM3/gEj0qL4eT1jr8DInE\nZxa4GPUCgNf8Q8H0BtXv/WWmee2KakHXoMcawmeJBtPpyo/eAHPTihxSjPDq\nEdTgqwSCzzRETU3ZgsRc3KpawUm8kPkyxoCGFt5FwS/PFJWredsSAHCWJQ==\n",
|
||||
"iv": "sPYjnXdqpABH9wrl\n",
|
||||
"auth_tag": "F5ajYZMx+6r333stbQ0E1Q==\n",
|
||||
"version": 3,
|
||||
"cipher": "aes-256-gcm"
|
||||
},
|
||||
"ssl_root_cert": {
|
||||
"encrypted_data": "hwwHOg/kuJxMEOLpDC2zCrIRoWkbcNzui849HEtootXsL8YPFMIo0wKzC4JS\nc5R5A7MOqgoijjrhymMKkWZ4nqdx0ZVjlLQoBpFd2D6OYmomID/e4Qi2fR4Q\nZ9eS1xoPi0cAcKKML83yHJ3bRkZhqcZLIauqm3N+pAwEdYjHo9HrNPs9stqL\noSyLIG5IwNvwh8DJMb9XU5tBlMOpI0eUDRptBHjecAdmSv59jxse7dSHVove\ndsooWNdsz48318QMG3e2ALRIWZHFb0t2C/01wYqk9PrazIX9upC1BHZ7f4XZ\nAOkukFD/uVa3wLrzQnGhh8bLxZmsRaKaGlY79vg6HgYqUoqmEuB6FHVRX7xb\nh4zt3CcWQMwU0r+Po1a2Qo5HT9xP40QgrHwtJwlpLgIP/9yxhTjpb2qdJzY3\n88MI/wZLvyezTZwMmZikE9+IlwfUBBmsSJVHOtKlPQ27YAHXmALczQUPrYG9\nqWLnWoqmyYFMpPF4u7QQUXNjde+z5sZb2gELRy1nBtHGPEZQY/Ji9P4AT0jW\n3tTidly4yYa0sXLGFH/ZbePRwrUX1qd7RalOLWUYkPwEUVcO5FzzWvCr58S0\n570VoHhyTrYWwaRfiEhEsOV/aSrVERa7T89NvDGpaKQmzpWCF1uGbnmRUI+a\nyYhSzgXaFiKiE8JFvev83slqRpsxF2z2bdHEBvSIce69pzC5VjWKVuHG/Lf8\nVseTapbVXNptMTgm+ToZHcbtBFdWlh3rpyaAKj5uKkKenY0n/R7s4M0GFviY\nj+zLQhHGYXNCybKTfguDfcKe6XiktguwXTCaXo8HpaZr49i2HsAYmSEHw4oE\nYKoYUfm9v1n6O6uxWXV92OIpRS0bkb4hUMWY9K6oG/hbUCupX/RWnBZW4wAS\nvh561oz1Ef1NVI85l2DDG++oCgXgiqzulIQxyNFOyofX5KLmJ8/nLSUc2R3E\nITPaqEG/5NUSyeQMPbIVRN4bsXcogWB/779QiXP6nDEuucNH6kpesiDbEmxC\n5J9i3xKI97zDL8HEmT7Tgp5Tu9FOyOA36qS14cMo8Ue4MWDGV1NrnbWf7LvE\nnx65h8tk1LzimnTE/NqhrYgodylUnNf6c76CaHUhqBDi3JUMF9O/IwRuYH7w\nTvOGphtyix7Lph3wCJJf/VVgK4jy2erq9+mr82dKBBCynEbUJVhpVlAkdKqX\n44LC+KIvJBb4UPerutEYmOOy2Ha1elQyFebSgUR6bxxG9JvZEOYY+UCdeRnz\nQTCQYEvUO7nHSI1uKDW2/BC0f6vzQxYWBT1XgWt5D+wlqz3ysW2AKCK2j4xL\nEFZEQF4ibX0Acm/dp/BVztq8ymhTtqW7pMPHbub0/Q4kgFiPq66FHxJdQU4Q\nuS9w2ciiPGbCbgdww3RfEU3c0kTieyHRcL/pU3aaO6RTA3SeGRX6DqXX3Si3\npkLiyuXBBIskbn0RiBn1SXYMJ17Vaye4BvFlDc2PywhEsXkRGn6Ad1gLOkyZ\nycLnXizhLX0kePSgyn/0N9RI067dlv2lzdaVuheQQEX7efrFCC2zMzvdgP8=\n",
|
||||
"iv": "TrPuASVYx7D2onkS\n",
|
||||
"auth_tag": "Gzn4kJCs87LK3ZKJxCHAnw==\n",
|
||||
"version": 3,
|
||||
"cipher": "aes-256-gcm"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
Usage:
|
||||
|
||||
When the `tls` attribute is set to true, a TLS certificate for the FQDN
|
||||
(`node['fqdn']`, for example `andromeda.kosmos.org`) is generated using Let's
|
||||
Encrypt and copied to the PostgreSQL data directory and added to the
|
||||
`postgresql.conf` file
|
||||
@@ -16,7 +15,6 @@ Encrypt and copied to the PostgreSQL data directory and added to the
|
||||
```ruby
|
||||
postgresql_custom_server "12" do
|
||||
role "primary"
|
||||
tls true
|
||||
end
|
||||
```
|
||||
|
||||
@@ -25,7 +23,6 @@ end
|
||||
```ruby
|
||||
postgresql_custom_server "12" do
|
||||
role "replica"
|
||||
tls true
|
||||
end
|
||||
```
|
||||
|
|
||||
|
||||
@@ -47,3 +44,47 @@ about PostgreSQL client authentication, see the
|
||||
|
||||
The primary opens up the PostgreSQL port (5432 TCP) to replicas, and replicas
|
||||
to the primary.
|
||||
|
||||
## TLS self-signed certificate
|
||||
|
||||
A wildcard (`*.kosmos.org` certificate) was generated with the following
|
||||
commands:
|
||||
|
||||
```
|
||||
openssl req -new -nodes -text -out root.csr -keyout root.key \
|
||||
-subj "/CN=root.kosmos.org"
|
||||
chmod og-rwx root.key
|
||||
openssl x509 -req -in root.csr -text -days 3650 \
|
||||
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
|
||||
-signkey root.key -out root.crt
|
||||
openssl req -new -nodes -text -out server.csr \
|
||||
|
raucao
commented
I don't see where that's done in this PR? I don't see where that's done in this PR?
greg
commented
I forgot to remove that part from the README, as we said in #160 that we don't care about verifying the root cert. It would be done in the cookbooks for software that connects to PostgreSQL (together with creating databases) and not in this cookbook I forgot to remove that part from the README, as we said in #160 that we don't care about verifying the root cert. It would be done in the cookbooks for software that connects to PostgreSQL (together with creating databases) and not in this cookbook
|
||||
-keyout server.key -subj "/CN=*.kosmos.org"
|
||||
chmod og-rwx server.key
|
||||
openssl x509 -req -in server.csr -text -days 1825 \
|
||||
-CA root.crt -CAkey root.key -CAcreateserial \
|
||||
-out server.crt
|
||||
```
|
||||
|
||||
It is valid until May 12 2025.
|
||||
|
||||
The content of `server.crt`, `server.key` and `root.crt` an stored in the
|
||||
`postgresql` encrypted data bag. The root key is stored in LastPass
|
||||
("Self-signed TLS root certificate"). `server.crt` & `server.key` are used by
|
||||
the PostgreSQL server.
|
||||
|
||||
The root certificate needs to be deployed to clients so they verify the cert
|
||||
can be trusted.
|
||||
|
||||
For example:
|
||||
|
||||
```ruby
|
||||
postgresql_data_bag_item = data_bag_item('credentials', 'postgresql')
|
||||
root_cert_path = "/etc/ssl/certs/root.kosmos.org.crt"
|
||||
file root_cert_path do
|
||||
content postgresql_data_bag_item['ssl_root_cert']
|
||||
mode "0644"
|
||||
end
|
||||
```
|
||||
|
||||
`/etc/ssl/certs/root.kosmos.org.crt` can be used as the CA root cert path in
|
||||
the client's configuration
|
||||
|
||||
@@ -2,7 +2,6 @@ resource_name :postgresql_custom_server
|
||||
|
||||
property :postgresql_version, String, required: true, name_property: true
|
||||
property :role, String, required: true # Can be primary or replica
|
||||
property :tls, [TrueClass, FalseClass], default: false
|
||||
|
||||
action :create do
|
||||
postgresql_version = new_resource.postgresql_version
|
||||
@@ -63,56 +62,33 @@ action :create do
|
||||
additional_config[:promote_trigger_file] = "#{postgresql_data_dir}/failover.trigger"
|
||||
end
|
||||
|
||||
if new_resource.tls
|
||||
include_recipe "kosmos-nginx"
|
||||
include_recipe "kosmos-base::letsencrypt"
|
||||
ssl_cert = postgresql_data_bag_item['ssl_cert']
|
||||
ssl_cert_path = "#{postgresql_data_dir}/server.crt"
|
||||
ssl_key = postgresql_data_bag_item['ssl_key']
|
||||
ssl_key_path = "#{postgresql_data_dir}/server.key"
|
||||
|
||||
domain = node[:fqdn]
|
||||
|
||||
postgresql_post_hook = <<-EOF
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# Copy the postgresql certificate and restart the server if it has been renewed
|
||||
# This is necessary because the postgresql user doesn't have access to the
|
||||
# letsencrypt live folder
|
||||
for domain in $RENEWED_DOMAINS; do
|
||||
case $domain in
|
||||
#{domain})
|
||||
cp "${RENEWED_LINEAGE}/privkey.pem" #{postgresql_data_dir}/#{domain}.key
|
||||
cp "${RENEWED_LINEAGE}/fullchain.pem" #{postgresql_data_dir}/#{domain}.crt
|
||||
chown postgres:postgres #{postgresql_data_dir}/#{domain}.*
|
||||
chmod 600 #{postgresql_data_dir}/#{domain}.*
|
||||
systemctl reload #{postgresql_service}
|
||||
;;
|
||||
esac
|
||||
done
|
||||
EOF
|
||||
|
||||
# This hook will be executed by certbot after every successful certificate
|
||||
# creation or renewal
|
||||
file "/etc/letsencrypt/renewal-hooks/post/postgresql" do
|
||||
content postgresql_post_hook
|
||||
mode 0755
|
||||
owner "root"
|
||||
group "root"
|
||||
end
|
||||
|
||||
template "#{node['nginx']['dir']}/sites-available/#{domain}" do
|
||||
source 'nginx_conf_empty.erb'
|
||||
owner node["nginx"]["user"]
|
||||
mode 0640
|
||||
notifies :reload, 'service[nginx]', :delayed
|
||||
end
|
||||
|
||||
nginx_certbot_site domain
|
||||
|
||||
additional_config[:ssl] = "on"
|
||||
additional_config[:ssl_cert_file] = "#{postgresql_data_dir}/#{domain}.crt"
|
||||
additional_config[:ssl_key_file] = "#{postgresql_data_dir}/#{domain}.key"
|
||||
file ssl_cert_path do
|
||||
content ssl_cert
|
||||
owner "postgres"
|
||||
group "postgres"
|
||||
mode "0640"
|
||||
sensitive true
|
||||
end
|
||||
|
||||
file ssl_key_path do
|
||||
content ssl_key
|
||||
owner "postgres"
|
||||
group "postgres"
|
||||
mode "0600"
|
||||
sensitive true
|
||||
end
|
||||
|
||||
additional_config[:ssl] = "on"
|
||||
additional_config[:ssl_cert_file] = ssl_cert_path
|
||||
additional_config[:ssl_key_file] = ssl_key_path
|
||||
# ejabberd does not support 1.3 yet
|
||||
additional_config[:ssl_min_protocol_version] = "TLSv1.2"
|
||||
|
||||
postgresql_server_conf "main" do
|
||||
version postgresql_version
|
||||
additional_config additional_config
|
||||
|
||||
Reference in New Issue
Block a user
The replica also needs to have "primary" as role?
Thanks, I've pushed a fix for the typo