Jika Anda mengelola server, menulis skrip otomatisasi, atau menerapkan aplikasi dalam infrastruktur perusahaan β cepat atau lambat Anda akan menghadapi kebutuhan untuk mengalihkan lalu lintas curl atau wget melalui proxy. Ini bisa berupa proxy perusahaan, menghindari pemblokiran geo saat mengunduh paket, atau rotasi IP saat melakukan permintaan massal ke API eksternal. Dalam artikel ini β hanya praktik: perintah, konfigurasi, contoh kode tanpa basa-basi.
1. Bagaimana curl dan wget bekerja dengan proxy: mekanisme dasar
Sebelum masuk ke konfigurasi, penting untuk memahami apa yang terjadi di balik layar. Kedua alat ini mendukung dua protokol proxy utama: HTTP/HTTPS dan SOCKS5. Mekanisme mereka berbeda, dan ini mempengaruhi jenis proxy yang harus dipilih untuk tugas tertentu.
Proxy HTTP berfungsi sebagai perantara di tingkat protokol aplikasi. Ketika curl mengirimkan permintaan melalui proxy HTTP, ia secara harfiah memberi tahu server proxy: βlakukan permintaan GET ke URL ini menggantikan sayaβ. Untuk lalu lintas HTTPS, metode CONNECT digunakan β curl meminta proxy untuk membuat terowongan ke host tujuan, setelah itu handshake TLS terjadi langsung antara klien dan server tujuan. Ini penting: proxy dalam hal ini tidak melihat konten lalu lintas HTTPS.
SOCKS5 bekerja di tingkat yang lebih rendah β ia memproksikan koneksi TCP/UDP tanpa terikat pada protokol tingkat aplikasi. Ini membuat SOCKS5 lebih universal: melalui ini Anda dapat mengalihkan tidak hanya HTTP/HTTPS, tetapi juga protokol lainnya. Selain itu, SOCKS5 mendukung resolusi DNS di sisi server proxy β ini sangat penting untuk mencegah kebocoran DNS.
π‘ Perbedaan kunci untuk praktik:
Jika Anda hanya perlu mengunduh file atau melakukan permintaan API β proxy HTTP sudah cukup. Jika Anda memerlukan anonimitas penuh, menghindari kebocoran DNS, atau bekerja dengan protokol yang tidak standar β gunakan SOCKS5.
curl mendukung kedua protokol secara native sejak versi yang sangat awal. wget secara historis memiliki dukungan SOCKS5 yang lebih terbatas β di versi lama (hingga 1.19) tidak ada dukungan SOCKS5 sama sekali, hanya proxy HTTP. Ini perlu diperhatikan saat menulis skrip yang harus berfungsi di berbagai distribusi.
Untuk memeriksa versi wget, gunakan perintah wget --version. Untuk curl β curl --version, di sana juga akan terlihat protokol mana yang didukung oleh pustaka libcurl.
2. Variabel lingkungan: cara tercepat untuk mengatur
Cara paling elegan untuk mengatur proxy untuk curl dan wget adalah melalui variabel lingkungan. Ini bekerja secara sistematis: Anda tidak perlu mengubah setiap skrip, cukup atur variabel sekali dalam sesi atau tambahkan ke profil pengguna.
Kedua alat ini membaca variabel standar yang sama:
# Untuk lalu lintas HTTP export http_proxy="http://proxy.example.com:3128" # Untuk lalu lintas HTTPS export https_proxy="http://proxy.example.com:3128" # Duplikasi dalam huruf besar (beberapa program hanya membaca ini) export HTTP_PROXY="http://proxy.example.com:3128" export HTTPS_PROXY="http://proxy.example.com:3128" # Untuk FTP (jika diperlukan) export ftp_proxy="http://proxy.example.com:3128" # Pengecualian β alamat yang TIDAK melalui proxy export no_proxy="localhost,127.0.0.1,::1,192.168.0.0/16,.internal.company.com"
Nuansa penting: curl sensitif terhadap huruf besar kecil variabel tergantung pada versinya. Agar tidak ada kejutan β selalu atur kedua versi: huruf kecil dan huruf besar. Ini adalah praktik standar dalam DevOps.
Agar pengaturan diterapkan secara permanen untuk pengguna tertentu, tambahkan baris ke ~/.bashrc atau ~/.profile. Untuk skrip dan layanan sistem β di /etc/environment atau di file unit systemd melalui direktif Environment=.
# /etc/systemd/system/myservice.service
[Service]
Environment="http_proxy=http://proxy.example.com:3128"
Environment="https_proxy=http://proxy.example.com:3128"
Environment="no_proxy=localhost,127.0.0.1"
ExecStart=/usr/bin/myapp
Jika proxy memerlukan otentikasi, login dan password dimasukkan langsung ke URL variabel:
export http_proxy="http://username:[email protected]:3128" export https_proxy="http://username:[email protected]:3128"
β οΈ Keamanan:
Jangan simpan password dalam bentuk terbuka di .bashrc atau di variabel lingkungan di server produksi. Gunakan solusi vault (HashiCorp Vault, AWS Secrets Manager) atau setidaknya batasi hak akses ke file variabel.
3. Flag curl untuk bekerja dengan proxy: analisis lengkap
curl menyediakan serangkaian flag yang kaya untuk mengelola proxy langsung dari baris perintah. Ini nyaman ketika Anda perlu melakukan permintaan satu kali melalui proxy tanpa mengubah pengaturan sistem.
Flag utama β -x atau --proxy:
# Proxy HTTP dasar curl -x http://proxy.example.com:3128 https://api.example.com/data # Bentuk singkat curl -x proxy.example.com:3128 https://api.example.com/data # Dengan penunjukan protokol yang jelas curl --proxy http://proxy.example.com:3128 https://api.example.com/data # Memeriksa IP eksternal melalui proxy curl -x http://proxy.example.com:3128 https://api.ipify.org
Untuk mengabaikan variabel lingkungan dan melakukan koneksi langsung (menghindari proxy yang telah diatur), gunakan flag --noproxy:
# Mengabaikan proxy untuk host tertentu curl --noproxy "internal.company.com" https://internal.company.com/api # Mengabaikan proxy sepenuhnya (meskipun variabel lingkungan diatur) curl --noproxy "*" https://api.example.com/data
Flag yang berguna untuk debugging koneksi proxy:
# Mode verbose: semua header terlihat, termasuk CONNECT ke proxy curl -v -x http://proxy.example.com:3128 https://api.example.com/data # Hanya header respons curl -I -x http://proxy.example.com:3128 https://api.example.com/data # Menampilkan waktu koneksi melalui proxy curl -w "Connect: %{time_connect}s\nTotal: %{time_total}s\n" \ -x http://proxy.example.com:3128 \ -o /dev/null -s https://api.example.com/data
Mengatur proxy melalui file konfigurasi ~/.curlrc β nyaman jika Anda tidak ingin menulis flag setiap kali:
# ~/.curlrc
proxy = http://proxy.example.com:3128
proxy-user = username:password
noproxy = localhost,127.0.0.1,.internal.company.com
Untuk skrip sistem, Anda dapat membuat konfigurasi terpisah dan menyebutkannya secara eksplisit melalui curl -K /path/to/config β ini memungkinkan Anda memiliki profil proxy yang berbeda untuk tugas yang berbeda.
4. Pengaturan proxy di wget: flag dan file konfigurasi
wget kurang fleksibel dibandingkan curl, tetapi untuk tugas-tugas umum β mengunduh file, mencerminkan situs secara rekursif β kemampuannya sudah cukup. Proxy di wget dapat diatur dengan tiga cara: melalui variabel lingkungan (telah dibahas di atas), melalui flag baris perintah, dan melalui file konfigurasi ~/.wgetrc.
Flag baris perintah wget untuk proxy:
# Proxy HTTP melalui flag wget -e use_proxy=yes \ -e http_proxy=http://proxy.example.com:3128 \ https://example.com/file.tar.gz # HTTPS melalui proxy wget -e use_proxy=yes \ -e https_proxy=http://proxy.example.com:3128 \ https://example.com/file.tar.gz # Dengan otentikasi wget -e use_proxy=yes \ -e http_proxy=http://username:[email protected]:3128 \ https://example.com/file.tar.gz # Menonaktifkan proxy untuk perintah tertentu (jika variabel lingkungan diatur) wget --no-proxy https://internal.company.com/file.tar.gz
File konfigurasi ~/.wgetrc β cara yang disukai untuk pengaturan permanen:
# ~/.wgetrc use_proxy = on http_proxy = http://proxy.example.com:3128 https_proxy = http://proxy.example.com:3128 ftp_proxy = http://proxy.example.com:3128 no_proxy = localhost,127.0.0.1,.internal.company.com # Jika proxy memerlukan otentikasi proxy_user = username proxy_password = secretpassword
Untuk penerapan sistem (semua pengguna), gunakan /etc/wgetrc β format yang sama, tetapi diterapkan secara global. Ini nyaman untuk server di mana semua operasi pengunduhan harus melalui proxy perusahaan.
Contoh praktis: pengunduhan situs secara rekursif melalui proxy dengan batasan kedalaman dan kecepatan:
wget -e use_proxy=yes \
-e http_proxy=http://proxy.example.com:3128 \
--recursive \
--level=2 \
--limit-rate=500k \
--wait=1 \
--random-wait \
--user-agent="Mozilla/5.0 (compatible; Googlebot/2.1)" \
https://example.com/docs/
5. Proxy SOCKS5 di curl dan wget: pengaturan dan contoh
SOCKS5 β protokol yang lebih disukai untuk tugas-tugas di mana anonimitas atau bekerja dengan port yang tidak standar penting. Untuk administrator sistem dan insinyur DevOps, SOCKS5 sering digunakan saat bekerja melalui terowongan SSH, serta saat terhubung ke proxy residensial, yang meniru lalu lintas pengguna nyata.
Di curl, SOCKS5 didukung melalui prefiks khusus di URL proxy:
# SOCKS5 dengan resolusi DNS di sisi klien (mungkin ada kebocoran DNS!) curl --socks5 proxy.example.com:1080 https://api.example.com/data # SOCKS5 dengan resolusi DNS di sisi proxy (direkomendasikan!) curl --socks5-hostname proxy.example.com:1080 https://api.example.com/data # Melalui flag -x dengan penunjukan protokol yang jelas curl -x socks5h://proxy.example.com:1080 https://api.example.com/data # Dengan otentikasi curl -x socks5h://username:[email protected]:1080 https://api.example.com/data # SOCKS5 melalui variabel lingkungan export all_proxy="socks5h://proxy.example.com:1080" curl https://api.example.com/data
π socks5 vs socks5h β apa perbedaannya?
socks5 β permintaan DNS dilakukan secara lokal, melalui proxy hanya koneksi TCP berdasarkan IP. Kemungkinan kebocoran DNS.socks5h (h = hostname) β permintaan DNS dilakukan di sisi server proxy. Anonimitas penuh. Direkomendasikan untuk sebagian besar tugas.
Skenario populer di DevOps β menggunakan SSH sebagai proxy SOCKS5 untuk men-tunnel lalu lintas melalui bastion host:
# Membuka terowongan SSH dengan SOCKS5 di port lokal 1080 ssh -D 1080 -f -C -q -N [email protected] # Sekarang gunakan terowongan ini di curl curl -x socks5h://localhost:1080 https://internal-api.private.network/data # Atau melalui variabel lingkungan untuk semua permintaan dalam sesi export all_proxy="socks5h://localhost:1080" wget https://internal-resource.private.network/file.tar.gz
wget mendukung SOCKS5 mulai dari versi 1.19. Di versi yang lebih lama (CentOS 7, Ubuntu 16.04) Anda harus menggunakan solusi alternatif: proxychains, tsocks, atau beralih ke curl untuk tugas yang memerlukan SOCKS5.
6. Otentikasi di proxy: login dan password
Sebagian besar proxy komersial dan server proxy perusahaan memerlukan otentikasi. Ada beberapa cara untuk mengirimkan kredensial β masing-masing dengan kelebihan dan kekurangan dari segi keamanan.
Cara 1: Kredensial di URL β sederhana, tetapi tidak aman (password terlihat di daftar proses):
curl -x http://user:p%[email protected]:3128 https://api.example.com/data # Karakter khusus dalam password perlu di URL-encode: @ β %40, : β %3A
Cara 2: Flag --proxy-user di curl β password tidak perlu dicantumkan di baris perintah, curl akan meminta secara interaktif:
# Login dan password di flag (masih terlihat di ps aux) curl -x http://proxy.example.com:3128 \ --proxy-user "username:password" \ https://api.example.com/data # Hanya login β curl akan meminta password secara interaktif curl -x http://proxy.example.com:3128 \ --proxy-user "username" \ https://api.example.com/data
Cara 3: Melalui file .netrc β paling aman untuk skrip:
# ~/.netrc machine proxy.example.com login username password secretpassword # Batasi hak akses ke file chmod 600 ~/.netrc # Digunakan di curl curl -x http://proxy.example.com:3128 --proxy-netrc https://api.example.com/data
Cara 4: Melalui variabel lingkungan dari penyimpanan rahasia β direkomendasikan untuk CI/CD dan lingkungan produksi:
# Dalam skrip, baca kredensial dari variabel (yang ditetapkan oleh CI/CD)
#!/bin/bash
PROXY_URL="http://${PROXY_USER}:${PROXY_PASS}@proxy.example.com:3128"
curl -x "${PROXY_URL}" https://api.example.com/data
Tabel perbandingan metode otentikasi:
| Metode | Kemudahan | Keamanan | Cocok untuk |
|---|---|---|---|
| URL (user:pass@host) | βββ | β | Pengujian |
| Flag --proxy-user | βββ | ββ | Perintah satu kali |
| File .netrc | ββ | βββ | Skrip lokal |
| Variabel lingkungan dari vault | ββ | βββββ | CI/CD, produksi |
7. Pengecualian dan no_proxy: cara menghindari proxy untuk alamat lokal
Di lingkungan perusahaan dan cloud, sering kali diperlukan pengaturan yang halus: lalu lintas eksternal β melalui proxy, internal β langsung. Variabel no_proxy (atau NO_PROXY) memungkinkan Anda untuk menetapkan daftar pengecualian.
# Pengecualian dasar export no_proxy="localhost,127.0.0.1,::1" # Pengecualian berdasarkan domain (dengan titik β semua subdomain) export no_proxy="localhost,127.0.0.1,.internal.company.com,.corp.local" # Pengecualian berdasarkan rentang IP (notasi CIDR tidak berfungsi di semua tempat!) export no_proxy="localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16" # Untuk AWS: kecualikan endpoint metadata dan alamat internal export no_proxy="localhost,127.0.0.1,169.254.169.254,.amazonaws.com.internal"
β οΈ Fitur penting no_proxy:
Notasi CIDR (10.0.0.0/8) tidak didukung oleh semua alat. curl mendukungnya mulai dari versi 7.86.0. wget β tidak mendukung sama sekali. Untuk kompatibilitas, lebih baik mencantumkan IP tertentu atau masker seperti 10. (semua yang dimulai dengan 10.).
Contoh praktis untuk lingkungan Kubernetes, di mana perlu mengecualikan API server dan layanan internal:
export no_proxy="localhost,127.0.0.1,10.96.0.0/12,10.244.0.0/16,.cluster.local,.svc,.default"
export NO_PROXY="${no_proxy}"
8. Proxy di CI/CD: GitHub Actions, GitLab CI, Docker
Pengaturan proxy dalam pipeline CI/CD β salah satu tugas paling umum bagi insinyur DevOps yang bekerja di jaringan perusahaan atau dengan akses terbatas ke internet. Mari kita bahas konfigurasi spesifik untuk platform populer.
GitHub Actions
# .github/workflows/deploy.yml
name: Deploy
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
env:
http_proxy: ${{ secrets.PROXY_URL }}
https_proxy: ${{ secrets.PROXY_URL }}
no_proxy: "localhost,127.0.0.1,.github.com"
steps:
- uses: actions/checkout@v3
- name: Unduh ketergantungan
run: |
curl -x "${http_proxy}" https://external-api.example.com/config.json -o config.json
wget -e use_proxy=yes -e http_proxy="${http_proxy}" https://releases.example.com/app-v1.0.tar.gz
GitLab CI
# .gitlab-ci.yml
variables:
http_proxy: "http://proxy.company.com:3128"
https_proxy: "http://proxy.company.com:3128"
no_proxy: "localhost,127.0.0.1,.gitlab.company.com"
build:
stage: build
script:
- curl -x "${http_proxy}" https://registry.npmjs.org/package -o package.json
- wget -e use_proxy=yes -e http_proxy="${http_proxy}" https://example.com/resource.tar.gz
Docker: proxy saat membangun image
# Mengirimkan proxy melalui build args docker build \ --build-arg http_proxy=http://proxy.example.com:3128 \ --build-arg https_proxy=http://proxy.example.com:3128 \ --build-arg no_proxy=localhost,127.0.0.1 \ -t myapp:latest . # Di Dockerfile, gunakan ARG untuk mendapatkan variabel
# Dockerfile FROM ubuntu:22.04 ARG http_proxy ARG https_proxy ARG no_proxy ENV http_proxy=${http_proxy} ENV https_proxy=${https_proxy} ENV no_proxy=${no_proxy} RUN apt-get update && apt-get install -y curl wget RUN curl -x "${http_proxy}" https://example.com/setup.sh | bash # Menghapus variabel proxy di image akhir (opsional) ENV http_proxy="" ENV https_proxy=""
Pengaturan global proxy untuk daemon Docker (untuk docker pull melalui proxy):
# /etc/systemd/system/docker.service.d/proxy.conf [Service] Environment="HTTP_PROXY=http://proxy.example.com:3128" Environment="HTTPS_PROXY=http://proxy.example.com:3128" Environment="NO_PROXY=localhost,127.0.0.1,.internal.registry.com" # Restart docker systemctl daemon-reload systemctl restart docker
9. Rotasi proxy dalam skrip bash
Jika Anda perlu melakukan banyak permintaan ke API eksternal atau layanan β rotasi proxy memungkinkan Anda untuk mendistribusikan beban dan menghindari pemblokiran berdasarkan IP. Ini sangat relevan saat memantau harga, mengumpulkan data, atau menguji ketersediaan sumber daya dari berbagai wilayah.
Untuk tugas semacam itu, proxy data center sangat cocok β mereka memberikan kecepatan tinggi dan stabilitas saat melakukan permintaan massal.
#!/bin/bash # rotate_proxy.sh β rotasi proxy dari daftar PROXY_LIST=( "http://user:[email protected]:3128" "http://user:[email protected]:3128" "http://user:[email protected]:3128" "http://user:[email protected]:3128" ) URLS_FILE="urls.txt" OUTPUT_DIR="./results" mkdir -p "${OUTPUT_DIR}" PROXY_COUNT=${#PROXY_LIST[@]} INDEX=0 while IFS= read -r url; do PROXY="${PROXY_LIST[$INDEX]}" FILENAME=$(echo "${url}" | md5sum | cut -d' ' -f1) echo "Meminta: ${url} melalui proxy $((INDEX + 1))/${PROXY_COUNT}" curl -x "${PROXY}" \ --max-time 30 \ --retry 3 \ --retry-delay 2 \ --silent \ --output "${OUTPUT_DIR}/${FILENAME}.html" \ "${url}" if [ $? -eq 0 ]; then echo " β Sukses" else echo " β Gagal, mencoba proxy berikutnya..." INDEX=$(( (INDEX + 1) % PROXY_COUNT )) curl -x "${PROXY_LIST[$INDEX]}" \ --max-time 30 \ --silent \ --output "${OUTPUT_DIR}/${FILENAME}.html" \ "${url}" fi # Beralih ke proxy berikutnya INDEX=$(( (INDEX + 1) % PROXY_COUNT )) # Sedikit jeda antara permintaan sleep 0.5 done < "${URLS_FILE}" echo "Selesai! Hasil disimpan di ${OUTPUT_DIR}"
Versi yang lebih canggih β memeriksa ketersediaan proxy sebelum digunakan:
#!/bin/bash # check_proxy.sh β memeriksa ketersediaan proxy check_proxy() { local proxy_url="$1" local test_url="https://api.ipify.org" result=$(curl -x "${proxy_url}" \ --max-time 10 \ --silent \ --write-out "%{http_code}" \ --output /dev/null \ "${test_url}") if [ "${result}" -eq 200 ]; then echo "HIDUP" else echo "MATI" fi } # Mendapatkan IP eksternal melalui proxy get_proxy_ip() { local proxy_url="$1" curl -x "${proxy_url}" --max-time 10 --silent https://api.ipify.org } PROXY="http://user:[email protected]:3128" STATUS=$(check_proxy "${PROXY}") echo "Status proxy: ${STATUS}" if [ "${STATUS}" == "HIDUP" ]; then EXTERNAL_IP=$(get_proxy_ip "${PROXY}") echo "IP eksternal melalui proxy: ${EXTERNAL_IP}" fi
10. Pemecahan masalah dan kesalahan umum
Bekerja dengan proxy tidak terhindarkan dari kesalahan β terutama saat pengaturan awal. Mari kita bahas masalah yang paling umum dan cara mendiagnosisnya.
Diagnostik menggunakan mode verbose
# Output curl yang paling mendetail curl -vvv -x http://proxy.example.com:3128 https://api.example.com/data 2>&1 | head -50 # Apa yang harus diperhatikan dalam output: # * Terhubung ke proxy.example.com β koneksi ke proxy telah dibuat # CONNECT api.example.com:443 β permintaan untuk terowongan # HTTP/1.1 200 Koneksi berhasil β terowongan terbuka # * Koneksi SSL menggunakan TLS β TLS berfungsi # Debugging wget wget -d -e use_proxy=yes -e http_proxy=http://proxy.example.com:3128 https://api.example.com/data
Kesalahan umum dan solusinya
| Kesalahan | Penyebab | Solusi |
|---|---|---|
407 Proxy Authentication Required |
Kredensial tidak diberikan | Tambahkan user:pass di URL proxy atau flag --proxy-user |
Connection refused |
Port salah atau proxy tidak tersedia | Periksa port: nc -zv proxy.host 3128 |
SSL certificate error |
Proxy perusahaan dengan inspeksi SSL | Tambahkan CA perusahaan: --cacert /path/to/ca.crt |
Could not resolve proxy |
DNS tidak meresolusi nama proxy | Gunakan IP alih-alih nama atau periksa DNS |
Timeout |
Proxy lambat atau kelebihan beban | Tingkatkan timeout: --max-time 60 |