PostgreSQL सर्वर के एसएसएल प्रमाणपत्र की जांच कैसे करें?


14

मान लीजिए कि एक PostgreSQL सर्वर चल रहा है और इसमें SSL सक्षम है। "मानक" लिनक्स और पोस्टग्रेक्यूएल टूल्स का उपयोग करके, मैं इसके एसएसएल प्रमाणपत्र की जांच कैसे कर सकता हूं?

मैं आउटपुट के लिए उम्मीद कर रहा हूं कि आपको चलाने से क्या मिलेगा openssl x509 -text ...। और मैं एक या दो-लाइनर कमांड लाइन के जवाब की उम्मीद कर रहा हूं, इसलिए मुझे एक पैकेट स्निफर चलाने का सहारा नहीं लेना है।

मेरे पास PostgreSQL सर्वर तक पहुंच नहीं है, इसलिए मैं इसकी कॉन्फ़िगरेशन फ़ाइलों को सीधे नहीं देख सकता।

मेरे पास एक सुपरयुसर लॉगिन नहीं है, इसलिए मैं ssl_cert_fileसेटिंग का मान नहीं पा सकता हूं और फिर उस pg_read_fileपर।

का उपयोग करते हुए openssl s_client -connect ...काम नहीं करता क्योंकि PostgreSQL प्रतीत नहीं होता एसएसएल हाथ मिलाना सही दूर करना चाहते हैं।

psqlदस्तावेज़ीकरण पर एक त्वरित नज़र से , मैं एक कमांड-लाइन पैरामीटर नहीं ढूंढ सका जो इसे स्टार्टअप पर उस जानकारी को दिखाता है। (हालांकि यह मुझे कुछ सिफर जानकारी दिखाता है।)

जवाबों:


7

ऐसा लगता है कि OpenSSL का s_clientटूल जोड़ा गया है -starttls। 1.1.1 के उपयोग से पोस्टग्रैज सपोर्ट , इसलिए अब आप अतिरिक्त हेल्पर स्क्रिप्ट के बिना OpenSSL के कमांड लाइन टूल्स की पूरी शक्ति का उपयोग कर सकते हैं:

openssl s_client -starttls postgres -connect my.postgres.host:5432 # etc...

संदर्भ:


10

क्रेग रिंगर की टिप्पणी में विचार के बाद:

एक विकल्प openssl s_clientPostgreSQL प्रोटोकॉल के साथ हाथ मिलाना है। आप संभवतः जावा के साथ भी कर सकते हैं, एक कस्टम SSLSocketFactory PgJDBC को पास करके। मुझे यकीन नहीं है कि कोई भी सरल विकल्प हैं।

... मैंने एक साधारण एसएसएल सॉकेट फैक्टरी लिखी। मैंने PgJDBC के स्वयं के NonValidatingFactoryवर्ग के कोड की प्रतिलिपि बनाई और प्रमाणपत्रों को मुद्रित करने के लिए बस जोड़ा गया कोड।

यहाँ यह देखा गया है, जब यह सब कहा और किया गया था:

import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;
import java.sql.Connection;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.postgresql.ds.PGSimpleDataSource;
import org.postgresql.ssl.WrappedFactory;

public class ShowPostgreSQLCert {
    public static void main(String[] args) throws Throwable {
        PGSimpleDataSource ds = new PGSimpleDataSource();
        ds.setServerName( ... );
        ds.setSsl(true);
        ds.setUser( ... );
        ds.setDatabaseName( ... );
        ds.setPassword( ... );
        ds.setSslfactory(DumperFactory.class.getName());
        try (Connection c = ds.getConnection()) { }
    }

