def test_003_init_secondary(): global node2 # Create a server certificate signed by the root Certificate Authority certs_dir = "/tmp/certs/node2" serverCert = cert.SSLCert("/tmp/certs/node2", "server", "/CN=node2.pgautofailover.ca") serverCert.create_signed_certificate(cluster.cert) # Now create the server with the certificates node2 = cluster.create_datanode("/tmp/cert/node2", authMethod="skip", sslMode="verify-ca", sslCAFile=cluster.cert.crt, sslServerKey=serverCert.key, sslServerCert=serverCert.crt) node2.create(level='-vv') with open(os.path.join("/tmp/cert/node2", "pg_hba.conf"), 'a') as hba: hba.write("hostssl all all %s cert\n" % cluster.networkSubnet) hba.write("hostssl replication all %s cert map=pgautofailover\n" \ % cluster.networkSubnet) with open(os.path.join("/tmp/cert/node1", "pg_ident.conf"), 'a') as ident: # use an ident map to allow using the same cert for replication ident.write("pgautofailover autoctl_node pgautofailover_replicator\n") node2.reload_postgres() node2.run() assert node2.wait_until_state(target_state="secondary") assert node1.wait_until_state(target_state="primary") node2.wait_until_pg_is_running() node2.check_ssl("on", "verify-ca")
def test_014_enable_ssl_require_primary(): node1Cert = cert.SSLCert("/tmp/certs/node1", "server", "/CN=node1.pgautofailover.ca") node1Cert.create_signed_certificate(cluster.cert) node1.stop_pg_autoctl() node1.enable_ssl(sslServerKey=node1Cert.key, sslServerCert=node1Cert.crt, sslMode="require") node1.run() node1.wait_until_pg_is_running() node1.check_ssl("on", "require", primary=True)
def test_012_enable_ssl_verify_ca_secondary(): node2Cert = cert.SSLCert("/tmp/certs/node2", "server", "/CN=node2.pgautofailover.ca") node2Cert.create_signed_certificate(cluster.cert) node2.stop_pg_autoctl() node2.enable_ssl(sslCAFile=cluster.cert.crt, sslServerKey=node2Cert.key, sslServerCert=node2Cert.crt, sslMode="verify-ca") node2.run() node2.wait_until_pg_is_running() node2.check_ssl("on", "verify-ca")
def test_011_enable_ssl_verify_ca_primary(): node1Cert = cert.SSLCert("/tmp/certs/node1", "server", "/CN=node1.pgautofailover.ca") node1Cert.create_signed_certificate(cluster.cert) node1.stop_pg_autoctl() node1.enable_ssl(sslCAFile=cluster.cert.crt, sslServerKey=node1Cert.key, sslServerCert=node1Cert.crt, sslMode="verify-ca") node1.run() node1.sleep(2) node1.check_ssl("on", "verify-ca", primary=True)
def test_014_enable_ssl_require_primary(): node1Cert = cert.SSLCert( "/tmp/certs/node1", "server", "/CN=node1.pgautofailover.ca" ) node1Cert.create_signed_certificate(cluster.cert) node1.enable_ssl( sslServerKey=node1Cert.key, sslServerCert=node1Cert.crt, sslMode="require", ) node1.pg_autoctl.sighup() time.sleep(6) # to avoid flackyness here, we allow a second run/timeout of waiting if not node1.wait_until_pg_is_running(): assert node1.wait_until_pg_is_running() node1.check_ssl("on", "require", primary=True)
def test_001_init_primary(): global node1 # Create a server certificate signed by the root Certificate Authority certs_dir = "/tmp/certs/node1" serverCert = cert.SSLCert("/tmp/certs/node1", "server", "/CN=node1.pgautofailover.ca") serverCert.create_signed_certificate(cluster.cert) # Now create the server with the certificates node1 = cluster.create_datanode( "/tmp/cert/node1", authMethod="skip", sslMode="verify-ca", sslCAFile=cluster.cert.crt, sslServerKey=serverCert.key, sslServerCert=serverCert.crt, ) node1.create(level="-vv") with open(os.path.join("/tmp/cert/node1", "pg_hba.conf"), "a") as hba: # node1.run_sql_query will need # host "172.27.1.1", user "docker", database "postgres" hba.write("hostssl postgres docker %s cert\n" % cluster.networkSubnet) hba.write("hostssl all all %s cert\n" % cluster.networkSubnet) hba.write("hostssl replication all %s cert map=pgautofailover\n" % cluster.networkSubnet) with open(os.path.join("/tmp/cert/node1", "pg_ident.conf"), "a") as ident: # use an ident map to allow using the same cert for replication ident.write("pgautofailover autoctl_node pgautofailover_replicator\n") node1.reload_postgres() node1.run() assert node1.wait_until_state(target_state="single") node1.wait_until_pg_is_running() node1.check_ssl("on", "verify-ca", primary=True)
def test_010_enable_ssl_verify_ca_monitor(): client_top_directory = os.path.join(os.getenv("HOME"), ".postgresql") print() print("Creating cluster root certificate") cluster.create_root_cert(client_top_directory, basename="root", CN="/CN=root.pgautofailover.ca") p = subprocess.run([ "ls", "-ld", client_top_directory, cluster.cert.crt, cluster.cert.csr, cluster.cert.key ], text=True, capture_output=True) print("%s" % p.stdout) # now create and sign the CLIENT certificate print("Creating cluster client certificate") clientCert = cert.SSLCert(client_top_directory, basename="postgresql", CN="/CN=autoctl_node") clientCert.create_signed_certificate(cluster.cert) p = subprocess.run([ "ls", "-ld", client_top_directory, clientCert.crt, clientCert.csr, clientCert.key ], text=True, capture_output=True) print("%s" % p.stdout) # the root user also needs the certificates, tests are connecting with it subprocess.run(["ln", "-s", client_top_directory, "/root/.postgresql"]) assert (p.returncode == 0) p = subprocess.run(["ls", "-l", "/root/.postgresql"], text=True, capture_output=True) print("%s" % p.stdout) # now create and sign the SERVER certificate for the monitor print("Creating monitor server certificate") monitorCert = cert.SSLCert("/tmp/certs/monitor", "server", "/CN=monitor.pgautofailover.ca") monitorCert.create_signed_certificate(cluster.cert) p = subprocess.run([ "ls", "-ld", client_top_directory, cluster.cert.crt, cluster.cert.csr, cluster.cert.key, clientCert.crt, clientCert.csr, clientCert.key, monitorCert.crt, monitorCert.csr, monitorCert.key ], text=True, capture_output=True) print("%s" % p.stdout) monitor.enable_ssl(sslCAFile=cluster.cert.crt, sslServerKey=monitorCert.key, sslServerCert=monitorCert.crt, sslMode="verify-ca") monitor.sleep(2) # we signaled, wait some time monitor.check_ssl("on", "verify-ca")
def test_000_create_monitor(): # create SSL certs and keys for this server # # https://www.postgresql.org/docs/11/ssl-tcp.html # # server.crt and server.key should be stored on the server, and root.crt # should be stored on the client so the client can verify that the # server's leaf certificate was signed by its trusted root certificate. # root.key should be stored offline for use in creating future # certificates. # # https://www.postgresql.org/docs/current/libpq-ssl.html # # If the server attempts to verify the identity of the client by # requesting the client's leaf certificate, libpq will send the # certificates stored in file ~/.postgresql/postgresql.crt in the user's # home directory # Now, create a server certificate signed by the new root certificate # authority client_top_directory = os.path.join(os.getenv("HOME"), ".postgresql") # now create and sign the CLIENT certificate clientCert = cert.SSLCert(client_top_directory, basename = "postgresql", CN = "/CN=autoctl_node") clientCert.create_signed_certificate(cluster.cert) # now create and sign the SERVER certificate for the monitor serverCert = cert.SSLCert("/tmp/certs/monitor", "server", "/CN=monitor.pgautofailover.ca") serverCert.create_signed_certificate(cluster.cert) p = subprocess.run(["ls", "-ld", client_top_directory, cluster.cert.crt, cluster.cert.csr, cluster.cert.key, clientCert.crt, clientCert.csr, clientCert.key, serverCert.crt, serverCert.csr, serverCert.key], text=True, capture_output=True) print("%s" % p.stdout) # the root user also needs the certificates, tests are connecting with it subprocess.run(["ln", "-s", client_top_directory, "/root/.postgresql"]) assert(p.returncode == 0) # # Now create the monitor Postgres instance with the certificates # monitor = cluster.create_monitor("/tmp/cert/monitor", authMethod="skip", sslMode="verify-ca", sslCAFile=cluster.cert.crt, sslServerKey=serverCert.key, sslServerCert=serverCert.crt) monitor.run() monitor.wait_until_pg_is_running() with open(os.path.join("/tmp/cert/monitor", "pg_hba.conf"), 'a') as hba: hba.write("hostssl all all %s cert\n" % cluster.networkSubnet) monitor.reload_postgres() # check the SSL settings cmd = ["openssl", "s_client", "-starttls", "postgres", "-connect", "172.27.1.2:5432", "-showcerts", "-CAfile", cluster.cert.crt] print(" ".join(cmd)) p = subprocess.run(["sudo", "-E", '-u', os.getenv("USER"), 'env', 'PATH=' + os.getenv("PATH")] + cmd, input="", text=True, capture_output=True) if p.returncode != 0: print("" % p.stdout) print("" % p.stderr) assert(p.returncode == 0) # print connection string print("monitor: %s" % monitor.connection_string()) monitor.check_ssl("on", "verify-ca")
def create_root_cert(self, directory, basename="root", CN="root"): self.cert = cert.SSLCert(directory, basename, CN) self.cert.create_root_cert()