Comment rendre la base de données (ou une partie) accessible à un processeur de données cloud ?

Je souhaitais utiliser des services ETL comme Stitch Data ou Skyvia pour intégrer différentes sources de données (y compris ma base de données Discourse), mais une personne de Skyvia m’a indiqué que cela n’était pas possible :

Skyvia peut se connecter à PostgreSQL via SSH, mais il n’est pas possible de s’y connecter lorsqu’il est contenu dans un conteneur Docker alors que le serveur SSH n’est pas dans le conteneur mais devant celui-ci.

Voici leurs exigences pour se connecter à PostgreSQL.

Existe-t-il une solution de contournement évidente ?

Vous pourriez activer SSH dans le conteneur Discourse (sur un port non standard) et permettre ainsi aux utilisateurs de s’y connecter. Je pense qu’il existe peut-être un exemple dans le répertoire d’exemples de Discourse_docker.

3 « J'aime »

Merci, Jay. J’ai fini par utiliser docker-ssh avec une authentification par clé publique. :+1:

2 « J'aime »

Il semble que je manque d’un concept clé, car je parviens à me connecter via SSH avec le port personnalisé, puis à exécuter su postgres -c 'psql discourse' sans problème. Tout fonctionne avec cette approche en deux étapes, mais je pense que ce dont j’ai besoin pour me connecter directement via pgAdmin (par exemple) est légèrement différent.

Voici la commande que j’utilise pour exposer un port personnalisé :

