PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Configurez un `DataSource` pour vous connecter à un serveur Postgres géré sur Digital Ocean avec cryptage SSL/TLS

Obtenir un DataSource mise en œuvre

Généralement, votre pilote JDBC fournit une implémentation de javax.sql.DataSource .

Pour plus de détails, voir ma réponse à une question similaire.

PGSimpleDataSource

Si vous utilisez le pilote JDBC de jdbc.postgresql.org , vous pouvez utiliser le org.postgresql.ds.PGSimpleDataSource class comme votre DataSource mise en œuvre.

Instancier un objet de type PGSimpleDataSource , puis appelez les méthodes setter pour fournir toutes les informations nécessaires pour vous connecter à votre serveur de base de données. La page Web du site DigitalOcean répertorie toutes ces informations pour votre instance de base de données particulière.

En gros ceci :

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" );

Plusieurs noms de serveurs et numéros de port

Malheureusement, la version singulière des méthodes setServerName et setPortNumber sont obsolètes. Bien qu'ennuyeux, nous devrions probablement utiliser la version plurielle de ces méthodes (setServerNames &setPortNumbers ) qui prennent chacun un tableau. Nous remplissons une paire de tableaux à un seul élément, String[] et int[] , avec l'adresse de notre serveur et numéro de port en utilisant des littéraux de tableau :

  • { "votre-adresse-de-serveur-va-ici" }
  • { votre-numéro-de-port-va-ici }
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" );

Cryptage SSL/TLS

Enfin, nous devons ajouter des informations sur le cryptage SSL/TLS abordé dans la question.

Ironiquement, ne faites pas appelez setSsl( true )

Vous penseriez que nous appellerions le setSsl méthode et passez true . Mais non. Bien que contre-intuitif, le définir sur true entraînera l'échec de vos tentatives de connexion. Je ne sais pas pourquoi. Mais les essais et erreurs m'ont amené à éviter cet appel.

Certificat CA

Pour que votre application Java côté client initie la connexion SSL/TLS, le pilote JDBC doit avoir accès au certificat CA utilisé par Digital Ocean. Sur votre page d'administration Digital Ocean, cliquez sur Download CA certificate lien pour télécharger un petit fichier texte. Ce fichier sera nommé ca-certificate.crt .

Nous devons transmettre le texte de ce fichier à notre pilote JDBC sous forme de chaîne. Procédez comme suit pour charger le fichier dans une chaîne de texte.

// 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." ); }

Transmettez ce texte de certificat CA à votre pilote JDBC avec un appel à DataSource::setSslCert . Notez que nous ne sommes pas appelant setSslRootCert . Ne confondez pas les deux méthodes portant le même nom.

dataSource.setSslCert( cert );

Tester la connexion

Enfin, nous pouvons utiliser le DataSource configuré objet pour établir une connexion à la base de données. Ce code ressemblera à ceci :

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

Exemple de code complet

En mettant tout cela ensemble, voyez quelque chose comme ça.

// 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();
}

Source fiable

Lors de la création de votre instance Postgres sur DigitalOcean.com, il vous sera proposé de restreindre les demandes de connexion entrantes. Vous pouvez spécifier une adresse IP unique attendue par le serveur Postgres, une "source de confiance" dans le jargon de Digital Ocean. Tous les pirates tentant de se connecter à votre serveur Postgres seront ignorés car ils proviennent d'autres adresses IP.

Astuce :Cliquez dans le champ de saisie de données pour ce numéro d'adresse IP pour que la page Web détecte et propose automatiquement l'adresse IP actuellement utilisée par votre navigateur Web. Si vous exécutez votre code Java à partir du même ordinateur, utilisez ce même numéro IP comme source unique de confiance.

Sinon, saisissez l'adresse IP de l'ordinateur exécutant votre code Java JDBC.

Autres problèmes

Je n'ai pas abordé les détails, tels que les protocoles de sécurité appropriés à utiliser pour gérer votre fichier de certificat CA, ou tels que l'externalisation de vos informations de connexion en obtenant un DataSource objet d'un JNDI serveur plutôt que codage en dur . Mais j'espère que les exemples ci-dessus vous aideront à démarrer.