A Django site.
Febrero 2, 2010
» Automatizando SSH

Algnas veces me ha tocado escriir líneas de ssh bastante complejas, como por ejemplo:

ssh -1 -p 23 -l root -i /etc/ssh/key01 -o CheckHostIP=no 192.134.27.24

que realmente terminan siendo un incordio, cuando esa conexión debe ser vuelta a realizar para repetir tareas de administración remota. Entonces, este artículo es un resúmen de algunos trucos de automatización que he logrado aprender hasta ahora, para hacer mi ssh más fácil y mi vida también.

1. el nombre

Escribir la IP 192.134.27.24 cada vez que me conecto es antidiluviano y no escala a IPv6. Así que lo ideal es disponer de un DNS bien configurado al cuál recurrir.

Lamentablemente en redes internas he visto que asignan nombres a las máquinas que resultan más difíciles que la dirección IPv4 misma, por ejemplo: sssd2p1r3db.sss.com, que significa sss es el nombre de la empresa, datacenter 2, piso 1, rack 3, db pues es el server de base de datos. Fantástico! Cómo no recordarlo? Claro, despues uno ve que terminan usando la IP.

Así que llamemos a nuestro servidor 192.134.27.24 sssd2p1r3db como “tito” (o cualquier otro nombre que me resulte fácil de recordar)

Para que funcione el ssh a tito debo llegar a la IP. Y esta tarea de personalización de los nombres en la red la hace el archivo /etc/hosts. Edito el archivo y agrego:

# Servidor sssd2p3r3db
192.134.27.24 tito

A partir de ahora, todo lo que yo haga a nivel de red con el nombre “tito” va a funcionar desde ssh tito, ping tito, hasta http://tito en el Firefox.

2. las opciones ssh

Las opciones del ssh que son necesarias para esta conexión de ejemplo son: -1 -p 23 -l root -i /etc/ssh/key01 -o CheckHostIP=no, que no es necesario explicar su significado, pues todas estas opciones están a un man de distancia.

El archivo que permite automatizar todo esto para todos los usuarios es /etc/ssh/ssh_config y para un usuario en específico es el archivo $HOME/.ssh/config. Edito el archivo y creo una entrada Host acorde a mis necesidades:

Host tito
Protocol 1
Port 23
User root
IdentityFile /etc/ssh/key01
CheckHostIP no

Y ya está!

Ahora puedo escribir ssh tito y mi conexión va a ser realizada exactamente como si escribiera toda la linea del principio.

Solo una aclaración: la sentencia Host funciona por string, es decir que si escribo ssh 192.134.27.24 no va a producir el mismo efecto de levantar los datos del ssh_config, aunque me esté conectando al mismo servidor.

3. Bash completion

Y por último, hacer que mi Bash permita usar tabulador para los nombres caprichozos y fáciles que he colocado a mis servidores… porque?, a ver: nadie pretende que me acuerde que el server se llama “tito”, es mucho más acordarme que empieza con “t” y sigue con “algo” ;)

Edito ~/.bashrc y agrego:

_completossh ()
{
actual=${COMP_WORDS[COMP_CWORD]};
COMPREPLY=($(compgen -W ‘$(cat /etc/ssh/config | grep “^Host\b” – | sed -e “s/Host //”)’ — $actual))
}
complete -F _completossh ssh

Y ahora puedo escribir ssh t + tabulador, y me completará “tito”. Y si tengo más de un servidor que comience con “t” pues dar dos veces tabulador y me muestra la lista.

4. Algunos documentos para leer del tema

Noviembre 8, 2009

Boris Quiroz
cereal_bars
wreeeeoooowww trata sobre »
» Como matar una seguridad “a toda prueba”

En donde trabajo, el dia que llegué me dieron un token ePass 2000. La idea es que esto lo use cuando se necesite acceder a algun servidor via vpn (cosa que aún no hago, I do not care…). Todo bien hasta ahí, el problema es que el coso este solo funciona en Windows (otra razón más para no usarlo), pero solo instalado directamente en el computador. Tampoco funciona en maquinas virtuales o al menos eso me dijeron (creo que con el passthrough podria andar), pero aun no he intentado hacer eso.

Mucho blabla…

El asunto es que hace un par de semanas dedicí buscar una forma de poder conectarme sin tener que usar el dispositivo aquel. Estuve toda una tarde pensando (asi que no hice nada en el trabajo) y no se me ocurrió. Pero ya saben lo que dicen, siempre hay una solución más simple. Y la encontré cuando iba camino a mi casa: ssh reverse (como no se me ocurrió antes).

Como?

Muy facil: Desde mi equipo en el trabajo abro una sesión ssh al compu de mi casa, asi:

ssh -R 14443:localhost:22 boris@mi-server.org -pXXXX

Y luego, desde el compu de mi casa hago:

ssh bquiroz@localhost -p14443

Y listo. Así funciona el ssh reverse.

Igual es un cacho… o no?

Personalmente creo que esto es un horrible bug (?) en la arquitectura de red de una empresa. Simpre se ha dicho que la mayor parte de los ataques vienen desde adentro de la organización y por lo tanto no basta con configurar el firewall para permitir accesos solo de algunas partes, forzar el uso de la conexión vía VPN (que ya demostré que es vulnerable), usar medidas de seguridad caras, etc, etc, etc…

Esta empresa igual es grande, tiene sistemas muy delicados y críticos, por lo mismo utilizan un sistema de acceso remoto, en teoria, seguro. Pero que pasa cuando queda demostrado que no es así? Nos fuimos al carajo? Espero que no. Ya buscaré alguna forma de evitar eso. Si lo hice yo, lo puede hacer cualquiera y como no hay un control en la red de qué conexiones estan abiertas ni hacia donde, cualquiera podria estar haciendo cualquier cosa…

» Como matar una medida de seguridad “a toda prueba”

En donde trabajo, el dia que llegué me dieron un token ePass 2000. La idea es que esto lo use cuando se necesite acceder a algun servidor via vpn (cosa que aún no hago, I do not care…). Todo bien hasta ahí, el problema es que el coso este solo funciona en Windows (otra razón más para no usarlo), pero solo instalado directamente en el computador. Tampoco funciona en maquinas virtuales o al menos eso me dijeron (creo que con el passthrough podria andar), pero aun no he intentado hacer eso.

Mucho blabla…

El asunto es que hace un par de semanas dedicí buscar una forma de poder conectarme sin tener que usar el dispositivo aquel. Estuve toda una tarde pensando (asi que no hice nada en el trabajo) y no se me ocurrió. Pero ya saben lo que dicen, siempre hay una solución más simple. Y la encontré cuando iba camino a mi casa: ssh reverse (como no se me ocurrió antes).

Como?

Muy facil: Desde mi equipo en el trabajo abro una sesión ssh al compu de mi casa, asi:

ssh -R 14443:localhost:22 boris@mi-server.org -pXXXX

Y luego, desde el compu de mi casa hago:

ssh bquiroz@localhost -p14443

Y listo. Así funciona el ssh reverse.

Igual es un cacho… o no?

Personalmente creo que esto es un horrible bug (?) en la arquitectura de red de una empresa. Simpre se ha dicho que la mayor parte de los ataques vienen desde adentro de la organización y por lo tanto no basta con configurar el firewall para permitir accesos solo de algunas partes, forzar el uso de la conexión vía VPN (que ya demostré que es vulnerable), usar medidas de seguridad caras, etc, etc, etc…

Esta empresa igual es grande, tiene sistemas muy delicados y críticos, por lo mismo utilizan un sistema de acceso remoto, en teoria, seguro. Pero que pasa cuando queda demostrado que no es así? Nos fuimos al carajo? Espero que no. Ya buscaré alguna forma de evitar eso. Si lo hice yo, lo puede hacer cualquiera y como no hay un control en la red de qué conexiones estan abiertas ni hacia donde, cualquiera podria estar haciendo cualquier cosa…

Setiembre 26, 2009

Boris Quiroz
cereal_bars
wreeeeoooowww trata sobre »
» Sobre el viaje a Puerto Montt

Ayer tuve la suerte de estar muchos kilometros al sur de Santiago, en la ciudad de Puerto Montt. Fui hasta allá para hablar sobre dos temas que me gustan mucho y consideré interesante poder presentarselos a la gente de allá.

El primer tema fue Virtualización for real men, es decir, con Xen. (Sí, para variar estuve hablando de Xen :P ). Aproveché de hacer una mini demo conectandome al server de la casa. Estuvo muy bueno.

La segunda charla, sobre seguridad en sistemas *nix, me dió la impresión de que estaba dando una clase. Las caras de la audiencia no era de aburrimiento, sino que era caras de interés. Todos prestando atención, varios tomando apuntes, preguntas al final… No, muy bueno.

En general en todas las charlas del dia se veia el respeto de los asistentes por el tema expuesto. Eso es lo bueno de hacer este tipo de cosas en Universidades o Institutos. La gente va y pone atención :) Personalmente quedé bastante contento con contenido y el resultado de las charlas que dí, asi que espero que esta experiencia se pueda repetir.

Cuanto aparte la atención: Me trataron excelente! Muy buenas personas, muy buenas conversaciones, buen almuerzo… Todo genial. Además de eso, a todos los expositores nos entregaron un regalo.

Me traje a Santiago un muy buen recuerdo de mi pasada flash por Puerto Montt.

Setiembre 8, 2009

Boris Quiroz
cereal_bars
wreeeeoooowww trata sobre »
» Charla de Seguridad y otras hierbas

El próximo Jueves 10 de Septiembre, a las 19.30 horas estaré en el Aula Tecnológica de INACAP Sede Santiago Sur hablando, a grandes rasgos, sobre seguridad en sistemas GNU/Linux. En esta sesión (sí, se vienen más charlas) hablaré de SSH (y OpenSSH). La idea es que los asistentes cachen mas o menos qué es, para qué funciona más allá de ser algo para conectarme a los servidores, tratar de hacerlos entender que SSH != Putty, qué son esas cosas RSA y DSA, que aprendan que la autenticación puede hacerse por vaaarios métodos y finalmente entregarles algunas “buenas prácticas” para los que trabajan y así las puedan poner en práctica.

En resumen, intentaré explicar en poco más de una hora lo que el profesor deberia explicarles en medio semestre. Veremos como me vá.

Cuando termine la presentación les dejo los slides en algun lugar. El que quiere ir, es libre de hacerlo. Además, como en todas mis charlas, hay sorteo!

pd: obviamente le haré propaganda a las JRSL :P

pd2: @egipcios, no llego al kikazo. Están avisados…

Mayo 13, 2009
» Cerrando la puerta a los crackers

cyber-criminal

No es noticia nueva que tener una computadora conectada a Internet la deja expuesta a una serie de riesgos de seguridad, y es por eso que los administradores de sistemas, normalmente tomamos una serie de medidas básicas preventivas para evitar un disgusto posterior.

Si bien mis servidores normalmente tienen un nivel de seguridad más que aceptable, los molestos bots de estas personas no dejan de intentar adivinar las claves de mis cuentas para poder acceder con privilegios de administrador a los servidores. Esto me causa un problema, pero no de seguridad, sino que me ocupan los recursos que tengo para otras cosas y a veces hasta producen enlentecimientos notables en los servidores virtuales mas pequeños.

Es por esto que me puse manos a la obra, a averiguar alguna manera de mantener a raya a estos muchachos, y lo que me encontré fue con un software pensado justamente para esto: fail2ban.

Este programa está ya listo para ser instalado y usado en mi distribución favorita (Debian GNU/Linux), y al instalarse comienza a chequear los accesos fallidos de conexión por SSH, dejando 6 intentos y prohibiendo el acceso por IP por 10 minutos. Para prohibir el acceso utiliza reglas de iptables, y su funcionamiento es en modo daemon, un pequeño programa queda corriendo (muy chiquito, sirve hasta en VPS de 256 MB de RAM) revisando los distintos archivos de registros de sistema.

Lo interesante además es que trae una serie de plantillas para poder chequear otros tipos de servicios como FTP, SMTP, Web, etc. todo esto mediante reglas de análisis y acciones acordes, que se pueden personalizar para un uso específico.

En resumen, una muy simpática herramienta para los administradores de sistemas GNU/Linux, fácil de instalar y poner a funcionar, y el beneficio es enorme.

¡Que la disfruten!

Abril 8, 2009
» Servidor SSH con Twisted

Actualicé este ejemplo, tamibién incluido en el libro de Twisted para que no tire Deprecation Warnings:

from twisted.cred import portal, checkers, credentials
from twisted.conch import error, avatar, recvline, interfaces as conchinterfaces
from twisted.conch.ssh import factory, userauth, connection, keys, session, common
from twisted.conch.insults import insults
from twisted.application import service, internet
from zope.interface import implements
import os

class SSHDemoProtocol(recvline.HistoricRecvLine):
    def __init__(self, user):
        self.user = user

    def connectionMade(self) :
        recvline.HistoricRecvLine.connectionMade(self)
        self.terminal.write("Welcome to my test SSH server.")
        self.terminal.nextLine()
        self.do_help()
        self.showPrompt()

    def showPrompt(self):
        self.terminal.write("$ ")

    def getCommandFunc(self, cmd):
        return getattr(self, 'do_' + cmd, None)

    def lineReceived(self, line):
        line = line.strip()
        if line:
            cmdAndArgs = line.split()
            cmd = cmdAndArgs[0]
            args = cmdAndArgs[1:]
            func = self.getCommandFunc(cmd)
            if func:
               try:
                   func(*args)
               except Exception, e:
                   self.terminal.write("Error: %s" % e)
                   self.terminal.nextLine()
            else:
               self.terminal.write("No such command.")
               self.terminal.nextLine()
        self.showPrompt()

    def do_help(self, cmd=''):
        "Get help on a command. Usage: help command"
        if cmd:
            func = self.getCommandFunc(cmd)
            if func:
                self.terminal.write(func.__doc__)
                self.terminal.nextLine()
                return

        publicMethods = filter(
            lambda funcname: funcname.startswith('do_'), dir(self))
        commands = [cmd.replace('do_', '', 1) for cmd in publicMethods]
        self.terminal.write("Commands: " + " ".join(commands))
        self.terminal.nextLine()

    def do_echo(self, *args):
        "Echo a string. Usage: echo my line of text"
        self.terminal.write(" ".join(args))
        self.terminal.nextLine()

    def do_whoami(self):
        "Prints your user name. Usage: whoami"
        self.terminal.write(self.user.username)
        self.terminal.nextLine()

    def do_quit(self):
        "Ends your session. Usage: quit"
        self.terminal.write("Thanks for playing!")
        self.terminal.nextLine()
        self.terminal.loseConnection()

    def do_clear(self):
        "Clears the screen. Usage: clear"
        self.terminal.reset()

class SSHDemoAvatar(avatar.ConchUser):
    implements(conchinterfaces.ISession)

    def __init__(self, username):
        avatar.ConchUser.__init__(self)
        self.username = username
        self.channelLookup.update({'session':session.SSHSession})

    def openShell(self, protocol):
        serverProtocol = insults.ServerProtocol(SSHDemoProtocol, self)
        serverProtocol.makeConnection(protocol)
        protocol.makeConnection(session.wrapProtocol(serverProtocol))

    def getPty(self, terminal, windowSize, attrs):
        return None

    def execCommand(self, protocol, cmd):
        raise NotImplementedError

    def closed(self):
        pass

class SSHDemoRealm:
    implements(portal.IRealm)

    def requestAvatar(self, avatarId, mind, *interfaces):
        if conchinterfaces.IConchUser in interfaces:
            return interfaces[0], SSHDemoAvatar(avatarId), lambda: None
        else:
            raise Exception, "No supported interfaces found."

def getRSAKeys():
    if not (os.path.exists('public.key') and os.path.exists('private.key')):
        # generate a RSA keypair
        print "Generating RSA keypair..."
        from Crypto.PublicKey import RSA
        KEY_LENGTH = 1024
        rsaKey = RSA.generate(KEY_LENGTH, common.entropy.get_bytes)
        publicKeyString = keys.Key(rsaKey).toString()
        privateKeyString = keys.makePrivateKeyString(rsaKey)
        # save keys for next time
        file('public.key', 'w+b').write(publicKeyString)
        file('private.key', 'w+b').write(privateKeyString)
        print "done."
    else:
        publicKeyString = file('public.key').read()
        privateKeyString = file('private.key').read()
    return publicKeyString, privateKeyString

if __name__ == "__main__":
    sshFactory = factory.SSHFactory()
    sshFactory.portal = portal.Portal(SSHDemoRealm())
    users = {'admin': 'aaa', 'guest': 'bbb'}
    sshFactory.portal.registerChecker(
 checkers.InMemoryUsernamePasswordDatabaseDontUse(**users))

    pubKeyString, privKeyString = getRSAKeys()
    sshFactory.publicKeys = {
        'ssh-rsa': keys.Key.fromString(pubKeyString)}
    sshFactory.privateKeys = {
        'ssh-rsa': keys.Key.fromString(privKeyString)}

    from twisted.internet import reactor
    reactor.listenTCP(2222, sshFactory)
    reactor.run()

Junio 25, 2008
» ssh

ssh

SSH!
DON’T GIVE AWAY YOUR PASSWORD TO ANYWONE WHO MIGHT BE LISTENING!

Always use SSH (Secure SHell) when connecting
to Computer Science Department hosts, instead of
telnet of rsh. For more information:
http://www.cs.umd.edu/faq/ssh.html

nose, la encontre el otro dia ‘por ahi’ y me cayo simpatica.