docker run -d -p 2222:22 \
        -v /var/run/docker.sock:/var/run/docker.sock \
        -v ~/.ssh/authorized_keys:/authorized_keys \
        --name my-sshd \
        -e FILTERS={\"name\":[\"^/app$\"]} -e AUTH_MECHANISM=publicKey \
        -e AUTHORIZED_KEYS=/authorized_keys \
        jeroenpeeters/docker-ssh

Ce qui me permet ensuite de faire cela directement (sans lancer le conteneur Docker via launcher enter app) :

ssh whatever@host -p 2222
su postgres -c 'psql discourse'

J’ai essayé plusieurs choses, mais sans succès. J’ai l’impression qu’il devrait y avoir un moyen d’exécuter ssh whatever@host -p XXXX et de me connecter directement à la base de données (ce qui est probablement ce que pgAdmin attend).

Vous ne parvenez pas à vous connecter ou rencontrez un problème d’autorisations ?

Je peux me connecter en ligne de commande via SSH, puis via psql. Je ne parviens pas à me connecter via pgAdmin.

1 « J'aime »

Vous devez exposer directement le port PostgreSQL pour pouvoir vous connecter via pgAdmin.

Dans le fichier app.yml, près du début, vous voyez que les ports 80 et 443 sont ouverts. Vous pouvez ajouter une autre ligne pour le port 5432 de PostgreSQL.

Cela dit, c’est presque certainement une très mauvaise idée. La base de données est passée de l’acceptation de connexions uniquement locales à une exposition complète sur Internet.

Si tout ce dont vous avez besoin est quelques rapports occasionnels, télécharger certains fichiers CSV depuis l’Explorateur de données et les charger dans votre outil préféré peut suffire. Vous pouvez également télécharger des sauvegardes de Discourse (sans les fichiers joints), qui sont au format standard de dump PostgreSQL. Avec cela en main, vous pouvez les restaurer sur une instance PostgreSQL locale pour analyse.

1 « J'aime »

Merci, Rafael

J’ai fait cela et reconstruit le conteneur. Mais cela ne fonctionne toujours pas (j’ai l’adresse IP réelle au lieu de XX.XX.XX.XX)

Et dans l’onglet Tunnel SSH :

Voici l’erreur que j’obtiens :

À ce sujet, je comprends que c’est une couche de protection en moins, mais cela nécessite toujours d’avoir la clé privée SSH, n’est-ce pas ?

Si vous ajoutez 5432 dans app.yml, il est exposé directement, sans avoir besoin du tunnel SSH.

Je ne peux pas donner de conseils concernant le tunnel SSH de pgAdmin, car je ne l’ai jamais utilisé. Je suppose qu’il attend que le port écoute les connexions locales, de sorte qu’il n’a pas besoin d’être exposé à Internet.

Essayez :

expose:
  - "80:80"
  - "443:443"
  - "5432"
1 « J'aime »

Mais il n’y a pas de mot de passe PostgreSQL car cela nécessite d’être superutilisateur : le fichier pg_hba.conf a les permissions de connexion “local” définies sur “peer”, ce qui dépend de l’utilisateur UNIX, ce qui nécessite une connexion via SSH, n’est-ce pas ?

Cela ne fonctionne pas : psql -h XX.XX.XX.XX -p 5432 -U postgres -d discourse

Vous pouvez vous connecter à psql en tant que superutilisateur

./launcher enter app
su postgres
psql

et créer l’utilisateur nécessaire avec les permissions requises pour vos rapports.

Bon, je n’ai aucun problème pour me connecter depuis le conteneur Docker de l’application. Mon problème est de me connecter directement à la base de données PostgreSQL depuis ma machine locale (pour pouvoir utiliser pgAdmin) ou depuis un processeur de données cloud comme Stitch. Ces deux solutions attendent une adresse IP d’hôte et des identifiants SSH, mais je n’ai pas réussi à les faire fonctionner (j’obtiens l’erreur que j’ai montrée plus haut).

La seule chose que j’ai pu faire est d’utiliser docker-ssh pour accéder directement au conteneur Docker de l’application (via une clé publique) depuis mon ordinateur local (sans faire launcher enter app), mais je dois toujours exécuter su postgres 'psql discourse' pour accéder à la base de données. Je suppose que c’est le problème avec pgAdmin/Stitch : ils attendent une connexion directe.

Avez-vous essayé de créer un nouveau PostgreSQL avec un mot de passe et de le fournir à votre service ?

Oui, ils ont une procédure assez longue.

Mais j’ai le même problème en utilisant simplement pgAdmin depuis mon ordinateur local.

Je pense que le guide Comment passer d’un conteneur autonome à des conteneurs web et de données séparés contient des instructions pour définir un mot de passe.

De plus, je pense que vous pourriez lier le port PostgreSQL uniquement à 127.0.0.1.

expose:
  - "80:80"
  - "443:443"
  - "127.0.0.1:5432:5432"
1 « J'aime »

J’ai décidé de faire un pas en arrière pour voir si je peux me connecter à la base de données sans exposer de ports. :grin:

Si j’entre dans le conteneur, je vois ceci :

# netstat -lp | grep postgres
tcp        0      0 0.0.0.0:postgresql      0.0.0.0:*               LISTEN      -
tcp6       0      0 [::]:postgresql         [::]:*                  LISTEN      -
unix  2      [ ACC ]     STREAM     LISTENING     263612292 -                    /var/run/postgresql/.s.PGSQL.5432

Si je sors du conteneur et que je suis sur mon serveur distant (pas encore sur mon ordinateur local), ne devrais-je pas pouvoir me connecter en utilisant ceci ?

/var/discourse# psql -h localhost -d discourse -U postgres

Le problème est que je reçois une invite de mot de passe. Comme l’utilisateur postgres n’en a pas, j’ai essayé de créer un autre utilisateur et de lui attribuer un mot de passe :

CREATE USER whatever_user WITH ENCRYPTED PASSWORD '<whatever password>';
GRANT CONNECT ON DATABASE discourse TO whatever_user;
GRANT USAGE ON SCHEMA public TO whatever_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO whatever_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO whatever_user;

J’ai ajouté une ligne pour cet utilisateur avec md5 dans pg_hba.conf et redémarré PG avec service postgresql restart

# Database administrative login by Unix domain socket
local   all             postgres                                peer
local   all             whatever_user                      md5

Cependant, lorsque j’essaie de me connecter depuis le serveur distant, je reçois un échec d’authentification :

# psql -h localhost -d discourse -U whatever_user
Password for user whatever_user:
psql: FATAL:  password authentication failed for user "whatever_user"
FATAL:  password authentication failed for user "whatever_user"

Qu’est-ce que je rate ? J’essaie au moins de pouvoir me connecter à la base de données depuis le même serveur. L’étape 2 consisterait à faire la même chose en utilisant un tunnel SSH, mais je suppose que je dois d’abord régler l’étape 1. Toute aide est appréciée.

Ok. J’ai enfin trouvé la solution :tada:

J’ai remplacé ceci :

par ceci - "127.0.0.1:5433:5432" car j’avais une erreur indiquant que le port était déjà utilisé.

J’ai reconstruit le conteneur et vérifié que le port était bien ouvert :

$ sudo docker ps
CONTAINER ID        IMAGE                           COMMAND             CREATED             STATUS              PORTS                      NAMES
whatever_id        local_discourse/app             "/sbin/boot"        20 minutes ago      Up 20 minutes       127.0.0.1:5433->5432/tcp   app

Je peux maintenant créer un tunnel SSH et me connecter depuis mon serveur distant en utilisant un utilisateur avec mot de passe :

# créer le tunnel (vous pouvez aussi utiliser ssh -f pour l'exécuter en arrière-plan)
ssh -v -N -L 5433:localhost:5433 ADRESSE_IP_SERVEUR

# se connecter dans un autre onglet et entrer le mot de passe
psql -h localhost -d discourse -U whatever_user -p 5433

Si quelqu’un essaie de faire cela et rencontre des problèmes, faites-le-moi savoir.

4 « J'aime »