Utilisez PrivateLink pour un accès privé inter-VPC ou inter-comptes, et activez Proxy Protocol v2 sur SLB afin d'identifier les VPC sources et les endpoints pour un contrôle d'accès granulaire.
Risques de sécurité
Dans les environnements cloud, des services tels que les plateformes de bases de données auto-gérées, les applications d'inférence IA et les services Alibaba Cloud comme Object Storage Service (OSS) sont souvent configurés avec des EIP ou des endpoints publics pour faciliter l'accès. Cette configuration expose directement les services à Internet et introduit des risques de sécurité :
Risque d'attaques via le réseau public : Tout service exposé à Internet constitue une cible potentielle pour les attaques DDoS, les scans de vulnérabilités et leur exploitation, ainsi que pour les attaques par force brute.
Risque d'usurpation d'identité : Les services Internet traditionnels s'appuient sur l'authentification par nom d'utilisateur et mot de passe. Si ces identifiants sont divulgués, des attaquants peuvent usurper l'identité d'utilisateurs légitimes depuis n'importe où pour accéder aux données, les voler ou les altérer. L'accès public ne permet pas de restreindre le réseau source des requêtes.
Canal d'exfiltration de données : Les employés internes peuvent utiliser des comptes cloud personnels pour exfiltrer des données d'entreprise via les endpoints publics des services Alibaba Cloud tels qu'OSS. Comme ce trafic transite par Internet, il est difficile d'appliquer les politiques de sécurité du réseau d'entreprise.
Bonnes pratiques
Utilisez PrivateLink pour l'accès inter-VPC au sein de la même zone
Description : Un service réseau (tel qu'un service web) est déployé sur une instance ECS dans le VPC2. Une connexion PrivateLink entre le VPC1 et le VPC2 permet d'accéder au service depuis le VPC1 via une adresse IP privée (endpoint).
: L'endpoint (consommateur de service) et le service d'endpoint (fournisseur de service) doivent se trouver dans la même zone. Les zones de l'endpoint doivent être un sous-ensemble des zones du service d'endpoint. Par exemple, si un service d'endpoint est déployé dans la zone A et la zone B, l'endpoint ne peut être créé que dans la zone A ou la zone B.
Étapes principales :
-
Configuration côté serveur (fournisseur de service)
Créez un équilibreur de charge : Dans le VPC2, créez une instance SLB prenant en charge PrivateLink, telle qu'un CLB ou un NLB orienté vers le réseau privé. Configurez un groupe de serveurs backend et un écouteur.
Créez un service d'endpoint : Dans la console PrivateLink, créez un service d'endpoint et associez-le à l'instance SLB créée à l'étape précédente.
Configurez une liste blanche de service (uniquement pour l'accès inter-comptes) : Si le VPC1 appartient à un autre compte Alibaba Cloud, ajoutez l'UID du compte à la liste blanche de service du service d'endpoint.
Acceptez la demande de connexion : Après l'initiation de la connexion par le client, accédez à l'onglet Connections du service d'endpoint et acceptez la demande en attente. Vous pouvez également configurer le service pour qu'il accepte automatiquement les connexions.
-
Configuration côté client (consommateur de service)
Créez un endpoint : Dans le VPC1, créez un endpoint et sélectionnez le service d'endpoint créé côté serveur.
Configurez le réseau : Sélectionnez un vSwitch et un groupe de sécurité dans le VPC1 pour l'endpoint afin de contrôler quelles ressources du VPC1 peuvent y accéder.
Obtenez les détails de l'endpoint : Après la création, un nom de domaine privé et une adresse IP sont générés.
Initiez l'accès : Une fois que le fournisseur de service a accepté la connexion, les applications du VPC1 peuvent accéder au service du VPC2 via le nom de domaine ou l'adresse IP générés.
Utilisez Proxy Protocol pour contrôler les VPC accessibles et leurs adresses IP privées
Lorsque vous fournissez des services via PrivateLink, le serveur peut identifier l'endpoint source ou le VPC de chaque requête et appliquer des règles de sécurité en conséquence. Par exemple, vous pouvez restreindre un compte pour qu'il n'accepte les accès que depuis un VPC légitime. Même si les identifiants sont divulgués, les réseaux non autorisés ne pourront pas accéder au service.
En vous appuyant sur Utilisez PrivateLink pour l'accès inter-VPC au sein de la même zone, vous pouvez permettre à l'application côté serveur d'identifier le VPC source et de mettre en œuvre un contrôle d'accès.
-
Activez Proxy Protocol v2 : Activez Proxy Protocol v2 sur l'écouteur NLB et abonnez-vous à l'ID VPC et à l'ID endpoint.
# Use the Cloud Assistant CLI to enable Proxy Protocol v2 for a specified listener and subscribe to the VPC ID and endpoint ID. aliyun nlb UpdateListenerAttribute \ --ListenerId lsn-xxxxxxxxxxxxxxxx \ --ProxyProtocolEnabled true \ --ProxyProtocolV2Config '{"Ppv2VpcIdEnabled":true,"Ppv2PrivateLinkEpIdEnabled":true}' \ --RegionId cn-hangzhou--ListenerId: L'ID de l'écouteur créé pour le service web.--ProxyProtocolEnabled: Définissez surtruepour activer Proxy Protocol. Ce protocole transmet les informations de connexion du client dans le premier paquet après la poignée de main TCP. Le service backend doit prendre en charge ce protocole. Consultez l'étape 2 pour plus de détails. Sinon, le service sera interrompu.--ProxyProtocolV2Config: Ajoute des champs Type-Length-Value (TLV) définis par Alibaba Cloud. Cet exemple s'abonne à l'ID VPC source et à l'ID endpoint PrivateLink.17 7.005726 10.0.0.186 10.0.0.184 TCP 74 3059 → 80 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=128 18 7.005753 10.0.0.184 10.0.0.186 TCP 62 80 → 3059 [SYN, ACK] Seq=0 Ack=1 Win=64240 Len=0 MSS=1460 WS=128 19 7.006781 10.0.0.186 10.0.0.184 TCP 54 3059 → 80 [ACK] Seq=1 Ack=1 Win=64256 Len=0 20 7.006804 10.0.0.186 10.0.0.184 HTTP 154 Continuation 21 7.006814 10.0.0.184 10.0.0.186 TCP 54 80 → 3059 [ACK] Seq=1 Ack=101 Win=64256 Len=0 22 7.006805 10.0.0.186 10.0.0.184 HTTP 210 GET /login HTTP/1.1 23 7.006821 10.0.0.184 10.0.0.186 TCP 54 80 → 3059 [ACK] Seq=1 Ack=257 Win=64128 Len=0Le tableau suivant décrit comment analyser le TLV.
Description/Contenu
Contenu original
En-tête de protocole
Signature fixe du Proxy Protocol
0d0a0d0a000d0a515549540a
Version 2, commande PROXY
21
TCP/IPv4
11
Les données suivantes ont une longueur de 84 octets
0054
Informations d'adresse
IP source : 10.0.0.14
0a00000e
IP de destination : 10.0.0.15
0a00000f
Port source : 59074
e6c2
Port de destination : 80
0050
TLV1
Type 03
034 octets
00040764b56b
0764b56b
TLV2
Type e1 (type personnalisé)
e124 octets
0018ID endpoint PrivateLink :
ep-bp1i288487e586152d4b
0265702d6270316932383834383765353836313532643462
TLV3
Type e1 (type personnalisé)
e1
26 octets
001a
ID VPC :
vpc-bp179qeke0wzo1mr8bxhl
017670632d627031373971656b6530777a6f316d72386278686c
TLV4
04(PP2_TYPE_NETNS), utilisé pour transmettre l'espace de noms réseau04
6 octets
0006000000000000000000000000 -
Si votre service web utilise Nginx, configurez-le pour prendre en charge Proxy Protocol :
(Requiert NGINX Plus R16 ou version ultérieure, ou Nginx open source 1.13.11 ou version ultérieure.)
server { listen 80 proxy_protocol; # Enable Proxy Protocol v1/v2. # Other configurations... }Nginx analyse automatiquement le TLV Proxy Protocol sur le port 80, mais la version standard ne prend en charge que la récupération de l'adresse IP à partir du TLV.
Utilisez une extension Lua pour gérer les ID VPC personnalisés par Alibaba Cloud et les ID endpoint PrivateLink.
Le plugin Lua suivant dans nginx.conf gère les connexions TCP, lit les paquets depuis le socket et analyse le tampon TLV.
Les données analysées sont stockées dans le contexte de la requête. Lorsqu'une requête /login est effectuée, le code vérifie l'ID endpoint PrivateLink :
-- Define shared memory before the http block. lua_shared_dict tlv_cache 10m; stream { server { listen 80; # Do not enable proxy_protocol. Let the Lua code below handle it. preread_by_lua_block { -- 1. Try to read the fixed 16-byte protocol header. local sock = ngx.req.socket(true) local header, err = sock:receive(16) if not header then ngx.log(ngx.ERR, "failed to receive proxy protocol header: ", err) return end -- 2. Check the protocol signature (12 bytes). if string.sub(header, 1, 12) ~= "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A" then -- If it is not the Proxy Protocol, put the read data back into the buffer to avoid corrupting the original request. sock:setreused(header) return end -- 3. Parse the rest of the protocol header. local ver_cmd = string.byte(header, 13) -- Version and command local family = string.byte(header, 14) -- Address family and protocol local len = string.byte(header, 15) * 256 + string.byte(header, 16) -- Total length of the variable part if len == 0 then -- No address or TLV information. Return directly. return end -- 4. Read the variable-length part (contains address and TLV). local variable_part, err = sock:receive(len) if not variable_part or #variable_part < len then ngx.log(ngx.ERR, "failed to read variable part (address + tlvs): ", err) return end -- 5. Determine the length of the address information based on the address family. local addr_len = 0 local protocol = family & 0x0F local address_family = family >> 4 if address_family == 1 then -- AF_INET (IPv4) addr_len = 12 elseif address_family == 2 then -- AF_INET6 (IPv6) addr_len = 36 elseif address_family == 3 then -- AF_UNIX addr_len = 216 end -- 6. Separate the address information and TLV data. local address_block = string.sub(variable_part, 1, addr_len) -- You can parse the address information if needed. local tlv_string = string.sub(variable_part, addr_len + 1) -- 7. Parse the TLV data. local tlvs = {} local pos = 1 while pos <= #tlv_string do -- Make sure there are at least 3 bytes (Type, Length). if pos + 2 > #tlv_string then ngx.log(ngx.ERR, "malformed TLV data: not enough bytes for type and length") break end local tlv_type = string.byte(tlv_string, pos) local tlv_length = string.byte(tlv_string, pos + 1) * 256 + string.byte(tlv_string, pos + 2) -- Make sure the length of the value does not exceed the boundary. if pos + 2 + tlv_length > #tlv_string then ngx.log(ngx.ERR, "malformed TLV data: length exceeds available data") break end local tlv_value = string.sub(tlv_string, pos + 3, pos + 2 + tlv_length) table.insert(tlvs, { type = tlv_type, length = tlv_length, -- Encode the binary value in Base64 for easy storage and viewing. value = ngx.encode_base64(tlv_value) }) pos = pos + 3 + tlv_length end -- 8. Cache the parsed TLV in shared memory. if #tlvs > 0 then local cjson = require "cjson" local tlv_cache = ngx.shared.tlv_cache -- Use the client IP address as the key to store the TLV data. local client_ip = ngx.var.remote_addr local tlv_json = cjson.encode(tlvs) tlv_cache:set(client_ip, tlv_json, 60) -- Cache for 60 seconds. -- Optional: Also store in ngx.ctx for the stream layer to use. ngx.ctx.proxy_protocol_tlvs = tlvs end } proxy_pass localhost:8080; # Pass subsequent HTTP requests to the HTTP server for processing. } } http { server { listen 8080; # Dedicated location to handle /login requests. location /login { access_by_lua_block { local cjson = require "cjson" local tlv_cache = ngx.shared.tlv_cache -- Get TLV data from shared memory. local client_ip = ngx.var.remote_addr local tlv_json = tlv_cache:get(client_ip) if not tlv_json then ngx.log(ngx.ERR, "No TLV data found for client: ", client_ip) return ngx.exit(ngx.HTTP_FORBIDDEN) end local tlvs = cjson.decode(tlv_json) -- Extract the value of the second TLV (PrivateLink endpoint ID). local privateLinkEndId = nil if tlvs[2] then privateLinkEndId = tlvs[2].value -- Base64-encoded value. end -- Define the expected endpoint ID (Base64-encoded). local expected_value = "ZXAtYnAxaTI4ODQ4N2U1ODYxNTJkNGI=" -- Example value. Modify it as needed. -- Verify the endpoint ID. if privateLinkEndId ~= expected_value then ngx.log(ngx.ERR, "Access to /login denied: TLV value mismatch. Expected '", expected_value, "', got '", tostring(privateLinkEndId), "'") return ngx.exit(ngx.HTTP_FORBIDDEN) end -- If the verification is successful, the request continues to be processed. } proxy_pass http://your_python_backend; } # Handle all other requests. location / { proxy_pass http://your_python_backend; } } # Your Python backend service upstream definition. upstream your_python_backend { server 127.0.0.1:5000; # Assume your backend program runs on port 5000. } }
Utilisez PrivateLink pour accéder aux services Alibaba Cloud
Certains services Alibaba Cloud prennent en charge l'accès via PrivateLink, ce qui vous permet de configurer des comptes autorisés pour un accès via réseau privé et d'éviter les risques de sécurité liés au réseau public.
Les comptes personnels présentent un risque d'exfiltration de données. Configurez les comptes d'entreprise pour n'autoriser l'accès qu'à partir de réseaux privés légitimes, empêchant ainsi toute exploitation en cas de compromission des identifiants.
Scénario de menace
Créez un endpoint pour un service Alibaba Cloud : Dans la console PrivateLink, créez un endpoint gateway pour le service Alibaba Cloud auquel vous devez accéder, tel qu'OSS, et associez-le au VPC et à la table de routage de votre entreprise.
Configurez une politique d'accès à l'endpoint : Restreignez l'accès aux identités RAM (telles que les utilisateurs ou les rôles) appartenant au compte Alibaba Cloud de votre entreprise. Cela empêche d'autres comptes, tels que les comptes personnels des employés, d'accéder à OSS via ce canal privé.
Configurez une politique RAM (facultatif) : Pour un contrôle plus granulaire, configurez des politiques pour les utilisateurs ou rôles RAM afin d'imposer que l'accès à OSS provienne d'un VPC spécifié.
Capacités de conformité
Vérifiez l'accès depuis un VPC vers une adresse IP publique Alibaba Cloud
Analysez les journaux de flux VPC pour identifier le trafic sortant de votre VPC vers les adresses IP publiques Alibaba Cloud qui peuvent être optimisées avec PrivateLink.
Étapes :
Activez les journaux de flux VPC : Activez les journaux de flux pour le VPC où réside votre activité principale et acheminez les journaux vers Simple Log Service (SLS).
Analysez le trafic sortant : Dans la console SLS, interrogez les journaux de flux VPC et filtrez le trafic sortant avec
direction = out.-
Filtrez et localisez :
Filtrez les paquets de réponse : Excluez le trafic dont les ports de destination sont inférieurs à 1024 et les autres trafics de réponse de service connus pour réduire le bruit.
Identifiez les adresses IP publiques Alibaba Cloud : Interrogez la propriété des adresses IP de destination (
dstaddr) à l'aide d'outils tels qu'ipip.net. Concentrez-vous sur les adresses IP publiques appartenant à Alibaba Cloud.Localisez l'instance ECS source : Utilisez le champ
vm-iddans le journal de flux pour identifier l'instance ECS qui a initié l'accès.
Exemple d'analyse des journaux
Analysez ces journaux pour identifier quelles instances accèdent aux ressources cloud via Internet.
Champs clés dans cet exemple de journal :
srcaddr: 10.0.1.171(adresse IP privée au sein du VPC)dstaddr: 47.110.154.20,dstport: 80(adresse IP publique et port de destination)direction: out,action: ACCEPT(sortant, autorisé)protocol: 6(TCP)vm-id: i-bp1ifnznc1m4tp4krmb1(instance ECS qui a initié l'accès)
Vérifiez le résultat :
Si l'adresse IP publique de destination est un endpoint public pour un service Alibaba Cloud tel qu'OSS ou ECS, basculez vers un endpoint PrivateLink.
Si une adresse IP publique de destination pointe vers un service (tel qu'une EIP ou un SLB) dans un autre VPC de votre compte, cette communication inter-VPC peut être optimisée avec PrivateLink.