    public static class DumperFactory extends WrappedFactory {
        public DumperFactory(String arg) throws GeneralSecurityException {
            SSLContext ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[] { new DumperTM() }, null);
            _factory = ctx.getSocketFactory();
        }
    }

    public static class DumperTM implements X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
        public void checkClientTrusted(X509Certificate[] certs, String authType) { }
        public void checkServerTrusted(X509Certificate[] certs, String authType) {
            for (int i=0; i<certs.length; ++i) {
                System.out.println("Cert " + (i+1) + ":");
                System.out.println("    Subject: " + certs[i].getSubjectX500Principal().getName());
                System.out.println("    Issuer: " + certs[i].getIssuerX500Principal().getName());
            }
        }
    }
}

आपने धमाल मचाया। बस इसे स्थापित करने के लिए जोड़ा गया- github.com/spyhunter99/installcert
जासूस

Awsome बहुत बहुत धन्यवाद। ऐसे लोग जो PGSimpleDataSource का उपयोग नहीं करना चाहते हैं। यहाँ सामान्य JDBC ड्राइवर सेटअप का उपयोग करने के लिए संस्करण: String connectionURL = "jdbc:postgresql://server:62013/dbname"; Properties props = new Properties(); props.setProperty("user", "username"); props.setProperty("password", "password"); props.setProperty("ssl", "true"); props.setProperty("sslfactory", DumperFactory.class.getName()); Connection con = null; // Load the Driver class. Class.forName("org.postgresql.Driver"); con = DriverManager.getConnection(connectionURL, props);
मार्कस

7

यदि आप जावा स्थापित करने और संकलन करने से परेशान नहीं होना चाहते हैं, और आपके पास पहले से ही अजगर है, तो आप इस अजगर स्क्रिप्ट की कोशिश कर सकते हैं: https://github.com/thusoy/postgres-mitm/blob/master//ostostgres_get_server_cert.py

मैं इसका उपयोग प्रमाण पत्र की तारीखों की जांच करने के लिए करता हूं:

postgres_get_server_cert.py example.com:5432 | openssl x509 -noout -dates

या पाठ के रूप में पूर्ण प्रमाण पत्र के लिए:

postgres_get_server_cert.py example.com:5432 | openssl x509 -noout -text

1
स्थापित किए बिना इसका उपयोग करने के लिए: curl https://raw.githubusercontent.com/thusoy/postgres-mitm/master/postgres_get_server_cert.py | python - example.com:5432(लेकिन इस बात को सुनिश्चित करें कि आप इस तरह से क्या करते हैं !!)
Yajo

3

सीएसडी के जवाब ने वास्तव में मुझे बचा लिया। यहाँ हम में से उन लोगों के लिए एक अधिक विस्तृत पूर्वाभ्यास है जो जावा को नहीं जानते हैं या भूल गए हैं।

  1. सुनिश्चित करें कि आपका सर्वर जावा को संकलित कर सकता है। "जो जेवैक" कमांड का प्रयास करें, अगर यह "... जेवैक इन ..." जैसा कुछ आउटपुट करता है, तो आपको एक जेडीके स्थापित करने की आवश्यकता है (जेआरई काम नहीं करेगा, इसमें "जावा" है, लेकिन "जेवैक" नहीं)।

  2. यदि आपके पास पहले से यह नहीं है तो postgresql-jdbc स्थापित करें। RHEL6 के लिए कमांड "yum install postgresql-jdbc" है। जहां जर्क फाइलें स्थापित हैं, वहां चित्र बनाएं। उनमें से कई होंगे, प्रत्येक संस्करण के लिए एक। मैंने "/usr/share/java/postgresql-jdbc3.jar" का उपयोग किया।

  3. सीएसडी के कोड को कॉपी करें और डेटाबेस की जानकारी (अन्य उत्तर) डालें, या इस उत्तर के अंत में मेरे थोड़े संशोधित संस्करण का उपयोग करें। इसे बिल्कुल "ShowPostgreSQLCert.java" नामक फ़ाइल में सहेजें। ऊपरी / निचले मामलों में, इसे और कुछ भी कहें और यह संकलन नहीं करेगा।

  4. ShowPostgreSQLCert.java फ़ाइल के साथ निर्देशिका में, निम्न आदेश चलाएँ (यदि आवश्यक हो तो postgresql-jdbc3.jar के स्थान को संशोधित करें): "javac -cp /usr/share -java/postgresql-jdbc3.jar ShowPostgreSQLCertava। जावा। अब आपके पास एक ही डायरेक्टरी में 3 .class फाइलें होनी चाहिए।

  5. अंत में, निम्न कमांड चलाएँ: "java -cp।: / usr / share / java / postgresql-jdbc3.jar ShowPostgreSQLCert"। ""। "-cp" के बाद इसका मतलब .class फ़ाइलों के लिए वर्तमान dir में देखना चाहिए। आप यहां क्लास फ़ाइलों में पूरा पथ सम्मिलित कर सकते हैं, बस .jar फ़ाइल के पथ और स्थान के बीच ":" रखना याद रखें।

  6. यदि आपको एक अलग मशीन पर कमांड चलाने की आवश्यकता है, तो आपको उसी जार फ़ाइल को स्थापित करने की आवश्यकता है (पोस्टग्रैस्कल-जेडडीबीसी 3।जर), या आप शायद इसे केवल उस सर्वर से कॉपी कर सकते हैं जिसे आपने .class फ़ाइलों पर संकलित किया है। तो बस .class फ़ाइलों को कॉपी करें और रास्तों को संशोधित करने के बाद 5 से कमांड चलाएं।

