Port yönlendirme için kısıtlanmış bir SSH kullanıcısı nasıl oluşturulur?

90

ændrük başkasıyla kolay bir SSH bağlantısı elde etmek için bir ters bağlantı önerdi (uzaktan yardım için). Bunun çalışması için, bağlantıyı kabul etmek için ek bir kullanıcıya ihtiyaç vardır. Bu kullanıcının portunu sunucu üzerinden iletebilmesi gerekiyor (sunucu proxy gibi davranıyor).

Yukarıda açıklananlardan daha fazlasını yapamayan kısıtlı bir kullanıcıyı nasıl oluştururum?

Yeni kullanıcı yapamaz :

yapabilmelidir:

  • kabuk komutlarını çalıştır
  • dosyalara erişin veya dosyaları sunucuya yükleyin
  • sunucuyu proxy olarak kullan (ör. webproxy)
  • Güvenlik duvarı nedeniyle başka şekilde erişilemeyen yerel hizmetlere erişme
  • sunucuyu öldür

Özetle, SSH sunucusuna yalnızca ayrıcalık olmaksızın bağlanabilen sınırlı bir SSH kullanıcısı nasıl oluşturabilirim, bu yüzden bu bağlantıyı bilgisayarıyla bağlayabilir miyim?

    
sordu Lekensteyn 10.06.2011 22:04

2 cevap

142

TL; DR - "Kısıtlamaların uygulanması" yanıtının sonuna git

Kısıtlı bir kullanıcı eklemek iki bölümden oluşur: 1. Kullanıcıyı oluşturma 2. SSH arka planını (sshd) yapılandırma

sshd'yi yapılandırma

SSH'nin olanaklarıyla bilinen en iyi yer, ilgili manuel sayfaları okuyarak:

SSH istemcisi eylemleri nerede yapabilir?

Bir şeyi kısıtlayabilmeniz için, SSH'nin özelliklerini bilmeniz gerekir. El ile sayfalar arasında gezinmek verim:

  • Kabuk komutları yürütme
  • sftp ile dosya yükleme
  • Port yönlendirme
    • İstemci sunucuya (un) kullanılmış bir bağlantı noktası iletir
    • Sunucu portunu müşteriye iletiyor
    • Sunucu başka bir ana bilgisayarın bağlantı noktasını istemciye iletir (proxy-ish)
  • X11 iletme (görüntülü iletme)
  • Kimlik doğrulama aracısı iletme
  • Bir tünel aygıtının iletilmesi

sshd sayfasının Kimlik Doğrulama bölümünden (8) :

  

İstemci kendini başarılı bir şekilde doğrularsa, hazırlama için bir iletişim kutusu   oturum girilir. Şu anda müşteri gibi şeyler isteyebilir    TCP yönlendirerek, sahte bir XT bağlantı iletme   bağlantıları veya kimlik doğrulama aracısı bağlantısını iletme   güvenli kanal.

     

Bundan sonra, istemci bir kabuk ister veya bir komutun yürütülmesini ister .   Taraflar daha sonra oturum moduna girer. Bu modda, her iki taraf da gönderebilir   Verileri herhangi bir zamanda ve bu veriler kabuk veya komuta iletilir   Sunucu tarafında ve kullanıcı tarafında kullanıcı terminali.

SSH özelliklerini kısıtlama seçenekleri

