Volver al blog

Cómo configurar un proxy en aplicaciones serverless: AWS Lambda, Vercel, Cloudflare Workers

Guía completa para integrar proxies en funciones serverless: desde la configuración de clientes HTTP hasta eludir límites de tasa y bloqueos geográficos en AWS Lambda, Vercel Edge Functions y Cloudflare Workers.

📅19 de febrero de 2026
```html

La arquitectura serverless se ha convertido en un estándar para aplicaciones web modernas, pero los desarrolladores se enfrentan regularmente a un problema: todas las solicitudes de funciones Lambda o Edge Functions provienen de las direcciones IP de los centros de datos de los proveedores de la nube. Esto conduce a bloqueos al acceder a API externas, al raspar datos o al automatizar tareas. En esta guía, analizaremos cómo integrar proxies en funciones serverless para eludir restricciones, límites de tasa y bloqueos geográficos.

Por qué las funciones serverless necesitan proxies

Las plataformas serverless (AWS Lambda, Google Cloud Functions, Vercel, Cloudflare Workers) ejecutan código en la infraestructura de la nube, utilizando direcciones IP de centros de datos. Esto crea varios problemas críticos para los desarrolladores:

Problema 1: Bloqueos por IP de centros de datos. Muchos servicios bloquean automáticamente las solicitudes de direcciones IP conocidas de AWS, Google Cloud o Azure. Por ejemplo, al raspar sitios de comercio electrónico (Amazon, eBay, Wildberries) o redes sociales (Instagram API, TikTok API), sus funciones Lambda recibirán un HTTP 403 o captcha en la primera solicitud. Los sistemas de protección contra bots (Cloudflare, Akamai, DataDome) reconocen instantáneamente el tráfico de los centros de datos en la nube.

Problema 2: Limitación de tasa a nivel de IP. Si despliega una aplicación serverless con miles de llamadas simultáneas, todas las solicitudes pueden provenir de una o varias direcciones IP de AWS. Las API externas alcanzan rápidamente los límites (por ejemplo, GitHub API — 60 solicitudes/hora desde una IP, Google Maps API — 100 solicitudes/segundo). Incluso si tiene un plan API extendido, la limitación por IP seguirá aplicándose.

Problema 3: Bloqueos geográficos. Las funciones serverless en la región us-east-1 no podrán acceder a contenido disponible solo desde Rusia, Europa o Asia. Esto es crítico al raspar mercados regionales (Ozon, Яндекс.Маркет), verificar anuncios de diferentes países o probar la localización de sitios.

Problema 4: IP compartida con otros usuarios. En un entorno serverless, sus funciones pueden obtener una dirección IP que ya ha sido utilizada por otros clientes del proveedor de la nube. Si alguien abusó previamente de esta IP (spam, DDoS, raspado), puede estar en listas negras. Recibirá un bloqueo sin ninguna culpa.

La solución a todos estos problemas es la integración de servidores proxy. Los proxies permiten que sus funciones serverless envíen solicitudes a través de direcciones IP residenciales o móviles, que parecen usuarios normales. Esto elimina bloqueos, elude límites de tasa y proporciona acceso a contenido bloqueado geográficamente.

Qué tipos de proxies son adecuados para serverless

La elección del tipo de proxy depende de la tarea de su aplicación serverless. Consideremos tres opciones principales y escenarios de uso:

Tipo de proxy Velocidad Anonimato Escenarios de uso
Proxies de centros de datos Muy alta (10-50 ms) Baja Acceso a API sin restricciones severas, verificación de disponibilidad de servicios, monitoreo de uptime
Proxies residenciales Media (100-500 ms) Alta Raspado de e-commerce, trabajo con redes sociales, eludir Cloudflare, acceso a contenido bloqueado geográficamente
Proxies móviles Media (150-600 ms) Muy alta Trabajo con API móviles (Instagram, TikTok), prueba de aplicaciones móviles, eludir las protecciones más estrictas

Para la mayoría de las aplicaciones serverless, se recomienda utilizar proxies residenciales. Proporcionan un equilibrio óptimo entre velocidad y anonimato. Las IP residenciales parecen usuarios domésticos normales, lo que permite eludir las protecciones contra bots y los límites de tasa sin un aumento significativo en la latencia.

Los proxies de centros de datos son adecuados solo para tareas simples (verificación de estados HTTP, trabajo con API públicas sin restricciones). Los proxies móviles son necesarios en casos específicos, cuando trabaja con API móviles o cuando la máxima anonimato es crítica.

Configuración de proxies en AWS Lambda

AWS Lambda es la plataforma serverless más popular, y la integración de proxies aquí requiere la configuración adecuada del cliente HTTP. Las funciones Lambda pueden usar varios lenguajes de programación (Node.js, Python, Go), consideremos ejemplos para los más comunes.

Node.js (axios)

Axios es la biblioteca más popular para solicitudes HTTP en Node.js. Para configurar el proxy, use el parámetro proxy en la configuración:

const axios = require('axios');

exports.handler = async (event) => {
  const proxyConfig = {
    host: 'proxy.example.com',
    port: 8080,
    auth: {
      username: 'your_username',
      password: 'your_password'
    },
    protocol: 'http'
  };

  try {
    const response = await axios.get('https://api.example.com/data', {
      proxy: proxyConfig,
      timeout: 10000 // 10 segundos
    });

    return {
      statusCode: 200,
      body: JSON.stringify(response.data)
    };
  } catch (error) {
    console.error('Error de proxy:', error.message);
    return {
      statusCode: 500,
      body: JSON.stringify({ error: error.message })
    };
  }
};

Punto importante: almacene las credenciales del proxy en AWS Systems Manager Parameter Store o AWS Secrets Manager, y no en el código. Esto garantizará la seguridad y permitirá cambiar fácilmente el proxy sin reconstruir la función.

Python (requests)

En Python, para trabajar con proxies se utiliza la biblioteca requests con el parámetro proxies:

import requests
import json

def lambda_handler(event, context):
    proxies = {
        'http': 'http://username:password@proxy.example.com:8080',
        'https': 'http://username:password@proxy.example.com:8080'
    }
    
    try:
        response = requests.get(
            'https://api.example.com/data',
            proxies=proxies,
            timeout=10
        )
        
        return {
            'statusCode': 200,
            'body': json.dumps(response.json())
        }
    except requests.exceptions.RequestException as e:
        print(f'Error de proxy: {str(e)}')
        return {
            'statusCode': 500,
            'body': json.dumps({'error': str(e)})
        }

Para proxies SOCKS5 (un protocolo más seguro) en Python, debe instalar la biblioteca adicional requests[socks] y cambiar el formato de la URL:

proxies = {
    'http': 'socks5://username:password@proxy.example.com:1080',
    'https': 'socks5://username:password@proxy.example.com:1080'
}

Optimización para arranques en frío

Las funciones Lambda tienen el problema de los arranques en frío: la primera solicitud después de un período de inactividad toma de 1 a 3 segundos. Al usar proxies, este tiempo aumenta. Para minimizar las demoras, cree el cliente HTTP fuera de la función handler:

const axios = require('axios');

// Creamos el cliente una vez al inicializar el contenedor
const httpClient = axios.create({
  proxy: {
    host: 'proxy.example.com',
    port: 8080,
    auth: {
      username: process.env.PROXY_USER,
      password: process.env.PROXY_PASS
    }
  },
  timeout: 10000
});

exports.handler = async (event) => {
  // Reutilizamos el cliente en cada llamada
  const response = await httpClient.get('https://api.example.com/data');
  return {
    statusCode: 200,
    body: JSON.stringify(response.data)
  };
};

Este enfoque reduce el tiempo de arranque en frío en 200-500 ms, ya que la configuración del proxy se realiza solo una vez al crear el contenedor Lambda.

Integración de proxies en Vercel Edge Functions

Vercel ofrece dos tipos de funciones serverless: Node.js Functions (análogas a Lambda) y Edge Functions (se ejecutan en CDN). Las Edge Functions funcionan en un runtime similar a Cloudflare Workers, con limitaciones en el uso de la API de Node.js. Analicemos ambas opciones.

Vercel Node.js Functions

Para las Vercel Functions normales, use el mismo enfoque que para AWS Lambda. Cree un archivo api/fetch-data.js:

import axios from 'axios';

export default async function handler(req, res) {
  const proxyConfig = {
    host: process.env.PROXY_HOST,
    port: parseInt(process.env.PROXY_PORT),
    auth: {
      username: process.env.PROXY_USER,
      password: process.env.PROXY_PASS
    }
  };

  try {
    const response = await axios.get(req.query.url, {
      proxy: proxyConfig,
      timeout: 8000
    });

    res.status(200).json(response.data);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
}

Agregue variables de entorno en el Vercel Dashboard (Configuración → Variables de Entorno): PROXY_HOST, PROXY_PORT, PROXY_USER, PROXY_PASS.

Vercel Edge Functions

Las Edge Functions utilizan la API Web Fetch en lugar de bibliotecas de Node.js. El proxy se configura a través de encabezados personalizados o middleware:

export const config = {
  runtime: 'edge',
};

export default async function handler(req) {
  const proxyUrl = `http://${process.env.PROXY_USER}:${process.env.PROXY_PASS}@${process.env.PROXY_HOST}:${process.env.PROXY_PORT}`;
  
  // Para Edge Runtime se necesita fetch con proxy a través de agent (requiere polyfill)
  // Alternativa: usar proxy API directamente
  const targetUrl = new URL(req.url).searchParams.get('target');
  
  const response = await fetch(targetUrl, {
    headers: {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    }
  });

  return new Response(await response.text(), {
    status: response.status,
    headers: response.headers
  });
}

