PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Configura un `DataSource` per connettersi a un server Postgres gestito su Digital Ocean con crittografia SSL/TLS

Ottenere un DataSource attuazione

Di solito il tuo driver JDBC fornisce un'implementazione di javax.sql.DataSource .

Per maggiori dettagli, vedere la mia risposta a una domanda simile.

PGSimpleDataSource

Se si utilizza il driver JDBC da jdbc.postgresql.org , puoi utilizzare org.postgresql.ds.PGSimpleDataSource class come il tuo DataSource attuazione.

Istanziare un oggetto di tipo PGSimpleDataSource , quindi chiama i metodi setter per fornire tutte le informazioni necessarie per connettersi al server del database. La pagina Web sul sito DigitalOcean elenca tutte queste informazioni per la tua particolare istanza di database.

Fondamentalmente questo:

PGSimpleDataSource dataSource = new PGSimpleDataSource();

dataSource.setServerName( "your-server-address-goes-here" );
dataSource.setPortNumber( your-port-number-goes-here );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "doadmin" );
dataSource.setPassword( "your-password-goes-here" );

Nomi server multipli e numeri di porta

Sfortunatamente, la versione singolare dei metodi setServerName e setPortNumber sono deprecati. Anche se fastidioso, dovremmo probabilmente usare la versione plurale di quei metodi (setServerNames &setPortNumbers ) che ciascuno accetta un array. Popoliamo una coppia di array a elemento singolo, String[] e int[] , con l'indirizzo del nostro server e numero di porta usando i valori letterali dell'array:

  • { "il tuo-indirizzo-server-va-qui" }
  • { il tuo-numero-porta-va-qui }
PGSimpleDataSource dataSource = new PGSimpleDataSource();

String[] serverAddresses = { "your-server-address-goes-here" };
dataSource.setServerNames( serverAddresses );
int[] serverPortNumbers = { your-port-number-goes-here };
dataSource.setPortNumbers( serverPortNumbers );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "doadmin" );
dataSource.setPassword( "your-password-goes-here" );

Crittografia SSL/TLS

Infine dobbiamo aggiungere le informazioni per la crittografia SSL/TLS affrontata nella domanda.

Ironia della sorte, non chiama setSsl( true )

Penseresti che chiameremmo setSsl metodo e passare true . Ma no. Sebbene sia controintuitivo, impostarlo su true causerà il fallimento dei tentativi di connessione. Non so perché è così. Ma tentativi ed errori mi hanno portato a evitare quella chiamata.

Certificato CA

Affinché l'app Java lato client possa avviare la connessione SSL/TLS, il driver JDBC deve avere accesso al certificato CA utilizzato da Digital Ocean. Nella pagina di amministrazione di Digital Ocean, fai clic su Download CA certificate link per scaricare un piccolo file di testo. Quel file si chiamerà ca-certificate.crt .

Dobbiamo inviare il testo di quel file al nostro driver JDBC come una stringa. Procedi come segue per caricare il file in una stringa di testo.

// Get CA certificate used in TLS connections.
Path path = Paths.get( "/Users/basilbourque/Downloads/ca-certificate.crt" );
String cert = null;
try
{
    cert = Files.readString( path , StandardCharsets.UTF_8 );
    System.out.println( "cert = " + cert );
}
catch ( IOException ex )
{
    throw new IllegalStateException( "Unable to load the TLS certificate needed to make database connections." );
}
Objects.requireNonNull( cert );
if ( cert.isEmpty() ) {throw new IllegalStateException( "Failed to load TLS cert." ); }

Passa il testo del certificato CA al tuo driver JDBC con una chiamata a DataSource::setSslCert . Nota che non lo siamo chiamando setSslRootCert . Non confondere i due metodi con nomi simili.

dataSource.setSslCert( cert );

Test della connessione

Infine, possiamo utilizzare il DataSource configurato oggetto per stabilire una connessione al database. Quel codice sarà simile a questo:

// Test connection
try (
        Connection conn = dataSource.getConnection() ;
        // …
)
{
    System.out.println( "DEBUG - Postgres connection made. " + Instant.now() );
    // …
}
catch ( SQLException e )
{
    e.printStackTrace();
}

Codice esempio completo

Mettendo tutto insieme, vedi qualcosa del genere.

// Get CA certificate used in TLS connections.
Path path = Paths.get( "/Users/basilbourque/Downloads/ca-certificate.crt" );
String cert = null;
try
{
    cert = Files.readString( path , StandardCharsets.UTF_8 );
    System.out.println( "cert = " + cert );
}
catch ( IOException ex )
{
    throw new IllegalStateException( "Unable to load the TLS certificate needed to make database connections." );
}
Objects.requireNonNull( cert );
if ( cert.isEmpty() ) {throw new IllegalStateException( "Failed to load TLS cert." ); }

// PGSimpleDataSource configuration
PGSimpleDataSource dataSource = new PGSimpleDataSource();

String[] serverAddresses = { "your-server-address-goes-here" };
dataSource.setServerNames( serverAddresses );
int[] serverPortNumbers = { your-port-number-goes-here };
dataSource.setPortNumbers( serverPortNumbers );
dataSource.setSslCert( cert );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "doadmin" );
dataSource.setPassword( "your-password-goes-here" );

// Test connection
try (
Connection conn = dataSource.getConnection() ;
// …
)
{
System.out.println( "DEBUG - Postgres connection made. " + Instant.now() );
// …
}
catch ( SQLException e )
{
e.printStackTrace();
}

Fonte attendibile

Quando crei la tua istanza Postgres su DigitalOcean.com, ti verrà offerta la possibilità di limitare le richieste di connessione in entrata. È possibile specificare un singolo indirizzo IP previsto dal server Postgres, una "fonte attendibile" nel gergo di Digital Ocean. Tutti gli hacker che tentano di connettersi al tuo server Postgres verranno ignorati poiché provengono da altri indirizzi IP.

Suggerimento:fare clic all'interno del campo di immissione dati per questo numero di indirizzo IP in modo che la pagina Web rilevi e offra automaticamente l'indirizzo IP attualmente utilizzato dal browser Web. Se stai eseguendo il tuo codice Java dallo stesso computer, utilizza lo stesso numero IP come unica fonte attendibile.

Altrimenti, digita l'indirizzo IP del computer che esegue il codice JDBC Java.

Altri problemi

Non ho affrontato elaborazioni, come protocolli di sicurezza adeguati da utilizzare per gestire il file del certificato CA, o come esternalizzare le informazioni di connessione ottenendo un DataSource oggetto da un JNDI server anziché hard-coding . Ma si spera che gli esempi sopra ti aiutino a iniziare.