Habilite el acceso de shell SSH pero deshabilite el acceso SFTP

21

He buscado una respuesta viable a esta pregunta, y la mayoría de las respuestas incluyen consejos sobre por qué no hacerlo. Sin embargo, aquí está el escenario y lo que lo hace necesario:

Tengo una aplicación de consola, y en el perfil .profile de cada usuario, hay un comando de inicio para la aplicación, y directamente después del comando que lo inicia, hay un comando "salir", que los desconecta del sistema. Solo quiero que puedan acceder a esta aplicación de consola a través de la interfaz que proporciona. Al iniciarse, la aplicación presenta al usuario una lista de clientes a los que se puede acceder a través de la aplicación, y cada cliente tiene su propio directorio de datos. Los usuarios tienen acceso solo a los clientes a los que necesitarán acceder.

Ahora, aquí está el problema: si les doy acceso SSH a los usuarios, también podrán iniciar sesión usando un cliente SFTP, lo que les dará acceso directo a los directorios de datos de la aplicación, lo cual es MUY indeseable, ya que eso también les dará ellos acceden a los directorios de datos a los que no deberían tener acceso.

Esto era algo tan simple de hacer cuando usaba una combinación de telnet / FTP, pero ahora que quiero dar acceso a los usuarios desde cualquier lugar en Internet, no he podido encontrar una manera de cerrarlos de SFTP, mientras todavía les permite acceder al shell donde pueden ejecutar la aplicación.

sosaisapunk
fuente
8
Olvidé los detalles, pero creo que SSH le permite restringir a los usuarios para que ejecuten un solo comando cuando inician sesión. No obtienen acceso completo al shell si configura esto. Puede ser útil para su caso de uso. (Después de todo, es posible emular el acceso SFTP usando SSHFS. Simplemente deshabilitar SFTP no impedirá que un usuario moderadamente determinado acceda a cualquier archivo al que tenga acceso su cuenta de usuario).
David Z
3
Además, es posible que desee considerar "hacer chrooting" a sus usuarios. y para el acceso de datos de repuesto, parece un problema de diseño
Dennis Nolte
2
Usar .profilepara eso suena como la solución incorrecta. Creo que configurar al usuario con un shell alternativo tendría mucho más sentido.
kasperd
3
No intentes usar el .profiletruco para restringir el acceso, ya que es fácil evitarlo. (ver mi respuesta para más detalles)
Aleksi Torhamo

Respuestas:

22

Editar:

En caso de que no sea obvio, la siguiente respuesta no pretende ser un método seguro para evitar que SFTP sea utilizado por cualquier persona con acceso de shell al servidor. Es solo una respuesta que explica cómo deshabilitarlo desde la visibilidad externa. Para una discusión sobre la seguridad a nivel de usuario, vea las respuestas de @cpast y @Aleksi Torhamo. Si la seguridad es su enfoque, esta respuesta no es la correcta. Si su enfoque es la simple visibilidad del servicio, esta es su respuesta.

Ahora continuamos con la respuesta original:


Comente el soporte de sftp en sshd_config (y, por supuesto, reinicie sshd):

#Subsystem sftp /usr/lib/openssh/sftp-server

Wesley
fuente
1
A veces la línea puede serSubsystem sftp internal-sftp
Kondybas
1
Tengo Subsystem sftp /usr/libexec/sftp-server pero eso hizo el truco. Muchas gracias
sosaisapunk
16
Esto no suena plausible. Si puede ejecutar comandos arbitrarios en el servidor, puede ejecutar el programa sftp del lado del servidor. Incluso si no está instalado, puede volver a implementarlo como un comando de shell largo y hacer que el cliente sftp envíe este comando en lugar de sftp. Este método puede hacer que sea menos conveniente usar sftp, pero no hay forma de evitar que un usuario que puede ejecutar comandos arbitrarios use esos comandos para realizar transferencias de archivos.
R ..
1
@sosaisapunk Eso no es cierto. Los usuarios pueden ejecutar cualquier comando que deseen ssh user@host command, ya .profileque no se ejecutará en absoluto si lo hace y, por lo tanto, su aplicación no se iniciará en absoluto. Pueden obtener acceso completo al shell simplemente diciendo ssh -t user@host bash. Solo pruébalo y verás. El subsistema es solo un alias de comando; si pudieran usar sftp antes, aún pueden usarlo, y cualquier otro comando que deseen. Lee mi respuesta a continuación.
Aleksi Torhamo
1
@sosaisapunk: No, el punto es que puedes hacer esto con ssh, pero no con .profileél, ya que no está destinado a la seguridad y se pasa por alto fácilmente. En mi respuesta, enumeré tres métodos diferentes de hacerlo con ssh. En resumen, simplemente mueva la invocación de su aplicación .profilea un script de shell y 1) configure el script de shell como el shell del usuario 2) configure el script de shell como (correctamente emparejado) ForceCommanden sshd_config3) cambie a la autenticación de clave pública y configure el script de shell como commanden .ssh/authorized_keys. (Además, debe usar @name para que las personas sean notificadas de los comentarios)
Aleksi Torhamo
28

Como otros han mencionado, la desactivación sftpno es suficiente: un usuario con sshacceso ilimitado puede ver cualquier archivo que su cuenta tenga permiso para ver, puede modificar cualquier cosa que tenga permiso para modificar y puede descargar fácilmente cualquier cosa que pueda leer. máquina. La única forma de evitar que hagan esto es restringir su acceso. Tampoco es ideal confiar en .profilerestringir a los usuarios, ya que no es para eso (Editar: como Aleksi menciona en su respuesta, de hecho es trivial eludirlo .profile; lo que pasa .profilees que es por conveniencia, no por seguridad, por lo que no es destinado a restringir al usuario. Utilice elementos diseñados para la seguridad, como los siguientes, para proporcionar seguridad).

Hay dos formas básicas de hacer esto: puede restringirlos mediante permisos de archivo o forzarlos a ejecutar solo la aplicación de consola. La segunda forma es mejor: asigne a los usuarios que deberían estar restringidos a la aplicación de consola a un grupo (por ejemplo customers); luego, en sshd_config, agregue las siguientes líneas:

Match Group customers
ForceCommand /path/to/app

Lo que esto hace es que todas las conexiones de los usuarios de ese grupo abran la aplicación de consola; no pueden iniciar nada más, incluida la sftpherramienta del servidor. Esto también les impide hacer cualquier otra cosa con el sistema y, a diferencia .profile, lo hace usando el servidor SSH en sí mismo (los .profilerestringe en el shell, ForceCommandtambién evita hacer otras cosas que no implican iniciar un shell). También a diferencia .profile, esto está diseñado como una cosa de seguridad; está hecho específicamente para resistir a un usuario malicioso que lo evade.

La alternativa (probablemente inferior) implicaría crear un nuevo usuario para ejecutar la aplicación de consola. Luego restringiría los directorios de datos a ese usuario, configuraría la aplicación de consola que poseía ese usuario y configuraría u+sel programa. Este es el setuidbit; significa que alguien que ejecuta el programa de consola lo hace con los permisos del propietario del programa. De esa forma, el usuario no tiene acceso a los directorios, solo lo obtiene a través del programa. Sin embargo, probablemente debería usar ForceCommand, ya que eso restringe todo el acceso a "simplemente ejecute este programa".

cpast
fuente
44
Me gustaría agregar que eso ForceCommandno impide el reenvío de puertos SSH.
nyuszika7h
1
En realidad, confiar .profilees más que "no ideal"; se pasa por alto fácilmente (vea mi respuesta para más detalles) y, por lo tanto, no proporciona protección alguna, solo una falsa sensación de seguridad.
Aleksi Torhamo
@AleksiTorhamo Ah. Sospeché que podría evitarlo, pero no estaba seguro de cómo (generalmente sospecho que las cosas que no están destinadas a la seguridad son evitables). Gracias por los detalles sobre cómo!
cpast
15

¡No intente hacer esto .profileporque no proporciona seguridad alguna y no restringe exactamente nada!

No importa lo que pone en .profile, ya que se puede pasar por alto que simplemente dando una orden a ejecutar en la línea de comandos ssh, así: ssh user@host command. Todavía puede obtener acceso de shell normal haciendo ssh -t user@host bash.

Deshabilitar el subsistema sftp, como se menciona en otra respuesta, no ayuda en absoluto. Los subsistemas son esencialmente alias de los comandos, y aún puede usar sftp normalmente al hacerlo sftp -s /path/to/sftp-executable user@host.

Como cpast y algunos comentaristas han dicho, debes usar los mecanismos adecuados para restringir el acceso. Es decir,

  • Uso ForceCommandensshd_config
  • Utilice el inicio de sesión sin contraseña y command="..."en.ssh/authorized_keys
  • Cambie el shell del usuario a algo que restrinja lo que el usuario puede hacer.

Notas:

  • command="..." solo se aplica a una clave, por lo que no restringe el inicio de sesión ssh para el usuario que utiliza una contraseña u otra clave
  • Es posible que también desee restringir el reenvío de puertos, etc. (el reenvío de puertos, el reenvío x11, el reenvío de agentes y la asignación de pty son los que he oído hablar)
    • AllowTcpForwarding etc. en sshd_config
    • no-port-forwarding etc. en .ssh/authorized_keys
  • Si tiene otros demonios en ejecución (como FTP), debe verificar que no permitan que el usuario ingrese (algunos demonios toman esta decisión en función del shell del usuario, por lo que si cambia eso, es posible que desee volver a verificar esto)
  • Puede cambiar el shell del usuario a un script que haga lo que quiera; se ejecuta sin argumentos o comoscript -c 'command-the-user-wanted-to-run'
  • Ambos ForceCommandy command="..."ejecutan el comando a través del shell del usuario, por lo que no funcionan si el shell del usuario está configurado en eg. /bin/falseo/sbin/nologin

Descargo de responsabilidad: no soy un experto en el tema de ninguna manera, así que si bien puedo decir que la .profilecosa no es segura, no puedo prometer que no hay algún "problema" con los otros métodos que no conozco acerca de. Están seguros hasta donde yo sé, pero no sería la primera persona en estar equivocada en Internet.

Aleksi Torhamo
fuente
1
Parece que al menos para ForceCommandy forzó inicio de sesión sin contraseña con command=en authorized_keys, mientras que se ha pasado por alto antes, eso se debe a un error en el servidor: se pretende que sea seguro ante un usuario malicioso, y sin pasar por un usuario se cuenta como una grave vulnerabilidad en el servidor SSH (y, por lo tanto, es una solución prioritaria). Como señala, el .profilediseño lo puede pasar por alto: como no se considera una característica de seguridad, un usuario que lo pase por alto está perfectamente bien desde el punto de vista del desarrollador de shell.
cpast
1
@cpast: Sí, estaba pensando en la existencia de más funciones como el reenvío de puertos. Quiero decir, si no sabías que ssh permite el reenvío de puertos y solo usaste ForceCommandpara restringir el acceso, y tuviste un demonio que solo escucha conexiones localmente y no realiza autenticación, el usuario ssh aún podría acceder al demonio. Las características que enumeré son las p. Ej. Las soluciones de alojamiento de git generalmente se deshabilitan, y no he visto otras "de aspecto maligno" adicionales en las páginas de manual, pero tampoco he encontrado ningún tipo de documento oficial "así es como se usa de ForceCommandforma segura".
Aleksi Torhamo
Es cierto que ~/.profilees editable por el usuario y no es útil para la seguridad, pero ¿podría hacer que la técnica de cpast sea significativa al ponerla en práctica /etc/profile? Puede verificar el UID para limitarlo a los usuarios correctos.
pollitos
1
@chicks: No, tiene exactamente el mismo problema. El problema no es que el archivo sea editable por el usuario; El problema es que ambos archivos se pueden omitir por completo. Los archivos solo se usan para shells de inicio de sesión, que obtienes si solo dices ssh user@host, pero si le dices a ssh que ejecute un comando, es decir. ssh user@host command- ya no obtienes un shell de inicio de sesión y los archivos no se tocan. Por lo tanto, puede omitir trivialmente cualquier restricción que alguien haya intentado crear con los archivos simplemente dando un argumento adicional a ssh.
Aleksi Torhamo
2
@chicks: Además, me di cuenta de que te referías a cpast; el método en la respuesta de cpast no usa .profile, usa sshd_configy debería ser seguro. Solo menciona .profilecomo un método que no debes usar para hacer esto.
Aleksi Torhamo
1

Es posible habilitar SSH y deshabilitar SFTP tanto globalmente como por usuario / grupo.

Personalmente necesito esto porque quiero dar acceso a algunos repositorios git a través de SSH, y me gusta deshabilitar los sistemas que no son necesarios. En ese caso, no se necesita SFTP.

Globalmente

Puede deshabilitar SFTP para todos los usuarios de dos maneras.

El subsistema faltante

El demonio SFTP utilizado por SSH se puede configurar a través de la Subsystempalabra clave. Del sshd_config(5)manual:

Subsystem
        Configures an external subsystem (e.g. file transfer daemon).
        Arguments should be a subsystem name and a command (with optional
        arguments) to execute upon subsystem request.

        The command sftp-server(8) implements the “sftp” file transfer
        subsystem.

        Alternately the name “internal-sftp” implements an in-process
        “sftp” server.  This may simplify configurations using
        ChrootDirectory to force a different filesystem root on clients.

        By default no subsystems are defined.

La última línea sugiere que debería ser suficiente para no definir ningún subsistema para "sftp".

Una mentira falsa

También puede desactivar SFTP configurando el demonio SFTP utilizado por SSH en algo inutilizable. Por ejemplo, configure el subsistema "sftp" para /bin/false:

Subsystem sftp /bin/false

Cuando algo intentara iniciar sesión a través de SFTP, el demonio SSH intentaría generar el "demonio sftp" /bin/false. El /bin/falseprograma solo hace una cosa, y es devolver un código de error. El intento de conexión SFTP se niega efectivamente.

Por usuario / grupo

También es posible deshabilitar SFTP por usuario, grupo o un par de otros criterios.

Esto no funciona si desea que su usuario obtenga un indicador de shell normal. Tampoco tiene sentido, ya que podría eludir la mayoría de las cosas si tiene acceso de shell. Solo funcionará si solo desea dar acceso a un programa específico.

Pareo

Para hacer coincidir un conjunto de usuarios, puede configurar SSH con la Matchpalabra clave. Del sshd_config(5)manual:

Match
        ...

        The arguments to Match are one or more criteria-pattern pairs or the
        single token All which matches all criteria.  The available criteria
        are User, Group, Host, LocalAddress, LocalPort, and Address.  The
        match patterns may consist of single entries or comma-separated
        lists and may use the wildcard and negation operators described in
        the PATTERNS section of ssh_config(5).

        ...

Un par de ejemplos:

  • Match User eva coincide con el usuario "eva"
  • Match User stephen,maria coincide con los usuarios "stephen" y "maria"
  • Match Group wheel,adams,simpsons coincide con los grupos "rueda", "adams", "simpsons"

Si desea más información, hay cargas en el sshd_config(5)manual.

Comando forzado

Normalmente obtiene el shell de inicio de sesión del usuario cuando se conecta a través de SSH, pero SSH se puede configurar para forzar un determinado comando. El comando es forzado para cualquier conexión SSH, incluido SFTP, y por lo tanto puede tener la opción de forzar el comando que desee.

El comando forzar se puede configurar con la ForceCommandpalabra clave. Del sshd_config(5)manual:

ForceCommand
        Forces the execution of the command specified by ForceCommand,
        ignoring any command supplied by the client and ~/.ssh/rc if
        present.  The command is invoked by using the user's login shell
        with the -c option.  This applies to shell, command, or subsystem
        execution.  It is most useful inside a Match block.  The command
        originally supplied by the client is available in the
        SSH_ORIGINAL_COMMAND environment variable.  Specifying a command of
        “internal-sftp” will force the use of an in-process sftp server that
        requires no support files when used with ChrootDirectory.  The
        default is “none”.

Por lo tanto, puede forzar el comando restringido que desea usar ForceCommand <your command>. Por ejemplo:

Match User kim
        ForceCommand echo 'successful login man, congrats'

Ejemplo

En mi caso donde quiero dar acceso a git, solo necesito que el usuario tenga acceso git-shell. Esta es la sección que deshabilita SFTP para mis usuarios de git, junto con algunas opciones de seguridad:

Match Group git

        # have to do this instead of setting the login shell to `git-shell`,
        # to disable SFTP
        ForceCommand /usr/bin/git-shell -c "$SSH_ORIGINAL_COMMAND"

        # disable stuff we don't need
        AllowAgentForwarding no
        AllowTcpForwarding no
        AllowStreamLocalForwarding no
        PermitOpen none
        PermitTunnel no
        PermitTTY no
        X11Forwarding no
aude
fuente
En mi caso, solo quería permitir el acceso a MySQL (no permitir tanto el acceso SFTP como las ventanas de terminal SSH) para una clave autorizada particular (es decir, sin cambios en el archivo sshd_config). Logré hacer esto con las siguientes opciones ~ / .ssh / Authorized_keys para la clave en particular: command = "/ usr / bin / echo 'Solo se permite el acceso a MySQL.'", No-pty, no-X11-forwarding, permitopen = "127.0.0.1:3306"
Martin_ATS