Limitación importante: Edge Runtime no admite agentes proxy estándar de Node.js. Para un funcionamiento completo con proxies, se recomienda usar Node.js Functions o crear un servidor proxy intermedio en un servidor separado que reciba solicitudes de las Edge Functions.

Proxies en Cloudflare Workers

Cloudflare Workers funcionan en V8 isolates y tienen restricciones aún más estrictas que Vercel Edge Functions. La forma estándar de conectar proxies a través de bibliotecas de Node.js no funciona aquí. Hay dos enfoques funcionales:

Método 1: Túnel HTTP CONNECT

Utilice un proxy que soporte el método HTTP CONNECT. Cree un túnel a través del servidor proxy:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const proxyUrl = 'http://proxy.example.com:8080';
  const targetUrl = 'https://api.example.com/data';
  
  const proxyAuth = btoa(`${PROXY_USER}:${PROXY_PASS}`);
  
  const response = await fetch(proxyUrl, {
    method: 'CONNECT',
    headers: {
      'Host': new URL(targetUrl).host,
      'Proxy-Authorization': `Basic ${proxyAuth}`
    }
  });

  if (response.status === 200) {
    // Túnel establecido, realizamos la solicitud principal
    const finalResponse = await fetch(targetUrl, {
      headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
      }
    });
    
    return finalResponse;
  }
  
  return new Response('Conexión de proxy fallida', { status: 502 });
}

