Acceso simple y seguro a sistemas remotos con Boundary

Escrito por el .
gnu-linux planeta-codigo
Enlace permanente Comentarios

Boundary es otra herramienta de HashiCorp dedicada a la seguridad. Vault está centrada en el almacenamiento de secretos, Boundary está centrada en otro aspecto de la seguridad que es el acceso a sistemas remotos. Una herramienta mejor adaptada y teniendo en cuenta las propiedades dinámicas de los sistemas actuales. Es una alternativa a los métodos de VPN, bastión y firewall que se utilizan para permitir estos accesos remotos.

HashiCorp Boundary

HashiCorp

El acceso de forma remota a sistemas es necesario y útil más cuando las máquinas ya no son máquinas físicas sino que están en centros de datos en diferentes ubicaciones en el mundo e incluso son máquinas lógicas como las máquinas virtuales ejecutadas en la computación de la nube.

El acceso a las máquinas no solo se requiere para las aplicaciones de forma automatizada sino que en algunas situaciones se requiere acceso manual para realizar tareas administrativas o conexión con clientes específicos como escritorio remoto o clientes de bases de datos.

Permitir el acceso remoto es necesario, sin embargo, requiere seguridad de forma que únicamente los usuarios autorizados accedan únicamente a los sistemas autorizados.

Funcionamiento acceso remoto tradicional

La forma habitual de proporcionar acceso remoto a sistemas de una red privada es mediante una VPN o a través de un sistema intermediario denominado bastión. Estos conceptos proporcionan acceso remoto en ciertos aspectos de forma segura pero no están exentas de problemas e inconvenientes.

El primer problema es que una vez conectado a una VPN o un bastión se tiene acceso a cualquier ordenador de la red privada a la que uno se ha conectado. Un usuario que necesite acceso a una máquina potencialmente tiene conectividad con otros sistemas en esa red, lo que es riesgo de seguridad por permitir la posibilidad de accesos a sistemas no autorizados.

El segundo problema es que las infraestructuras actuales de computación en la nube no son estáticas sino que son dinámicas en las que los sistemas cambian de dirección IP o se crean y destruyen instancias.

Mediante un firewall ubicado entre el bastión y el sistema de acceso remoto es posible limitar a que sistemas de la red es posible conectarse. Sin embargo, un firewall constituye un elemento más a administrar que añade más complejidad en la infraestructura.

Boundary

Casos de uso de Boundary

Boundary

Acceso remoto con Boundary

Para tratar de solventar los problemas de acceso remoto con VPN, bastión y firewall, simplificar la infraestructura y una administración de más alto nivel lógico de usuarios, permisos y sistemas HashiCorp ha publicado otra herramienta dedicada a la seguridad específica para el acceso remoto.

Boundary es una herramienta adaptada a los entornos modernos de computación en la nube y dinámicos agnóstica de la infraestructura y de las aplicaciones utilizadas por los clientes remotos. Su funcionamiento es similar al de un bastión con una diferencia importante de que Boundary es el que realiza la conexión a los equipos remotos y no la aplicación cliente.

Boundary gestiona el inventario de hosts, usuarios, grupos y roles y permisos con los que es capaz de permitir o denegar el acceso únicamente a los hosts permitidos y denegar el acceso a los hosts para los que no se dispone acceso. Funciona en modo cliente y servidor, el servidor hace de bastión y es el que realmente se conecta al sistema remoto, en el modo cliente proporciona a la aplicación cliente conexión con el servidor, a diferencia de un sistema con un bastión o VPC la aplicación cliente no se conecta con el sistema remoto sino que únicamente se conecta al servidor de Boundary.

Boundary es un único binario tanto cuando actúa en modo servidor como en modo cliente, dispone una interfaz de línea de comandos y una interfaz web. En las primeras versiones no están todas la funcionalidades planificadas en el roadmap, a medida que madure el servicio ganará en funcionalidades y utilidad. Integrando Boundary con Consul tendrá acceso al inventario de servicios y hosts. Integrando Boundary con Vault en el momento de acceso al sistema remoto Vault será capaz de crear credenciales de forma dinámica y efímeras.

