Tous les produits
Search
Centre de documentation

Elastic Compute Service:Reduce public network exposure with PrivateLink

Dernière mise à jour :Aug 25, 2026

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é :

  1. 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.

  2. 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.

  3. 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

image

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 :

  1. Configuration côté serveur (fournisseur de service)

    1. 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.

    2. 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.

    3. 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.

    4. 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.

  2. Configuration côté client (consommateur de service)

    1. Créez un endpoint : Dans le VPC1, créez un endpoint et sélectionnez le service d'endpoint créé côté serveur.

    2. 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.

    3. 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.

    4. 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.

  1. 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 sur true pour 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=0

    Le 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

    03

    4 octets

    0004

    0764b56b

    0764b56b

    TLV2

    Type e1 (type personnalisé)

    e1

    24 octets

    0018

    ID 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éseau

    04

    6 octets

    0006

    000000000000

    000000000000

  2. 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

  1. 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.

  2. 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é.

  3. 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 :

  1. 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).

  2. Analysez le trafic sortant : Dans la console SLS, interrogez les journaux de flux VPC et filtrez le trafic sortant avec direction = out.

  3. 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-id dans 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.