Este método solo funciona con proxies HTTP que soportan CONNECT. La mayoría de los proveedores de proxies residenciales ofrecen esta posibilidad.

Método 2: Puente de proxy (recomendado)

Una forma más confiable es desplegar un puente proxy intermedio en un servidor separado (por ejemplo, en VPS o AWS EC2). Cloudflare Worker envía solicitudes a su puente, y este las reenvía a través del proxy:

// Cloudflare Worker
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const targetUrl = new URL(request.url).searchParams.get('url');
  const gatewayUrl = 'https://your-proxy-gateway.com/fetch';
  
  const response = await fetch(gatewayUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': API_KEY // Protección de su puente
    },
    body: JSON.stringify({
      url: targetUrl,
      method: 'GET'
    })
  });

  return response;
}

En el lado del puente proxy (servidor Node.js):

const express = require('express');
const axios = require('axios');

const app = express();
app.use(express.json());

const proxyConfig = {
  host: 'proxy.example.com',
  port: 8080,
  auth: {
    username: process.env.PROXY_USER,
    password: process.env.PROXY_PASS
  }
};

app.post('/fetch', async (req, res) => {
  if (req.headers['x-api-key'] !== process.env.API_KEY) {
    return res.status(401).json({ error: 'No autorizado' });
  }

  try {
    const response = await axios({
      url: req.body.url,
      method: req.body.method || 'GET',
      proxy: proxyConfig,
      timeout: 10000
    });

    res.json(response.data);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.listen(3000);

Este enfoque agrega un salto adicional (aumento de latencia de 50-100 ms), pero proporciona compatibilidad y control total sobre la conexión proxy.

Rotación de direcciones IP en un entorno serverless

Una de las principales razones para usar proxies es distribuir solicitudes entre múltiples direcciones IP para eludir límites de tasa. En la arquitectura serverless hay dos enfoques para la rotación:

Rotación automática en el lado del proveedor de proxies

La mayoría de los proveedores de proxies residenciales ofrecen proxies rotativos: se conecta a un solo endpoint, y la IP cambia automáticamente con cada solicitud o a través de un intervalo establecido (por ejemplo, cada 5 minutos). Esta es la opción más simple para serverless:

// Un endpoint, la IP cambia automáticamente
const proxyConfig = {
  host: 'rotating.proxy.example.com',
  port: 8080,
  auth: {
    username: 'user-session-' + Date.now(), // Sesión única
    password: 'password'
  }
};

Algunos proveedores permiten gestionar la rotación a través de parámetros en el nombre de usuario: user-session-random (nueva IP en cada solicitud), user-session-sticky-300 (una IP durante 300 segundos).

Rotación manual a través de un pool de proxies

Si tiene una lista de proxies estáticos (por ejemplo, compró proxies dedicados), puede implementar la rotación a nivel de aplicación. En un entorno serverless, use DynamoDB (AWS) o KV Storage (Cloudflare) para almacenar el estado:

const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();

const PROXY_POOL = [
  { host: 'proxy1.example.com', port: 8080 },
  { host: 'proxy2.example.com', port: 8080 },
  { host: 'proxy3.example.com', port: 8080 }
];

async function getNextProxy() {
  // Obtenemos el índice actual de DynamoDB
  const result = await dynamodb.get({
    TableName: 'ProxyRotation',
    Key: { id: 'current_index' }
  }).promise();

  const currentIndex = result.Item?.index || 0;
  const nextIndex = (currentIndex + 1) % PROXY_POOL.length;

  // Actualizamos el índice
  await dynamodb.put({
    TableName: 'ProxyRotation',
    Item: { id: 'current_index', index: nextIndex }
  }).promise();

  return PROXY_POOL[currentIndex];
}

exports.handler = async (event) => {
  const proxy = await getNextProxy();
  
  const response = await axios.get('https://api.example.com/data', {
    proxy: {
      ...proxy,
      auth: {
        username: process.env.PROXY_USER,
        password: process.env.PROXY_PASS
      }
    }
  });

  return { statusCode: 200, body: JSON.stringify(response.data) };
};

Este método proporciona control total sobre la rotación, pero requiere consultas adicionales a DynamoDB (agrega 10-30 ms de latencia). Para aplicaciones de alta carga, se recomienda almacenar en caché el índice en la memoria del contenedor Lambda y actualizarlo cada 100-1000 solicitudes.

Manejo de errores y timeouts

Los proxies añaden un punto adicional de falla a su aplicación serverless. Es crítico manejar los errores correctamente para no perder las solicitudes de los usuarios.

Errores típicos al trabajar con proxies

Error Razón Solución
ETIMEDOUT El proxy no responde o funciona lentamente Reduzca el timeout a 5-8 segundos, agregue un retry con otro proxy
ECONNREFUSED El servidor proxy no está disponible Verifique la disponibilidad del proxy, use un fallback a otro proxy
407 Proxy Authentication Required Credenciales incorrectas Verifique el nombre de usuario/contraseña, asegúrese de que la IP de Lambda esté permitida en la lista blanca del proxy
502 Bad Gateway El proxy no puede conectarse al sitio de destino El sitio puede estar bloqueando el proxy, intente con otra IP o tipo de proxy

Implementación de lógica de retry con fallback

Agregue intentos automáticos con un cambio a un proxy de respaldo en caso de errores:

const axios = require('axios');

const PRIMARY_PROXY = {
  host: 'primary.proxy.com',
  port: 8080,
  auth: { username: 'user', password: 'pass' }
};

const FALLBACK_PROXY = {
  host: 'fallback.proxy.com',
  port: 8080,
  auth: { username: 'user', password: 'pass' }
};

async function fetchWithRetry(url, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const proxy = attempt === 0 ? PRIMARY_PROXY : FALLBACK_PROXY;
    
    try {
      const response = await axios.get(url, {
        proxy,
        timeout: 8000
      });
      
      return response.data;
    } catch (error) {
      console.log(`Intento ${attempt + 1} fallido:`, error.message);
      
      // No retry en errores del cliente (4xx)
      if (error.response && error.response.status < 500) {
        throw error;
      }
      
      // Último intento — lanzamos el error
      if (attempt === maxRetries - 1) {
        throw error;
      }
      
      // Retraso exponencial antes del retry
      await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, attempt)));
    }
  }
}

