Proxy ve HTTP Tünel Üzerinden Bağlantı Sorunlarını Giderme

Kurumsal ağlarda proxy arkasında çalışmak, sistem yöneticilerinin en sık karşılaştığı ve en çok baş ağrıtan durumlardan biridir. Bir şey düzgün çalışmıyorsa ve ağda proxy varsa, suçlu büyük ihtimalle odur. Bu yazıda proxy ve HTTP tünel bağlantı sorunlarını metodolojik bir yaklaşımla nasıl çözeceğinizi, hangi araçları kullanacağınızı ve gerçek dünya senaryolarında nereye bakmanız gerektiğini ele alacağım.

Proxy Nedir, HTTP Tüneli Nedir?

Önce temel kavramları netleştirelim. HTTP proxy, istemci ile sunucu arasında aracı olarak çalışan ve istekleri yönlendiren bir servistir. Kurumsal ortamlarda güvenlik, içerik filtreleme ve bant genişliği yönetimi için yaygın olarak kullanılır.

HTTP tüneli ise farklı bir şeydir. CONNECT metodu aracılığıyla proxy üzerinden TCP tüneli oluşturur. Özellikle HTTPS trafiği için kritik öneme sahiptir çünkü proxy, şifreli içeriği göremez; sadece tüneli geçirir. CONNECT hedef.sunucu.com:443 HTTP/1.1 şeklinde bir istek ile proxy’ye “bu bağlantıyı benim için tünel et” demiş olursunuz.

Ortam Değişkenlerini Kontrol Et

Proxy sorunlarının büyük çoğunluğu yanlış yapılandırılmış ortam değişkenlerinden kaynaklanır. Linux’ta ilk yapmanız gereken şey mevcut proxy ayarlarına bakmaktır.

# Tüm proxy ile ilgili ortam değişkenlerini listele
env | grep -i proxy

# Veya daha temiz bir görünüm için
printenv | grep -iE "http_proxy|https_proxy|ftp_proxy|no_proxy|all_proxy"

Sık karşılaşılan sorun: http_proxy küçük harfle tanımlanmış ama uygulama büyük harfli HTTP_PROXY‘yi okuyor. Ya da tam tersi. Güvenli tarafta olmak için her ikisini de tanımlayın:

# /etc/environment veya ~/.bashrc dosyasına ekleyin
export http_proxy="http://proxy.sirket.com:8080"
export HTTP_PROXY="http://proxy.sirket.com:8080"
export https_proxy="http://proxy.sirket.com:8080"
export HTTPS_PROXY="http://proxy.sirket.com:8080"
export no_proxy="localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,.sirket.com"
export NO_PROXY="localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,.sirket.com"

no_proxy değişkeni kritik öneme sahip. İç ağ adreslerini buraya eklemezseniz, iç kaynaklara erişmeye çalışırken trafik proxy üzerinden geçer ve bağlantı başarısız olur. Özellikle Kubernetes ortamlarında pod’ların birbirleriyle haberleşmesi için servis CIDR bloklarını mutlaka no_proxy‘e ekleyin.

curl ile Proxy Bağlantısını Test Et

curl, proxy sorunlarını debug etmek için en güçlü araçlardan biridir. Verbose modda kullanıldığında proxy üzerinden gerçekte ne olduğunu gösterir.

# Proxy üzerinden basit HTTP testi
curl -v --proxy http://proxy.sirket.com:8080 http://example.com

# HTTPS testi - CONNECT tünelini görmek için
curl -v --proxy http://proxy.sirket.com:8080 https://example.com

# Kimlik doğrulama gerektiren proxy
curl -v --proxy http://kullanici:[email protected]:8080 https://example.com

# Proxy bypass testi - direkt bağlantı
curl -v --noproxy "*" https://example.com

Verbose çıktısında dikkat etmeniz gereken satırlar şunlar:

  • * Connected to proxy.sirket.com (10.1.2.3) port 8080 – Proxy’ye ulaşıldı
  • > CONNECT example.com:443 HTTP/1.1 – Tünel isteği gönderildi
  • < HTTP/1.1 200 Connection established – Tünel kuruldu, artık HTTPS konuşuluyor
  • < HTTP/1.1 407 Proxy Authentication Required – Kimlik doğrulama gerekiyor
  • < HTTP/1.1 403 Forbidden – Proxy bu hedefe izin vermiyor

Eğer < HTTP/1.1 200 Connection established yerine farklı bir hata kodu görüyorsanız, sorun proxy konfigürasyonundadır, uygulamanın kendisinde değil.

Kimlik Doğrulama Sorunları

