Lors d’un précédent article sur Google BigQuery nous parlions de la data comme le nerf de la guerre dans la concurrence que se mènent les fournisseurs cloud.
Cette affirmation se base sur la logique suivante: Là où se trouve ma donnée, se trouveront les processus qui la crée ainsi que les calculs qui l'explorent.

Un nombre substantiel de services clouds sont donc proposés, chacun ayant LA particularité censée faire pencher le choix vers telle ou telle plateforme.
A ce titre BigQuery apparaît comme un modèle de complexité et d’innovation mis au service du plus grand nombre. En restant sur la Google Cloud Platform, nous trouverons d’autres services tout aussi innovants et complexes qui aux dires de Google vous permettront de créer l’avantage compétitif qui manque à votre business pour trouver la voie du succès. Pour autant, la réalité du monde de l’entreprise se veut plus terre à terre. Où mettre ma donnée existante, celle-là même qui permet à ma société d’exister depuis tant d'années? A cette question revient invariablement le besoin d’une base de données SQL. Il est d’ailleurs probable que ce soient ces questions basiques et non le côté bling bling de la Big Data et de l'intelligence artificielle qui motivent le choix d’une plateforme cloud.
En ayant récemment pratiqué Cloud SQL, j’ai constaté que la documentation relative aux connexions aux instances qui portent la base de données pourrait gagner en clarté. La documentation est complète mais éclatée sur plusieurs points d’entrées qui nuisent à sa compréhension. Pourtant les concepts sous-jacents sont simples. L'incompréhension de l’un de ces concepts vous fera prendre des décisions non optimales à votre besoin.
Cet article a pour but de rassembler les principaux points d’entrée à la compréhension de ce produit GCP.

Rappels sur Google Cloud SQL

Google Cloud SQL correspond au service managé de la GCP pour héberger une base de données. Il se décline en trois nuances, MySQL, PostgreSQL et SQLServer. L’adjectif managé est cependant quelque peu surfait et se nuance selon le point de vue que l’on prend.
Semi-managé serait plus adapté puisqu’il est nécessaire de créer les bases de données, les utilisateurs associés ainsi que les accès réseau, sujet de cet article. L’aspect managé prend son sens sur l’aspect VPC et haute disponibilité du service sur lequel repose l’instance Cloud SQL.
La gestion de la base de données en elle-même reste à la charge d’un DBA.

Enfin, rappelons que ce service n’est pas serverless et que les instances seront allumées en permanence faute d’action directe (manuelle ou automatique) de votre part. Cela peut induire une sous-utilisation non négligeable financièrement parlant et des outils comme Cloud Custodian y apportent des solutions.

La création de connections aux instances Cloud SQL

L’instance cloud SQL est sur un VPC contrôlé par Google. Vous n’y avez pas accès depuis votre cloud console autrement que pour y créer des connexions vers vos VPCs. Une instance se contacte par des IPs de deux sortes:

  • Une IP publique
    L’instance est accessible depuis internet mais nécessite quoi qu’il arrive une authentification pour s’y connecter. Deux possibilités:
    → Soit par l’usage du SQL proxy, à installer sur la machine hôte du processus qui cherche à se connecter sur la machine (mon ordinateur personnel, une VM, etc)
    → Soit via une identification par IP. La création de sources dite de confiance permet d’identifier des IPs ou plage d’IP de machine “autorisées” à se connecter aux bases de données portées par l’instance Cloud SQL.
    Bien que le qualificatif "publique" ait mauvaise presse dans le monde de l’IT, cela n’est pas synonyme dans le cadre d’un service GCP de mauvaise pratique. Au contraire dans une approche Zero-Trust Security Network, nous dépassons ce clivage privé/publique pour se concentrer sur l'authentification mutuelle entre un émetteur d'une requête et son récepteur.
  • Une IP privée
    Dans ce cas, la connexion doit nécessairement venir d'un environnement de confiance. Un VPC GCP n’est pas par défaut un tel environnement. Il faut créer une connexion privée via une “VPC peering connection” pour avoir ce statut.
    Notons toutefois que l’activation d’une IP privé va créer par défaut une telle connexion avec votre VPC “default”. Ce sur quoi vous pouvez revenir ensuite.
    Une IP privée, une fois attribuée, n’est pas révocable et il est nécessaire de supprimer le peering pour révoquer un accès d’un VPC (et donc celui de toutes les machines associées).
La connexion privée


En rouge apparaissent le VPC cloud SQL et son projet GCP dont on peut clairement voir le côté managé par Google. Enfin, notons que IP publique et privée peuvent coexister.

Note: dans le cas d’un shared VPC, la création de la connexion se fera depuis le projet hôte. Rien d’autre de particulier.

Cloud SQL Proxy