exports.handler = async (event) => {
  try {
    const data = await fetchWithRetry('https://api.example.com/data');
    return { statusCode: 200, body: JSON.stringify(data) };
  } catch (error) {
    return { statusCode: 500, body: JSON.stringify({ error: error.message }) };
  }
};

Esta implementación da tres intentos de solicitud: el primero a través del proxy principal, los demás a través del de respaldo. Se ha añadido un retraso exponencial entre los intentos (1 seg, 2 seg, 4 seg) para no generar una carga excesiva.

Monitoreo y alertas

Configure el monitoreo de errores de proxy a través de CloudWatch (AWS), Vercel Analytics o Sentry. Monitoree las métricas:

  • Porcentaje de solicitudes exitosas a través del proxy (debe ser >95%)
  • Latencia media de las solicitudes (un aumento puede indicar problemas con el proxy)
  • Número de errores de timeout (si >5% — el proxy está sobrecargado o es lento)
  • Distribución de errores por códigos (407, 502, ETIMEDOUT, etc.)

Configure alertas al superar los umbrales — esto permitirá cambiar rápidamente a un proveedor de proxy de respaldo o modificar la configuración.

Conclusión

La integración de proxies en aplicaciones serverless resuelve problemas críticos: bloqueos por IP de centros de datos, limitaciones de tasa y bloqueos geográficos. Hemos revisado la configuración de proxies en AWS Lambda (Node.js y Python), Vercel Functions y Cloudflare Workers, así como la implementación de rotación de direcciones IP y manejo de errores.

Recomendaciones clave: use proxies residenciales para tareas que requieren alta anonimidad (raspado, trabajo con API de redes sociales), almacene las credenciales en almacenes seguros (AWS Secrets Manager, Vercel Environment Variables), implemente lógica de retry con fallback a proxies de respaldo y configure el monitoreo de errores.

Para aplicaciones serverless con altos requisitos de estabilidad, recomendamos utilizar proxies residenciales con rotación automática — proporcionan un equilibrio óptimo entre velocidad, anonimato y confiabilidad, minimizando el riesgo de bloqueos al trabajar con API y servicios externos.

```