예제 #1
0
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")
예제 #2
0
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)
예제 #3
0
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")
예제 #4
0
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)
예제 #5
0
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)
예제 #6
0
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)
예제 #7
0
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")
예제 #8
0
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")
예제 #9
0
 def create_root_cert(self, directory, basename="root", CN="root"):
     self.cert = cert.SSLCert(directory, basename, CN)
     self.cert.create_root_cert()