Herhangi bir komut için bir komut istemi kullanarak hassas verileri bash içerisinde aktarmanın bir yolu var mı?


40

sha1passKomut satırında bazı hassas şifrelerden oluşan bir karma oluşturmak için kullandığımı varsayalım . sha1pass mysecretBir karma üretmek için kullanabilirim , mysecretancak bu mysecretşimdi bash tarihinde olan bir dezavantaja sahiptir . Bu komutun son hedefini, mysecretdüz stilde açıklamaktan passwdkaçının , belki de bir stil sorgusu kullanarak ulaşmanın bir yolu var mı ?

Ayrıca, hassas verileri herhangi bir komuta aktarmak için bunu genel bir yöntemle de ilgileniyorum. Hassas veriler argüman olarak (in gibi sha1pass) veya STDIN'de bazı komutlara iletildiğinde yöntem değişecektir .

Bunu başarmanın bir yolu var mı?


Düzenleme : Bu soru çok dikkat çekti ve aşağıda sunulan birkaç iyi cevap var. Bir özet:

  • Gereğince Kusalananda cevabı @ ideal bir bir yardımcı program için bir komut satırı bağımsız değişken olarak bir şifre veya gizli vermek zorunda asla. Bu, onun tarafından tanımlandığı gibi birçok yönden savunmasızdır ve kişi STDIN'e gizli girdi alabilen daha iyi tasarlanmış bir yardımcı program kullanmalıdır.
  • @ vfbsilva'nın cevabı , işlerin bash tarihinde saklanmasını nasıl önleyeceğini açıklıyor
  • @ Jonathan'ın cevabı , program STDIN'deki gizli verilerini alabildiği sürece bunu başarmak için mükemmel bir yöntemdir. Bu nedenle, bu cevabı kabul etmeye karar verdim. sha1passOP'mde sadece bir örnek vardı, ancak tartışma STDIN hakkında veri alan daha iyi araçların var olduğunu ortaya koydu.
  • olarak @R .. notlar onun cevabı , bir değişken üzerinde komut genişleme kullanılmasıdır değil güvenli.

Bu yüzden, özet olarak, Jonathan'ın cevabını kabul ettim çünkü çalışmak için iyi tasarlanmış ve iyi niyetli bir programa sahip olduğunuza göre en iyi çözüm bu. Bir parola veya sırrı komut satırı argümanı olarak iletmek temelde güvensiz olsa da, diğer cevaplar basit güvenlik kaygılarını azaltmanın yollarını sunar.


6
Sadece bu değil: Aynı makinede çalışan işlemleri listeleme izni olan herkes potansiyel olarak bunun sha1pass mysecretçalıştığını görebilir ve dolayısıyla ne mysecretolduğunu bilir . (Bu program elbette çalışırken elbette sadece birkaç saniye çalışır ... elbette ...)
MathematicalOrchid

@MathematicalOrchid Özel bir sanal makinede çalıştırılarak bu önlenebilir. Ancak bu sadece tek bir şifre oluşturmak için ayarlamak için çok fazla iş olabilir ... :-)
Kusalananda

5
@Kusalananda Amacım "Komut satırını nasıl kapattığınızı öğrenseniz bile" komut satırına hiçbir zaman hassas veriler koymayın "...
MathematicalOrchid

2
Sadece bildiğiniz gibi, SHA-1, birkaç yıldan beri anahtar veya şifre karmaşası nedeniyle kullanımdan kaldırıldı.
David Foerster

2
Sistem bir denetim arka plan programı kullanıyorsa, tüm komutların ve tüm kullanıcıların tüm argümanlarının merkezi olarak kökten kaydedildiğini, bu nedenle bu günlüklere erişebilen herkesin bunu göreceğini unutmayın.
Randall

Yanıtlar:


20

Ya zshda bashshell kullanıyorsanız read, uçbirim aygıtından bir çizgi okumak için dışkıya kabuk eklemek için -s seçeneğini kullanın .

IFS= read -rs VARIABLE < /dev/tty

Ardından değişkeni stdin olarak kullanmak için bazı süslü yönlendirmeler kullanabilirsiniz.

sha1pass <<<"$VARIABLE"

Eğer biri pskoşarsa, tek görecekleri "sha1pass" olur.