Kurumsal proxy’lerin büyük çoğunluğu NTLM veya Kerberos tabanlı kimlik doğrulama kullanır. Bu, Linux sistemlerde özellikle karmaşık bir hal alabilir.

407 Proxy Authentication Required hatasıyla karşılaşıyorsanız:

# NTLM kimlik doğrulama ile curl
curl -v --proxy http://proxy.sirket.com:8080 
     --proxy-ntlm 
     --proxy-user "DOMAIN\kullanici:sifre" 
     https://example.com

# Negotiate/Kerberos için
curl -v --proxy http://proxy.sirket.com:8080 
     --proxy-negotiate 
     --proxy-user ":" 
     https://example.com

Eğer şifreyi komut satırında yazmak istemiyorsanız .netrc dosyasını kullanabilirsiniz:

# ~/.netrc dosyası oluştur
cat > ~/.netrc << 'EOF'
machine proxy.sirket.com
login kullanici_adi
password sifre_buraya
EOF

chmod 600 ~/.netrc

# curl .netrc'yi otomatik okur
curl -v --proxy http://proxy.sirket.com:8080 --proxy-netrc https://example.com

Önemli bir not: Ortam değişkenine şifreyi gömerken dikkatli olun. http_proxy="http://kullanici:sifre@proxy:8080" şeklinde tanımladığınızda, ps aux veya env çıktısında şifre açıkça görünür. Bunu bilen bir saldırgan şifrenizi kolayca ele geçirebilir.

SSL/TLS Sertifika Sorunları

Kurumsal ortamlarda sıkça karşılaşılan başka bir senaryo: Proxy, HTTPS trafiğini denetlemek için SSL inspection (SSL interception veya MITM proxy) yapıyor. Bu durumda proxy kendi sertifikasını imzalıyor ve istemciler orijinal sertifikayı görmüyor.

Belirtiyi şöyle anlarsınız: curl: (60) SSL certificate problem: unable to get local issuer certificate

# Hangi sertifikayı gördüğünüzü kontrol et
openssl s_client -connect hedef.com:443 -proxy proxy.sirket.com:8080

# Proxy sertifikasını incele
echo | openssl s_client -connect hedef.com:443 
      -proxy proxy.sirket.com:8080 2>/dev/null | 
      openssl x509 -noout -issuer -subject -dates

Çözüm: Kurumsal CA sertifikasını sisteme ekleyin.

# Debian/Ubuntu
sudo cp kurumsal-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

# RHEL/CentOS/Rocky
sudo cp kurumsal-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

# Doğrulama
curl -v https://hedef.com
# Artık --insecure olmadan çalışmalı

curl için geçici çözüm (production’da kullanmayın):

curl --insecure --proxy http://proxy.sirket.com:8080 https://hedef.com

--insecure bayrağını production ortamlarda kullanmak güvenlik açığı oluşturur. Bunu sadece sorunun kaynağını tespit etmek için diagnostik amaçlı kullanın.

wget ve apt/yum Proxy Sorunları

Paket yöneticilerinin proxy üzerinden çalışmaması, özellikle yeni sunucu kurulumlarında sık karşılaşılan bir durumdur.

apt için:

# /etc/apt/apt.conf.d/02proxy dosyası oluştur
cat > /etc/apt/apt.conf.d/02proxy << 'EOF'
Acquire::http::Proxy "http://proxy.sirket.com:8080/";
Acquire::https::Proxy "http://proxy.sirket.com:8080/";
Acquire::ftp::Proxy "http://proxy.sirket.com:8080/";
EOF

# Test et
apt-get update

yum/dnf için:

# /etc/yum.conf veya /etc/dnf/dnf.conf dosyasına ekle
echo "proxy=http://proxy.sirket.com:8080" >> /etc/yum.conf
echo "proxy_username=kullanici" >> /etc/yum.conf
echo "proxy_password=sifre" >> /etc/yum.conf

# Test et
yum makecache

wget için:

# ~/.wgetrc veya /etc/wgetrc
cat >> ~/.wgetrc << 'EOF'
http_proxy = http://proxy.sirket.com:8080/
https_proxy = http://proxy.sirket.com:8080/
use_proxy = on
EOF

# Komut satırından da belirtebilirsiniz
wget -e use_proxy=yes 
     -e http_proxy=http://proxy.sirket.com:8080 
     https://example.com/dosya.tar.gz

Docker ve Container Ortamlarında Proxy

Docker daemon’ı proxy arkasında çalıştırmak bambaşka bir hikaye. İki ayrı yeri yapılandırmanız gerekiyor: Docker daemon’ın kendisi (image pull için) ve container’ların içi (container’ların dışarıya erişimi için).

