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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
|
#### SSH alias !!! ####
```sh
ssh-keygen --help # -h
vim ~/.ssh/config
UseRoaming no
Host <newHostName>
Hostname 178.20.46.157 # или vlapa.ru
User vlapa
Port 22
##########################:
# заходим на сервер
ssh newHostName
```
#### Проброс портов SSH: ####
```sh
ssh -L 9000:localhost:8000 server2
ssh -L [локальный_адрес:]порт:удалённый_адрес:порт [user@]hostname
# Если не указывать [локальный_адрес:], соединение по умолчанию будет привязано к интерфейсу localhost.
```
#### SSH ####
```sh
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub
ssh-keygen -t ed25519
ssh-keygen -t ed25519 -f ~/.ssh/key2 -C "new key"
# -сменить пароль на ключ
ssh-keygen -p
# -открытый ключ. копируют на сервера
~/.ssh/id_rsa.pub
# -закрытый ключ (у нас)
~/.ssh/id_rsa
~/.ssh/authorized_keys
chown -R vlapa:vlapa /home/vlapa/.ssh
# Права обязательно !!!
chmod 700 ~/.ssh
chmod 644 ~/.ssh/*
chmod 600 authorized_keys
ssh -i ~/.ssh/key2 vlapa@192.168.88.2
cd /etc/ssh
ll
vim /etc/sshd_config
Port 22
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
systemctl restart sshd
systemctl status sshd
ssh -i ~/.ssh/key2 vlapa@192.168.88.2
vim .ssh/config
Host \*.com
StrictHostKeyChecking no
User etoosamoe
ForwardAgent yes
IdentityFile /Users/username/.ssh/id_rsa
IdentitiesOnly yes
UserKnownHostsFile=/dev/null
UseKeychain yes
AddKeysToAgent yes
ServerAliveInterval 60
ServerAliveCountMax 1200
Host std-\*
StrictHostKeyChecking no
User ci-user
ForwardAgent yes
IdentityFile /Users/username/.ssh/id_rsa_second
IdentitiesOnly yes
UserKnownHostsFile=/dev/null
UseKeychain yes
AddKeysToAgent yes
ServerAliveInterval 60
ServerAliveCountMax 1200
```
```sh
# В каталоге пользователя, под которым вы хотите зайти, если создать файл и положить туда открытый ключ, то можно будет заходить без пароля. Обратите внимание, права на файл не должны давать возможность писать в этот файл посторонним пользователям (и группам !!!), иначе ssh его не примет. В ключе последнее поле — user@machine Оно не имеет никакого отношения к авторизации и служит только для удобства определения где чей ключ. Заметим, это поле может быть поменяно (или даже удалено) без нарушения структуры ключа.
ssh-copy-id user@server
# позволяет скопировать ключ не редактируя файлы вручную.
# Если у вас ssh на нестандартном порту, то ssh-copy-id требует особого ухищрения при работе:
ssh-copy-id '-p 443 user@server' # внимание на кавычки !
# Первый раз, когда вы заходите на сервер, ssh вас спрашивает, доверяете ли вы ключу. Если отвечаете нет, соединение закрывается. Если да — ключ сохраняется в файл ~/.ssh/known_hosts Узнать, где какой ключ нельзя (ибо несекьюрно).
# Удалить известный ключ сервера можно командой:
ssh-keygen -R server
# При этом нужно удалить ещё и ключ IP (они хранятся раздельно):
ssh-keygen -R 127.0.0.1
# Ключ сервера хранится в
/etc/ssh/ssh_host_rsa_key
/etc/ssh/ssh_host_rsa_key.pub
# Их можно:
# а) скопировать со старого сервера на новый.
# б) сгенерировать с помощью ssh-keygen Пароля при этом задавать не надо (т.е. пустой). Ключ с паролем ssh-сервер использовать не сможет.
# Заметим, если вы сервера клонируете (например, в виртуалках), то ssh-ключи сервера нужно обязательно перегенерировать.
# Старые ключи из know_hosts при этом лучше убрать, иначе ssh будет ругаться на duplicate key
sudo ssh service restart
sudo sshd service restart
# Чтобы удаленно выполнить команду с локального компьютера, добавьте инструкцию к команде SSH. Например, чтобы удалить файл, введите:
ssh test.server.com rm ~/Desktop/Dir1/sample4
# Введите пароль, и файл на удаленном сервере будет удален без создания новой оболочки.
sudo systemctl restart ssh
vim /etc/ssh/sshd_config
- PasswordAuthentication no
- PermitRootLogin no
- AllowUsers www root
sudo service ssh restart
# Ключ игнорируется сервером
# В редких случаях можно столкнуться с проблемой, что вы настроили все корректно, но не можете подключиться к серверу с использованием SSH-ключей. Видя следующий вывод, можно подумать, что сервер не видит ключ:
Permission denied (publickey).
# Вероятнее всего, сервер SSH считает, что установлены неподходящие разрешения к некоторым каталогам. Для решения этой проблемы следует изменить права доступа.
# Настройка удаленного узла
# Полный доступ к папке .ssh только владельцу, остальным — полный запрет:
chmod rwx------ ~/.ssh
# Права на запись и чтение для файла authorized_keys только владельцу, остальным — полный запрет:
chmod rw------- ~/.ssh/authorized_keys
# Отмена записи группой и остальными пользователями:
chmod go-w ~/
# Настройка локальной машины
# Полный доступ к папке .ssh только владельцу, остальным — полный запрет:
chmod rwx------ ~/.ssh
# Права на запись и чтение для файла ключа только владельцу, остальным — полный запрет:
chmod rw------- ~/.ssh/*key* ( 600)
# После применения этих политик ошибка должна исчезнуть.
```
===========================================
### Как общаться с удаленным сервером через SSH
`ssh-keygen -t rsa -b 4096 -f host_ca -C host_ca
Файл `host_ca` является закрытым ключом центра сертификации хоста и должен храниться в защищенном месте. Не выдавайте его никому, не копируйте куда-либо и убедитесь, что как можно меньше людей имеют к нему доступ. В идеале он «живет» на машине, которая не допускает прямого доступа, и все сертификаты выдаются автоматически.
Рекомендуется использовать два отдельных CA – один для подписания сертификатов хостов, другой для пользователей. Одни и те же процессы не будут добавлять и хосты, и юзеров. А если закрытый ключ скомпрометируют, нужно будет лишь пересоздать сертификаты для хостов или пользователей, а не оба сразу.
Вот так создается `user_ca`:
`$ ssh-keygen -t rsa -b 4096 -f user_ca -C user_ca`
Файл `user_ca` – закрытый ключ пользователя, который должен быть защищен, как и закрытый ключ хоста.
### Выдача сертификатов хостам
Создадим новый ключ и подпишем с помощью центра сертификации.
ssh_host_rsa_key-cert.pub содержит подписанный сертификат хоста.
```sh
$ ssh-keygen -f ssh_host_rsa_key -N '' -b 4096 -t rsa
$ ls -l
-rw------- 1 palpatine palpatine 3247 Mar 17 14:49 ssh_host_rsa_key
-rw-r--r-- 1 palpatine palpatine 764 Mar 17 14:49 ssh_host_rsa_key.pub
$ ssh-keygen -s host_ca -I host.example.com -h -n host.example.com -V +52w ssh_host_rsa_key.pub
Enter passphrase: # the passphrase used for the host CA
Signed host key ssh_host_rsa_key-cert.pub: id "host.example.com" serial 0 for host.example.com valid from 2020-03-16T15:00:00 to 2021-03-15T15:01:37
$ ls -l
-rw------- 1 palpatine palpatine 3247 Mar 17 14:49 ssh_host_rsa_key
-rw-r--r-- 1 palpatine palpatine 2369 Mar 17 14:50 ssh_host_rsa_key-cert.pub
-rw-r--r-- 1 palpatine palpatine 764 Mar 17 14:49 ssh_host_rsa_key.pub
```
Вот описание используемых флагов:
- **-s host_ca**: указывает имя файла закрытого CA-ключа, используемого для подписи.
- **-I host.example.com**: буквенно-цифровая строка, идентифицирующая сервер. При необходимости значение можно использовать для отзыва сертификата.
- **-h**: указывает, что сертификат выдается хосту, а не юзеру.
- **-n host.example.com**: указывает разделенный запятыми список участников, для проверки подлинности которых будет действителен сертификат.
- **-V +52w**: срок действия сертификата. В данном случае 52 недели (один год). По умолчанию сертификаты действительны вечно. Указание периода истечения срока действия сертификатов хоста настоятельно рекомендуется для ротации и замены сертификатов.
## Настройка SSH для использования сертификатов
Нужно указать серверу, чтобы он использовал новый сертификат. Скопируйте три сгенерированных файла на сервер в каталог `/etc/ssh`, установите разрешения и добавьте в файл `/etc/ssh/sshd_config` следующую строку:
`HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub`
Перезагрузите **sshd** с помощью `systemctl restart sshd`. Теперь сервер настроен на выдачу сертификата. Чтобы локальный ssh-клиент мог автоматически доверять хосту на основе удостоверения сертификата, нужно добавить открытый ключ CA в `known_hosts`. Вы можете сделать это, добавив в начало файла `host_ca.pub` следующее: `@cert-authority *.example.com`, а затем и в `~/.ssh/known_hosts`:
`@cert-authority *.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDwiOso0Q4W+KKQ4OrZZ1o1X7g3yWcmAJtySILZSwo1GXBKgurV4jmmBN5RsHetl98QiJq64e8oKX1vGR251afalWu0w/iW9jL0isZrPrmDg/p6Cb6yKnreFEaDFocDhoiIcbUiImIWcp9PJXFOK1Lu8afdeKWJA2f6cC4lnAEq4sA/Phg4xfKMQZUFG5sQ/Gj1StjIXi2RYCQBHFDzzNm0Q5uB4hUsAYNqbnaiTI/pRtuknsgl97xK9P+rQiNfBfPQhsGeyJzT6Tup/KKlxarjkMOlFX2MUMaAj/cDrBSzvSrfOwzkqyzYGHzQhST/lWQZr4OddRszGPO4W5bRQzddUG8iC7M6U4llUxrb/H5QOkVyvnx4Dw76MA97tiZItSGzRPblU4S6HMmCVpZTwva4LLmMEEIk1lW5HcbB6AWAc0dFE0KBuusgJp9MlFkt7mZkSqnim8wdQApal+E3p13d0QZSH3b6eB3cbBcbpNmYqnmBFrNSKkEpQ8OwBnFvjjdYB7AXqQqrcqHUqfwkX8B27chDn2dwyWb3AdPMg1+j3wtVrwVqO9caeeQ1310CNHIFhIRTqnp2ECFGCCy+EDSFNZM+JStQoNO5rMOvZmecbp35XH/UJ5IHOkh9wE5TBYIeFRUYoc2jHNAuP2FM4LbEagGtP8L5gSCTXNRM1EX2gQ== host_ca`
Значение `*.example.com` указывает на то, что этому сертификату следует доверять для идентификации любого хоста, к которому вы подключаетесь и который имеет домен `*.example.com`. Это разделенный запятыми список имен хостов для сертификата: **host1**, **host2**, **host3** или **1.2.3.4**, **1.2.3.5** в зависимости от обстоятельств.
Как только закончите настройку, удалите все старые записи для `host.example.com` в `~/.ssh/known_hosts` и запустите подключение. Правильность создания сертификата проверяется так:
`$ ssh -vv host.example.com 2>&1 | grep "Server host certificate" debug1: Server host certificate: ssh-rsa-cert-v01@openssh.com SHA256:dWi6L8k3Jvf7NAtyzd9LmFuEkygWR69tZC1NaZJ3iF4, serial 0 ID "host.example.com" CA ssh-rsa SHA256:8gVhYAAW9r2BWBwh7uXsx2yHSCjY5OPo/X3erqQi6jg valid from 2020-03-17T11:49:00 to 2021-03-16T11:50:21 debug2: Server host certificate hostname: host.example.com`
На этом этапе вы можете продолжить выдачу сертификатов всех хостов, используя центр сертификации. Польза от этого следующая: вам больше не нужно полагаться на небезопасную модель **Trust On First Use (TOFU)** для новых хостов, и если вы когда-нибудь повторно развернете сервер и, следовательно, измените ключ хоста, новый хост автоматически представит подписанный сертификат без ужасного предупреждения: **WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!**
## Выдача сертификатов пользователям (для аутентификации пользователей на хостах)
В этом примере мы создадим новый ключ пользователя и подпишем с помощью центра сертификации.
`$ ssh-keygen -f user-key -b 4096 -t rsa $ ls -l -rw-r--r--. 1 tatooine tatooine 737 Mar 19 16:33 user-key.pub -rw-------. 1 tatooine tatooine 3369 Mar 19 16:33 user-key $ ssh-keygen -s user_ca -I gus@gravitational.com -n ec2-user,gus -V +1d user-key.pub Enter passphrase: # the passphrase used for the user CA Signed user key user-key-cert.pub: id "gus@gravitational.com" serial 0 for ec2-user,gus valid from 2020-03-19T16:33:00 to 2020-03-20T16:34:54 $ ls -l -rw-------. 1 tatooine tatooine 3369 Mar 19 16:33 user-key -rw-r--r--. 1 tatooine tatooine 2534 Mar 19 16:34 user-key-cert.pub -rw-r--r--. 1 tatooine tatooine 737 Mar 19 16:33 user-key.pub`
`user-key-cert.pub` содержит подписанный сертификат пользователя. Для входа в систему понадобится как этот, так и приватный ключ. Вот описание используемых флагов:
- **-s user_ca**: указывает приватный ключ CA, используемый для подписи.
- **-I tatooine@proglib.io**: буквенно-цифровая строка, которая будет видна в логе SSH. Для точной идентификации пользователя рекомендуем использовать адрес электронной почты или логин.
- **-n palpatine, tatooine**: указывает разделенный запятыми список участников, для проверки подлинности которых будет действителен сертификат. В примере мы предоставляем сертификат доступа как для `palpatine`, так и для `tatooine`.
- **-V +1d**: указывает срок действия сертификата, в данном случае +1d означает 1 день.
Если нужно увидеть параметры подписи сертификата, используйте`ssh-keygen -L`:
`$ ssh-keygen -L -f user-key-cert.pub user-key-cert.pub: Type: ssh-rsa-cert-v01@openssh.com user certificate Public key: RSA-CERT SHA256:egWNu5cUZaqwm76zoyTtktac2jxKktj30Oi/ydrOqZ8 Signing CA: RSA SHA256:tltbnMalWg+skhm+VlGLd2xHiVPozyuOPl34WypdEO0 (using ssh-rsa) Key ID: "palpatine@proglib.io" Serial: 0 Valid: from 2020-03-19T16:33:00 to 2020-03-20T16:34:54 Principals: tatooine palpatine Critical Options: (none) Extensions: permit-X11-forwarding permit-agent-forwarding permit-port-forwarding permit-pty permit-user-rc`
## Настройка SSH для проверки подлинности
После того как сертификат подписан, нужно сообщить серверу, что можно доверять пользователским сертификатам. Копируем `user_ca.pub` в директорию `/etc/ssh`, поправляем права и добавляем в конфиг `/etc/ssh/sshd_config` строку:
`TrustedUserCAKeys /etc/ssh/user_ca.pub`
Как раньше, перезагружаем **sshd** с помощью `systemctl restart sshd`. Теперь сервер настроен на пропуск всех, кто представляет сертификат, выданный центром сертификации при подключении. Если сертификат хранится в том же каталоге, что и ваш приватый ключ (указанный с флагом `-i`, например `ssh -i /home/tatooine/user-key` `palpatine @proglib.io`), он будет автоматически использоваться при подключении к серверам.
## Проcмотр логов
Если вы посмотрите в журнал sshd сервера, запустив `journalctl -u sshd`, то увидите имя используемого для аутентификации сертификата, а также данные центра сертификации:
`sshd[14543]: Accepted publickey for tatooine from 1.2.3.4 port 53734 ssh2: RSA-CERT ID palpatine@proglib.io (serial 0) CA RSA SHA256:tltbnMalWg+skhm+VlGLd2xHiVPozyuOPl34WypdEO0`
Если пользователь попытается войти в систему под логином, у которого нет доступа, в логе вы увидите такую ошибку:
`sshd[14612]: error: key_cert_check_authority: invalid certificate sshd[14612]: error: Certificate invalid: name is not a listed principal`
Если срок действия сертификата истек, вы увидите следующую ошибку:
`sshd[14240]: error: key_cert_check_authority: invalid certificate sshd[14240]: error: Certificate invalid: expired`
В качестве домашнего задания напишите скрипт, который будет использовать центр сертификации для выдачи сертификатов, действительных в течение следующих двух часов. Каждое использование этого скрипта должно журналировать того, кто запросил сертификат и его почту, а потом встраивать этот email в сертификат. Это поможет в мониторинге.
Взгляните на `man ssh-keygen` для новых идей.
|