sha1passHerhangi bir argüman verilmediğinde şifreyi stdin'den (bir satırda, satır sınırlayıcıyı yok sayarak) okuduğunu varsayar .


sha1passStandart girdi akışını kullanmadığını belirlediğimizi düşünüyorum .
Kusalananda

@Kusalananda Tamam, ama bu yöntem stdin'den okuyan programlar için işe yarayacak.
Jonathan,

Yani, STDIN'e yardımcı programın gizli girdisini alabileceğini varsayarsak, bu güvenlik açısından sağlam ve güvenli bir çözümdür?
30'da

Çalışmak için iyi tasarlanmış bir programa sahip olduğunuza verilen en iyi çözüm olduğu için bu cevabı kabul etmeye karar verdim . sha1passOP'mde sadece bir örnekti ve bunun için kullanılabilecek en iyi seçenek değildi.
18’de

1
@cemulate, ... komut satırında güvende değil . Bir yorumlu metin ya da (burada cevap gibi) herestring bağlamında, bu maruz değil ps, ama olabilir geçici bir dosyaya yazılacak - Bir önlemek istiyorsa, o zaman sshpass < <(printf '%s\n' "$VARIABLE")düşünülebilir (çünkü printfbir yerleşik değil, bir olduğunu dış komut, iletilmez execvve üzerinden erişilebilir ps).
Charles Duffy

35

İdeal olarak, komut satırında hiçbir zaman bir komutun argümanı olarak bir açık metin parolası yazmazsınız. Bunu yapmak parolayı komuta bir argüman haline getirir ve komut tablosundaki argümanlar işlem tablosunda psbazı denetim günlüklerinde olduğu gibi veya basit girişler kullanılarak görülebilir .

Bunu söyledikten sonra, gerçek parolayı kabuğun komut geçmişinden gizlemenin kesin yolları vardır.

sha1pass "$( head -n 1 )"

Ardından şifreyi yazın ve tuşuna basın Enter. headBurada kullanılan komut tam olarak bir giriş hattı ve geçirilir verilerin parçası olmayacaktır yazın bu son yeni satır kabul sha1pass.

Karakterlerin yankılanmasını önlemek için:

sha1pass "$( stty -echo; head -n 1; stty echo )"

stty -echoTerminalde yazılan karakterlerin yankılanan kapalı komut dönüşler. Eko daha sonra ile geri yüklenir stty echo.

Standart girdiyi iletmek için, bu son komut değiştirilebilir ( sha1passstandart girdiyle ilgili veri kabul edilirse bunu yapardınız , ancak bu özel yardımcı program standart girdisini görmezden geliyormuş gibi görünür):

{ stty -echo; head -n 1; stty echo; } | somecommand

Çok satırlı giriş gerekiyorsa (yukarıdaki satır sonunda yeni satır karakteri olmayan tek bir satırın geçilmesi gerektiğini varsayar), ardından tüm headkomutu değiştirin catve ( somecommandile dosya sonuna kadar okuduğunu varsayarak) girişini sonlandırın Ctrl+D( aşağıdaki Returnyeni satır girişinde karakteri ya) değilse iki kez dahil etmek istiyorum.

Bu, hangi kabuğu kullandığınızdan bağımsız olarak işe yarar (Bourne benzeri veya rc benzeri bir kabuk olduğu sürece).

Komuttan önce boşluk varsa, girilen komutları geçmiş dosyalarına kaydetmemek için bazı kabuklar yapılabilir. Bu genellikle HISTCONTROLdeğere ayarlamak zorunda kalır ignorespace. Bu en azından tarafından desteklenmektedir bashve kshOpenBSD'deki değil örneğin tarafından ksh93veya dash. zshKullanıcılar yoksayılacak bir desen tanımlamak için histignorespaceseçeneği veya HISTORY_IGNOREdeğişkenlerini kullanabilir.

readTerminale karakterleri yankısız olarak okumayı destekleyen kabuklarda , ayrıca

IFS= read -rs password     # -s turns off echoing in bash or zsh
                           # -r for reading backslashes as-is,
                           # IFS= to preserve leading and trailing blanks
sha1pass "$password"

