Tienes la dirección de un proxy que te dio tu proveedor y quieres saber si funciona antes de ponerla en un scraper, una tarea cron o un pipeline de CI. cURL es la comprobación más rápida: un solo comando envía una petición a través del proxy e imprime la dirección IP que ve el sitio de destino, y ese mismo comando pasa después tal cual a un script de shell.
Este artículo cubre la opción -x, las credenciales, SOCKS5, cómo fijar el proxy para todos los comandos, un script de descarga con reintentos y los mensajes de error exactos. Todos los comandos se ejecutaron con curl 8.21 contra un proxy de prueba local; las opciones están documentadas en la página de manual de curl.
¿Qué es cURL?
cURL (se pronuncia «kerl») es una herramienta de línea de comandos para transferir datos mediante URL: descarga páginas y archivos, envía formularios y peticiones a API, y muestra o guarda la respuesta. El trabajo lo hace libcurl, una biblioteca de transferencia que también usan PHP y otros lenguajes.
Como todo comando, cURL sigue una sintaxis fija:
curl [opciones] [URL]La parte de «opciones» indica qué debe hacer el comando, y de estos parámetros, también llamados flags, hay más de 250. -o pagina.html guarda la respuesta en un archivo, -I pide solo las cabeceras, -L sigue las redirecciones y -x usa un proxy. Todas las opciones distinguen mayúsculas de minúsculas: -x fija un proxy, mientras que -X fija el método HTTP.
cURL viene incluido en macOS, en Windows 10 y 11 como curl.exe y en la mayoría de las distribuciones Linux; en las imágenes de contenedor mínimas puede que tengas que instalarlo (apt install curl en Debian y Ubuntu). Ejecuta curl --version: si la línea Features: contiene HTTPS-proxy, tu compilación también puede conectarse a un proxy por TLS.
¿Qué protocolos admite cURL?
cURL solo trabaja con protocolos que se pueden escribir como URL; los protocolos de red que no se direccionan mediante una URL no son compatibles. La versión actual incluye DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS y WSS. curl --version muestra lo que admite tu compilación; RTMP, que aparece en listas antiguas, ya no está.
Sin esquema, cURL deduce el protocolo del nombre de host (ftp.example.com significa FTP; la mayoría de los nombres, HTTP). Si ese protocolo falla, no prueba otro por su cuenta. Para los proxies esto importa en un punto: un proxy HTTP transporta HTTP y HTTPS; los demás protocolos solo pasan por un túnel CONNECT (-p) y solo si el proxy permite ese puerto. SOCKS5 transporta cualquier conexión TCP, así que FTP o SMTP a través de un proxy suele significar SOCKS5.
¿Por qué usar cURL con un proxy?
- Pasos visibles.
-vmuestra la conexión con el proxy, la petición CONNECT y las dos respuestas, así que ves en qué punto falla una petición. - Todos los tipos de proxy en una sola opción. HTTP, HTTPS, SOCKS4, SOCKS4a, SOCKS5 y SOCKS5h pasan por
-x. - Scripts. Los códigos de salida,
--retry, los tiempos de espera y--write-outpermiten que un script de shell gestione los fallos, y las funcionescurl_*de PHP aceptan las mismas opciones. - Muchas URL en un comando. Puedes indicar varias variantes de una URL en un solo comando con corchetes o llaves:
page[1-20].htmlo{a,b,c}se expanden en varias peticiones, todas por el mismo proxy.
Usos típicos: comprobar el país de una IP de salida antes de una tarea de extracción de datos, probar destinos de seguimiento de precios desde otro mercado y descargas en tareas programadas. Los equivalentes en Node.js están en cURL en JavaScript: fetch, Axios y proxy, y los de PHP en Web scraping con PHP.
¿Cómo envía cURL una petición a través de un proxy?
- cURL se conecta al proxy, no al destino.
- Destino HTTP, proxy HTTP: cURL envía la petición con la URL completa (
GET http://example.com/ HTTP/1.1). El proxy puede leerla. - Destino HTTPS, proxy HTTP: cURL envía
CONNECT example.com:443, con una cabeceraProxy-Authorizationsi indicaste credenciales. Cuando el proxy responde200, el TLS con el destino va dentro de ese túnel, así que el proxy solo ve el host y el puerto. El método CONNECT está definido en la RFC 9110. - Proxy SOCKS5: cURL inicia sesión (con usuario y contraseña, si los indicaste) y pide al proxy que se conecte al destino (RFC 1928). Con
socks5://envía una IP que resolvió él mismo; consocks5h://envía el nombre de host. - El destino responde a la IP del proxy. Tu IP no le llega, pero tus consultas DNS salen por tu propia conexión si cURL resuelve los nombres localmente.
Cómo configurar un proxy en cURL: la opción -x
curl --help proxy muestra todas las opciones de proxy. La principal es esta:
-x, --proxy <[protocol://]host[:port]> Use this proxy-x y --proxy son la misma opción, en forma corta y larga:
curl -x "http://user:pass@pr.proxynet.io:8000" https://httpbin.org/iphttpbin.org/ip devuelve la IP de origen de la petición: si el proxy funciona, ahí verás la IP de salida del proxy y no la tuya.
- Sin esquema, el proxy es HTTP.
-x "user:pass@pr.proxynet.io:8000"se comporta igual que la forma conhttp://. - Escribe siempre el puerto. Sin él, cURL elige uno por defecto: en nuestra prueba con curl 8.21, el 80 para
http://, el 443 parahttps://y el 1080 para SOCKS (el manual sigue diciendo 1080). Es poco probable que alguno coincida con el puerto de tu proveedor, así que la conexión falla o agota el tiempo de espera. - Pon la dirección entre comillas dobles. Es la forma recomendada para que el intérprete de comandos no interprete
&,?o!dentro de la URL. -xvale para un solo comando y tiene prioridad sobre las variables de entorno del proxy. El siguiente comando vuelve a salir directamente.
En los productos residenciales y móviles de Proxynet, un mismo gateway atiende HTTP y SOCKS5 en puertos distintos, y el Generador de endpoints del panel construye el nombre de usuario con el país, la ciudad y la sesión que elijas.
¿Cómo se usa cURL con un proxy HTTP o HTTPS?
Un proxy HTTP transporta los dos tipos de destino:
# Destino HTTPS: túnel CONNECT, la página sigue cifrada
curl -x "http://user:pass@pr.proxynet.io:8000" https://httpbin.org/ip
# Destino HTTP: el proxy reenvía la petición en claro
curl -x "http://user:pass@pr.proxynet.io:8000" http://httpbin.org/ipUn proxy HTTPS (https://) cifra además la conexión con el propio proxy. Úsalo solo si el puerto habla TLS; https:// apuntando a un puerto HTTP normal falla en el handshake (SEC_E_INVALID_TOKEN en Windows, normalmente wrong version number con OpenSSL).
Las opciones de certificado se reparten entre las dos conexiones:
-k(--insecure) omite la comprobación del certificado solo en el sitio de destino. Con un destinohttp://no hace nada.--proxy-insecureomite la comprobación del certificado de un proxy HTTPS.--proxy-cacert archivo.pemes más seguro: confía en la CA del proxy de una empresa sin desactivar las comprobaciones.
Si aparecen errores de certificado SSL, deja -k para pruebas rápidas y no lo uses nunca en scripts que envían tokens. Para protocolos que no son HTTP a través de un proxy HTTP, añade -p (--proxytunnel). En la página de Proxies HTTPS verás cómo pasa el tráfico cifrado por un proxy.
¿Cómo se pasan el usuario y la contraseña del proxy?
Las dos formas envían la misma cabecera Proxy-Authorization:
curl -x "http://user:pass@pr.proxynet.io:8000" https://httpbin.org/ip
curl -x "http://pr.proxynet.io:8000" -U "user:pass" https://httpbin.org/ipDentro de la dirección, los caracteres especiales de la contraseña deben ir codificados con porcentaje: @ como %40, : como %3A y # como %23. cURL los decodifica antes de enviarlos; en nuestra prueba, p%40ss llegó al proxy como p@ss. Con -U (--proxy-user) no hace falta codificar nada. La autenticación básica es la predeterminada; los proxies corporativos pueden necesitar --proxy-ntlm, --proxy-digest o --proxy-anyauth.
Las contraseñas escritas en la línea de comandos quedan en el historial de la shell. En scripts, léelas de un archivo de configuración privado (-K archivo) o usa una lista de IP autorizadas (Proxynet acepta hasta 10 IP). Autenticación de proxy: user:pass o lista blanca de IP compara los dos métodos y explica el error 407.
¿Cómo se usa cURL con un proxy SOCKS5?
Escribe la versión de SOCKS como esquema:
curl -x "socks5h://user:pass@pr.proxynet.io:1080" https://httpbin.org/ip| Esquema | Quién resuelve el nombre de host | Usuario y contraseña | Para qué usarlo |
|---|---|---|---|
http:// | El proxy | Sí | Web scraping, API, la mayoría de las herramientas |
https:// | El proxy | Sí | Un puerto de proxy que habla TLS |
socks5h:// | El proxy | Sí | SOCKS5 con un DNS acorde a la ubicación |
socks5:// | Tu equipo | Sí | Destinos que solo tu DNS puede resolver |
socks4a:// | El proxy | Solo ID de usuario | Servidores SOCKS4 antiguos |
socks4:// | Tu equipo | Solo ID de usuario | Servidores SOCKS4 antiguos |
Con socks5://, tu servidor DNS ve cada host que visitas y los sitios que tienen en cuenta la ubicación responden según la tuya; socks5h:// evita las dos cosas, y por eso suele ser la opción recomendable para web scraping (Fugas de WebRTC y DNS explica por qué importa). La opción antigua --socks5-hostname host:puerto equivale a socks5h://, con las credenciales en -U; --socks5, en cambio, equivale a socks5://.
Para las diferencias entre protocolos, consulta Diferencia entre SOCKS y HTTP: ¿cuál elegir? y Proxies SOCKS5: cómo funcionan y en qué se diferencian. Los Proxies SOCKS5 de Proxynet funcionan en su propio puerto, junto al puerto HTTP.
¿Cómo se configura un proxy para todos los comandos de cURL?
| Método | Alcance | Ejemplo |
|---|---|---|
-x | Un comando | curl -x "http://user:pass@host:port" URL |
| Variable de entorno | La sesión de la shell | export https_proxy="http://user:pass@host:port" |
.curlrc | Cada ejecución de ese usuario | proxy = "http://host:port" |
Variables de entorno. cURL lee http_proxy para destinos HTTP, https_proxy o HTTPS_PROXY para HTTPS y ALL_PROXY como alternativa general. http_proxy solo funciona en minúsculas (una protección para programas CGI), así que HTTP_PROXY se ignora en Linux y macOS. En PowerShell: $env:HTTPS_PROXY = "http://user:pass@host:port". wget, pip y git leen las mismas variables; consulta Proxy con wget: comandos y ejemplos y la página de everything curl sobre las variables de proxy.
El archivo de configuración. cURL lee ~/.curlrc (en Windows, %USERPROFILE%\.curlrc o _curlrc) antes de cada ejecución:
proxy = "http://pr.proxynet.io:8000"
proxy-user = "user:pass"curl -q URL, con -q en primer lugar, lo omite en esa ejecución.
Excepciones. --noproxy "localhost,.internal.example" o la variable NO_PROXY hacen que esos hosts se conecten directamente. Un nombre incluye también sus subdominios, los rangos CIDR como 192.168.0.0/16 funcionan y el único comodín es un * solo. NO_PROXY se aplica incluso con -x.
cURL no tiene motor de JavaScript, así que no puede ejecutar archivos PAC. Si tu red usa uno, léelo (¿Qué es un archivo PAC?) y pasa con -x el proxy que devuelve.
¿Cómo compruebas que cURL está usando el proxy?
Ejecuta curl https://api.ipify.org sin -x y con -x: si la segunda vez obtienes otra dirección, en el país esperado, el proxy funciona. Una petición HTTPS correcta a través de un proxy HTTP muestra estas líneas con -v:
* Establishing HTTP proxy tunnel to httpbin.org:443
> CONNECT httpbin.org:443 HTTP/1.1
> Proxy-Authorization: Basic dXNlcjpwYXNz
< HTTP/1.1 200 Connection Established
* CONNECT tunnel established, response 200El valor de Proxy-Authorization solo está codificado en Base64, no cifrado; bórralo antes de compartir la salida. En scripts, -w imprime el resultado en una línea:
curl -s -o /dev/null -x "http://user:pass@pr.proxynet.io:8000" \
-w "%{http_code} connect=%{http_connect} proxy_used=%{proxy_used}\n" https://httpbin.org/iphttp_connect es la respuesta del proxy al CONNECT; proxy_used (curl 8.7 o posterior) vale 1 cuando se usó un proxy. Para comprobar la ubicación, la velocidad y las fugas, consulta ¿Funciona tu proxy? Cómo probar un proxy.
Ejemplo: descargar una lista de URL a través de un proxy con reintentos
Este script descarga las URL de urls.txt de cuatro en cuatro a través del proxy, reintenta los fallos temporales e imprime el código de estado y la duración de cada una. Necesita cURL y una shell POSIX (Linux, macOS o Git Bash):
#!/usr/bin/env bash
# fetch.sh: descarga cada URL de urls.txt a través del proxy, 4 a la vez
set -u
PROXY="${PROXY:-http://user:pass@pr.proxynet.io:8000}"
sed 's/^/url = /' urls.txt | curl \
--parallel --parallel-max 4 \
--proxy "$PROXY" \
--connect-timeout 10 --max-time 30 \
--retry 3 --retry-connrefused \
--fail --silent --show-error \
--create-dirs --output-dir pages --remote-name-all \
--write-out "%{http_code} %{time_total}s %{url}\n" \
--config ---config -lee las líneasurl = …que generasedy debe ir al final, porque--remote-name-allsolo se aplica a las URL añadidas después.--retry 3reintenta los tiempos de espera agotados y las respuestas HTTP 408, 429, 500, 502, 503, 504, 522 y 524; espera 1, 2 y 4 segundos y respeta la cabeceraRetry-After.--max-timecorta una transferencia atascada;--failconvierte los errores HTTP en el código de salida 22.- Mantén bajo
--parallel-maxcuando todas las URL son del mismo sitio; demasiadas peticiones en paralelo pueden provocar respuestas 429.
En nuestra prueba se guardaron cuatro páginas y una URL que devolvía 503 se reintentó tres veces antes de que el script terminara con el código 22.
Repite una petición contra api.ipify.org para ver si tu gateway rota: un gateway rotativo devuelve una IP nueva cada vez, y una sesión fija mantiene la misma IP entre 1 y 60 minutos en Proxynet. Qué es la rotación de IP y cómo funciona explica cuándo conviene cada modo; los Proxies residenciales admiten los dos. Para descargas masivas desde sitios que no bloquean las IP de centro de datos, suelen bastar los Proxies de centro de datos.
Errores comunes de cURL con proxy y cómo solucionarlos
Los mensajes aparecen tal como los imprimió curl 8.21 en nuestras pruebas:
curl: (5) Could not resolve proxy: …El nombre de host del proxy está mal: revisa la ortografía y que no sobren comillas.curl: (7) Failed to connect to … over proxy …Nada responde en ese puerto (o cURL recurrió a un puerto por defecto porque no se indicó ninguno), o un firewall lo bloquea.curl: (7) CONNECT tunnel failed, response 407Credenciales incorrectas, caracteres especiales sin codificar o una IP que no está en la lista de IP autorizadas. Las versiones antiguas imprimencurl: (56) Received HTTP code 407 from proxy after CONNECT; con destinoshttp://simplemente recibes el estado 407. Consulta Códigos de estado HTTP en web scraping.curl: (56) Proxy CONNECT abortedEl proxy cerró la conexión; en nuestra prueba, una direcciónhttp://apuntaba a un puerto SOCKS5.curl: (97) Received invalid version in initial SOCKS5 response.Una direcciónsocks5://apunta a un puerto HTTP.User was rejected by the SOCKS5 serversignifica que las credenciales SOCKS son incorrectas.curl: (28) Connection timed out after … millisecondsNo hubo respuesta a tiempo; consulta El servidor proxy no responde.curl: (35) …oSSL_ERROR_SYSCALLFalló el handshake TLS:https://en un puerto de proxy sin TLS, o un dispositivo de red que corta las conexiones TLS.curl: (60) SSL certificate problem: unable to get local issuer certificateSuele ser un proxy corporativo que inspecciona el tráfico TLS. Instala su certificado de CA en lugar de usar-k.- El proxy se ignora. Busca
NO_PROXY, unHTTP_PROXYen mayúsculas u otro.curlrc;-vmuestra a qué dirección intenta conectarse cURL primero. La versión en Python de estos fallos está en Max Retries Exceeded With URL: qué es y cómo solucionarlo.
Guía de decisión
| Necesidad | Recomendación |
|---|---|
| Probar un proxy nuevo una vez | curl -x "http://user:pass@host:port" https://httpbin.org/ip |
La contraseña contiene @, : o # | -U "user:pass", o codificarla con porcentaje |
| DNS resuelto en el proxy | socks5h://, no socks5:// |
| FTP, SMTP u otro protocolo que no es HTTP | SOCKS5, o -p con un proxy HTTP |
| Proxy para una sesión de shell | export https_proxy=… y http_proxy en minúsculas |
| Proxy para todas las ejecuciones | proxy = "…" en ~/.curlrc |
| Sin contraseñas en los scripts | Lista de IP autorizadas en el panel |
| La misma IP para un flujo de inicio de sesión | Sesión fija desde el Generador de endpoints |
Preguntas frecuentes
¿cURL usa la configuración de proxy del sistema en Windows o macOS?
No. cURL solo toma el proxy de -x, de las variables de entorno y de .curlrc. Un proxy definido en la Configuración de Windows o en los Ajustes del Sistema de macOS no le afecta.
¿Cómo hago que cURL ignore el proxy en una sola petición?
Añade --noproxy "*" o -x "". Cualquiera de las dos opciones envía ese comando directamente aunque https_proxy o .curlrc definan un proxy.
¿Por qué falla mi comando de cURL con proxy en PowerShell?
En Windows PowerShell 5.1, curl es un alias de Invoke-WebRequest, que no conoce -x. Escribe curl.exe para ejecutar el cURL real. PowerShell 7 ya no tiene ese alias.
¿Qué diferencia hay entre socks5 y socks5h en cURL?
Con socks5://, tu equipo resuelve el nombre de host; con socks5h:// lo resuelve el proxy, así que el DNS coincide con la ubicación del proxy.
¿Puedo usar un proxy con cURL en PHP?
Sí. Las funciones cURL de PHP usan libcurl: CURLOPT_PROXY fija la dirección, CURLOPT_PROXYUSERPWD las credenciales y CURLOPT_PROXYTYPE el tipo de SOCKS. Tienes ejemplos en Web scraping con PHP: cURL, Guzzle y uso de proxy.
¿Puede cURL rotar el proxy en cada petición?
cURL usa un proxy por comando. Un gateway rotativo asigna una IP de salida nueva por conexión, así que un bucle de comandos obtiene una IP distinta cada vez. Varias URL en un mismo comando suelen reutilizar una conexión y comparten su IP.
En resumen
Para usar cURL con un proxy, añade -x con la dirección completa: esquema, credenciales, host y puerto. Usa http:// para la mayoría de los trabajos y socks5h:// para SOCKS5 con DNS remoto, pon el proxy en https_proxy o en .curlrc cuando todos los comandos lo necesiten y deja -k para las pruebas. Cuando un comando falla, el código de salida y la salida de -v indican si el problema está en la dirección, en las credenciales o en el destino. Si buscas endpoints residenciales, móviles y SOCKS5 que funcionen con estos comandos, consulta los proxies de Proxynet.