# Docker daemon için proxy ayarı
sudo mkdir -p /etc/systemd/system/docker.service.d/
cat > /etc/systemd/system/docker.service.d/proxy.conf << 'EOF'
[Service]
Environment="HTTP_PROXY=http://proxy.sirket.com:8080"
Environment="HTTPS_PROXY=http://proxy.sirket.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,.sirket.com"
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

# Ayarların uygulandığını doğrula
sudo systemctl show --property=Environment docker

Container içinde proxy kullanmak için Dockerfile’da:

# Build argümanları ile
docker build 
  --build-arg HTTP_PROXY=http://proxy.sirket.com:8080 
  --build-arg HTTPS_PROXY=http://proxy.sirket.com:8080 
  --build-arg NO_PROXY=localhost,.sirket.com 
  -t uygulama:latest .

# Docker compose ile
# docker-compose.yml içinde
# environment:
#   - HTTP_PROXY=http://proxy.sirket.com:8080
#   - HTTPS_PROXY=http://proxy.sirket.com:8080

Dikkat edilmesi gereken nokta: ~/.docker/config.json içindeki proxy ayarları sadece Docker CLI için geçerlidir, daemon için değil. Bu farkı bilmemek saatlerce debug yapmaya yol açabilir.

Git ve SSH Tünel Sorunları

Git’in proxy üzerinden çalışmaması, geliştirici makinelerinde sık görülen bir durumdur.

# Git HTTP/HTTPS proxy ayarı
git config --global http.proxy http://proxy.sirket.com:8080
git config --global https.proxy http://proxy.sirket.com:8080

# Belirli bir domain için farklı proxy veya proxy bypass
git config --global http.https://github.com.proxy ""
git config --global http.https://iç-gitlab.sirket.com.proxy ""

# Git proxy ayarlarını göster
git config --global --list | grep proxy

# SSL doğrulamayı kapat (sadece test için)
git config --global http.sslVerify false

SSH üzerinden Git kullanıyorsanız ([email protected] gibi), proxy konusu daha da karmaşık hale gelir çünkü SSH proxy’yi anlamaz. Burada nc (netcat) veya corkscrew devreye girer:

# ~/.ssh/config dosyasına ekle
cat >> ~/.ssh/config << 'EOF'
Host github.com
    ProxyCommand nc -X connect -x proxy.sirket.com:8080 %h %p
    # veya corkscrew kullanarak:
    # ProxyCommand corkscrew proxy.sirket.com 8080 %h %p
EOF

# nc ile tünel testi
nc -X connect -x proxy.sirket.com:8080 -v github.com 22

Python ve Node.js Uygulamalarında Proxy

Uygulama geliştiriyorsanız veya script çalıştırıyorsanız, bazı kütüphanelerin sistem proxy ayarlarını otomatik olarak okumadığını fark edersiniz.

# Python requests kütüphanesi - ortam değişkenini okur
# Ama eksplisit olarak da belirtebilirsiniz
python3 -c "
import requests
proxies = {
    'http': 'http://proxy.sirket.com:8080',
    'https': 'http://proxy.sirket.com:8080',
}
r = requests.get('https://example.com', proxies=proxies, verify=True)
print(r.status_code)
"

# pip için proxy
pip install paket_adi --proxy http://proxy.sirket.com:8080

# Node.js npm için
npm config set proxy http://proxy.sirket.com:8080
npm config set https-proxy http://proxy.sirket.com:8080

# npm proxy ayarlarını doğrula
npm config get proxy
npm config get https-proxy

tcpdump ve Wireshark ile Trafik Analizi

Proxy sorununu uygulama seviyesinde çözemediyseniz, trafik yakalamaya geçme zamanı. Bu, gerçekten ne olduğunu anlamanın en kesin yoludur.

# Proxy sunucusuna giden trafiği yakala
sudo tcpdump -i any -n -v 
     host proxy.sirket.com and port 8080 
     -w /tmp/proxy_debug.pcap

# Paralel terminalde curl çalıştır
curl -v --proxy http://proxy.sirket.com:8080 https://example.com

# Yakalama bittikten sonra analiz et
tcpdump -r /tmp/proxy_debug.pcap -A | head -100

# HTTP başlıklarına bak (şifreli olmayan kısım)
tcpdump -r /tmp/proxy_debug.pcap -A | grep -E "CONNECT|HTTP|Host:"

tcpdump çıktısında CONNECT hedef.com:443 HTTP/1.1 isteğini ve ardından HTTP/1.1 200 Connection established veya hata kodunu görmelisiniz. 200 gelmiyorsa sorun proxy tarafındadır.

Squid Proxy Log Analizi