ancak bu açıkça, işlem tablosundaki parolayı potansiyel olarak açığa çıkarmayla aynı sorunu yaşıyor.

Yardımcı program standart girdiden okursa ve kabuk "here-string" destekliyorsa, yukarıdakiler değiştirilebilir.

IFS= read -rs password
somecommand <<<"$password"

Aşağıdaki yorumların özeti:

  • Verileri komuta gönderenlerin dışında, yukarıdaki komutların hepsinin yaptığı komut satırında verilen bir parola ile bir komut çalıştırmak ps, aynı anda çalışan herkes için parolayı potansiyel olarak gösterebilir . Ancak yukarıdaki komutların hiçbiri, eğer etkileşimli bir kabuktan çalıştırılmamışsa, girilen şifreyi kabuğun geçmiş dosyasına kaydetmez.

  • Düzgün metin şifreleri okuyan iyi kalpli programlar bunu standart girdilerinden, bir dosyadan veya doğrudan terminalden okuyarak yaparlar.

  • sha1pass komut satırında ya doğrudan girilmiş ya da bazı komut değiştirme biçimleri kullanılarak şifreyi gerektirir.

  • Mümkünse, başka bir araç kullanın.


11
Bu yanlış. Komut genişletmenin sonucu $(...), komut satırının bir parçası olacak ve pssertleştirilmiş / proc'lu bir sistem dışında çıktıda görülebilir .
R. ..

3
@Kusalananda, başladıktan sonra argv'nin üzerine yazmak bile, üzerine yazma gerçekleşmeden önce savunmasız bir pencere bırakır; bu bir azaltma, düzeltme değil.
Charles Duffy

5
@Kusalananda, şifreleri toplamak için iyi tasarlanmış bir programın komut satırına giriş yapılmasını gerektirmez, bu nedenle koşullu temelde bir verilmiş olur - değilse , biri farklı bir araç seçmelidir.
Charles Duffy

4
@ CharlesDuffy: Buradaki araç temelde bozuk görünüyor. sha1passkomut satırında parola olmadan çalıştırma hiçbir şey okumadan bir çıktı veriyor gibi görünüyor ... Bu yüzden OP farklı bir araç seçmeli.
R. ..

8
Bu cevap, güvenlik açısından güvensizdir ve tek avantaj, parolanın kabuk geçmişinde görünmemesidir, ancak bu avantajı komutun önüne bir boşluk
ekleyerek

25

Eğer böyle ayarlarsan HISTCONTROL:

HISTCONTROL=ignorespace

ve komutu bir boşlukla başlatın:

~$  mycommand

tarihte depolanmayacak.


10

Hassas verileri bir boru veya here-doc yoluyla iletin

command_with_secret_output | command_with_secret_input

veya:

command_with_secret_input <<EOF
$secret
EOF

Sırların (dışa aktarılmayan) kabuk değişkenlerinde olması iyidir, ancak bu değişkenleri komut satırlarında yalnızca burada-belgelerde ve kabuk içindekilerde kullanamazsınız.

Kusalananda'nın bir yorumda belirtildiği gibi, etkileşimli bir kabuğa komutlar giriyorsanız, burada bir belge için girdiğiniz satırlar kabuk geçmişinde depolanacaktır, bu nedenle oraya bir parola yazmak güvenli değildir, ancak yine de sır içeren kabuk değişkenlerini kullanmak güvenli; tarih, $secretneye $secretgenişletilmişse metni içerecektir .

Komut genişletmelerinin kullanımı güvenli değil :

command_with_secret_input "$(command_with_secret_output)"

çünkü çıktı komut satırına dahil edilecek ve pssertleştirilmiş / proc'lu sistemler hariç çıktıda (veya manuel olarak / proc'den okunacak şekilde) görünecektir .

Bir değişkene atama da tamamdır:

secret=$(command_with_secret_output)

Ne aradığım gerçek bir komuttur command_with_secret_outputbana izin tip gizli çıkışı. Burada değiştirilebilecek böyle bir komut var mı?
Nisanda

Buraya bir belgeyi etkileşimli bash oturumda yazmanın belgeyi geçmiş dosyasına kaydedeceğini unutmayın.
Kusalananda