Dosyaları ve davranışları değiştiren seçenekleri:

  • ~/.ssh/authorized_keys - hangi seçeneklerin verilebildiğine izin verilen anahtarlar içerir:
    • command="command" - Kullanıcı tarafından sağlanan komut (varsa) yoksayılır. İstemcinin açıkça yasaklanmadıkça TCP ve / veya X11 iletimi belirtebileceğini unutmayın . Bu seçeneğin kabuk, komut veya alt sistem yürütmesi için geçerli olduğunu unutmayın.
    • no-agent-forwarding - Kimlik doğrulama için bu anahtar kullanıldığında kimlik doğrulama aracısının iletimini yasaklar.
    • no-port-forwarding - Bu anahtar kimlik doğrulama için kullanıldığında TCP iletimini yasaklar
    • no-X11-forwarding - "Bu anahtar, kimlik doğrulama için kullanıldığında X11 iletmeyi yasaklar."
    • permitopen="host:port" - Yerel 'ssh -L' bağlantı noktasını, yalnızca belirtilen ana makine ve bağlantı noktasına bağlanacak şekilde yönlendirin.
  • ~/.ssh/environment - Bu dosya oturum açıldığında çevreye okunur (varsa). Çevre işleme varsayılan olarak devre dışıdır ve PermitUserEnvironment seçeneği ile kontrol edilir
  • ~/.ssh/rc - Kullanıcının giriş dizini erişilebilir hale gelmeden önce çalıştırılacak başlatma yordamlarını içerir.
  • /etc/ssh/sshd_config - sistem genelinde yapılandırma dosyası
    • AllowAgentForwarding - ssh-agent (1) yönlendirmesine izin verilip verilmediğini belirtir.
    • AllowTcpForwarding
    • ForceCommand - "İstemci tarafından sağlanan komutları göz ardı ederek ForceCommand tarafından belirtilen komutun yürütülmesini zorlar ve varsa ~ / .ssh / rc komutunu kullanır. Komut, kullanıcının giriş kabuğunu -c seçeneğiyle kullanarak çağrılır."
    • GatewayPorts - "Uzak ana bilgisayarların istemci için yönlendirilen bağlantı noktalarına bağlanmasına izin verilip verilmeyeceğini belirtir. Varsayılan olarak, sshd (8) uzak bağlantı noktası iletilerini geri döngü adresine bağlar. Bu, diğer uzak ana bilgisayarların iletilen bağlantı noktalarına bağlanmasını engeller. sshd'nin uzak bağlantı noktası iletimlerinin geri döngü dışı adreslere bağlanmasına izin vermesi için kullanılır, böylece diğer ana bilgisayarların bağlanmasına izin verilir. "
    • % Co_de%:
        

      TCP bağlantı noktasının yönlendirildiği varış yerlerini belirtir.   izin verdi. İletim belirtiminden biri olmalıdır.   aşağıdaki formlar:

      PermitOpen host:port
      PermitOpen IPv4_addr:port
      PermitOpen [IPv6_addr]:port
      
           

      Birden çok ileriye, bunları ayırarak   Beyaz boşluk. Tümünü kaldırmak için 'herhangi bir' argümanı kullanılabilir   kısıtlamalar ve herhangi bir yönlendirme isteğine izin verir. Varsayılan olarak tüm   port yönlendirme isteklerine izin verilir.

    •   
    • PermitOpen - Tun (4) cihaz yönlendirmesine izin verilip verilmediğini belirtir. Varsayılan 'hayır' dır.
    •   
    • PermitTunnel - X11 iletmeye izin verilip verilmeyeceğini belirtir.Varsayılan 'hayır' dır.
    •   
  •   

Kısıtlamaların uygulanması

Sistem genelinde yapılan yapılandırma dosyası X11Forwarding değiĢtirmesi, parola tabanlı kimlik doğrulaması uygulanmış olsa bile veya /etc/ssh/sshd_config cinsinden kısıtlamaların yanlışlıkla kaldırılması durumunda yapılandırmanın uygulanmasına izin verir. Genel varsayılanları değiştirdiyseniz, seçenekleri uygun şekilde kaldırmalısınız.

Match User limited-user
   #AllowTcpForwarding yes
   #X11Forwarding no
   #PermitTunnel no
   #GatewayPorts no
   AllowAgentForwarding no
   PermitOpen localhost:62222
   ForceCommand echo 'This account can only be used for [reason]'

Şimdi bir kullanıcı ekleyin:

sudo useradd -m limited-user

% ko_de% kabuğunun% ko_de% gibi bir kabuk dışı değerine (veya ~/.ssh/authorized_keys ) ayarlanmışsa ForceCommand seçeneği atlanabilir. /bin/false bir şey yapmaz.

Artık istemci, sunucunun geri döngü adresi üzerinde 62222 numaralı bağlantı noktasına yalnızca SSH üzerinden bağlanabiliyor (genel IP adresinde dinlenmeyecek)

/bin/true 'nin devre dışı bırakılması da /bin/false -c [command] ' nin kullanılmasına izin vermeyecek ve böylece tek bir portu iletmek için böyle kısıtlı bir hesabın kullanımını yitirecektir. AllowTcpForwarding , sunucuda bağlantı noktası 62222'nin hiçbir zaman kullanımda olmadığını, çünkü istemcinin buna kolayca bağlanabileceğini ve dinleyebildiğini varsayar.

Sistem genelinde yapılandırma ve devre dışı bırakılmış parola tabanlı kimlik doğrulamasında TCP iletme izinliyse, anahtar başına ayarları da kullanabilirsiniz. % Co_de% 'yi düzenleyin ve -R ' den önceki seçeneklerden birini ekleyin (seçenekler ile PermitOpen localhost:62222 arasında bir boşluk ile):

command="echo 'This account can only be used for [reason]'",no-agent-forwarding,no-X11-forwarding,permitopen="localhost:62222"

doğrula

Beklendiği gibi çalıştığından emin olmak için, bazı test durumlarının çalıştırılması gerekir. Aşağıdaki komutlarda, ~/.ssh/authorized_keys değeri ssh- olarak ayarlanmamışsa gerçek girişle değiştirilmelidir. Komutun arkasında, istemci veya sunucuda (belirtildiği gibi) çalıştırılması gereken bir komut gösterilir.

# connection closed:
ssh host
# connection closed (/bin/date is not executed):
ssh host /bin/date
# administratively prohibited (2x):
ssh host -N -D 62222 # client: curl -I --socks5 localhost:62222 example.com
ssh host -N -L 8080:example.com:80 # client: curl -I localhost:8080
sftp host
# should be possible because the client should forward his SSH server
ssh host -N -R 8080:example.com:80 # server: curl -I localhost:8080
# This works, it forwards the client SSH to the server
ssh host -N -R 62222:localhost:22
# unfortunately, the client can listen on that port too. Not a big issue
ssh host -N -L 1234:localhost:62222

Sonuç

Kontrol Listesi: SSH kullanıcısı şunları yapamamalıdır:

  • kabuk komutlarını çalıştır - yapıldı
  • dosyalara erişin veya dosyaları sunucuya yükleyin - yapıldı
  • sunucuyu proxy olarak kullan (ör. webproxy) - yapıldı
  • güvenlik duvarı nedeniyle erişime açık olmayan yerel hizmetlere - kısmen , istemcinin 62222'den başka bağlantı noktalarına erişemediği, ancak sunucuda 62222 numaralı bağlantı noktasını dinleyip bağlantı kurabildiği
  • yerel hizmetlere erişme
  • sunucuyu öldür - yapıldı (Bu kontrollerin SSH sunucusu ile sınırlı olduğunu unutmayın. Eğer makinede başka bir güvenlik açığı varsa, olası bir saldırganın komutları çalıştırmasına, sunucuyu öldürmesine vb. izin verebilir.)
verilen cevap Lekensteyn 22.06.2011 11:11
2

Eminim bunun için birçok çözüm var ve önerdiğimden çok daha sağlam. Ancak, bu ihtiyaçlarınız için yeterli olabilir. Bunu yapmak için, kullanıcının ssh anahtar tabanlı kimlik doğrulaması yapabildiğini varsayıyorum (macun veya herhangi bir unix ssh bunu desteklemelidir).

  • Normalde yaptığınız gibi bir kullanıcı ekleyin ('adduser' veya başka bir araç)

  • .ssh dizinini ve .ssh / authorized_keys

    kullanıcılarını oluşturun
your_user $ sudo -Hu ssh_forwarder /bin/bash

ssh_forwarder $ cd ~
ssh_forwarder $ mkdir .ssh
ssh_forwarder $ ( umask 066 && cat > .ssh/authorized_keys ) <<EOF
no-agent-forwarding,no-X11-forwarding,command="read a; exit" ssh-rsa AAAB3NzaC1y....2cD/VN3NtHw== [email protected]
EOF
  • Bu hesaba şifre erişimini devre dışı bırak.
your_user $ sudo usermod --lock ssh_forwarder

Şimdi, kullanıcının sisteminize girebilmesinin tek yolu, uygun ssh anahtarına erişimdir ve ssh, "/ bin / bash -c" yi çalıştırmak için ne çalışırlarsa çalışsın . 'read a' sadece bir satırsonu kadar okuyacaktır ve sonra kabuk çıkacaktır, böylece kullanıcı sadece bağlantıyı kesmek için 'enter' tuşuna basmalıdır.

'command =' da yapabileceğiniz pek çok şey var. Daha fazla bilgi için man authorized_keys bölümüne bakın ve 'komut' araması yapın.

Eğer enter tuşuna basmanın bağlantıyı öldürdüğünü sevmiyorsanız, 'command =' girişi için aşağıdaki gibi bir şey kullanabilirsiniz:

command="f=./.fifo.$$ && mkfifo $f && trap \"rm -f $f\" EXIT && read a <$f && echo $a; exit;"

Bu, kullanıcıların giriş dizininde geçici bir fifo oluşturur ve bundan sonra okumaya çalışır. Bu dosyaya hiçbir şey yazılmayacak, bu yüzden süresiz asılacak. Ayrıca, bu bağlantıyı zorla sonlandırmak isterseniz, aşağıdaki gibi bir şey yapabilirsiniz:

 your_user$ echo GOODBYE | sudo tee ~ssh_forwarder/.fifo.*

Bu, çok az kaynak kullanmalı ve o komut dosyasında, kabuk sonlandırılmayacak hiçbir şey ters gitmemelidir.

sleep 1h; echo You have been here too long. Good bye.

Kullanıcının uzaklaşmasını nasıl sağlayabileceğinizi ( ssh -R ) ancak sınırı ( ssh -L ) nasıl kullanabileceğinizi görmedim. Belki de 'permitopen' kullanılabilir. Googling çok yardımcı olmadı. 'No-port-forwarding, permitremoteopen = 10001' gibi bir şeyin ssh -R 6901:localhost:6901 'ye izin vermek için yararlı olacağını düşünüyoruz.

Bu bir çözümdür. Kesinlikle geliştirilebilir ve uzak portların herhangi bir açıklığı dikkatle incelenmelidir. Amacım büyükannemin LAN'ıma bağlanmasına izin vermekse, ekranını görüntülemek için vnc kullanabilirdim ve bu anahtarlara erişim onunla sınırlıydı, kişisel olarak makul derecede güvenli hissederdim. Bu bir girişim içinse, daha kapsamlı bir soruşturma gerekli olacaktır. Farkında olmak için bir şey ssh -N hiç bir kabuk istemez, bu nedenle 'command =' kodu yürütülmez.

Diğer, muhtemelen daha güvenli mekanizmalar, kullanıcı için özel bir kabuk oluşturmayı ve hatta bunu apparmour ile kilitlemeyi içerebilir.

    
verilen cevap smoser 21.06.2011 15:09

Etiketlerdeki diğer soruları oku