Hassas verileri chpasswd'ye geçirmek için echo kullanmak güvenli midir?


17

Toplu kullanarak birkaç kullanıcı hesabı parolaları topluyor çalışıyorum chpasswd. Parolalar rasgele oluşturulmalı ve yazdırılmalıdır stdout(Bunları yazmam veya bir şifre deposuna koymam gerekiyor) ve ayrıca aktarıldı chpasswd.

Safça, bunu böyle yapardım

{
  echo student1:$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '')
  echo student2:$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '')
} | tee >(chpasswd)

Ancak, yeni parolayı bir komut satırı argümanı olarak geçirme konusunda endişeliyim echo, çünkü argümanlar genellikle diğer kullanıcılar tarafından görülebilir ps -aux(ancak hiçbir echosatır görmedim ps).

Döndürülen şifreme bir değer eklemenin ve sonra onu geçirmenin alternatif bir yolu var mı chpasswd?


6
echoyerleşik bir kabuktur. İşlem tablosunda ortaya çıkmaz.
Kusalananda

Yanıtlar:


15

Kodunuz, echoyerleşik bir kabuk olduğu için işlem tablosunda görünmeyeceğinden güvenli olmalıdır .

İşte alternatif bir çözüm:

#!/bin/bash

n=20
paste -d : <( seq -f 'student%.0f' 1 "$n" ) \
           <( tr -cd 'A-Za-z0-9' </dev/urandom | fold -w 13 | head -n "$n" ) |
tee secret.txt | chpasswd

Bu n, herhangi bir komutun herhangi bir komut satırına herhangi bir parola geçirmeden öğrenci adlarınızı ve parolalarınızı oluşturur .

Yardımcı pasteprogram birkaç dosyayı sütun olarak yapıştırır ve aralarına bir sınırlayıcı ekler. Burada, :sınırlayıcı olarak kullanıyoruz ve ona iki "dosya" veriyoruz (işlem ikameleri). Birincisi seq, 20 öğrenci kullanıcı adı oluşturan bir komutun çıktısını içerir ve ikincisi, 13 uzunluktaki 20 rastgele dizeyi oluşturan bir boru hattının çıktısını içerir.

Kullanıcı adlarının önceden oluşturulduğu bir dosyanız varsa:

#!/bin/bash

n=$(wc -l <usernames.txt)

paste -d : usernames.txt \
           <( tr -cd 'A-Za-z0-9' </dev/urandom | fold -w 13 | head -n "$n" ) |
tee secret.txt | chpasswd

Bunlar secret.txt, oluşturulan şifreleri terminalde göstermek yerine şifreleri ve kullanıcı adlarını dosyaya kaydeder .


2
Bu ihtiyacı yoktur akıllı bir çözüm var echoya printfancak kod deşifre etmek biraz garip,
Nils Werner

@NilsWerner Biraz daha açıklama eklendi. Genişlememi istediğin belirli bir şey varsa bana haber ver.
Kusalananda

1
echoYine de bir kabuk yerleşik olmasına güvenmemelisiniz . Çoğu mermide öyle, ama kesinlikle hiçbir şartı yoktur.
Austin Hemmelgarn

1
@Kusalananda Sadece merak ediyorum, tee secret.txt > >(chpasswd)ve arasında etkili bir fark var tee secret.txt | chpasswdmı? İkincisi çok daha yaygın görünüyor, bu yüzden neden düz bir boru yerine proses ikamesini kullanmayı seçtiğinizi merak ediyorum
Christopher Shroba

1
@ChristopherShroba Zaten söz konusu olan koda (bunun yerine bir işlem ikamesi kullanarak tee) benzer başka bir neden yok . Şimdi işaret ettiğine göre, aslında değiştireceğim (daha iyi görünüyor). Teşekkürler.
Kusalananda

8

echobüyük olasılıkla kabukta yerleşiktir, bu yüzden psayrı bir işlem olarak görünmez .

Ancak komut ikamesini kullanmanıza gerek yoktur, sadece boru hattından çıktıyı doğrudan aşağıdakilere alabilirsiniz chpasswd:

{  printf "%s:" "$username";
   head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo ''
} | chpasswd 

Bir çalıştırmayla birden fazla şifreyi değiştirmek istiyorsanız chpasswd, temel parçaların tekrarlanması kolay olmalıdır. Veya bir işlev haline getirin:

genpws() {
    for user in "$@"; do
        printf "%s:" "$user";
        head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13
        echo
    done
}
genpws username1 username2... | chpasswd 

Bir kenara: hat odaklı olmadığından head /dev/urandombu biraz garip geliyor urandom. Çekirdeğin mevcut entropi kavramını etkileyecek aşırı miktarda bayt okuyabilir ve bu da blokaja neden olabilir /dev/random. Sadece sabit miktarda veri okumak base64ve rastgele baytları yazdırılabilir karakterlere dönüştürmek gibi bir şey kullanmak daha temiz olabilir (sadece aldığınız baytların yaklaşık 3/4'ünü atmak yerine).

Böyle bir şey size yakl. 16 karakter ve sayı:

head -c 12 /dev/urandom | base64 | tr -dc A-Za-z0-9 

(yani, çıktıdaki karakter sayısı +ve /karakterleri daha azdır base64. Her ikisinin de şansı karakter başına 1/32'dir, bu yüzden kombinatoriklerimi doğru bulduğumda, en az 14 karakter bırakma şansı yaklaşık% 99'dur ve % 99,99 en az 12 ayrılma şansı.)


Sizin printfbirden fazla kullanıcı adları için birden fazla satır döndürür, ama üzerinde Sözlerinizi takdir: Çözüm benim orijinal kod mu ne yapmazhead urandom
Nils Werner

@NilsWerner, pek çok kullanıcıya genişlemesine rağmen açık. Ama önemli değil, kullanıcı adını üretmek için bir işlev yapabiliriz: tek seferde birden fazla kullanıcı için şifre çiftleri. (bakınız düzenleme)
ilkkachu

3
İstediğiniz kadar karakter içeren urandom'dan ilk 10 "satıra" gerçekten güvenemezsiniz. Sadece urandom'u doğrudan tr üzerinden çalıştırın.
Kusalananda

@Kusalananda, benim head -c 10 | base64boru hattımı mı yoksa Nils'in de olduğunu mu söylüyorsun head | tr? Rasgele baytların 10 "satırının" yüzlerce bayt olması muhtemeldir (256'da sadece 1'in yeni satır olacağı göz önüne alındığında), ancak teoride tam olarak 10 bayt olabilir, ancak olasılıklar tamamen ihmal edilebilir. Benzer şekilde base64, rastgele baytlar sadece söylenirse \xff, base64 sadece bir eğik çizgi dizisi olacaktır, ancak bu da pek olası değildir. Eğer ilgilenirseniz, 10 bayttan fazlasını okuyabilir, bunun olasılığını azaltabilir ve daha sonra elde edilen çıktının uzunluğunu kesebilirsiniz.
ilkkachu

1
@ilkkachu Her iki koda da atıfta bulunuyorum. Rastgele bayt okursanız ve istemediğinizi filtreledikten sonra belirli bir uzunlukta bir şey istiyorsanız, ihtiyacınız olanı aldığınızdan emin oluncaya kadar veri kaynağını kesmeyin. Dediğiniz gibi, çok var olası sen on satırbaşıyla bir dizi elde etmesi /dev/urandom, ancak riski% 0 değil.
Kusalananda
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.