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.
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.
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.
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.
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
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