Skip to content
Bloga Dönün
Güvenlik

.htpasswd Dosyası Oluşturma: HTTP Basic Auth Rehberi

bcrypt veya apr1 ile .htpasswd dosyası oluşturun; Apache, nginx, Docker ve Kubernetes üzerinde HTTP Basic Auth yapılandırın ve güvenli hâle getirin. 2026 rehberi.

11 dakika okuma

.htpasswd dosyası oluşturma: HTTP Basic Auth rehberi

Bir .htpasswd dosyası, HTTP Basic Authentication için sunucu tarafındaki kimlik bilgisi deposudur: her satırı tek bir username:hash çiftinden oluşan düz metin bir dosya. Dosyayı oluşturmak için bu hash’li satırı üretip web sunucunuzun okuyabileceği bir yere kaydedin. Üç yol var:

  • htpasswd komutu (apache2-utils / httpd-tools paketinden): tam bu iş için yapılmış araç.
  • openssl passwd: neredeyse her yerde zaten kuruludur, ek paket istemez.
  • Tarayıcınızda: bir satırı yerel olarak, hiçbir kurulum yapmadan ve ağ üzerinden hiçbir şey göndermeden üretmek için htpasswd üreticisini kullanın.

Bu rehber tek satırlık komutla yetinmiyor. Basic Auth el sıkışmasının nasıl çalıştığına, dosyayı üç yoldan nasıl üreteceğinize, beş hash biçiminden hangisini seçeceğinize, bunu Apache, nginx, Docker, Kubernetes, Caddy ve Traefik ile nasıl bağlayacağınıza ve herkesin indirebileceği bir kimlik bilgisi dosyasını yayına vermemek için neleri kilitlemeniz gerektiğine bakıyoruz.

.htpasswd dosyası nedir?

Bir .htpasswd dosyasındaki her satır, bir kullanıcının kimlik bilgilerini iki nokta üst üste ile ayrılmış bir çift olarak tutar. Kullanıcı adı olduğu gibi saklanır; parola yalnızca tek yönlü bir hash olarak durur, yani düz metin diske hiç yazılmaz. Tek bir bcrypt satırı parçalarına ayrıldığında şöyle görünür:

admin    :    $2y$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
│             │
└─ username   └─ hash (algorithm prefix $2y$ + cost + salt + digest)

Önce kullanıcı adı gelir, sonra tek bir :, ardından hash. Kullanıcı adı en fazla 255 bayt olabilir ve iki nokta üst üste içeremez, çünkü alanları ayıran karakter odur. Hash kendi algoritma işaretçisini ön ek olarak taşır (bcrypt için $2y$, Apache MD5 için $apr1$, SHA-1 için {SHA}), dolayısıyla sunucu ek bir yapılandırma olmadan onu nasıl doğrulayacağını bilir.

Birden çok kullanıcı için, kullanıcı başına bir satır eklersiniz:

admin:$2y$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
alice:$2y$10$3bQ8xY7tLp2mZ0xW5cR4fO9vK1jH6sD2nG8aQ5wE3rT7uI4oP1cm
bob:$apr1$mZ0xW5cR$4fK1jH6sD2nG8aQ5wE3rT2

Aynı dosyada farklı algoritmalar karışabilir. Sunucu her satırı okur, biçimi ön ekinden tanır ve ne kullanılmışsa ona göre doğrular. Burada iki bcrypt kullanıcısıyla bir apr1 kullanıcısı sorunsuz yan yana duruyor.

.htpasswd ile .htaccess karşılaştırması

Bu ikisi sürekli karıştırılır, çünkü Apache’de birlikte çalışırlar, ama işleri farklıdır. .htaccess, Apache’nin dizin başına yapılandırma dosyasıdır ve yönergeleri tutar; Basic Auth’u açan ve kimlik bilgisi deponuza işaret eden yönergeler de bunların arasındadır. .htpasswd ise kimlik bilgisi veritabanının kendisidir: yalnızca username:hash satırları, hiç yapılandırma yok.