En su modo servidor requiere de una base de datos PostgreSQL que inicia como un contenedor de Docker. La consola de administración se inicia en el puerto 9200 y el usuario y contraseña se emite en la salida de la terminal al iniciar la herramienta.

Consola de administración de Boundary Consola de administración de Boundary

Consola de administración de Boundary

Conceptos

Boundary tiene varios conceptos de dominio, por un lado está el catálogo o inventario de hosts, un conjunto de hosts agrupados en un host set y estos a su vez en un host catalog. Por otro lado, están los usuarios, grupo y roles. Finalmente los targets son la abstracción del elemento al que se quiere realizar una conexión, el target se traduce en un host. Finalmente, todos estos elementos se agrupan en ámbitos o scopes y proyectos o projects.

En una organización con unas cuantas decenas de sistemas y usuarios, la gestión de este inventario se vuelve ciertamente complicado.

Clientes soportados

Boundary incorpora varios clientes en su modo de funcionamiento como cliente. Estos son:

  • ssh: por defecto es el cliente SSH local (ssh)
  • postgres: por defecto el del cliente oficial de línea de comandos de Postgres (psql)
  • rdp: por defecto es el cliente de Windows RDP (mstsc)
  • http: por defecto es curl
  • kube: por defecto es kubectl

Boundary soportar estos clientes de forma nativa sin embargo es agnóstico de la herramienta cliente, con la opción exec es posible utilizar cualquier herramienta que se conecte con un sistema remoto.

Ejemplo de conexión SSH con Boundary

En el siguiente ejemplo muestro como conectarse a un host a través de Boundary con SSH. En el mismo ejemplo muestro como usar Boundary con autenticación con claves SSH y como usar Boundary con Vault que generar un OTP para realizar la misma conexión sin usar claves SSH y únicamente con credenciales temporales. En este ejemplo el host remoto es una Raspberry Pi con sistema operativo Raspberry Pi OS instalado y con el servicio de SSH iniciado.

En este ejemplo el servidor de Boundary y Vault están en la misma máquina. Los pasos del ejemplo para usar Boundary y SSH, los pasos que involucran ORP son opcionales si se usan claves SSH:

  • Iniciar el servidor de Boundary.
  • Configurar el servidor SSH para que valide los OTP conectándose a Vault.
  • Iniciar Vault y permitir su acceso al host remoto para validar los OTP.
  • Realizar la conexión SSH con Boundary desde la máquina local a la máquina remota.

Iniciar el servidor Boundary es sencillo, basta instalar el binario de Boundary en el PATH del sistema e instalar el gestor de contenedores Docker previamente. Al iniciar el servidor de Boundary este descarga la imagen de Postgres e inicia su contenedor.

1
2
$ sudo systemctl start docker.service