Il s’agit d’un binaire Go open-source à installer sur la machine hôte du processus qui doit accéder à l’instance SQL. Pour cela il se connecte à l’instance soit via une socket Unix (non possible sous Windows) soit par une connexion TCP. Dans les deux cas, la connexion utilisera le protocole TLS avec un self-signed certificat de l’instance cloud SQL afin de chiffrer les échanges.
L’authentification à une instance se fait via un keyfile de compte de service ou les credentials locaux, créés avec l'outil gcloud. Cette intégration avec Gcloud est très pratique pour les développements locaux car elle permet une détection automatique des instances Cloud SQL accessibles à votre profil actif.
Il est nécessaire de choisir l’un des rôles suivants pour établir une connexion via le proxy :

  • Cloud SQL Client
  • Cloud SQL Editor
  • Cloud SQL Admin

Pour avoir plus de contrôle sur la ou les instances Cloud SQL auxquelles vous souhaitez vous connecter, cette page vous décrit les différentes possibilités.
Un dernier point concernant cet outil. En termes de connexion, il est indifférent au type d’IP derrière l’instance Cloud SQL et utilise par défaut la publique. Le proxy résout la question de l'autorisation et la sécurisation de la connexion, pas celle de sa création. Cette dernière est adressée par le choix d’une IP publique et/ou privée ainsi que la création de connexion privée entre VPC (dans le cas d’une IP privée).
Ne mélangeons donc pas les sujets. le SQL proxy répond à un besoin d’authentification et de sécurisation d’une connexion à une instance Cloud SQL et non à la possibilité de cette connexion.

Note à propos de l’ “authentification IAM” sous Postgre
Sous sa version PostgreSQL, il est possible d’associer les GRANT d’utilisateurs de bases de données et leurs tables à des profils IAM GCP.
Cela facilite l’authentification à la base de donnée (et non l’instance SQL, gérée par le proxy) qui peut se faire par access token plutôt que user/mdp.

Cloud SQL proxy, bien que se basant sur l’IAM pour déterminer le bien fondé d’une connexion depuis une machine cliente, n’est pas encore compatible avec le Cloud SQL IAM permission sur Postgre. Cela oblige à faire une double authentification alors qu’une seule pourrait suffire.
Notons que si la limitation est mentionnée dans la documentation il n’est pas impossible de voir s’effacer cette dernière dans un futur proche.

Considération de sécurité: IP publique VS IP privée

Restreindre l’accès d’une instance Cloud SQL à une IP privée ne la sécurise pas par nature. Au contraire, l’accès devient possible pour des instances d’un réseau de confiance, qui lui peut être compromis si mal sécurisé.
Une IP publique, en imposant l’usage du cloud SQL proxy, impose également une authentification basée sur l’identité d’utilisateur ou de compte de service. C’est le principe de l’approche Zero-trust security Network. L’accès à une ressource peut être exposé sur le net, mais tout accès doit y être authentifié contrairement à l’approche d’une confiance accordée à des machines à partir du moment où elles font partie de mon réseau.
On remarquera à ce titre que Google IAP (présenté dans un précédent article) et cloud SQL Proxy ont de fortes similitudes fonctionnelles. Le terme “proxy” met déjà la puce à l’oreille.  
Cela facilite grandement les accès aux ressources (de n’importe où) sans pour autant diminuer leur sécurisation.

Seule une mauvaise pratique demeure: l’identification par IP (IP whitelisting).
Une IP pouvant en cacher des centaines d’autres cachées derrière un NAT par exemple.
Retenons qu’exposer une IP publique (géré par GCP) n’est pas une faille de sécurité si l’on impose l’usage du cloud SQL proxy. A l’inverse, l’usage d’une IP privé n’est pas secured by design et impose des contraintes d’accès difficilement compatibles avec du développement sur machine de développeur.
Un juste milieu serait de réserver les IPs privés pour de la production, là où des instances de développement pourraient exposer des IPs publique.
Passer par une IP privée est par ailleurs un gage de latence de connexions aux instance SQL réduite dans la mesure où l'on passe exclusivement par le réseau Google et non l'internet public.

Exemple de connexion depuis d’autres services GCP

Voyons quelques exemples testés empiriquement de connexions à une instance Cloud SQL depuis d’autres services GCP. L’instance en question expose une IP publique et une IP privée pour tester les différents cas.

Compute Engine (qu’on peut généraliser à d’autres type de compute tel GKE) :

  • En créant une instance compute Engine (peut importe la région), penser à y activer l’API cloud SQL
  • Installer sur la VM le proxy cloud SQL
  • Donner les rôles SQL nécessaires au compte de service qui représente l’instance compute engine (ou que vous utilisez spécifiquement avec le proxy cloud SQL)
  • Dans le cas où il y a  uniquement une IP privée sur l’instance Cloud SQL, l’instance compute engine doit faire partie d’un VPC bénéficiant d’un peering avec le réseau de l'instance cloud SQL. L’accès se fait ensuite au choix avec le proxy ou directement en pointant l’IP privé dans ces paramètres de connexion.

Note 1: les accès VPCs ne sont pas transitifs. Considérons des VPCs {A,B,C}. B contient deux connexions privées vers A et C respectivement. Pour autant, les instances hébergées sur A et C ne pourront pas communiquer.
Pour des raisons de sécurité, nous pouvons dire qu’il s’agit d’une feature et non d’un bug.

Note 2: Une instance compute Engine peut servir de bastion à une connexion sur une instance SQL imposant une IP privée. La connexion au bastion depuis une machine distante pouvant s’authentifier et se sécuriser avec Google IAP.

Service Serverless: AppEngine

  • AppEngine utilise le cloud SQL proxy par défaut à travers des sockets UNIX situées au niveau du chemin /cloudsql de chaque instance qui portent comme nom la “connection_name” de l’instance visée. Il y en a autant que d’instances SQL accessibles par le compte de service associé à AppEngine.
  • L’authentification est portée par le compte de service associé au projet AppEngine et présent dans la console IAM.
  • Il est possible de bypasser cette connexion par socket en précisant directement l’IP (public ou privée) et le port.
  • Dans le cas d’une IP privée, l’instance Appengine ne pourra se connecter à l’instance SQL que si un “VPC serverless access” est configuré pour  pointer vers un VPC du même GCP projet bénéficiant d’un VPC peering avec le VPC contenant l’instance SQL.
    Il ne faut pas oublier de préciser dans son fichier app.yaml de préciser d’utiliser cet accès.

vpc_access_connector:
  name: "projects/[PROJECT_ID]/locations/[REGION]/connectors/[CONNECTOR_NAME]"

Note 1: Le dernier point est clairement une exception à la règle de la non transitivité des accès puisque le réseau hébergeant les instances App Engine bénéficiera de la connexion privée de notre VPC lié au réseau de l’instance Cloud SQL. Cela n’est en réalité pas choquant outre mesure car le VPC relatif à App Engine est totalement contrôlé par Google et on peut raisonnablement penser qu’il est sécurisé.

Note 2: Lorsque l’instance Cloud SQL n’expose qu’une IP privée, il n’est pas possible d’utiliser la socket provisionnée sur App Engine et il faudra passer par l’IP directement. La documentation ne dit rien à ce sujet, cependant une hypothèse peut être la suivante:
Pour que le SQL proxy puisse contacter l’IP privée, il faut au moment de créer une socket préciser l’option “-ip_address_types=PRIVATE”. Au vu du comportement observé on peut penser que cette option n’est pas précisée sur une instance App Engine.  

Les résultats observés sous forme d’un tableau:


IP publique

IP privée

Compute Engine

Accessible par whitelisting d’IP ou le cloud SQL proxy

Inaccessible

Compute Engine avec une connexion privée vers le réseau hébergeant Cloud SQL

Accessible par whitelisting d’IP ou le cloud SQL proxy

Accessible par IP ou le cloud SQL proxy

App Engine

Accessible par Cloud SQL proxy par défaut

Inaccessible

App Engine avec VPC serverless access

Accessible par Cloud SQL proxy par défaut

Connexion par IP seulement et besoin de préciser l’accès VPC dans app.yaml

Récapitulons

  1. L’instance SQL est hébergée sur un VPC contrôlé par Google

2. Pour y accéder depuis des machines hébergées sur Internet, il faut une IP publique. Elle est accédé via un proxy ou des machines autorisées par IP. Une IP privée sera inaccessible (proxy ou non).



3. Si pour des raisons de conformité à la sécurité d’une entreprise, l’IP publique n’est pas acceptée, une IP privée peut servir de point d’accès. Elle ne sera accessible que depuis des VPC sur lequel existe un peering avec le VPC hébergeant l’instance SQL. Le proxy peut aussi accéder aux IP privées.



4. Dans le cas de ressources serverless, un VPC serverless access  vers un réseau de confiance permettra de contacter l’instance SQL



Conclusion

Lorsque l’on considère la connexion à une base de donnée Cloud SQL il y a trois questions à se poser:

  1. Comment créer cette connexion ? Et nous avons vu que le choix se raisonne à travers l’exposition d’une IP et la création de connexion privée via du Network peering.
  2. Comment autoriser la connexion ? Plusieurs méthodes encore, allant de la moins optimale avec l’autorisation d’IP à des pratiques plus sécurisées avec le Cloud SQL proxy.
  3. Comment l’authentifier ? En général on se basera sur le classique user/mdp, mais il faut avoir en tête que la version Postgre permet une authentification par access token lié à l’IAM GCP.

Les combinaisons des différents choix qui s’offrent à nous dépendent largement de la politique d’une entreprise mais aussi de la compréhension des principes derrière les choix possibles. C’est à cette compréhension que cet article s’est proposé d’aider.