CGNAT arkasında port yönlendirme nasıl yapılır?
CGNAT nedeniyle genel IP adresi alamayan kullanıcılar için VPS ve frp kullanarak ters tünel kurma rehberi. Evdeki servislere dışarıdan erişim sağlamanın kesin yolu.
CGNAT arkasında port yönlendirme neden işe yaramaz
CGNAT (carrier-grade network address translation) arkasında yönlendiricinizin WAN adresi diğer abonelerle paylaşılır; dolayısıyla size ait bir genel IP adresi yoktur ve yönlendirilecek bir port bulunmaz. Bir ters tünel (reverse tunnel) bu sorunu çözer: ucuz bir VPS genel IP adresini tutar, evdeki cihazınız VPS'e dışarıdan bağlanır ve gelen istekler evdeki cihazın zaten açmış olduğu bağlantı üzerinden geri döner. Mevcut donanımınızı kullanmaya devam edersiniz. ISS'nizin size sağlamayacağı tek şeyi, yani yönlendirilebilir bir adresi, kiralarsınız.
Aşağıdaki her komut, üzerinde çalıştırılacağı makine ile etiketlenmiştir. Bu işlem iki makine gerektirir: genel IP adresine sahip VPS ve erişmek istediğiniz servisi çalıştıran evdeki cihaz.
CGNAT arkasında olup olmadığınızı anlama
Yönlendiricinizin (router) yönetim sayfasına girin ve WAN adresini kontrol edin. Ardından internetin sizi hangi adresle gördüğünü sorgulayın.
# on the home box
curl -4 -s https://ifconfig.me; echoEğer bu iki adres birbiriyle eşleşiyorsa, genel (public) bir IP adresine sahipsiniz demektir ve bu rehberdeki işlemlere ihtiyacınız yoktur. Port yönlendirmesi yapın ve okumayı bırakın. Eğer yönlendiricinizin WAN adresi 100.64.0.0/10 bloğu içindeyse, CGNAT arkasındasınız demektir. Bu blok, tam olarak bu kullanım için ayrılmış RFC 6598 paylaşımlı adres alanıdır. Bazı İSS'ler WAN tarafında bunun yerine 10.0.0.0/8 kullanır; bu da farklı bir etiketle aynı durumun yaşandığı anlamına gelir.
Herhangi bir kiralama işlemi yapmadan önce bir noktayı kontrol edin. Birçok CGNAT kullanan İSS, gerçek bir IPv6 öneki (prefix) sağlar. Eğer evinizdeki cihaz genel bir IPv6 adresine sahipse, bu adres üzerinde güvenlik duvarını açabilir ve tünel kurulumuna gerek kalmadan bağlantı sağlayabilirsiniz. Ancak ziyaretçiniz yalnızca IPv4 destekleyen bir ağdaysa bu yöntem çalışmayacaktır; çoğu kullanıcının bu noktaya gelmesinin temel sebebi de budur.
Bir VPS ters tünelinin içeriden dışarıya doğru çalışma mantığı
CGNAT ve standart ev tipi yönlendiriciler, dışarıdan gelen istenmeyen bağlantıları engeller. Kurumsal güvenlik duvarları da aynı şekilde davranır. Ancak hiçbir cihaz giden bağlantıları engellemez; çünkü tarayıcılar ve güncelleme istemcileri sürekli olarak dışarıya veri gönderir. Giden bir TCP bağlantısını tespit eden bir NAT cihazı, bu bağlantı için bir eşleme oluşturur ve ardından dönüş trafiğine izin verir. Dışarıdaki hiçbir yapı, evinizdeki sunucuya doğrudan bir bağlantı başlatamaz. Bu nedenle bağlantıyı evdeki sunucu başlatır ve tünel, trafiği aynı bağlantı üzerinden ters yönde taşır.
Mekanizmanın tamamı bundan ibarettir. Evdeki sunucu, belirli bir port üzerinden VPS'e bağlanır ve bu bağlantıyı açık tutar. VPS, genel ağdan gelen istekleri kabul eder ve bunları mevcut bağlantı üzerinden aşağıya iletir. Dışarıdan hiçbir yapı evinizin IP adresine ulaşmaya çalışmaz, dolayısıyla buna gerek de kalmaz.
Bu durumun iki faydalı sonucu vardır. DNS kaydınız evinizi değil, VPS'i işaret eder. Ayrıca genel IP adresiniz artık VPS'in adresi olduğundan, bir gözlemci IP sorgusu yaptığında ev hattınız yerine kiralık bir sunucunun bilgilerini görür.
Kurulum için üç yöntem
ssh -R: Her iki uçta da halihazırda yüklüdür; tek bir servis veya geçici demolar için uygundur. Herhangi bir kontrol paneli sunmaz ve kayda değer bir yeniden bağlanma mantığı içermez.- frp: Küçük bir Go sunucusu (
frps) ve buna uygun bir istemciden (frpc) oluşur. Tek bir ana makine adı (hostname) arkasında birden fazla servisin bulunduğu kalıcı kurulumlar için uygundur. Bu kılavuzun büyük bir kısmı bu yöntemi ele almaktadır. - Mesh VPN: Tailscale veya kendi yönettiğiniz bir WireGuard sunucusu. Kendi cihazlarınızın internete bir şey yayınlamak yerine, özel bir ağ üzerinden birbirine erişmesini istediğiniz durumlar için uygundur.
Amacınız kontrol ettiğiniz cihazlardan özel erişim sağlamaksa mesh VPN yöntemini seçin. Tailscale Serve ve Funnel bir tailnet içinden yayın yapmayı, aynı VPS üzerinde kendi kendine barındırılan WireGuard VPN ise araya üçüncü taraf bir koordinasyon sunucusu girmeden aynı yapıyı kurmayı anlatır. Bu seçeneklerden birini okuyun ve sayfanın geri kalanını atlayın. Aşağıdaki tüm içerik, herkesin yükleyebileceği herkese açık bir HTTPS ana makine adı istediğiniz varsayımıyla hazırlanmıştır.
Hızlı sürüm: Tek bir servis için ssh -R
Evdeki sunucunuzun 127.0.0.1:3000 üzerinde bir uygulama çalıştırdığını ve VPS'e halihazırda SSH erişiminizin olduğunu varsayalım.
# on the home box
ssh -N \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-R 127.0.0.1:8080:127.0.0.1:3000 \
tunnel@vps.example.com-R 127.0.0.1:8080:127.0.0.1:3000, VPS üzerindeki sshd sürecine kendi 127.0.0.1:8080 portunu dinlemesini ve buraya gelen trafiği evdeki sunucunun 127.0.0.1:3000 portuna iletmesini söyler. -N, bir kabuk (shell) çalıştırmamanız gerektiğini belirtir. İki adet ServerAlive seçeneği, SSH'in kopan bir bağlantıyı artık var olmayan bir bağlantıda asılı kalmak yerine yaklaşık doksan saniye içinde fark etmesini sağlar.
Şimdi herkesin kafasını karıştıran kısma gelelim. Bu dinleyici loopback üzerinde olduğu için, başka herhangi bir yerden gelen curl http://vps.example.com:8080 başarısız olur. sshd, GatewayPorts no seçeneği etkin olarak gelir; bu, uzak yönlendirmenin yalnızca loopback arayüzüne bağlanacağı anlamına gelir. Bunu GatewayPorts yes ayarını değiştirerek düzeltmeye çalışmayın. Yönlendirmeyi loopback üzerinde bırakın ve aşağıda anlatılan frp kurulumunda olduğu gibi önüne nginx koyun. Böylece genel port 443 olur, sertifika ile korunur ve tünel portu asla internete açık kalmaz. Şu anda hangi portun hangi arayüzde dinleme yaptığından emin değilseniz, Linux'ta portlar ve dinleyiciler üzerine kısa bir tur adlı rehbere göz atmak on dakikanızı ayırmaya değer.
Eğer port VPS üzerinde halihazırda kullanımdaysa, ssh bunu yazdırır ve ExitOnForwardFailure=yes seçeneği, çalışan bir tünel olmadan bağlantı kurmak yerine işlemin sonlandırılmasını sağlar:
Warning: remote port forwarding failed for listen port 8080Bunun yaygın nedeni, sshd fark etmeden sonlanan önceki bir oturumdur. Ölü oturumların temizlenmesi ve portu serbest bırakması için VPS üzerindeki /etc/ssh/sshd_config dosyasında ClientAliveInterval 30 ve ClientAliveCountMax 3 ayarlarını yapın. Tüm komutu Restart=always ve özel bir anahtar ile bir systemd birimi içine alın veya autossh kullanın. Birden fazla servis içeren her durum için burada durun ve frp kullanın.
VPS uzerine frp kurulumu ve surum sabitleme
frp, statik bir Go binary dosyasi olarak dagitilir ve Ubuntu veya Debian arsivlerinde yer almaz; bu nedenle bir surumu indirip dogrulamaniz gerekir. Surumu sabitleyin. Yapilandirma formati v0.52.0 surumunde degisti ve secenek isimleri tasindi; bu nedenle guncel olmayan bir rehber, binary dosyanizin tanimadigi anahtarlar sunabilir. Bu rehber, 14 Agustos 2026 tarihinde yayinlanan v0.71.0 surumunu kullanmaktadir.
# on the VPS
FRP_VERSION=0.71.0
ARCH=amd64 # use arm64 if `uname -m` prints aarch64
cd /tmp
curl -fsSLO "https://github.com/fatedier/frp/releases/download/v${FRP_VERSION}/frp_${FRP_VERSION}_linux_${ARCH}.tar.gz"
curl -fsSLO "https://github.com/fatedier/frp/releases/download/v${FRP_VERSION}/frp_sha256_checksums.txt"
sha256sum --check --ignore-missing frp_sha256_checksums.txtsha256sum tam olarak bir satir cikti vermelidir:
frp_0.71.0_linux_amd64.tar.gz: OK--ignore-missing gereklidir cunku saglama toplami dosyasi on sekiz surum varliginin tamamini kapsar ancak siz bunlardan yalnizca birini indirdiniz. Bu bayrak olmadan sha256sum, diger on yedi dosyanin eksik oldugunu bildirir ve sifirdan farkli bir cikis kodu dondurur; bu durum, herhangi bir sorun yokken dogrulamanin basarisiz oldugu seklinde algilanabilir.
# on the VPS
tar xzf "frp_${FRP_VERSION}_linux_${ARCH}.tar.gz"
sudo install -m 755 "frp_${FRP_VERSION}_linux_${ARCH}/frps" /usr/local/bin/frps
sudo useradd --system --no-create-home --shell /usr/sbin/nologin frp
sudo install -d -m 750 -o root -g frp /etc/frp
frps --versionfrps --version, 0.71.0 ciktisini verir. VPS uzerine yalnizca frps kurulmalidir. frpc ise evdeki bilgisayara kurulur. Her iki binary dosyasini da her yere kurmak, kullanicilarin yanlislikla evlerinde bir tunel sunucusu calistirmasina neden olur.
VPS yapılandırması: token, zorunlu TLS ve loopback dinleyicileri
Öncelikle bir token oluşturun. Tüneliniz ile VPS üzerinde port taraması yapan herkes arasındaki tek engel budur.
# on the VPS
openssl rand -base64 32Bu değeri /etc/frp/frps.toml dosyasına yazın:
bindAddr = "0.0.0.0"
bindPort = 7000
# Every listener frp creates for a proxy, including the HTTP vhost, stays on loopback.
proxyBindAddr = "127.0.0.1"
vhostHTTPPort = 8080
auth.method = "token"
auth.token = "PASTE_THE_OPENSSL_OUTPUT_HERE"
transport.tls.force = true
webServer.addr = "127.0.0.1"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "PASTE_A_SECOND_SECRET_HERE"
log.level = "info"Bu satırlardan dördü güvenlik işlevini yerine getirir, bu yüzden her birini sırayla inceleyin.
auth.token, istemci tarafındaki auth.token ile eşleşmelidir. Bu eşleşme olmazsa, frps 7000 numaralı portu bulan her istemciyi kabul eder ve bu istemci, VPS'niz ve sertifikanız üzerinden istediği her şeyi yayınlayabilir.
transport.tls.force = true, TLS (transport layer security) olmayan tüm kontrol bağlantılarını reddeder. İstemciler v0.50.0 sürümünden beri varsayılan olarak TLS kullanmaktadır, bu nedenle pratikte bir maliyeti yoktur; ancak eski veya elle yapılandırılmış bir istemcinin, size bildirmeden açık metin üzerinden bağlanması riskini ortadan kaldırır.
proxyBindAddr = "127.0.0.1", çoğu kılavuzun atladığı satırdır ve bu kurulumun çalışır durumda bırakılmasının güvenli olmasının nedenidir. frp'nin bir proxy adına açtığı tüm dinleyicileri (hem HTTP vhost hem de istemcinin talep ettiği remotePort) loopback arayüzüne taşır. İnternet bu dinleyicilere hiçbir şekilde erişemez. Tek halka açık kapı, yapılandırdığınız ve kontrol ettiğiniz 443 numaralı porttaki nginx'tir.
webServer.addr = "127.0.0.1", paneli halka açık arayüzden uzak tutar. Panel, özel servislerinizin ve trafiklerinin tam bir haritasıdır ve yalnızca bir HTTP basic auth parolasıyla korunduğundan 0.0.0.0 üzerinde bulunmamalıdır.
Token'ın herkes tarafından okunabilir olmaması için sahiplik ayarlarını yapın ve herhangi bir işlem başlatmadan önce sözdizimini kontrol edin:
# on the VPS
sudo chown root:frp /etc/frp/frps.toml
sudo chmod 640 /etc/frp/frps.toml
sudo -u frp frps verify -c /etc/frp/frps.tomlGeçerli bir dosya şu çıktıyı verir:
frps: the configuration file /etc/frp/frps.toml syntax is okSize zaman kazandıracak bir biçim notu: frp, ayrıştırıcısını dosya uzantısına göre seçer ve .toml, .yaml, .yml ve .json formatlarını tanır. Eski .ini dosyaları hala eski bir dönüştürme yoluyla yüklenebilir, ancak INI formatı kullanımdan kaldırılmıştır ve yeni seçenekler yalnızca TOML için belgelenmiştir. Eğer bir eğitimde [common] bölümü ve server_addr = x.x.x.x görüyorsanız, bu v0.52.0 sürümünden öncesine aittir ve anahtar isimleri yüklediğiniz ikili dosya ile eşleşmeyecektir.
frps'yi yetkisiz bir servis olarak çalıştırma
bindPort değeri 7000, vhostHTTPPort değeri ise 8080'dir. Her ikisi de 1024'ün üzerinde olduğundan, frps hiçbir zaman root yetkisine veya CAP_NET_BIND_SERVICE kullanımına ihtiyaç duymaz. vhost'u 80 numaralı port üzerine koymayıp bunun yerine Nginx'in bu portu devralmasını sağlamanın nedeni budur.
/etc/systemd/system/frps.service dosyasını oluşturun:
[Unit]
Description=frp reverse tunnel server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=frp
Group=frp
ExecStart=/usr/local/bin/frps -c /etc/frp/frps.toml
Restart=on-failure
RestartSec=5s
LimitNOFILE=65535
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ProtectKernelTunables=true
[Install]
WantedBy=multi-user.target# on the VPS
sudo systemctl daemon-reload
sudo systemctl enable --now frps
sudo journalctl -u frps -n 20 --no-pagerGünlük kayıtları her iki dinleyiciyi de göstermelidir; burada portlardan ziyade adresler önem taşır:
frps tcp listen on 0.0.0.0:7000
http service listen on 127.0.0.1:8080ProtectSystem=strict, bu servis için tüm dosya sistemini salt okunur hale getirir. frps, günlük kayıtlarını varsayılan olarak standart çıktıya gönderdiği ve journald bunu yakaladığı için bu durumu tolere eder. Eğer log.to değerini bir dosya yoluna ayarlarsanız, uygun bir ReadWritePaths= satırı eklemediğiniz sürece servis yazma işlemi gerçekleştiremeyeceği için hata verecektir; bu nedenle varsayılan ayarı değiştirmeyin.
Güvenlik duvarı: Aralık değil, tek bir port açın
# on the VPS
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 7000/tcp
sudo ufw enable
sudo ufw status numberedDört kural mevcuttur ve bunlardan biri yalnızca sertifika yenileme işlemi içindir. 22 numaralı port SSH içindir. 80 numaralı port, 443 numaralı porta yönlendirme yapar ve ACME (otomatik sertifika yönetim ortamı) doğrulama isteklerini yanıtlar. 443 numaralı port, tünellenen tüm uygulamalara hizmet verir. 7000 numaralı port ise frp kontrol portudur ve bir istemcinin erişmesi gereken tek port budur.
sudo ufw allow 20000:30000/tcp gibi bir port aralığını açmanızı öneren kılavuzlar, her servisin kendi genel TCP portunu talep ettiği farklı bir mimariyi tarif etmektedir. Burada buna ihtiyacınız yoktur; çünkü her şey 443 numaralı porta ulaşır ve frp trafiği ana makine adına göre yönlendirir. İleride gerçekten genel erişime açık bir TCP portuna ihtiyaç duyarsanız, proxyBindAddr ayarını tekrar 0.0.0.0 değerine getirin ve bir istemcinin yalnızca sizin belirlediğiniz portları talep edebilmesi için sınırlamalar ekleyin:
allowPorts = [
{ start = 20000, end = 20010 }
]
maxPortsPerClient = 5Çoğu sağlayıcı, sunucu üzerindeki ufw'den bağımsız olarak kontrol panelinde bir ağ güvenlik duvarı da çalıştırır. sudo ufw status içinde doğru görünen ancak zaman aşımına uğrayan bir kural, genellikle orada engelleniyordur. Bir VPS'in gerçekten ihtiyaç duyduğu ufw kuralları rehberi, bu bölümün varsaydığı "varsayılan olarak reddet" (default-deny) yapılandırmasını adım adım açıklar.
VPS üzerinde gerçek bir sertifika ile HTTPS sonlandırma
home.example.com için bir A kaydını VPS'in genel IP adresine yönlendirin. Evinize yönlendirmeyin. Evinizin yönlendirilebilecek bir adresi yoktur; çözmeye çalıştığınız sorun da budur.
# on the VPS
sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginxÖnce düz bir 80 numaralı port bloğu ile /etc/nginx/sites-available/home.example.com dosyasını oluşturun; böylece certbot'un çalışabileceği eşleşen bir server_name bloğu olur:
server {
listen 80;
listen [::]:80;
server_name home.example.com;
location / { return 404; }
}# on the VPS
sudo ln -s /etc/nginx/sites-available/home.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot certonly --nginx -d home.example.comnginx -t, dosyalar ayrıştırıldığında nginx: configuration file /etc/nginx/nginx.conf test is successful çıktısını verir. Her yeniden yükleme işleminden önce bu komutu çalıştırın. nginx, yeniden yükleme başarısız olduğunda eski yapılandırmayı çalıştırmaya devam eder; bu nedenle hatalı bir düzenleme, hiçbir şey yapmamışsınız gibi görünebilir.
WebSocket yükseltmeleri için http seviyesinde bir map gereklidir. Bunu /etc/nginx/conf.d/upgrade.conf içine ekleyin:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}Şimdi site dosyasını gerçek olanla değiştirin:
server {
listen 80;
listen [::]:80;
server_name home.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name home.example.com;
ssl_certificate /etc/letsencrypt/live/home.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/home.example.com/privkey.pem;
client_max_body_size 512m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
}
}proxy_set_header Host $host; burada isteğe bağlı değildir. frp'nin HTTP vhost yönlendirmesi, Host başlığına göre yapılır ve bu başlığı istemci yapılandırmasındaki customDomains listesiyle eşleştirir. Bu başlığı çıkarırsanız nginx Host: 127.0.0.1 gönderir, frp bu isim için bir proxy bulamaz ve ziyaretçiniz uygulamadan bir sayfa almak yerine frp'den boş bir 404 hatası alır. Bir nginx reverse proxy bloğundaki her satırın açıklaması diğer başlıkların ne işe yaradığını kapsar.
# on the VPS
sudo nginx -t && sudo systemctl reload nginx
sudo certbot renew --dry-runDeneme çalıştırması (dry run), başında olmadığınız doksan gün sonra yenilemenin çalışacağını kanıtlar. Bu işlem 80 numaralı portun erişilebilir olmasını gerektirir; ufw kuralının orada bulunmasının nedeni budur.
Ev tarafı: ayrıcalıksız bir servis olarak frpc
frpc uygulamasını, frps uygulamasını kurduğunuz yöntemle, aynı sürüm ve aynı sağlama toplamı adımlarını izleyerek evdeki makinenize kurun. Ardından aynı frp kullanıcısını ve /etc/frp dizinini oluşturun. /etc/frp/frpc.toml dosyasını şu şekilde yazın:
serverAddr = "vps.example.com"
serverPort = 7000
auth.method = "token"
auth.token = "PASTE_THE_SAME_TOKEN_HERE"
transport.tls.enable = true
loginFailExit = false
proxies = [
{ name = "home-app", type = "http", localIP = "127.0.0.1", localPort = 3000, customDomains = ["home.example.com"] }
]Bu dosyada anahtar sırası, biçimsel nedenlerden değil, teknik gereklilikten dolayı önemlidir. TOML, bir tablo başlığından sonra gelen her anahtarı o tabloya atar; bu nedenle bir proxy tablo başlığının altına yazılan serverAddr gibi üst düzey bir ayar, sessizce proxy ayarına dönüşür ve frp tarafından görmezden gelinir. Proxy listesini yukarıda görüldüğü gibi satır içi dizi (inline array) olarak yazmak bu hatayı önler: her üst düzey anahtar, belirsizliğe yer bırakmayacak şekilde üst düzey kalır.
type = "http", bu proxy'yi kendine ait bir genel TCP portu talep etmek yerine vhost dinleyicisi üzerinden yönlendirir; güvenlik duvarı kurallarının dört adetle sınırlı kalmasının nedeni budur. customDomains, nginx'in Host başlığında ilettiği ana bilgisayar adını (hostname) içermelidir; bu nedenle VPS'in IP adresi değil, home.example.com olmalıdır.
loginFailExit = false, göründüğünden daha önemlidir. Varsayılan değer true şeklindedir ve bu, ilk oturum açma girişimi başarısız olursa frpc'nin kapanmasına neden olur. İnternet bağlantısı henüz kurulmadan açılışını tamamlayan bir ev makinesinde bu, siz fark edene kadar ölü kalan bir servis demektir. Bunu false olarak ayarlayın; böylece frpc, VPS yanıt verene kadar yeniden denemeye devam eder.
/etc/systemd/system/frpc.service dosyasını şu şekilde yazın:
[Unit]
Description=frp reverse tunnel client
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=frp
Group=frp
ExecStart=/usr/local/bin/frpc -c /etc/frp/frpc.toml
Restart=always
RestartSec=10s
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
[Install]
WantedBy=multi-user.target# on the home box
sudo chown root:frp /etc/frp/frpc.toml
sudo chmod 640 /etc/frp/frpc.toml
sudo -u frp frpc verify -c /etc/frp/frpc.toml
sudo systemctl daemon-reload
sudo systemctl enable --now frpc
sudo journalctl -u frpc -n 20 --no-pagerBağlanan bir istemci, bir run id kaydeder:
login to server success, get run id [3a1f9c2b7d4e5f60]Tarayıcınızda https://home.example.com adresini açtığınızda, evinizdeki 127.0.0.1:3000 üzerinde çalışan uygulamaya erişebiliyor olmalısınız. İstemci üzerindeki Restart=always kasıtlıdır: ev bağlantıları kopabilir ve servis, sizin müdahalenize gerek kalmadan kendiliğinden geri gelmelidir.
Paneli genel ağ arayüzünden uzak tutun
webServer.addr = "127.0.0.1" ile panel yalnızca VPS üzerinde yanıt verir. Bir port açmak yerine, dizüstü bilgisayarınızdan yerel bir yönlendirme (local forward) kullanarak panele erişin:
# on your laptop
ssh -N -L 7500:127.0.0.1:7500 you@vps.example.comhttp://127.0.0.1:7500 adresini açın ve frps.toml içindeki webServer.user ve webServer.password bilgilerini kullanarak giriş yapın. Sayfa, bağlı olan tüm istemcileri ve her bir proxy için trafik sayaçlarını listeler; bu, "evdeki cihaz şu an gerçekten bağlı mı" sorusuna yanıt bulmanın en hızlı yoludur. ssh oturumunu kapattığınızda panel tekrar erişilemez hale gelir.
Tünelin yapmadığı işlemler
Bu bölümü iki kez okuyun; kullanıcıların en çok hata yaptığı nokta burasıdır. Tünel, özel bir servisi genel internetten erişilebilir hale getirir. Servise erişen kişilerin kimlik doğrulamasını yapmaz. https://home.example.com çözümlendiği anda, tarayıcılar birkaç gün içinde onu bulacaktır; bu ismi kimseye söylememiş olsanız dahi tarayıcılar onu tespit eder. Sertifika şeffaflık günlükleri, sertifika oluşturduğunuz her ana bilgisayar adını (hostname) yayınlar; bu nedenle certbot başarılı olduğu anda isim herkese açık hale gelir.
Dışarıya açtığınız her şey kendi kimlik doğrulama mekanizmasına sahip olmalıdır. Eğer uygulamanın hız sınırlamalı (rate limiting) gerçek bir giriş sistemi varsa, bu iyidir. Eğer giriş sistemi tek bir ortak paroladan ibaretse veya hiç giriş sistemi yoksa, VPS üzerinde uygulamanın önüne kimlik doğrulama yapan bir proxy yerleştirin. Uygulamanın önünde çalışan bir oauth2-proxy yaygın bir çözümdür; nginx ile frp vhost arasına yerleşir ve tünelin her iki ucunda da değişiklik gerektirmez.
frps.toml içindeki token tüneli korur, uygulamaları değil. Yabancı birinin VPS'niz üzerinde kendi proxy'sini kaydetmesini engeller. Kasıtlı olarak yayınladığınız bir ana bilgisayar adı için 443 numaralı port üzerinden gelen bir istek hakkında hiçbir işlem yapmaz.
İki alışkanlığı sürdürmek faydalıdır. Token'ı her iki dosyayı da düzenleyip her iki servisi de yeniden başlatarak periyodik olarak değiştirin; çünkü token kendiliğinden süresi dolan bir yapıya sahip değildir. Ayrıca frp'yi güncel tutun: bu ikili dosya, dış dünyaya açılan ön kapınızdır. v0.71.0 sürüm notları, istemciden gönderilen hatalı bir değerin tetiklediği bir sunucu panik durumundan bahseder; bu, üzerinde mantık yürütmek yerine yamalanmasını isteyeceğiniz türden bir hata sınıfıdır.
Hata modları ve karşılaşacağınız dizgeler
İstemci asla bağlanamıyor. journalctl -u frpc, connect to server error: ve ardından bir bağlantı zaman aşımı hatasını tekrarlar. 7000 numaralı porta hiçbir şey ulaşmıyor. VPS üzerindeki ufw ayarlarını, ardından kontrol panelindeki sağlayıcı ağ güvenlik duvarını kontrol edin ve son olarak getent hosts vps.example.com ile alan adı çözümlemesini doğrulayın.
Token hatalı. İstemci bunu açıkça belirtir:
login to the server failed: token in login doesn't match token from configurationToken değerini tekrar kopyalayın. Sondaki bir satır başı karakteri veya tırnak içine alınmamış bir shell dizgisinde boşluğa genişleyen bir $, bu hataların neredeyse tamamına neden olur. openssl rand -base64 32 çıktısının TOML dosyasında tırnak içinde kullanılmasının nedeni budur.
Tünel aktif ancak tarayıcı boş bir 404 döndürüyor. frpc başarılı bir giriş kaydetti ve panelde proxy listeleniyor, ancak sayfa uygulamanın stil dosyaları olmadan 404 hatası veriyor. Bu, frp'nin bu Host başlığı için herhangi bir proxy bulamadığını gösterir. vhost ayarını nginx ve TLS'yi devre dışı bırakarak doğrudan VPS üzerinde test edin:
# on the VPS
curl -s -o /dev/null -w '%{http_code}\n' -H 'Host: home.example.com' http://127.0.0.1:8080/Bu komuttan gelen 404 yanıtı, customDomains değerinin hatalı olduğu anlamına gelir. Başka bir kod, isteğin nginx üzerinden doğru Host başlığını almadığını gösterir.
nginx üzerinden 502 hatası. nginx yanıt veriyor ancak frp vermiyor. VPS üzerinde sudo ss -lntp | grep 8080 komutu, frps'nin 127.0.0.1:8080 üzerinde dinlemede olduğunu göstermelidir. Çıktının boş olması, frps'nin durdurulduğunu veya frps.toml dosyasında vhostHTTPPort değerinin ayarlanmadığını gösterir.
Uygulama her ziyaretçiyi yerel olarak algılıyor. Uygulamanız her istek için 127.0.0.1 kaydediyor. frp, X-Forwarded-For başlığını ayarlar ve nginx buna ekleme yapar; bu nedenle gerçek istemci adresi bu başlıkta yer alır. Uygulamayı bu başlığa güvenecek şekilde yapılandırın. Uygulama IP adresine göre hız sınırlaması (rate limiting) yapıyorsa bu adımı atlamayın; aksi takdirde internetteki tüm ziyaretçiler tek bir havuzda toplanır.
Uzun süreli istekler 60 saniyede kesiliyor. Yüklemeler veya akış yanıtları yarıda kesiliyor. Bu, tünelden değil, nginx'in varsayılan proxy_read_timeout değerinden kaynaklanır. Yukarıdaki blok bu süreyi 3600 saniyeye çıkarır. client_max_body_size, yükleme boyutu için eşleşen sınırdır ve varsayılan 1 MB değeri, daha büyük gövdeleri 413 hatasıyla reddeder.
Her şey çalışıyor ancak yönlendirici yeniden başlatıldıktan sonra duruyor. frpc birimindeki Restart=always ve loginFailExit = false ayarları bu durumu kapsar. enabled çıktısını vermesi gereken sudo systemctl is-enabled frpc komutu ile durumu doğrulayın.
FAQ
CGNAT arkasında olup olmadığımı nasıl anlarım?
Yönlendiricinizin yönetim sayfasındaki WAN adresini, aynı ağ içinden curl -4 -s https://ifconfig.me aracılığıyla görüntülenen adresle karşılaştırın. Eğer bu adresler farklıysa ve yönlendiricinin WAN adresi 100.64.0.0/10 aralığındaysa, servis sağlayıcınız carrier-grade NAT kullanıyor demektir. Bu aralık RFC 6598 paylaşımlı adres alanıdır ve bu amaçla kullanılır. Bazı servis sağlayıcılar WAN tarafında bunun yerine 10.0.0.0/8 kullanır, bu da aynı anlama gelir. İki adres eşleşiyorsa genel bir IP adresine sahipsiniz demektir: port yönlendirmesini yapın ve işlemi tamamlayın.
Reverse tunnel için alan adına ihtiyacım var mı?
Burada açıklanan HTTPS kurulumu için evet. Sertifika bir ana bilgisayar adına düzenlenir ve frp'nin HTTP vhost özelliği istekleri Host başlığına göre yönlendirir; bu nedenle her iki tarafın da üzerinde anlaştığı bir isme ihtiyacı vardır. Numaralandırılmış bir port üzerindeki ham TCP proxy, alan adı olmadan doğrudan VPS'in IP adresiyle çalışabilir; ancak bu durumda sertifikanız ve ana bilgisayar adı yönlendirmeniz olmaz, dolayısıyla tek bir genel port yalnızca tek bir servise hizmet eder.
Genel bir VPS üzerinde frp çalıştırmak güvenli mi?
Kontrol portu dışa açık olan tek şey olduğunda ve kimlik doğrulaması yapıldığında güvenlidir. auth.token değerini her iki tarafta da rastgele bir değerle, transport.tls.force = true değerini ise sunucuda ayarlayın. Ardından, frp'nin proxy için açtığı hiçbir şeyin internete doğrudan maruz kalmaması için proxyBindAddr = "127.0.0.1" ayarını yapın ve paneli webServer.addr = "127.0.0.1" üzerinde tutarak sadece SSH yerel yönlendirmesi (local forward) üzerinden erişin. Genel adresinizi dinleyen süreç olduğu için, yeni sürümler yayınlandığında ikili dosyayı güncelleyin.
Neden kimse ssh -R ile yönlendirdiğim porta erişemiyor?
sshd varsayılan olarak GatewayPorts no ile gelir, bu nedenle uzak yönlendirme (remote forward) yalnızca VPS'in loopback arayüzüne bağlanır. VPS üzerinde çalışan curl başarılı olurken, başka bir yerden gelen curl zaman aşımına uğrar. Doğru çözüm, yönlendirmeyi loopback üzerinde bırakıp önüne 443 portunda nginx koymaktır. GatewayPorts yes ayarını yapmak, sertifikasız ve TLS'siz ham bir portu dışa açar ki bu, çözmeye çalıştığı sorundan daha kötü bir durumdur.
frp mi yoksa Tailscale veya WireGuard gibi bir mesh VPN mi kullanmalıyım?
Yalnızca kendi cihazlarınızın erişimine ihtiyaç duyduğunuzda mesh VPN kullanın; çünkü bu durumda hiçbir şey dışa açılmaz ve kimsenin tarayabileceği genel bir ana bilgisayar adı olmaz. Herhangi bir tarayıcının yükleyebileceği genel bir HTTPS adresine ihtiyaç duyduğunuzda (webhook alıcısı veya VPN istemcisi kurmayacak kişilerle paylaştığınız bir sayfa gibi) frp kullanın. Bu ikisi, farklı portlarda farklı işler yaparak aynı VPS üzerinde sorunsuz bir şekilde bir arada çalışabilir.