Özetle: .htaccess, bir dizinin oturum açma gerektirip gerektirmediğine ve kullanıcı listesinin nerede olduğuna karar verir; .htpasswd de o kullanıcı listesidir. nginx, .htaccess’i hiç kullanmaz; Basic Auth yapılandırması ana yapılandırmanın server ya da location bloğunda durur, ama yine aynı .htpasswd kimlik bilgisi biçimini okur.

HTTP Basic Authentication nasıl çalışır

HTTP Basic Authentication, HTTP belirtiminin içine gömülü bir meydan okuma-yanıt (challenge-response) el sıkışmasıdır. Üç adımını kavradığınızda sonraki sorun giderme adımlarının çoğu kendiliğinden netleşir:

  1. İstemci, kimlik bilgisi olmadan korumalı bir kaynak ister.
  2. Sunucu 401 Unauthorized yanıtı verir ve bir WWW-Authenticate: Basic realm="..." başlığı ekler; meydan okuma budur.
  3. İstemci isteği yeniden dener; bu kez bir Authorization: Basic <base64(user:password)> başlığıyla. Kimlik bilgileri .htpasswd dosyasındaki bir satırla eşleşirse, sunucu kaynağı döndürür.

Protokol bundan ibaret. Oturum açma formu, oturum cookie’si, token yok. Sonraki her istek aynı başlığı yanında getirir.

401 / WWW-Authenticate meydan okuması

WWW-Authenticate başlığının iki işi var. Basic token’ı istemciye hangi şemayı kullanacağını söyler, realm dizesi de koruma alanını etiketler. Tarayıcılar oturum açma kutusunda realm metnini gösterir (“Site şunu diyor: …”) ve onu önbellek anahtarı olarak kullanır: bir realm için girilen kimlik bilgileri, aynı realm’deki diğer URL’lerde yeniden kullanılır, böylece kullanıcı her sayfada yeniden sorgulanmaz.

curl -i ile yakalanan ham alışveriş şöyle:

$ curl -i https://example.com/admin/
HTTP/2 401
www-authenticate: Basic realm="Restricted Area"

$ curl -i -u admin:s3cret https://example.com/admin/
HTTP/2 200

Authorization: Basic başlığı

İstemcinin gönderdiği kimlik bilgisi base64(username:password) biçimindedir. Basic Auth’ta akılda tutulması gereken en önemli güvenlik gerçeği de bu: base64 bir kodlamadır, şifreleme değil. Herkes tarafından eksiksiz geri çevrilebilir, yani kimlik bilgisi pratikte düz metin olarak hat üzerinde gider. Gidiş-dönüşü kendiniz görebilirsiniz:

# Encode the credential the way a browser does
printf 'admin:s3cret' | base64
# → YWRtaW46czNjcmV0

# Anyone who captures the header can decode it instantly
printf 'YWRtaW46czNjcmV0' | base64 -d
# → admin:s3cret

Basic Auth’un neden HTTPS üzerinden çalışması gerektiği işte bu geri çevrilebilirlikten kaynaklanır: TLS olmadan parolayı ağ yolundaki herkes okuyabilir. Bu başlığı elle oluşturmak ya da incelemek isterseniz, Base64 koder ve çözücü aynı user:password dönüşümünü tarayıcıda yapar.

.htpasswd dosyası nasıl oluşturulur

Dosyayı oluşturmanın üç pratik yolu var. Neyin kurulu olduğuna ve parolanın nerede üretilmesini istediğinize göre seçin.

htpasswd komutunu kullanma

htpasswd ikili dosyası, Apache’nin yardımcı program paketiyle birlikte gelir. Önce paketi kurun:

# Debian / Ubuntu
sudo apt install apache2-utils

# RHEL / CentOS / Fedora
sudo yum install httpd-tools

Dosyayı ve ilk kullanıcısını oluşturun. -c bayrağı create (oluştur) demektir ve var olan bir dosyanın üzerine yazar, o yüzden onu yalnızca en başta, bir kez kullanın:

htpasswd -c /etc/nginx/.htpasswd admin
# prompts twice for the password, then writes the file

Daha fazla kullanıcı eklemek için -c’yi bırakın; böylece dosyanın üzerine yazmak yerine sona ekleme yapılır:

htpasswd /etc/nginx/.htpasswd alice

Platform varsayılanı yerine bcrypt’i zorlamak için -B ekleyin. Satırı hiçbir dosyaya dokunmadan stdout’a yazdırmak isterseniz (bir yapılandırmaya ya da Dockerfile’a aktarırken işe yarar), -b (parola komut satırında) ile -n (dosya yok) bayraklarını birleştirin:

htpasswd -Bbn admin 's3cret'
# → admin:$2y$10$N9qo8uLOickgx2ZMRZoMye...

Gerçekte kullanacağınız bayraklar:

BayrakAnlamı
-cYeni bir dosya oluştur (varsa üzerine yazar); yalnızca ilk kullanıcı
-Bbcrypt kullan
-bParolayı komut satırı argümanı olarak al (sormaz)
-nDosyaya yazmak yerine stdout’a yazdır
-DAdı verilen kullanıcıyı dosyadan sil

-b konusunda bir uyarı: parola kabuk geçmişinize düşer. Tek seferlik üretim kimlik bilgileri için soran biçimi ya da aşağıdaki tarayıcı seçeneğini yeğleyin.

apache2-utils olmadan: OpenSSL kullanarak

htpasswd ikili dosyası elinizde yok mu? OpenSSL neredeyse her sistemde bulunur ve doğrudan bir apr1 hash’i üretebilir. Tam bir satır oluşturmak için onu printf içine sarın:

printf "admin:$(openssl passwd -apr1 's3cret')\n" >> /etc/nginx/.htpasswd
# admin:$apr1$k3l4Hj9.$qN8vY7tLp2mZ0xW5cR4f.

apr1 biçimi Apache ile nginx arasında taşınabilir olduğu için, sade bir makinede en az bağımlılık isteyen yol budur.

Tarayıcıda: kurulum yok, sızıntı yok

Bir paket kurmak istemiyorsanız ya da üretim parolasını ~/.bash_history’e düşecek bir kabuğa yazmamayı yeğliyorsanız, satırı istemci tarafında üretin. htpasswd üreticisi bcrypt, apr1 ve SHA-1 hash’lerini tamamen tarayıcınızda hesaplar, yapıştırmaya hazır bir user:hash satırı ile eşleşen sunucu yapılandırma bloğunu verir ve hiçbir şeyi dışarı iletmez. Hazır oradayken, eskisini yeniden kullanmak yerine rastgele parola üreticisi ile güçlü ve benzersiz bir parola üretin.

htpasswd parola biçimleri karşılaştırması

htpasswd komutu beş biçim üretebilir ve hiçbiri eşit değil. Aşağıdaki tablo, hızlıca birini seçmeniz için:

BiçimÖn ekTuzlu (salted)GüçŞunun için kullanın
bcrypt$2y$EvetEn güçlüApache, Docker Registry, Caddy, Traefik
apr1 (Apache MD5)$apr1$EvetOrtanginx (taşınabilir, güvenli varsayılan)
SHA-1{SHA}HayırZayıfYalnızca eski sistem uyumluluğu
crypt (DES)(yok)Evet (2 karakter)Çok zayıfKullanmayın
plain(yok)HayırYokYalnızca yerel test

Tablo hücresine sığmayan birkaç not. bcrypt, rastgele 16 baytlık bir tuz (salt) ve uyarlanabilir bir maliyet faktörü (varsayılan 10, bugün önerilen 12) kullanır; bu yüzden aynı parolalar farklı hash’ler üretir ve iş faktörü donanımla birlikte ölçeklenir. Tek tuhaflığı, parolayı 72 baytta kesmesidir; bundan uzun olan her şey sessizce yok sayılır. apr1, tuzlanmış MD5’in 1.000 turunu çalıştırır. bcrypt’ten epey zayıftır, ama hem Apache hem nginx içinde dahili olarak uygulandığı için taşınabilir seçenek odur. SHA-1 tuzsuzdur, yani aynı parolalar aynı özeti verir ve gökkuşağı tabloları (rainbow tables) işe yarar; onu yalnızca eski sistemler için saklayın. crypt ile plain tarihsel ve test amaçlarıyla durur, ikisinin de üretimde yeri yoktur.

