Sudo yerine SSH kullanımı
(whynothugo.nl)sudovedoas, setuid ikili dosyalarına ve yetki yükseltmeye dayandığı için, root komutlarının çalıştırılmasını yerel birsshd’yi Unix domain socket’e bağlayarak üstlendiren bir deney- Amaç, yalnızca izin verilen kullanıcıların root komutları çalıştırabilmesini sağlarken, kullanıcı oturumunun tamamında yetki yükseltme kabiliyeti bırakmamak
- Uygulama; root’a özel SSH anahtar dosyası, erişimi kısıtlanmış
/run/sshd/sshd.sock,AuthorizedKeysFilevePermitRootLogin=yesseçeneklerine sahip ayrı birsshdinstance’ından oluşuyor ssh’te mevcut bir socket’i doğrudan aktaran bir seçenek olmadığı için başlangıçtaProxyCommandvesocatkullanılmış; daha sonra ProxyUseFdpass ve kısa bir Python betiğiyle socket dosya tanımlayıcısı aktarılmış- Bu yöntem çalışıyor ve güvenlik işlemleri ağırlıklı olarak OpenSSH’e dayanıyor; ancak günlük kullanım için
passfd.py’yi küçük bir çalıştırılabilir dosyaya dönüştürmek ve tümsshkomutunu bir wrapper ile sarmak daha uygun
sudo ve doasın yapısal kısıtları
sudovedoas, komutları root olarak çalıştırmak içinsetuidikili dosyalarına ve yetki yükseltmeye dayanır- Bu tasarımın birkaç sınırı vardır
- Kullanıcı oturumunun tamamının yetki yükseltme gerçekleştirebilme kabiliyetini koruması gerekir
- Tüm kullanıcı oturumu kısıtlı bir kullanıcı ad alanı içinde çalıştırıldığında işlemez
setuidikili dosyaları sistem genelindeki güvenlik yapılandırmasına kısıtlar getirir
s6-sudod, programı yetkili bir sunucu ve yetkisiz bir istemci olarak ayıran bir alternatiftir
Deneyin hedefi
- Yerelde
sshkullanaraksudoile aynı rolü yerine getirmek; ancak ilgilisshdinstance’ını ağa açmamak - Temel koşul iki tanedir
- Yalnızca izin verilen kullanıcılar root olarak komut çalıştırabilir
- Yetki yükseltme kullanılmaz
Yerel root girişi için sshd yapılandırması
- Yalnızca root kimlik doğrulamasında kullanılacak özel bir SSH anahtarı oluşturulur ve genel
authorized_keysyerine/root/.ssh/local_keysiçinde saklanır - Ayrı bir
sshdinstance’ı Unix domain socket’e bind edilir ve izin verilmeyen kullanıcıların socket’e erişememesi için/run/sshd/izinleri kısıtlanır - Çalıştırma örneği,
s6-ipcserverile/run/sshd/sshd.sockoluşturupsshd’ye şu seçenekleri aktarma biçimindedirAuthorizedKeysFile=/root/.ssh/local_keysPermitRootLogin=yes
/etc/ssh/sshd_configdeğiştirilmez- Çünkü ağa bind edilmiş mevcut
sshdüzerinde root girişine izin verilmek istenmez - Mevcut ayarda
PermitRootLogin nokorunur
- Çünkü ağa bind edilmiş mevcut
Root hesabı kilidi ve parola ile girişin işlenmesi
- Root hesabı hiçbir şekilde giriş yapılamayacak biçimde kilitliydi; bu, parola hash’inin başına
!eklenerek yapılmıştı sshd, bu!önekini hesap kilidi olarak yorumlar ve root girişine izin vermez/etc/passwdiçindeki root parola değeri değiştirilerek!yerine*konursshd,*karakterini özel bir kilit değeri olarak yorumlamaz*hiçbir parola hash’iyle eşleşmediği için parola ile giriş fiilen devre dışı kalmış olur
- Ayrıca
sshd_configiçindePasswordAuthentication noayarlıdır;sshdüzerinde parola tabanlı kimlik doğrulamayı kapatan yapılandırma güvenlidir
ssh ile Unix socket’e bağlanmak
sshdmevcut bir socket’i aktarabilen-ibayrağına sahiptir, ancaksshiçinde aynı rolü üstlenen bir bayrak yoktur- Başlangıçta
ProxyCommandilesocatkullanılarak/run/sshd/sshd.sockadresine bağlanılmıştır - Bağlantı komutu şu öğelerden oluşur
ProxyCommand='socat STDIO UNIX-CONNECT:/run/sshd/sshd.sock'- Özel root anahtarını
-i .ssh/root-key.pubile belirtme root@rootolarak bağlanma- Mevcut dizine geçtikten sonra login shell çalıştırma
- Kullanılan SSH anahtarı donanıma bağlı anahtar olduğundan, bağlantıyı onaylamak için fiziksel cihaza dokunmak gerekir
- Anahtarı yalnızca açık onaydan sonra açığa çıkaran
ssh-agent, örneğinhissh-agent, bir alternatif olabilir
socat ek yükü ve ProxyUseFdpass
socat,ssh’in tüm girdisini okuyup ardından socket’e yazdığı için bağlantı ek yükü fiilen yinelenirProxyUseFdpass, komutun socket dosya tanımlayıcısınıstdoutüzerindenssh’e göndermesini vessh’in bu socket üzerinden bağlanmasını sağlar- 2016 tarihli OpenSSH ProxyUseFdpass kullanım örneği temel alınarak Python betiği
passfd.pyyazılmıştır- Unix domain socket
/run/sshd/sshd.sockadresine bağlanır sendmsgveSCM_RIGHTSile dosya tanımlayıcısını aktarır
- Unix domain socket
- Sonrasında bağlantı komutu,
ProxyCommandiçindepassfd.pybelirtilipProxyUseFdpass=yeseklenen bir biçime dönüşmüştür nc -FU /run/sshd/sshd.sockda mümkün görünüyor; ancak kılavuz-Fseçeneğinin-Uile birlikte kullanılamayacağını açıkça belirtir
Sonuç ve pratik kullanım biçimi
- Bu teknik çalışır ve hassas güvenlik işlemleri ağırlıklı olarak OpenSSH’e bırakılır
- OpenSSH’in iyi bir geçmişi vardır ve donanım tabanlı SSH anahtarları dahil çeşitli kimlik doğrulama yöntemleri kullanılabilir
- Yeni bir host üzerinde kurulum sürecinde karmaşık adımlar yoktur ve
ipcserverkomutu sistem servis yöneticisi aracılığıyla çalıştırılabilir passfd.py, deneyi yürütmek için yapılmış hızlı bir hack’e daha yakındır- Günlük kullanımda aynı rolü üstlenen küçük bir çalıştırılabilir dosya oluşturup
/usr/local/biniçine koymak ve tümsshkomutunu da küçük bir wrapper ile sarmak daha uygundur
1 yorum
Hacker News yorumları
Bu yaklaşıma yönelik en büyük itiraz nedeni karmaşıklığın artması. Bir yapılandırma dosyasını okuyup
exec()çağıran tek birsuidikilisi yerine, root olarak çalışan ve bir UNIX soketini dinleyen bir ikili ile o soketle konuşan bir ikili ortaya çıkıyor; üstelik ikisinin de asimetrik şifrelemeyi işlemesi gerekiyor.sudo/doas’a yönelik temel itiraz “tüm kullanıcıların erişebildiği bir
suidikilisi var ve bir hata olursa yetki yükseltmek için kötüye kullanılabilir” ise, aşağıdaki gibi yapılabilir:chgrp wheel /usr/bin/sudochmod o-rwx /usr/bin/sudosudo kullanıcılarını
wheelgrubuna koyarsanız, yalnızca sudo kullanabilen kullanıcılar dosya baytlarını diskten okuyabilir ve çalıştırabilir. UNIX soketini yalnızcawheelkullanıcılarının erişebileceği hâle getiren sshd yaklaşımıyla erişim denetimi açısından güvenlik neredeyse aynıdır, ama karmaşıklık çok daha düşüktür.Ayrıca sshd yaklaşımı, sudo gibi root erişimini belirli komutlarla sınırlayamaz; dolayısıyla sudo’nun komut kısıtlamalarını aşan bir hata olsa bile, sshd yaklaşımından daha fazla yetki vermez.
Paket yöneticisinin
/usr/bin/sudoizinlerini bozacağından endişeleniyorsanız, cron ile periyodik olarak düzelttirebilir ya da sudo’yu tamamen kaldırıp kaynaktan farklı bir konuma elle kurabilirsiniz. Elbette bunu yaparsanız bakım ve yükseltmeleri de kendiniz yapmanız gerekir./etcaltındaki tüm değişiklikleri etckeeper ile izliyorum. Yazılım kurulumu/yükseltmesi olsun, bir kişinin yaptığı değişiklik olsun kaydediliyor; yeni bir sürüme yükseltirken de yerel değişiklikler için bir yama oluşturup temiz kuruluma uygulayarak çakışmaları 3-way merge ile kontrol edebilmek kullanışlı.https://etckeeper.branchable.com/
wheelgrubuna koyup yalnızca sudo kullanabilen kullanıcıların dosyayı okuyup çalıştırabilmesini sağlamak oldukça makul. Bunun neden her yerde varsayılan ayar olmadığını merak ediyorum./usr/bin/sudoyu immutable yapmak da mümkün olmaz mı? Bu, paket yöneticisinin ona dokunmasını engellemeye yardımcı olur gibi.Bu, şu anda systemd run0’ın yaptığı şey değil mi? systemd’de
run0adlı yeni bir araç var; aslında tamamen yeni bir araçtan ziyade, uzun süredir var olansystemd-runırun0adlı sembolik bağlantı üzerinden çağırınca sudo alternatifi gibi davranması söz konusu.Temel fark, gerçekten
SUIDolmaması. Servis yöneticisinden hedef kullanıcının UID’siyle bir komut ya da kabuk çalıştırmasını istiyor, yeni bir PTY ayırıyor ve özgün TTY ile bu PTY arasında veri aktarıyor.Başka bir deyişle hedef komut, istemcinin bağlamını devralmıyor; PID 1’den yeni fork edilmiş yalıtılmış bir yürütme bağlamında çalışıyor.
$TERMaktarılıyor, ama bu açık bir istisna; yani bir engelleme listesinden çok izin listesine yakın.Birçok açıdan
run0ın davranışınınsudodan çoksshe daha yakın olduğu söylenebilir.https://mastodon.social/@pid_eins/112353324518585654
Bir şeyi mi kaçırıyorum? root olarak ssh ile oturum açmanın, sudo kullanmaktan nasıl daha güvenli olduğunu anlamıyorum. Hep buna izin vermememiz gerektiği öğretildiği için gerçekte ne kadar tehlikeli olduğunu da pek bilmiyorum.
Burada uzak kullanıcıları engellemeye yönelik bir düşünce var gibi, o yüzden o güvenlik yönünden bahsetmiyorum.
Sudo’nun 3. sınırlamasıyla ilgili olabilir, ama en azından 1. maddeyle karşılaştırınca bir avantaj göremiyorum.
Bunun bir deney olduğunu anlıyorum, ama sudo’dan daha az kırılgan değil, daha kırılgan olacakmış gibi geliyor. Açık soket proxy’si ortadaki adam saldırılarına açık görünüyor.
Yine de eski araçlarla yapılabilecek birkaç teknik öğrendim; yeni bir şey göstermesi hoştu.
sudoikilisi suid root ve ayrıcalıklı bir ikili olduğu için güvenilmeyen kullanıcılara doğrudan açılıyor. sudo içinde bir şey ters giderse kullanıcının tüm ortamı saldırı yüzeyi hâline gelip kötüye kullanılabilir.ssh yaklaşımı bir
suidikilisini açığa çıkarmaz, ssh ağ katmanını kullanır. Dolayısıyla ağ üzerinden ssh’e erişmekten daha güvensiz değildir; bu da epey güvenli kabul edilir.sudo bashgibi bir şey başlatmak yerine tek tek komutları sudo ile çalıştırarak denetlenebilirliği artırabilmesidir.O daemon’da da yapılandırma hataları veya açıklar olabilir ve kullanıcı tabanlı birkaç yetkilendirme katmanını tek bir root seviyesine indirger.
Buna rağmen daha güvenli sayılıyor gibi. Makul bir güvenlik bakış açısından daha güvenli sayılamaz; sadece farklı bir yöntemdir.
Gerçekte, uzak SSH’de kullanıcı olarak oturum açıp sonra
sudokullanmaktansa, doğrudan root olarak SSH oturumu açmak kesin anlamda daha güvenlidir.user@home,root@servera ssh yaparsaroot@serveryalnızcauser@homeele geçirildiğinde tehlikeye girer.Buna karşılık
user@home,user@servera ssh yapıp ardından sudo ileroot@serverolursa,user@homeya dauser@serverdan yalnızca biri ele geçirilse bile root tehlikeye girer. Özellikleuser@serverüzerinde daemon’lar veya cron işleri gibi başka yazılımlar sıkça çalışır.Bu yolla bulaşmayı başaran birine bedava root yetki yükseltmesi ve parola yeniden kullanımı nedeniyle sık görülen yatay hareket imkânı verilmemeli.
Elbette sudo yalnızca izin listesine alınmış komutlar modunda kullanılıyorsa ve parola ya da uzak ana makineden tamamen erişilebilen kimlik bilgileri almıyorsa bu geçerli değildir.
Önyükleme sırasında ssh başlamazsa ne olur? Tipik yapılandırmada ağ bağlantısına bağlı olarak başladığını hatırlıyorum. O zaman failsafe konsoldan da giriş yapamazsınız.
sudo veya su ile karşılaştırınca pratikte ne kazanıldığını bilmiyorum. setuid ikililerinden kaçınmak yerine, root yetkisiyle bir ağ servisi çalıştırmış oluyorsunuz; yalnızca sokete bağlı olsa bile.
SSD ölürse ne olacak? O durumda da failsafe konsola giriş yapamazsınız.
30 yıldır Linux kullanıyorum; sabit diskin öldüğü durumlar, sshd daemon’unun başlamadığı durumlardan katbekat fazla oldu; oran olarak bakarsak sıfıra bölmek gibi.
İşletim sisteminin sshd daemon’u rastgele başlamıyorsa, bunu daha kararlı bir işletim sistemine geçme zamanının geldiğine dair bir işaret sayarım.
sudo veya su’ya göre kazanç, yerel yetki yükseltme exploit’lerinin çok daha zorlaşmasıdır.
ttyS*aygıtları sudo veya su kullanmaz.Bu tür konsollar
gettygibi programlar ya da pencere yöneticileri kullanır; bunlar root olarak başlatılan, suid olmayan programlardır.Konsol girişi için bir root parolası ayarlı tutmak doğrudur.
kubectluç noktasını kullanmak yeterli.Giriş yapabiliyorsanız root’a setuid yapabilecek şekilde ayarlıyorum. Bu bir k8s kutusuysa bu, platform altyapı ekibinin işidir; üzerindeki servislere erişim ise k8s yetki sağlayıcısı üzerinden olur.
Platform altyapı ekibi açısından yalnızca metrik ve log gerekiyorsa bunlar zaten kutunun dışındadır; bir iş ya da iş akışı tetiklemek gerekiyorsa pipeline kullanılır.
Yine de biri giriş yapıp root işi yapıyorsa denetim günlüğü bırakmak isterim.
Sahip olduğum kutular arasında, giriş yetkisi olan birinin tam root yetkisine sahip olmadığı bir örnek aklıma gelmiyor.
Elbette servislerin setuid yaptığı durumları anlıyorum; ama servislerde genelde systemd yetkiyi yükseltmek için değil, düşürmek için setuid uygular.
systems.unit=emergency.target,init=/bin/bash,rd.break=pre-pivotayarlayabilir veya live CD ortamından önyükleme yapabilirsiniz. Alışıldık acil kurtarma seçeneklerinin hepsi çalışır.Daha az ölümcül acil durumlarda ise bu sshd örneğinin ağa bağlı olması için bir neden de görmüyorum.
Bu yaklaşımın tüm dezavantajlarını içermemesi biraz üzücü. sudo, hangi grubun hangi komutları çalıştırabileceğini, o komutların hangi argümanları alabileceğini, alt kabuk oluşturulmasına izin verilip verilmeyeceğini vb. denetleyebilir.
Bu yöntem bu tür ince ayarlı denetimin çoğunu kaybediyor ve sudoers dosyasını düzenlemekten daha zor yönetilen güvenilir anahtarlara dayanıyor.
sudo’nun yapabildiği şaşırtıcı şeyleri görmek için Sudo Mastery kitabını gerçekten öneririm.
Bu, Systemd’nin run0’ına benzer bir fikir: https://news.itsfoss.com/systemd-run0/
ssh’nin sorunlarından biri, süreç oluşturmanın protokolün bir parçası olmaması. Ayrıca uzak protokol olduğu için yerel kaynakları çocuk sürece aktaramazsınız.
Bu yüzden null ile ayrılmış argüman dizisi geçemez, ek dosya tanıtıcıları aktaramaz veya çalıştırılacak dosyayı belirtemezsiniz.
Bunun yerine sunucuda ayarlı kabuğa tek bir string gönderirsiniz. Bu da kabuk kaçışlaması gerektirir ve sunucu tarafında hangi kabuğun çalıştığını bilmeniz gerekir.
SSH’yi doğru dürüst bir sudo alternatifi olarak kullanmak için, eklenti olarak
posix_spawn’a yakın bir işlevsellik gerekir.https://bugzilla.mindrot.org/show_bug.cgi?id=2283
Tamamen katılıyorum. Ben de benzer bir şey yapıyorum ve daha önce HN yorumlarında da anlatmıştım.
Benim yöntemim biraz farklı. Fiziksel SSH konsolu olarak adanmış bir makine kullanıyorum; bu makine evdeki diğer makinelerden ayrılmış özel bir LAN’da. Yönetilebilir switch değil, sıradan switch; Ethernet kablosu kullanıyor ve trunk yok.
Giriş yalnızca SSH ile mümkün ve buna Yubikey bağladım.
Masaüstü PC’nin kendi güvenlik duvarı var ve yalnızca bu SSH konsolunun IP/MAC adresinden gelen SSH trafiğine izin veriyor. Bu sadece ikisinin paylaştığı özel LAN için geçerli; başka bir fiziksel LAN üzerinden masaüstü internete erişebiliyor.
sshd daemon’u yalnızca açık/özel anahtar ile girişi kabul ediyor, parola ile girişi engelliyor.
Root gerekiyorsa “SSH konsolu”nu açıyorum. Neredeyse hiçbir şeyi olmayan bir makine olduğu için çok hızlı açılıyor. Giriş yapıp yukarı okla
ssh root@...satırını geri çağırıyorum, Enter’a basıyorum ve Yubikey’e dokunuyorum.O SSH konsolu ve klavye masanın üzerinde, her zaman elimin altında.
Özel LAN’da, üstelik diğer özel LAN’lardan fiziksel olarak ayrılmış bir yerdeki iptables/nftables + sshd’nin sudo ikilisi veya su’dan daha güvenli mi daha güvensiz mi olduğuna herkes kendi karar versin.
“Neden?” diye sorarsanız “çünkü yapabiliyorum” derim. O kadar uzun zaman önce kurdum ki ne zaman yaptığımı bile hatırlamıyorum. Muhtemelen yaklaşık 2 yıl önce bu fikirle oynamaya başladım ve o zamandan beri kullanıyorum. Hiç sorun olmadı.
Bu sorun için zarif bir çözüm. Kullanıcılara çocuk muamelesi yapmak gerekmez, ama aynı zamanda makul varsayılanlarla olası hatalardan kaçınmak gerekir.
Root gerekiyorsa konsoldan root olarak giriş yapılabilir; bu yüzden
subile gerekmez diye düşünüyorum. Bu yöntem, konsol tty’sinden root olarak giriş yapmaya olabildiğince yakın.Birincisi, sudo’nun aksine tüm kullanıcıların root parolasını bilmesi gerekir.
İkincisi, herkes doğrudan root olarak giriş yaparsa gerçekte kimin giriş yapıp ne yaptığını denetlemenin yolu yoktur.
10 yıl önce benzer bir şey denemiştim. UNIX soket kısmı yoktu; yalnızca localhost üzerinde dinleyen ayrı bir sshd çalıştırmıştım ve
SCM_RIGHTSile uğraşmam da gerekmemiştiÖzellikle iyi ya da kötü bir sonuç olmadı; sadece ilgimi kaybettiğim için ayarı bir sonraki makineye taşımadım