Comment puis-je configurer une API HTTP pour autoriser l'accès uniquement à des adresses IP spécifiques ?
Je souhaite intégrer une API HTTP à une fonction AWS Lambda pour autoriser et autoriser uniquement des adresses IP spécifiques.
Brève description
Pour restreindre l'accès á l’API HTTP à des adresses IP spécifiques et prédéfinies, déployez une fonction Lambda en tant que mécanisme d'autorisation. La fonction Lambda effectue la validation des adresses IP pour déterminer si les requêtes entrantes proviennent de sources approuvées. Le mécanisme d'autorisation accorde ou refuse ensuite l'accès à l'API HTTP en fonction de l'adresse IP.
Résolution
Créer une fonction Lambda
Tout d'abord, créez une fonction Lambda à utiliser comme mécanisme d’autorisation. Vous pouvez configurer la fonction Lambda pour utiliser des variables d'environnement pour une liste d'autorisations :
Key: IP_RANGE, Value: ['0.0.0.0','XX.XX.XX.XX']
La valeur peut être soit une adresse IP spécifique que vous souhaitez autoriser, soit une plage d'adresses CIDR complète.
Après avoir déployé le code, configurez les variables d'environnement pour la fonction Lambda afin de définir une variable spécifique comme IP_RANGE.
Pour des raisons de sécurité, il est recommandé de chiffrer les variables d'environnement avec AWS Key Management Service (AWS KMS).
Créer une API HTTP
Créez une API HTTP à utiliser comme point d'entrée pour les requêtes entrantes. Les API HTTP étant publiques par défaut, utilisez la fonction Lambda d'autorisation pour contrôler l'accès.
Attacher le mécanisme d’autorisation Lambda
Associez la fonction Lambda en tant que mécanisme d'autorisation à l'API. Lorsqu'une requête atteint l'API, le mécanisme d'autorisation évalue l'adresse IP source par rapport à la liste autorisée. Si le mécanisme d’autorisation autorise l'adresse IP, il accorde l'accès au point de terminaison de l'API HTTP. Dans le cas contraire, il refuse la requête.
Pour évaluer les adresses IP en fonction de vos variables d'environnement autorisées, utilisez l'exemple de fonction Lambda suivant :
Remarque : Cet exemple transmet un jeton d'autorisation dont la valeur est secretcode. Toutefois, vous pouvez configurer ces paramètres pour utiliser une autre valeur.
# -*- coding: utf-8 -*- # ======================== # AWS Lambda Python Runtime # ======================== # Import necessary modules import os from ipaddress import ip_network, ip_address import uuid import ast # Function to check if an IP address is within the specified IP range def check_ip(IP_ADDRESS, IP_RANGE): VALID_IP = False # Check if any of the elements in IP_RANGE contain a CIDR notation (e.g., "192.168.0.0/24") cidr_blocks = list(filter(lambda element: "/" in element, IP_RANGE)) if cidr_blocks: for cidr in cidr_blocks: # Create an IP network from the CIDR notation net = ip_network(cidr) # Check if the IP_ADDRESS is within the network VALID_IP = ip_address(IP_ADDRESS) in net if VALID_IP: break # If the IP_ADDRESS is not within any CIDR block, check if it matches an exact IP in IP_RANGE if not VALID_IP and IP_ADDRESS in IP_RANGE: VALID_IP = True return VALID_IP # Lambda function handler def lambda_handler(event, context): # Extract the source IP address from the request's RequestContext IP_ADDRESS = event["requestContext"]["http"]["sourceIp"] # Parse the IP_RANGE environment variable, which is a list of allowed IP addresses or CIDR blocks IP_RANGE = ast.literal_eval(os.environ.get("IP_RANGE", "[]")) # Check if the source IP is within the allowed IP range VALID_IP = check_ip(IP_ADDRESS, IP_RANGE) # Extract relevant information from the request event # Extract the AWS API Gateway's API ID from the event API_ID = event["requestContext"]["apiId"] # Extract the AWS account ID from the event ACC_ID = event["requestContext"]["accountId"] # Extract the AWS API Gateway's Details Method, Stage and Route from the event METHOD = event["requestContext"]["http"]["method"] STAGE = event["requestContext"]["stage"] ROUTE = event["requestContext"]["http"]["path"] # Check if the request includes a valid authorization token and the source IP is allowed # Use the {region} based on the region of the API Gateway's configuration. if event["headers"]["authorizationtoken"] == "secretcode" and VALID_IP: # If authorized, allow the execution of the API response = { "principalId": f"{uuid.uuid4().hex}", "policyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": f"arn:aws:execute-api:{region}:{ACC_ID}:{API_ID}/{STAGE}/{METHOD}{ROUTE}", } ], }, "context": {"exampleKey": "exampleValue"}, } return response # If the request is not authorized or the IP is not allowed, deny execution # Use the Acc_ID, region & API_ID as per the HTTP API ID Details response = { "principalId": f"{uuid.uuid4().hex}", "policyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Deny", "Resource": f"arn:aws:execute-api:{region}:{ACC_ID}:{API_ID}/*/*/*", } ], }, "context": {"exampleKey": "exampleValue"}, } return response
Remarque : Si vous nécessitez des modules Python supplémentaires, utilisez pip pour installer les modules dans l'environnement de la fonction Lambda. Packagez la fonction Lambda avec les dépendances nécessaires.
Tester votre mécanisme d’autorisation
Avant de déployer votre fonction pour la production, assurez-vous de la tester dans un environnement de test. Pour vérifier les adresses IP auxquelles vous souhaitez accéder au point de terminaison de l'API HTTP, utilisez la journalisation des accès. Utilisez des variables de contexte pour identifier une adresse IP et incluez-la dans votre liste d'autorisations via la variable d’environnement IP_RANGE. L'exemple suivant inclut des variables de contexte pour la journalisation des accès dans l'API HTTP :
{"ownerAccountId":"$context.accountId","apiId":"$context.apiId","requestId":"$context.requestId", / "ip":"$context.identity.sourceIp","requestTime":"$context.requestTime","httpMethod":"$context.httpMethod", / "routeKey":"$context.routeKey","status":"$context.status","protocol":"$context.protocol", / "responseLength":"$context.responseLength","errorMessage":"$context.error.message", / "errorMessageString":"$context.error.messageString","extendedRequestId":"$context.extendedRequestId", / "responseLatency":"$context.responseLatency","stage":"$context.stage","path":"$context.path", / "requestTimeEpoch":"$context.requestTimeEpoch","protocol":"$context.protocol","userAgent":"$context.identity.userAgent", / "errorResponseType":"$context.error.responseType","integrationStatus":"$context.integration.status", / "integrationErrorMessage":"$context.integrationErrorMessage","integrationRequestId":"$context.integration.requestId", / "integrationLatency":"$context.integration.latency","integrationStatusfromIntegration":"$context.integration.integrationStatus", / "integrationError":"$context.integration.error","awsEndpointRequestId":"$context.awsEndpointRequestId", / "customAuthorizerUser":"$context.identity.user","authorizerProperty":"$context.authorizer.property", / "customAuthorizerprincipalId":"$context.authorizer.principalId","authorizerError":"$context.authorizer.error"}
La variable ip":"$context.identity.sourceIp fournit l'adresse IP qui demande le point de terminaison de l'API. Cela vous permet d'identifier les adresses IP et de les ajouter à votre liste d'autorisation.
Contenus pertinents
- demandé il y a 5 moislg...
- demandé il y a 10 moislg...
- demandé il y a 8 moislg...
- demandé il y a un anlg...
- AWS OFFICIELA mis à jour il y a 2 ans
- AWS OFFICIELA mis à jour il y a 3 ans
- AWS OFFICIELA mis à jour il y a 2 ans
- AWS OFFICIELA mis à jour il y a 2 ans