$2a$ / $2b$ / $2y$ ön ekleri

bcrypt hash’lerinin $2a$, $2b$ ya da $2y$ ile başladığını görürsünüz. Hepsi aynı algoritmadır ve birbirinin yerine geçebilen, eşdeğer hash’ler üretir; sürüm harfleri, kimi kütüphanelerin yüksek bitli karakterleri ve dize uzunluğunu nasıl işlediğine dair eski hata düzeltmelerinden kalmadır. Apache’nin htpasswd’si $2y$ üretir; Caddy, Traefik ve Docker Registry de bunu doğru biçimde doğrular.

bcrypt’i modern alternatifleriyle daha ayrıntılı karşılaştırmak isterseniz, bcrypt vs Argon2 vs scrypt rehberi bu parola hash’leme algoritmalarının maliyet, bellek sertliği ve tehdit modeli bakımından nasıl ayrıştığını anlatır.

Sunucunuzda Basic Auth yapılandırma

Kimlik bilgisi dosyası tek başına hiçbir işe yaramaz; sunucunuza onu zorunlu kılmasını söylemeniz gerekir. Altı platform için yapılışı şöyle.

Apache (.htaccess)

Bunu, korumak istediğiniz dizindeki bir .htaccess dosyasına (ya da vhost’unuzdaki bir <Directory> bloğuna) koyun:

AuthType Basic
AuthName "Restricted Area"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user

Burada AuthName, tarayıcının gösterdiği realm dizesidir; AuthUserFile, kimlik bilgisi dosyanızın mutlak yoludur; Require valid-user ise dosyada listelenen her kullanıcıyı kabul eder.

nginx (auth_basic)

nginx, yapılandırmayı bir location ya da server bloğuna koyar; .htaccess diye bir şey yoktur:

location /admin/ {
    auth_basic           "Restricted Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

nginx -s reload ile yeniden yükleyin. Burada apr1 biçimini kullanın. nginx, bcrypt doğrulamasını sistemin crypt()’ine bırakır ve bu birçok derlemede başarısız olur (sorun giderme bölümünde ayrıntısı var); apr1 ise her platformda dahili olarak doğrulanır.

Docker Registry ve Kubernetes ingress-nginx

Özel bir Docker Registry’nin htpasswd arka ucu yalnızca bcrypt kabul eder. Satırı üretin, bağlayın (mount) ve registry’yi ona yönlendirin:

# Generate a bcrypt entry into a file
htpasswd -Bbn admin 's3cret' > auth/htpasswd

# Run the registry with that file
docker run -d -p 5000:5000 \
  -v "$(pwd)/auth:/auth" \
  -e REGISTRY_AUTH=htpasswd \
  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  registry:2

Kubernetes ingress-nginx içinse dosyayı bir Secret olarak saklayın ve ona annotation’larla başvurun:

kubectl create secret generic basic-auth --from-file=auth=./auth/htpasswd
metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"

Secret anahtarının adının auth olması gerekir; ingress-nginx tam olarak o anahtarı arar.

Caddy ve Traefik

İkisi de bcrypt hash’i bekler. Caddy, basic_auth yönergesini kullanır (düz metni değil, bcrypt hash’ini yapıştırın):

example.com {
    basic_auth /admin/* {
        admin $2y$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
    }
}

Traefik, basicauth ara yazılımını (middleware) user:bcrypt-hash çiftleriyle kullanır (yapılandırma biçiminize göre $ karakterlerini kaçış (escape) ile yazın):

http:
  middlewares:
    admin-auth:
      basicAuth:
        users:
          - "admin:$2y$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy"

Bir uç noktayı koruduktan sonra, komut satırından çalıştığını doğrulayın. cURL komut oluşturucu sizin için -u user:pass isteğini bir araya getirir, böylece hem 401’i hem de kimliği doğrulanmış 200’ü görebilirsiniz.

Güvenlik en iyi uygulamaları

Basic Auth basittir; bu yüzden onu yanlış kullanmanın sayılı yolunu görmek de kolaydır.

  • Her zaman HTTPS üzerinden sunun. Kimlik bilgisi geri çevrilebilir base64 olduğu için düz HTTP, parolayı hat üzerinde açığa çıkarır. TLS’i istisnasız her korumalı uç noktanın önünde sonlandırın.
  • Dosyayı web kök dizininin dışında tutun. .htpasswd sunulan bir dizinde dururken bir yanlış yapılandırma, birinin onu indirmesine kapı aralayabilir. Onu /etc/nginx/.htpasswd gibi bir yerde tutun, chmod 640 verin ve sahibini web sunucusu kullanıcısı (www-data, nginx) yapın; böylece sunucu okur, başka hesaplar okuyamaz.
  • Güçlü ve benzersiz parolalar kullanın. Her hesap, rastgele parola üreticisinden kendi yüksek entropili parolasını almalı ve onu hiç yeniden kullanmamalıdır. “Yeterince güçlü”nün bit cinsinden anlamını merak ediyorsanız, parola entropisi açıklaması matematiği ayrıntısıyla anlatır.
  • Sınırlarını bilin. Basic Auth’ta oturum kapatma da oturum da yoktur: tarayıcı, kimlik bilgisini realm başına önbelleğe alır ve siz kapatana dek her istekte yeniden gönderir. Hash’leme, başlıklar ve doğrulama üzerine daha geniş bir kontrol listesi için web güvenliği en iyi uygulamaları yazımıza bakın.

Yaygın hataların sorun giderme

nginx: crypt_r() failed (22: Invalid argument)

En sık görülen nginx Basic Auth hatası budur ve hep aynı şeye işaret eder: nginx, Blowfish şemasını içermeyen bir libc üzerinde bir bcrypt ($2y$) hash’ini doğrulamaya çalışmış; bu da çoğunlukla Alpine’ın musl’ı ya da daha eski bir glibc demektir. Çözüm, satırı nginx’in her platformda dahili olarak doğruladığı apr1 olarak yeniden üretmektir:

printf "admin:$(openssl passwd -apr1 's3cret')\n" > /etc/nginx/.htpasswd
nginx -s reload

libc’si bcrypt’i destekleyen bir temel imaja geçmek de işe yarar, ama apr1 daha basit ve daha taşınabilir bir çözümdür.

Doğru parola ile bile 401

Parolanın doğru olduğundan eminken yine de 401 alıyorsanız, şu kontrol listesini sırayla geçin:

  1. Dosya yolu. AuthUserFile / auth_basic_user_file’ın gerçekten o dosyaya işaret ettiğini doğrulayın (mutlak yol, yazım hatası yok).
  2. İzinler. Web sunucusu kullanıcısının dosyayı okuyabilmesi gerekir. sudo -u www-data cat /etc/nginx/.htpasswd ile bakın.
  3. Satır sonları / kodlama. Windows’ta düzenlenen bir dosya, hash’i bozan \r karakterleri taşıyabilir. file .htpasswd çalıştırın, gerekiyorsa dos2unix uygulayın.
  4. Bayat tarayıcı önbelleği. Tarayıcı, kimlik bilgilerini realm başına önbelleğe alır. Akılda kalan eski bir parolayı elemek için özel/gizli bir pencerede deneyin.
  5. Hash uyuşmazlığı. Saklanan hash’in parolayla gerçekten eşleştiğini doğrulayın; yapılandırmayı suçlamadan önce ikisini de htpasswd üreticisinin doğrulama moduna yapıştırıp teyit edin.

Basic Auth NE ZAMAN kullanılmamalı

Basic Auth, dar bir iş kümesinde doğru araçtır: bir hazırlık (staging) sitesi, dahili bir yönetim yolu, bir CI artefakt uç noktası, bir metrik panosu, özel bir registry. Hiçbir bağımlılığı yoktur ve kurulumu iki dakika sürer.

Bir ürün oturum açması içinse yanlış araçtır. Oturum kapatma, parola sıfırlama, hız sınırlama (rate limiting), hesap kilitleme ve MFA yoktur. Kimlik bilgileri her istekte yeniden gönderilir ve tarayıcı kapanana dek önbellekte kalır. Kullanıcıların oturum açtığı her yerde bunun yerine oturumlara (sessions), OAuth’a ya da OIDC’ye geçin. Bu sınır konusunda dürüst davranmak, Basic Auth’u tam yerinde kullanışlı kılan şeydir.

SSS

Bir .htpasswd dosyasındaki tek bir satır gerçekte ne içerir?

İki nokta üst üste ile ayrılmış bir username:hash çifti. Hash, bir algoritma ön ekiyle başlar (bcrypt için $2y$, Apache MD5 için $apr1$, SHA-1 için {SHA}), ardından tuz (salt) ve özet gelir. Düz metin parola dosyada hiç görünmez.

.htpasswd ile .htaccess arasındaki fark nedir?

.htaccess, Apache’nin dizin başına yapılandırma dosyasıdır; Basic Auth’u açar ve kimlik bilgisi deposuna işaret eder. .htpasswd ise o kimlik bilgisi deposunun kendisidir ve username:hash satırlarını tutar. nginx, .htpasswd biçimini kullanır ama kimlik doğrulamayı .htaccess ile değil, server/location bloklarında yapılandırır.

Bir .htpasswd dosyasında nasıl kullanıcı eklerim, değiştiririm veya kaldırırım?

Bir kullanıcı eklemek ya da değiştirmek için htpasswd /path/.htpasswd username’i -c olmadan çalıştırın; kullanıcı zaten varsa hash’i güncellenir. Birini kaldırmak için htpasswd -D /path/.htpasswd username çalıştırın. -c’yi yalnızca ilk kullanıcıda kullanın, çünkü dosyanın tamamının üzerine yazar.

Tarayıcı Basic Auth kimlik bilgilerini nasıl hatırlar ve kullanıcılar nasıl oturum kapatır?

Tarayıcı, kimlik bilgilerini realm’e göre anahtarlayıp önbelleğe alır ve eşleşen her istekte otomatik olarak yeniden gönderir. Standart bir oturum kapatma yoktur: onları temizlemenin tek yolu tarayıcıyı kapatmak ya da önbelleğini silmektir. Bu eksik oturum kapatma, Basic Auth’un ürün kimlik doğrulamasına uymamasının sebeplerinden biridir.

Aynı .htpasswd dosyasını hem Apache hem de nginx için kullanabilir miyim?

Hash biçimi ikisinde de destekleniyorsa evet. apr1 (Apache MD5), Apache ve nginx tarafından her yerde dahili olarak doğrulandığı için en güvenli paylaşılan seçimdir. bcrypt, Apache’de çalışır ama nginx’te sistemin crypt()’ine bağlıdır ve bu, Alpine/musl derlemelerinde başarısız olur.

HTTP Basic Authentication 2026’da hâlâ geçerli mi?

Evet. HTTPS’in üstünde hafif bir kapı olarak (dahili araçlar, hazırlık ortamları, özel registry’ler, izleme uç noktaları) hâlâ pratik ve bağımlılıksızdır. Yeter ki onu, Basic Auth’un sağlayamadığı oturum, sıfırlama, hız sınırlama ve MFA isteyen kullanıcıya dönük ürün kimlik doğrulamasıyla karıştırmayın.

Go Tools ekibi tarafından incelendi: bu kılavuzdaki her komut, yapılandırma bloğu ve hash biçimi, Apache htpasswd (apache2-utils) ve OpenSSL referans çıktısıyla karşılaştırılarak doğrulandı.

Etiketler: htpasswd basic-auth http-authentication nginx apache bcrypt security