start-docker.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$ vault server -dev -dev-listen-address "0.0.0.0:8200"
==> Vault server configuration:

             Api Address: http://0.0.0.0:8200
                     Cgo: disabled
         Cluster Address: https://0.0.0.0:8201
              Go Version: go1.15.8
              Listener 1: tcp (addr: "0.0.0.0:8200", cluster address: "0.0.0.0:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
               Log Level: info
                   Mlock: supported: true, enabled: false
           Recovery Mode: false
                 Storage: inmem
                 Version: Vault v1.5.7
             Version Sha: 81d55e35dbbe844a6feb4f52a9a3d072c052d228+CHANGES

WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory
and starts unsealed with a single unseal key. The root token is already
authenticated to the CLI, so you can immediately begin using Vault.

You may need to set the following environment variable:

    $ export VAULT_ADDR='http://0.0.0.0:8200'

The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.

Unseal Key: oqt+hwz0gOD9nxz8gc9C79B0M6mDx7rsbJelYZDsg5I=
Root Token: s.PAPTxv16g0o9amLr82NYcxBT

Development mode should NOT be used in production installations!

==> Vault server started! Log data will stream in below:

2021-03-05T15:07:47.964+0100 [INFO]  proxy environment: http_proxy= https_proxy= no_proxy=
2021-03-05T15:07:47.964+0100 [WARN]  no `api_addr` value specified in config or in VAULT_API_ADDR; falling back to detection if possible, but this value should be manually set
start-vault.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ boundary dev
==> Boundary server configuration:

        [Controller] AEAD Key Bytes: A7NiMQ0fNlBiCpFxMxg21k8TAdSNcui/okJGxBg6eZs=
          [Recovery] AEAD Key Bytes: H4U5vaCh1ZmgrRJXhlljvOqkLDzU9ZNy4Cn9Z4+a7Bo=
       [Worker-Auth] AEAD Key Bytes: rWZi4UxADHAlsqbhemdM6YIIyFG9+AuqIcCbAOZILtQ=
               [Recovery] AEAD Type: aes-gcm
                   [Root] AEAD Type: aes-gcm
            [Worker-Auth] AEAD Type: aes-gcm
                                Cgo: disabled
     Controller Public Cluster Addr: 127.0.0.1:9201
             Dev Database Container: confident_mcnulty
                   Dev Database Url: postgres://postgres:password@localhost:49153/boundary?sslmode=disable
         Generated Admin Login Name: admin
           Generated Admin Password: password
           Generated Auth Method Id: ampw_1234567890
          Generated Host Catalog Id: hcst_1234567890
                  Generated Host Id: hst_1234567890
              Generated Host Set Id: hsst_1234567890
             Generated Org Scope Id: o_1234567890
         Generated Project Scope Id: p_1234567890
                Generated Target Id: ttcp_1234567890
  Generated Unprivileged Login Name: user
    Generated Unprivileged Password: password
                         Listener 1: tcp (addr: "127.0.0.1:9200", cors_allowed_headers: "[]", cors_allowed_origins: "[*]", cors_enabled: "true", max_request_duration: "1m30s", purpose: "api")
                         Listener 2: tcp (addr: "127.0.0.1:9201", max_request_duration: "1m30s", purpose: "cluster")
                         Listener 3: tcp (addr: "127.0.0.1:9202", max_request_duration: "1m30s", purpose: "proxy")
                          Log Level: info
                              Mlock: supported: true, enabled: false
                            Version: Boundary v0.1.7
                        Version Sha: bc565922fbd3a18c9f6a22cd2e80a93df0d7cd45
           Worker Public Proxy Addr: 127.0.0.1:9202

==> Boundary server started! Log data will stream in below:

2021-03-05T15:08:05.051+0100 [INFO]  worker: connected to controller: address=127.0.0.1:9201
2021-03-05T15:08:05.054+0100 [INFO]  controller: worker successfully authed: name=dev-worker
2021-03-05T15:08:05.059+0100 [WARN]  worker: got no controller addresses from controller; possibly prior to first status save, not persisting
start-boudary.sh
1
2
3
$ docker ps -a
CONTAINER ID   IMAGE         COMMAND                  CREATED       STATUS       PORTS                     NAMES
e48475a774bb   postgres:11   "docker-entrypoint.s…"   2 hours ago   Up 2 hours   0.0.0.0:49153->5432/tcp   confident_mcnulty
docker-ps.sh

Conexión SSH a sistema remoto

Realizando la conexión directamente al host remoto con SSH se realiza con el siguiente comando, esta es la forma tradicional de hacerlo usando claves SSH.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[picodotdev@archlinux ~]$ ssh pi@192.168.1.101
Linux raspberrypi 5.10.11+ #1399 Thu Jan 28 12:02:28 GMT 2021 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Feb 25 21:21:31 2021 from 192.168.1.7
[pi@raspberrypi ~]$
ssh.sh

Utilizando Boundary como intermediario estos son los comandos. Primero hay que realizar la autenticación en Boundary y luego usar Boundary para que establezca la conexión SSH con el host destino, previamente hay es necesario haber configurado los recursos en Boundary.

1
2
3
4
5
6
7
8
$ boundary authenticate password -auth-method-id=ampw_1234567890 -login-name=admin -password=password
Authentication information:
  Account ID:      apw_cxGWZ0KOIc
  Auth Method ID:  ampw_1234567890
  Expiration Time: Fri, 12 Mar 2021 15:21:11 CET
  Token:           at_1PE5BRB96M_s18pNSYQHzzoZmPD8eyuUyEpqiZw5VFBvAPN7bs2MUamBpdY316whSfZthEVw3KED7khERfPxRTKAm8TH14vNAWW7UrCamxSgYToYBQ3x7kxJHPfeZdtEwhfwx7NZ8TWaXVL2gdppJ4sZ
  User ID:         u_1234567890
$ export BOUNDARY_TOKEN="at_1PE5BRB96M_s18pNSYQHzzoZmPD8eyuUyEpqiZw5VFBvAPN7bs2MUamBpdY316whSfZthEVw3KED7khERfPxRTKAm8TH14vNAWW7UrCamxSgYToYBQ3x7kxJHPfeZdtEwhfwx7NZ8TWaXVL2gdppJ4sZ"
boundary-authentication.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[picodotdev@archlinux ~]$ boundary connect ssh -target-id ttcp_23T9SbQ7ce -username pi -- -i "~/.ssh/pico.dev@gmail.com"
Linux raspberrypi 5.10.11+ #1399 Thu Jan 28 12:02:28 GMT 2021 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Mar  5 15:12:56 2021 from 192.168.1.4
[pi@raspberrypi ~]$ 
ssh-boundary-1.sh

Utilizar Boundary como intermediario requiere configurar la herramienta para que tenga un inventario de host a los cuales es posible conectarse y usuarios con sus permisos. En el ejemplo utilizo una Raspberry Pi como host al que realizar la conexión en la dirección IP 192.168.1.101. Para utilizar la linea de comandos de Boundary hay que autenticarse y establecer la variable de entorno BOUNDARY_TOKEN.

Las operaciones de estos comandos para crear los recursos están disponibles también para realizarlas desde su consola web de administración.

Crear recursos de Boundary Crear recursos de Boundary

Crear recursos de Boundary
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
$ boundary scopes create -name bitix-scope -description "Example Bitix scope"

Scope information:
  Created Time:        Fri, 05 Mar 2021 15:24:33 CET
  Description:         Example Bitix scope
  ID:                  o_PuL7bdpoKw
  Name:                bitix-scope
  Updated Time:        Fri, 05 Mar 2021 15:24:33 CET
  Version:             1

  Scope (parent):
    ID:                global
    Name:              global
    Type:              global

  Authorized Actions:
    read
    update
    delete
$ boundary scopes create -name bitix-project -description "Example Bitix project" -scope-id=o_PuL7bdpoKw

Scope information:
  Created Time:        Fri, 05 Mar 2021 15:26:54 CET
  Description:         Example Bitix project
  ID:                  p_MPpTkaalUm
  Name:                bitix-project
  Updated Time:        Fri, 05 Mar 2021 15:26:54 CET
  Version:             1

  Scope (parent):
    ID:                o_PuL7bdpoKw
    Name:              bitix-scope
    Parent Scope ID:   global
    Type:              org

  Authorized Actions:
    read
    update
    delete
$ boundary host-catalogs create static -name bitix-host-catalog -description "Bitix host-catalog" -scope-id=p_MPpTkaalUm

Host Catalog information:
  Created Time:        Fri, 05 Mar 2021 15:30:22 CET
  Description:         Bitix host-catalog
  ID:                  hcst_8t06PaPJHK
  Name:                bitix-host-catalog
  Type:                static
  Updated Time:        Fri, 05 Mar 2021 15:30:22 CET
  Version:             1

  Scope:
    ID:                p_MPpTkaalUm
    Name:              bitix-project
    Parent Scope ID:   o_PuL7bdpoKw
    Type:              project

  Authorized Actions:
    read
    update
    delete

  Authorized Actions on Host Catalog\'s Collections:
    host-setss:
      create
      list
    hostss:
      create
      list
$ boundary host-sets create static -name=raspberrypi -description="Raspberry Pi host set" -host-catalog-id=hcst_8t06PaPJHK 

Host Set information:
  Created Time:        Fri, 05 Mar 2021 15:58:01 CET
  Description:         Raspberry Pi host set
  Host Catalog ID:     hcst_8t06PaPJHK
  ID:                  hsst_e6BJkM7PqR
  Name:                raspberrypi
  Type:                static
  Updated Time:        Fri, 05 Mar 2021 15:58:01 CET
  Version:             1

  Scope:
    ID:                p_MPpTkaalUm
    Name:              bitix-project
    Parent Scope ID:   o_PuL7bdpoKw
    Type:              project

  Authorized Actions:
    read
    update
    delete
    add-hosts
    set-hosts
    remove-hosts
$ boundary hosts create static -name raspberrypi -description "Static host for Raspberry Pi" -address "192.168.1.101" -host-catalog-id=hcst_8t06PaPJHK

Host information:
  Created Time:        Fri, 05 Mar 2021 15:38:18 CET
  Description:         Static host for Raspberry Pi
  Host Catalog ID:     hcst_8t06PaPJHK
  ID:                  hst_2eN5yaTE41
  Name:                raspberrypi
  Type:                static
  Updated Time:        Fri, 05 Mar 2021 15:38:18 CET
  Version:             1

  Scope:
    ID:                p_MPpTkaalUm
    Name:              bitix-project
    Parent Scope ID:   o_PuL7bdpoKw
    Type:              project

  Authorized Actions:
    read
    update
    delete

  Attributes:
    address:           192.168.1.101
$ boundary host-sets add-hosts --host=hst_2eN5yaTE41 -id=hsst_e6BJkM7PqR

Host Set information:
  Created Time:        Fri, 05 Mar 2021 15:58:01 CET
  Description:         Raspberry Pi host set
  Host Catalog ID:     hcst_8t06PaPJHK
  ID:                  hsst_e6BJkM7PqR
  Name:                raspberrypi
  Type:                static
  Updated Time:        Fri, 05 Mar 2021 16:01:36 CET
  Version:             2

  Scope:
    ID:                p_MPpTkaalUm
    Name:              bitix-project
    Parent Scope ID:   o_PuL7bdpoKw
    Type:              project

  Authorized Actions:
    read
    update
    delete
    add-hosts
    set-hosts
    remove-hosts

  Host IDs:
    hst_2eN5yaTE41
$ boundary targets create tcp -name raspberrypi -description "Raspberry Pi target" -default-port=22 -scope-id=p_MPpTkaalUm

Target information:
  Created Time:               Fri, 05 Mar 2021 15:42:04 CET
  Description:                Raspberry Pi target
  ID:                         ttcp_23T9SbQ7ce
  Name:                       raspberrypi
  Session Connection Limit:   1
  Session Max Seconds:        28800
  Type:                       tcp
  Updated Time:               Fri, 05 Mar 2021 15:42:04 CET
  Version:                    1

  Scope:
    ID:                       p_MPpTkaalUm
    Name:                     bitix-project
    Parent Scope ID:          o_PuL7bdpoKw
    Type:                     project

  Authorized Actions:
    read
    update
    delete
    add-host-sets
    set-host-sets
    remove-host-sets
    authorize-session
$ boundary targets add-host-sets -host-set=hsst_e6BJkM7PqR -id=ttcp_23T9SbQ7ce

Target information:
  Created Time:               Fri, 05 Mar 2021 15:42:04 CET
  Description:                Raspberry Pi target
  ID:                         ttcp_23T9SbQ7ce
  Name:                       raspberrypi
  Session Connection Limit:   1
  Session Max Seconds:        28800
  Type:                       tcp
  Updated Time:               Fri, 05 Mar 2021 15:59:03 CET
  Version:                    2

  Scope:
    ID:                       p_MPpTkaalUm
    Name:                     bitix-project
    Parent Scope ID:          o_PuL7bdpoKw
    Type:                     project

  Authorized Actions:
    read
    update
    delete
    add-host-sets
    set-host-sets
    remove-host-sets
    authorize-session

  Host Sets:
    Host Catalog ID:          hcst_8t06PaPJHK
    ID:                       hsst_e6BJkM7PqR
boundary-configuration.sh

Una de las funcionalidades que proporciona Boundary es trazabilidad en el log se muestran los inicio de las conexiones y su finalización, permite ver las conexiones abiertas y forzar el cierre de una conexión.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
2021-03-05T16:31:06.880+0100 [INFO]  controller.worker-handler: authorized connection: session_id=s_S91yFIr4qi connection_id=sc_tg5qgexhhe connections_left=0
2021-03-05T16:31:06.888+0100 [INFO]  controller.worker-handler: connection established: session_id=s_S91yFIr4qi connection_id=sc_tg5qgexhhe client_tcp_address=127.0.0.1 client_tcp_port=40058 endpoint_tcp_address=192.168.1.101 endpoint_tcp_port=22
2021-03-05T16:31:09.001+0100 [INFO]  controller.worker-handler: connection closed: connection_id=sc_tg5qgexhhe
2021-03-05T16:33:29.299+0100 [INFO]  controller.worker-handler: session activated: session_id=s_7yPhGF7hHz target_id=ttcp_23T9SbQ7ce user_id=u_1234567890 host_set_id=hsst_e6BJkM7PqR host_id=hst_2eN5yaTE41
2021-03-05T16:33:29.305+0100 [INFO]  controller.worker-handler: authorized connection: session_id=s_7yPhGF7hHz connection_id=sc_u5dxQjveKv connections_left=0
2021-03-05T16:33:29.314+0100 [INFO]  controller.worker-handler: connection established: session_id=s_7yPhGF7hHz connection_id=sc_u5dxQjveKv client_tcp_address=127.0.0.1 client_tcp_port=40078 endpoint_tcp_address=192.168.1.101 endpoint_tcp_port=22
2021-03-05T16:33:32.302+0100 [INFO]  controller.worker-handler: connection closed: connection_id=sc_u5dxQjveKv
2021-03-05T16:33:34.745+0100 [INFO]  controller.worker-handler: session activated: session_id=s_xmwSyOuFgW target_id=ttcp_23T9SbQ7ce user_id=u_1234567890 host_set_id=hsst_e6BJkM7PqR host_id=hst_2eN5yaTE41
2021-03-05T16:33:34.757+0100 [INFO]  controller.worker-handler: authorized connection: session_id=s_xmwSyOuFgW connection_id=sc_XkYBKBV1J0 connections_left=0
2021-03-05T16:33:34.772+0100 [INFO]  controller.worker-handler: connection established: session_id=s_xmwSyOuFgW connection_id=sc_XkYBKBV1J0 client_tcp_address=127.0.0.1 client_tcp_port=40088 endpoint_tcp_address=192.168.1.101 endpoint_tcp_port=22
boundary.log

Conexiones realizadas con Boundary

Conexiones realizadas con Boundary

Autenticación con SSH

La autenticaión de SSH usando Boudary no cambia, se solicita la contraseña del usuario con el que se realiza la conexión, la clave pública en caso de que el servidor se haya configurado con clave pública y privada o incluso un segundo factor de autenticación.

Segundo factor de autenticación con Vault

Vault permite generar contraseñas de un solo uso y configurando SSH validar los OTP proporcionados en la conexión. La ventaja de usar OTP es que no es necesario distribuir las claves públicas en cada una de las máquinas en las que se quiera realizar la conexión SSH. Hay que cambiar los archivos de configuración /etc/pam.d/sshd, /etc/ssh/sshd_config, /etc/vault-ssh-helper.d/config.hcl y reiniciar el servicio de SSH, estos cambios permiten al servidor SSH validar los tokens proporcionados conectándose con Vault.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
$ ssh pi@192.168.1.101
$ wget https://releases.hashicorp.com/vault-ssh-helper/0.2.1/vault-ssh-helper_0.2.1_linux_amd64.zip
$ wget https://releases.hashicorp.com/vault-ssh-helper/0.2.1/vault-ssh-helper_0.2.1_linux_arm.zip
$ sudo unzip -q vault-ssh-helper_0.2.1_linux_arm.zip -d /usr/local/bin
$ sudo chmod 0755 /usr/local/bin/vault-ssh-helper
$ sudo chown root:root /usr/local/bin/vault-ssh-helper
$ sudo mkdir /etc/vault-ssh-helper.d/

$ sudo tee /etc/vault-ssh-helper.d/config.hcl <<EOF
vault_addr = "http://192.168.1.4:8200"
tls_skip_verify = false
ssh_mount_point = "ssh"
allowed_roles = "*"
EOF

$ vault-ssh-helper -verify-only -dev -config /etc/vault-ssh-helper.d/config.hcl
==> WARNING: Dev mode is enabled!
[INFO] using SSH mount point: ssh
[INFO] using namespace: us
[INFO] vault-ssh-helper verification successful!
install-ssh-helper.sh
1
2
$ sudo vim /etc/pam.d/sshd

sshd.sh
1
2
3
#@include common-auth
auth requisite pam_exec.so quiet expose_authtok log=/var/log/vault-ssh.log /usr/local/bin/vault-ssh-helper -dev -config=/etc/vault-ssh-helper.d/config.hcl
auth optional pam_unix.so not_set_pass use_first_pass nodelay
sshd
1
2
$ sudo vim /etc/ssh/sshd_config

sshd_config.sh
1
2
3
ChallengeResponseAuthentication yes
UsePAM yes
PasswordAuthentication no
sshd_config

Para validar el OTP el servidor SSH a través del módulo de autenticación PAM le pide a Vault que lo valide, para ello necesita conectividad de red, si es necesario activando la regla del firewall para permitir el tráfico de red para el puerto 8200 que utiliza Vault.

1
2
$ sudo ufw allow 8200/tcp

vault-configuration-firewall.sh

También hay que configurar Vault con las políticas y permisos para permitir a un usuario autenticado generar los OTP de autenticación.

1
2
3
4
5
6
$ export VAULT_ADDR='http://127.0.0.1:8200'
$ vault secrets enable ssh
$ vault write ssh/roles/otp_ssh \
    key_type=otp \
    default_user=pi \
    cidr_list=192.168.1.0/24
vault-configuration.sh

El comando para generar el OTP e iniciar la conexión es el siguiente. Este comando realiza dos acciones, generar el OTP e iniciar la conexión SSH, el OTP hay que copiarlo y pegarlo de forma manual en la solicitud de contraseña que corresponde con el OTP generado.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[picodotdev@archlinux ~]$ vault ssh -role otp_ssh -mode otp -strict-host-key-checking=no pi@192.168.1.101
Vault could not locate "sshpass". The OTP code for the session is displayed
below. Enter this code in the SSH password prompt. If you install sshpass,
Vault can automatically perform this step for you.
OTP for the session is: 31233d29-e822-6891-6a34-9a101fb2e344
Password:
Linux raspberrypi 5.10.11+ #1399 Thu Jan 28 12:02:28 GMT 2021 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Mar  5 15:12:56 2021 from 192.168.1.4
[pi@raspberrypi ~]$ 
ssh-vault-otp-1.sh

Generar el OTP y realizar la conexión se puede realizar en dos pasos separados.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[picodotdev@archlinux ~]$ vault write ssh/creds/otp_ssh username=pi ip=192.168.1.101
Key                Value
---                -----
lease_id           ssh/creds/otp_ssh/7vB38cBFRWl883ePHusCBAMI
lease_duration     768h
lease_renewable    false
ip                 192.168.1.101
key                93e489c2-c30c-6e4e-f22c-96e719d41fd3
key_type           otp
port               22
username           pi
[picodotdev@archlinux ~]$ ssh pi@192.168.1.101
Password:
Linux raspberrypi 5.10.11+ #1399 Thu Jan 28 12:02:28 GMT 2021 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Mar  5 15:12:56 2021 from 192.168.1.4
[pi@raspberrypi ~]$ 
ssh-vault-otp-2.sh

Usando Vault la conexión se realiza entre la máquina local y la máquina destino, usando Boundary como intermediario el comando es el mismo que al usar una clave SSH pero al iniciar la conexión se solicita la contraseña OTP.

1
2
$ boundary connect ssh -target-id ttcp_23T9SbQ7ce -username pi

ssh-boundary-2.sh


Comparte el artículo: