Présentation de l’architecture du serveur: diffusion de contenu à partir d’AWS S3 à l’aide du serveur proxy inverse ou du serveur Apache de Nginx

L’objective de cette question est de comprendre la stratégie lors de la conception de l’architecture côté serveur.

Cas d’utilisation: Je veux créer un serveur http pour une application qui permet aux utilisateurs de télécharger et de télécharger du contenu multimédia (images, vidéos, etc.). Un grand nombre d’utilisateurs simultanés (environ 50 000) doivent télécharger / télécharger le contenu.

Tout le contenu sera stocké sur le compartiment AWS S3. Les informations concernant le compartiment S3, à savoir le nom du compartiment et les en-têtes d’authentification, doivent être masquées par l’utilisateur. Comme il existe plusieurs options de contrôle d’access ( AWS-ACL ) pour le compartiment S3, il serait préférable de ne pas rendre le compartiment disponible pour All_Users (utilisateurs authentifiés et anonymes). Je ne veux pas exposer le contenu dans le domaine public.

Requêtes

  • Puisque je souhaite masquer AWS S3 auprès des utilisateurs, je devrai utiliser un serveur Web ou un proxy inverse. J’ai parcouru plusieurs ressources qui comparent Apache vs Nginx. Étant donné que le serveur doit fournir un contenu statique de S3 à un nombre élevé d’utilisateurs simultanés, Nginx semble être une meilleure option. N’est-ce pas ??

  • La définition du niveau de contrôle d’access sur S3 vers ALL_USERS (vers des utilisateurs authentifiés et anonymes) compromet-elle la confidentialité des données? Si j’utilise le proxy inverse, l’utilisateur n’a aucun moyen de déterminer les URL du compartiment S3. Les données sont-elles sûres et privées?

  • Cependant, si le compartiment S3 est uniquement disponible pour les utilisateurs authentifiés, le proxy inverse nginx fonctionnera-t-il? Je suis passé par Nginx Reverse Proxy pour S3 . Pour que Nginx fonctionne en tant que proxy inverse, une URL pré-signée doit être préparée. Le délai d’expiration de l’URL pré-signé est encore une décision délicate. Est-il judicieux de définir un délai d’expiration énorme pour l’URL pré-signé? Cela compromet-il la sécurité ou la confidentialité des données (similaire au contrôle d’access s3 à ALL_USERS)? Si oui, existe-t-il un moyen d’inverser la demande de proxy vers une URL pré-signée générée dynamicment (avec un délai d’expiration court) via nginx uniquement?

Toute information et ressource pour consolider ma compréhension sera vraiment utile.

La définition du niveau de contrôle d’access sur S3 vers ALL_USERS (vers des utilisateurs authentifiés et anonymes) compromet-elle la confidentialité des données?

Absolument. Ne le fais pas

Si j’utilise le proxy inverse, l’utilisateur n’a aucun moyen de déterminer les URL du compartiment S3. Les données sont-elles sûres et privées?

Théoriquement, ils ne peuvent pas le déterminer, mais que se passe-t-il si un message d’erreur ou une mauvaise configuration fuit les informations? C’est la sécurité par l’obscurité , qui ne vous donne rien d’autre qu’un faux sentiment de sécurité. Il y a toujours une meilleure façon.

Les informations concernant le compartiment S3, à savoir le nom du compartiment et les en-têtes d’authentification, doivent être masquées par l’utilisateur.

Le mécanisme d’authentification de S3, avec des URL signées, est conçu de manière à ce qu’il ne soit pas dangereux de l’exposer à l’utilisateur. La seule chose secrète est votre clé secrète AWS, que vous ne noterez pas dans une URL signée. Il ne peut pas non plus être raisonnablement inversé, et une URL signée n’est valable que pour la ressource et l’action autorisées par la signature.

Signer des URL et les présenter à l’utilisateur ne pose pas de risque pour la sécurité, même s’il est vrai que vous ne souhaitez peut-être pas le faire pour d’autres raisons. Je le fais régulièrement – en signant une URL pendant le rendu d’une page, avec un délai d’expiration relativement long, ou en signant une URL et en redirigeant un utilisateur vers l’URL signée en cliquant sur un lien vers mon serveur d’application (ce qui valide leur autorisation d’accéder à la ressource, puis retourne une URL signée avec un délai d’expiration très court, par exemple 5 à 10 secondes, l’expiration pouvant se produire pendant un téléchargement sans causer de problème – la signature ne doit pas expirer avant la demande à S3 est acceptée).

Cependant, si vous voulez utiliser la route proxy (ce qui, en plus de ce qui précède, est quelque chose que je fais aussi dans mes systèmes), il existe un moyen beaucoup plus simple que ce que vous envisagez: la stratégie de compartiment peut être configurée pour autoriser permissions spécifiques à accorder en fonction des adresses IP source … de vos serveurs.

Voici une politique (assainie) prise directement depuis l’un de mes seaux. Les adresses IP proviennent de la RFC-5737 pour éviter la confusion que provoqueraient les adresses IP privées dans cet exemple.

Ces adresses IP sont des adresses IP publiques … ce sont vos adresses IP élastiques attachées à vos serveurs Web ou, de préférence, aux instances NAT utilisées par les serveurs Web pour leurs requêtes sortantes.

{ "Version": "2008-10-17", "Id": "Policy123456789101112", "Statement": [ { "Sid": "Stmt123456789101112", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::example-bucket/*", "Condition": { "IpAddress": { "aws:SourceIp": [ "203.0.113.173/32", "203.0.113.102/32", "203.0.113.52/32", "203.0.113.19/32" ] } } } ] } 

Qu’est-ce que cela fait? Si une demande arrive à S3 à partir de l’une des adresses IP répertoriées, l’autorisation GetObject est accordée au demandeur. Avec un proxy, l’adresse IP de votre proxy sera l’adresse IP vue par S3, et la demande sera accordée si elle correspond à la stratégie de compartiment, permettant à vos proxys de récupérer des objects à partir de S3 sans autoriser le rest d’Internet. les informations d’identification sont présentées, par exemple avec une URL signée. Cette politique ne “refuse” rien directement, car le refus est implicite. Surtout, ne chargez pas vos objects avec la liste de contrôle d’access à public-read , car cela permettrait à quiconque de télécharger l’object. La liste de contrôle private access private par défaut fonctionne parfaitement pour cette application.

S3 peut accorder des permissions comme celle-ci en fonction d’autres critères, tels que l’en Referer: tête Referer: vous pouvez en trouver des exemples en ligne, mais ne le faites pas . Faire confiance à ce que le navigateur Web signale comme page de référence est un mécanisme de sécurité extrêmement faible et primitif qui ne fournit pratiquement aucune protection réelle – les en-têtes sont incroyablement simples à usurper. Ce type de filtrage n’est vraiment utile que pour les fainéants qui créent des liens vers votre contenu. L’adresse IP source est totalement différente, car elle n’est pas stockée dans un en-tête de couche 7 et ne peut pas être facilement usurpée.

Etant donné que S3 n’interagit qu’avec Internet via le protocole TCP, vos adresses source – même si vous saviez comment vous avez permis au compartiment de faire confiance à ces adresses – ne peuvent pas être usurpées de manière concrète, car cela signifierait violer la sécurité de l’infrastructure réseau IP principale d’AWS – TCP exige que la machine d’origine soit accessible à travers les limites de sous-réseau par l’adresse IP source utilisée, et le réseau AWS ne transmettra ces réponses qu’à votre adresse IP n’ont pas d’autre choix que de réinitialiser ou de supprimer les connexions, car elles n’ont pas été initiées avec vous.

Notez que cette solution ne fonctionne pas avec les points de terminaison S3 VPC annoncés récemment par Amazon, car avec les points de terminaison S3 VPC, votre adresse IP source (vue par S3) sera l’adresse privée, qui n’est pas propre à votre VPC … mais cela ne devrait pas poser de problème. Je ne mentionne cette mise en garde que par souci de rigueur. Les points de terminaison SPC VPC ne sont pas requirejs et ne sont pas activés par défaut. Si cette option est activée, ils peuvent être configurés pour chaque sous-réseau.