Eğer proxy sunucusuna erişiminiz varsa (veya ağ ekibiyle çalışıyorsanız), Squid logları altın değerindedir.

# Squid access log'u gerçek zamanlı izle
sudo tail -f /var/log/squid/access.log

# Belirli bir IP'nin isteklerini filtrele
sudo grep "10.1.2.100" /var/log/squid/access.log | tail -50

# DENIED istekleri filtrele
sudo grep "DENIED" /var/log/squid/access.log | tail -20

# Squid log formatı: timestamp duration client action/code size method url
# Örnek: 1699000000.000 1200 10.1.2.100 TCP_DENIED/403 4096 CONNECT github.com:443

Squid log’unda sık görülen action kodları:

  • TCP_MISS: Cache’de yok, sunucudan alındı
  • TCP_DENIED: ACL tarafından reddedildi
  • TCP_TUNNEL: CONNECT tüneli kuruldu
  • TCP_CONNECT_FAIL: Hedefe bağlantı kurulamadı
  • HIER_DIRECT: Direkt bağlantı (proxy bypass)

Gerçek Dünya Senaryosu: Ansible Proxy Sorunları

Şirkette Ansible ile 200 sunucuya deployment yapıyorsunuz ama yarısında modüller başarısız oluyor. Sebep: O sunucular farklı bir ağ segmentindeydi ve proxy üzerinden internete çıkıyordu, diğerleri değil.

# ansible.cfg veya grup değişkenleri
# group_vars/proxy_segment/vars.yml
cat > group_vars/proxy_segment/vars.yml << 'EOF'
ansible_environment:
  http_proxy: "http://proxy.sirket.com:8080"
  https_proxy: "http://proxy.sirket.com:8080"
  no_proxy: "localhost,127.0.0.1,10.0.0.0/8,.sirket.com"
EOF

# Playbook içinde de belirtebilirsiniz
# environment:
#   http_proxy: "{{ proxy_url | default('') }}"

# Bağlantı sorununu debug et
ansible sunucu_grubu -m uri 
  -a "url=https://example.com validate_certs=yes" 
  -e "ansible_environment={'http_proxy': 'http://proxy.sirket.com:8080'}"

Sorun Giderme Akış Sırası

Proxy sorunuyla karşılaştığınızda sistematik bir yaklaşım benimseyin:

  • Önce proxy’ye ulaşabildiğinizi doğrulayın: curl -v http://proxy.sirket.com:8080 ile proxy’nin ayakta olup olmadığını kontrol edin.
  • Proxy kimlik doğrulamasını test edin: 407 hatası alıyorsanız credential sorunu var demektir.
  • CONNECT metodunu test edin: curl -v --proxy http://proxy:8080 https://hedef.com ile 200 Connection established alıp almadığınızı kontrol edin.
  • SSL sertifika sorununu izole edin: --insecure ile deneyin, eğer çalışıyorsa sorun CA sertifikasındadır.
  • no_proxy ayarını kontrol edin: İç kaynaklara erişemiyorsanız büyük ihtimalle iç adreslerin proxy’e gönderilmesi sorunudur.
  • Uygulama özelinde ayarları kontrol edin: Sistem değişkenleri doğru olsa bile uygulama kendi proxy ayarına bakıyor olabilir.
  • Ağ seviyesine inin: tcpdump ile gerçekte ne olduğunu görün.

Sonuç

Proxy sorunları, katmanlı yapıları nedeniyle debug edilmesi en sinir bozucu ağ sorunları arasındadır. Sorun; ortam değişkenlerinde, kimlik doğrulamada, SSL sertifikalarında, uygulamanın kendi proxy mantığında veya proxy’nin kendisindeki ACL kurallarında olabilir.

Metodolojik yaklaşım her zaman işe yarar: Önce en basit şeyi test et (proxy’ye ulaşabiliyor musun?), ardından katman katman ilerle. curl -v neredeyse her zaman sorunu ortaya koyar. Squid loglarına erişebiliyorsanız işiniz çok daha kolay; access log’daki DENIED satırları size doğrudan ne olduğunu söyler.

Kurumsal ortamlarda çalışan sysadmin’lerin proxy konfigürasyonlarını belgeleme alışkanlığı edinmesini öneririm. Hangi segmentin hangi proxy’yi kullandığı, kimlik doğrulama yöntemi, SSL inspection yapılıp yapılmadığı ve no_proxy listesinin güncel hali, yeni ekip üyelerinin saatler harcamasını önler. Bir runbook’a veya wiki’ye bu bilgileri düzenli olarak güncellemek, uzun vadede ekibin verimliliğini ciddi ölçüde artırır.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir