SDK Multiplataforma en C logo

SDK Multiplataforma en C

Habilitar SSH

❮ Anterior
Siguiente ❯

La base de la Integración continua es la comunicación en red o, más concretamente, la posibilidad de ejecutar comandos de forma remota desde una máquina a otra. A día de hoy el estándar es SSH (Secure Shell), un protocolo y aplicación que permite ejecutar comandos a través de una red, añadiendo una capa de cifrado entre emisor y receptor (Listado 1) (Listado 1). Deberemos asegurar que SSH está presente y funcionando en todas las máquinas del Build Grid.

Listado 1: Obtener la lista de archivos de una máquina remota mediante SSH.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
C:\Users>ssh fran@192.168.1.24 ls
fran@192.168.1.24's password:
Desktop
Documents
Downloads
examples.desktop
Music
Pictures
Public
Templates
Videos
Comunicación de dos ordenadores mediante SSH indicando la encriptación de la información.
Figura 1: El protocolo SSH encripta la información que intercambian dos nodos.

1. SSH en Windows

Windows 10 incluye soporte para SSH, pero no está activo por defecto. Debes activarlo en Settings->Apps->Manage Optional Features->Add a Feature->OpenSSH Client/Server (Figura 2). Para asegurar que servicio está funcionando ejecuta services.msc y arranca OpenSSH SSH Server si no está corriendo ya.

Captura de las opciones SSH en Windows 10.
Figura 2: Activación de SSH en Windows.

2. SSH en macOS

SSH también está incluido en los sistemas operativos de Apple. Para activarlo:

  • Abre System Preferences desde el menú Apple y haz clic en el panel Sharing.
  • Activa la opción Remote Login (Figura 3).
  • Esto arrancará instantáneamente varios servicios, incluidos SFTP y SSH.

Por razones de seguridad, SSH no accede a todas las variables de entorno del shell bash en macOS. Esto puede provocar que un comando remoto falle, pero que tecleado desde un terminal en la propia máquina sí que funcione. Por ejemplo, esto ocurre al intentar ejecutar cmake o svn de forma remota. Para subsanarlo:

  • Añadimos las rutas necesarias a la variable PATH en /.ssh/environment.
  • Listado 2: Modificación de PATH en /.ssh/environment
    1
    
    PATH=$PATH:/bin:/usr/bin:/Applications/CMake.app/Contents/bin
    
  • Editamos el archivo /private/etc/ssh/sshd_config, habilitando la variable PermitUserEnvironment yes.
  • Paramos y re-lanzamos el servicio mediante el check Remote Login de Sharing.
  • Captura de las opciones SSH en macOS.
    Figura 3: Activación de SSH en macOS.

3. SSH en Linux

Por defecto, SSH no está incluido en Ubuntu. Para esta distribución y otras basadas en Debian, el servicio se instala y activa con este comando.

1
sudo apt-get install openssh-server -y

4. SSH sin password

Una vez activado el SSH en todas las máquinas de la red, ya podemos ejecutar comandos remotos desde el Build Master como hemos visto en (Listado 1). El problema es que SSH nos pedirá continuamente la contraseña del usuario remoto, algo que va a entorpecer la automatización del sistema de IC. Para evitar esto, tenemos que instalar el certificado rsa del Build Master en todas las máquinas remotas (los Build Host) para que reconozcan al emisor del comando y no le pidan contraseña.

  • Desde el Build Master, abre un terminal y teclea ssh-keygen. Esto generará dos certificados rsa en .ssh uno privado, que se quedará en el master y otro público que irá al host.
  • Listado 4: Generando el certificado rsa en el Master.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    fran~>ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/fran/.ssh/id_rsa): 
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    Your identification has been saved in /home/fran/.ssh/id_rsa.
    Your public key has been saved in /home/fran/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:Up6KjbnEV4Hgfo75YM393QdQsK3Z0aTNBz0DoirrW+c fran@192.168.1.24
    The key's randomart image is:
    +---[RSA 2048]----+
    |    .      ..oo..|
    |   . . .  . .o.X.|
    |    . . o.  ..+ B|
    |   .   o.o  .+ ..|
    |    ..o.S   o..  |
    |   . %o=      .  |
    |    @.B...     . |
    |   o.=. o. . .  .|
    |    .oo  E. . .. |
    +----[SHA256]-----+
    
  • Copia el archivo id_rsa.pub en el directorio de usuario de cada Build Host.
  • Listado 5: Paso del certificado rsa del Master al Host
    1
    2
    
    cd .ssh
    scp id_rsa.pub fran@192.168.1.24:/Users/fran/.ssh
    
  • Abre un terminal en el Host y teclea:
  • Listado 6: Instalando el certificado rsa
    1
    2
    3
    4
    5
    
    cd .ssh
    type id_rsa.pub >> authorized_keys   (Windows)
    ...
    cd .ssh
    cat id_rsa.pub >> authorized_keys    (macOS/Linux)
    
  • Si todo ha ido bien, ya podemos ejecutar un comando remoto sin que nos pida contraseña (Figura 4), ya que el servidor SSH que corre en el Build Host, reconoce al computador Build Master.
  • Listado 7: SSH sin contraseña.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    C:\Users>ssh fran@192.168.1.24 ls
    Desktop
    Documents
    Downloads
    examples.desktop
    Music
    Pictures
    Public
    Templates
    Videos
    
    Comando ssh en máquina remota sin password.
    Figura 4: Ejecución de un comando en una máquina remota sin necesidad de utilizar password.

5. SSH desde C

El sistema de IC debe ser capaz de lanzar comandos SSH desde el propio programa en vez del terminal, con el fin de coordinar a los Build Host para completar las tareas de los Build Profile. En (Listado 8) vemos como hacerlo desde el lenguaje C. En Lanzando procesos tienes más información sobre el API de multi-procesamiento de NAppGUI.

Listado 8: Ejecución de un comando SSH desde un procedimiento en C.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Proc *proc = bproc_exec("ssh fran@192.168.1.24 ls", NULL, NULL);
if (proc != NULL)
{
    byte_t buffer[512];
    uint32_t rsize;
    Stream *stm = stm_memory(1024);
    while (bproc_read(proc, buffer, sizeof(buffer), &rsize, NULL) == TRUE)
        stm_write(stm, buffer, rsize);

    bproc_wait(proc);
    bproc_close(&proc);
    return stm;
}
❮ Anterior
Siguiente ❯