मैंने कोड को थोड़ा संशोधित किया है ताकि आप .class फ़ाइल में संकलित करने के बजाय कमांड लाइन पर डेटाबेस की जानकारी पास कर सकें। बस इसे बिना किसी तर्क के चलाएं और यह एक संदेश प्रदर्शित करेगा जो यह तर्क देगा कि यह अपेक्षा करता है। csd का कोड + संशोधन है:

import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;
import java.sql.Connection;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.postgresql.ds.PGSimpleDataSource;
import org.postgresql.ssl.WrappedFactory;

public class ShowPostgreSQLCert {
    public static void main(String[] args) throws Throwable {
        PGSimpleDataSource ds = new PGSimpleDataSource();
        if( args.length != 4 ) {
            System.out.println("Not enough arguments. Usage: ShowPostgreSQLCert ServerName User DatabaseName Password");
            System.exit(1);
        }
        ds.setServerName( args[0] );
        ds.setSsl(true);
        ds.setUser( args[1] );
        ds.setDatabaseName( args[2] );
        ds.setPassword( args[3] );
        ds.setSslfactory(DumperFactory.class.getName());
        try (Connection c = ds.getConnection()) { }
    }

    public static class DumperFactory extends WrappedFactory {
        public DumperFactory(String arg) throws GeneralSecurityException {
            SSLContext ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[] { new DumperTM() }, null);
            _factory = ctx.getSocketFactory();
        }
    }

    public static class DumperTM implements X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
        public void checkClientTrusted(X509Certificate[] certs, String authType) { }
        public void checkServerTrusted(X509Certificate[] certs, String authType) {
            for (int i=0; i<certs.length; ++i) {
                System.out.println("Cert " + (i+1) + ":");
                System.out.println("    Subject: " + certs[i].getSubjectX500Principal().getName());
                System.out.println("    Issuer: " + certs[i].getIssuerX500Principal().getName());
            }
        }
    }
}

1

मैंने PEM के रूप में प्रमाणपत्रों को आउटपुट करने के लिए /programming/3313020/write-x509-certificate-into-pem-formatted-string-in-java से कुछ कोड जोड़े और db को निर्दिष्ट करने की आवश्यकता को हटा दिया। उपयोगकर्ता नाम या पासवर्ड (उन्हें प्रमाण पत्र प्राप्त करने की आवश्यकता नहीं है)।

इसका उपयोग करते हुए, मैं यह सत्यापित करने में सक्षम था कि PostgreSQL का पुनरारंभ दुर्भाग्य से एक नए प्रमाणपत्र पर स्विच करने के लिए आवश्यक लगता है।

जावा डेवलपर नहीं होने के कारण, निर्माण और चलाने के लिए मेरे कदम शायद इतने महान नहीं हैं, लेकिन वे काम करते हैं, इसलिए जब तक आप एक पोस्टग्रैडल जेडबीसी को पा सकते हैं

# locate postgresql | grep jar
/path/to/a/lib/postgresql-9.1-901-1.jdbc4.jar   <-- this one will do
...

संकलन करना:

javac -cp /path/to/a/lib/postgresql-9.1-901-1.jdbc4.jar ./ShowPostgreSQLCert.java

चलाने के लिए:

java -cp /path/to/a/lib/postgresql-9.1-901-1.jdbc4.jar:. ShowPostgreSQLCert 127.0.0.1

नमूना उत्पादन:

Cert 1:
    Subject: CN=...
    Issuer: CN=...
    Not Before: Fri Oct 21 11:14:06 NZDT 2016
    Not After: Sun Oct 21 11:24:00 NZDT 2018
-----BEGIN CERTIFICATE-----
MIIHEjCCBfqgAwIBAgIUUbiRZjruNAEo2j1QPqBh6GzcNrwwDQYJKoZIhvcNAQEL
...
IcIXcVQxPzVrpIDT5G6jArVt+ERLEWs2V09iMwY7//CQb0ivpVg=
-----END CERTIFICATE-----

Cert 2:
...

स्रोत:

import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;
import java.sql.Connection;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.postgresql.ds.PGSimpleDataSource;
import org.postgresql.ssl.WrappedFactory;

import javax.xml.bind.DatatypeConverter;
import java.security.cert.X509Certificate;
import java.io.StringWriter;

public class ShowPostgreSQLCert {
    public static void main(String[] args) throws Throwable {
        PGSimpleDataSource ds = new PGSimpleDataSource();
        if( args.length != 1 ) {
            System.out.println("Not enough arguments.");
            System.out.println("Usage: ShowPostgreSQLCert ServerName");
            System.exit(1);
        }
        ds.setServerName( args[0] );
        ds.setSsl(true);
        ds.setUser( "" );
        ds.setDatabaseName( "" );
        ds.setPassword( "" );
        ds.setSslfactory(DumperFactory.class.getName());
        try (Connection c = ds.getConnection()) { }
        catch (org.postgresql.util.PSQLException e) {
            // Don't actually want to login
        }
    }

    public static class DumperFactory extends WrappedFactory {
        public DumperFactory(String arg) throws GeneralSecurityException {
            SSLContext ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[] { new DumperTM() }, null);
            _factory = ctx.getSocketFactory();
        }
    }

    public static String certToString(X509Certificate cert) {
        StringWriter sw = new StringWriter();
        try {
            sw.write("-----BEGIN CERTIFICATE-----\n");
            sw.write(DatatypeConverter.printBase64Binary(cert.getEncoded()).replaceAll("(.{64})", "$1\n"));
            sw.write("\n-----END CERTIFICATE-----\n");
        } catch (java.security.cert.CertificateEncodingException e) {
            e.printStackTrace();
        }
        return sw.toString();
    }

    public static class DumperTM implements X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
        public void checkClientTrusted(X509Certificate[] certs, String authType) { }
        public void checkServerTrusted(X509Certificate[] certs, String authType) {
            for (int i=0; i<certs.length; ++i) {

                System.out.println("Cert " + (i+1) + ":");
                System.out.println("    Subject: " + certs[i].getSubjectX500Principal().getName());
                System.out.println("    Issuer: " + certs[i].getIssuerX500Principal().getName());
                System.out.println("    Not Before: " + certs[i].getNotBefore().toString());
                System.out.println("    Not After: " + certs[i].getNotAfter().toString());

                System.out.println(certToString(certs[i]));
            }
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.