@cemulate: Sadece mermi kovanını kullanın read, örn read -r secret. O zaman sırrın içeride $secret. İsterseniz girişi gizlemek için önce / sonra stty komutunu çalıştırabilirsiniz.
R. ..

3
@Kusalananda: sha1passtemelde kırılmış / kullanılamaz / güvensiz gözüküyor çünkü şifreyi stdin veya bir dosyadan okuyamıyor. Bence sorunu çözmek için farklı bir yardımcı program gerekli.
R. ..

1
@cemulate R'ye son yorumunuz tam olarak yerinde. Bu yüzden yardım etmeyecek. read -rsişi yapacak ( -rbunlara ters eğik çizgi içeren şifreler ekleyebilecekseniz), ancak daha sonra işlem listesinde parolanızı gösterme potansiyelinde geri dönüyorsunuz (ve işlem muhasebesinin açık olup olmamasına ve nasıl yapılandırıldığına bağlı olarak) , muhasebe sürecinde de günlükleri).
Kusalananda

6

Sadece değeri bir dosyaya yazın ve dosyayı iletin:

$ cat > mysecret
Big seecreeeet!
$ cat mysecret | sha1pass 

Nasıl sha1passçalıştığını bilmiyorum, eğer bir dosyayı girdi olarak alabilirse kullanabilirsiniz sha1pass < mysecret. Aksi takdirde, catson yeni satırı içerdiğinden kullanım bir sorun olabilir. Bu durumda, kullanın ( headdestekliyorsanız -c):

head -c-1 mysecret | sha1pass 

2
Sadece ilk yaptığınız zaman neden şifreyi diske yazmalısınız cat | sha1pass? cat mysecret | sha1passve sha1pass < mysecretson satırsonları için aynı davranışa sahip. catyeni satır eklemiyor. Her neyse, sha1passşifreyi standart girdiden geçirmeyi destekliyorsa, son satırın tek başına yoksaymasını beklerdim. Yeni satırlarla sonlandırılmayan satırlı dosyalar, sonuçta unix'te doğal değildir, bu nedenle yeni satır ile sonlandırılmayan bir dosya beklemek garip olur.
JoL

@JoL i) Bunu düşünmemiştim: / Ama bu nasıl çalışırdı? bana herhangi bir girdiye girme şansı vermeden önce cat | sha1passkoşmak gibi görünüyor sha1pass. ii) Hayır, tabii ki cat mysecretbir yeni satır eklemez, ben hiç catkeşke bu, ekler içeren bunu.
terdon

Anladım, ama bu da onu < mysecretkaldırmak gibi değil. :)
JoL

Boşver. Şimdi tekrar okudum, bunu daha sonra önermek için söylediğini görüyorum head -c-1. Sanırım neden kullandığı konusunda kafam karıştı cat mysecret | sha1passve daha sonra önerdim sha1pass < mysecret. Endişe duyuyorum ki sha1pass stdin için normal dosyalar hakkında şikayet edebilir; Neden olduğundan emin değilim.
JoL

Ben hiç kullanmadım çünkü @JoL daha var sha1passve bir manuel veya bulamadık -hya ben aramaya harcanan birkaç dakika içinde dokümantasyon başka bir biçimde çalışır durumda eğer öyleyse çözemedim sha1pass footedavi foobir giriş dizesi olarak veya bir giriş dosyası olarak . Bu yüzden her olasılıkla başa çıkabilmek için seçenekler verdim.
terdon

1

Terdonun yaptığı mümkün ise, standart girdiden geçerek en iyi çözüm budur. Geriye kalan tek sorun, şifreyi diske yazması. Bunun yerine bunu yapabiliriz:

stty -echo
echo -n "password: "
head -1 | sha1pass
stty echo

Kusalananda'nın dediği gibi, tekrar stty -echoyazana kadar yazdıklarınızın görülmemesini sağlar stty echo. head -1standart girişten bir satır alır ve iletir sha1pass.


0

Kullanmak istiyorum

sha1pass "$(cat)"

catsttr'den EOFCtrl + D ye basmakla sonuçlanabilecek olana kadar okunacaktı . Ardından, sonuç argüman olarak iletilir.sha1pass


3
R .. 'ın cevabı, bunun neden güvenli olmadığını açıklar.
HVD
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.