Skip to content

Commit aa13dd0

Browse files
committed
Update note
1 parent 46f2d2e commit aa13dd0

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed
+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Docker容器间SSH公钥自动交换实现免密登录的一次尝试
2+
3+
## 咋想到这茬了
4+
5+
最近开始忙毕设的事儿了,想部署个伪分布式的Spark + Hadoop集群来进行测试。思来考去,最终咱把目光放在了Docker上。
6+
7+
盘了两天,发现这玩意意外的有趣,镜像构建好后开箱即用,省去了些配置环境的成本。
8+
9+
不过呢,在配置Hadoop的时候我发现了一个问题——Hadoop分布式搭建要求各节点间能通过SSH执行指令(比如启动时就需要在其他节点上执行指令以启动相应守护进程),即需要配置免密登录(Passphraseless),怎么在尽量保证安全的情况下尽快让容器之间交换SSH公钥以信任对方呢?
10+
11+
<img src="https://raw.githubusercontent.com/cat-note/bottleassets/main/img/learntbefore-2024-01-25.jpeg" width="150px"/>
12+
13+
首先咱当然是去Github找了个Hadoop容器化部署项目的Dockerfile看了看,发现有一种方案是在构建镜像的时候就建立SSH密钥对,然后把公钥加入到自己`authorized_keys`文件中。
14+
15+
```dockerfile
16+
# Dockerfile中
17+
RUN ssh-keygen -t rsa -f ~/.ssh/id_rsa &&
18+
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys &&
19+
chmod 600 ~/.ssh/authorized_keys
20+
```
21+
22+
理论上说,用这个镜像建立的容器之间就可以实现免密登录了(毕竟每台机器上`authorized_keys`中都有相同的公钥)。
23+
24+
然鹅,我在本机WSL上装的docker中测试时发现这种方式怎么也行不通...盘了大半天,文件权限和SSH配置改来改去,SSH服务硬是没给我个好脸色,每次登录多少得报个`Permission denied`,查了很久也没解决这问题。
25+
26+
于是我索性想了另一套方案来解决各容器间交换SSH公钥的问题。
27+
28+
![losingMemories-2024-01-25](https://raw.githubusercontent.com/cat-note/bottleassets/main/img/losingMemories-2024-01-25.jpg)
29+
30+
****:这篇文章写到这,我恍然大悟,发现自己犯了个很蠢的错误 ↓ 展开查看
31+
32+
<details>
33+
34+
<summary>展开查看</summary>
35+
36+
--------
37+
38+
我在生成密钥对的时候不知是脑袋哪里缺根筋,偏偏就改了密钥对的默认文件名,当时在Dockerfile里是这样写的:
39+
40+
```dockerfile
41+
RUN ssh-keygen -t rsa -f /root/.ssh/rsa_pair -N '' \
42+
&& cat /root/.ssh/rsa_pair.pub >> /root/.ssh/authorized_keys
43+
```
44+
45+
这样一来`/root/.ssh`目录下会生成`rsa_pair`(密钥)和`res_pair.pub`(公钥)。
46+
47+
这里简述一下SSH密钥对认证的过程:
48+
49+
1. 客户端发送**连接请求**给服务端;
50+
2. 服务端用**客户端的公钥**对一串随机数据`data`进行加密生成`challenge`,返回给客户端;
51+
3. 客户端用**客户端的私钥**`challenge`进行解密,得到`data`,然后利用哈希算法`HASH`计算`data`的摘要,将摘要用**客户端的私钥**签名为`signature`后,再发给服务端。
52+
4. 服务端收到数字签名`signature`后用**客户端的公钥**解密,得到摘要。此时服务端用相同的哈希算法计算出第2步中原数据`data`的摘要,然后比较摘要是否一致。
53+
5. 如果摘要一致,签名成功验证,认证成功。
54+
55+
我测试的时候用的是`ssh root@主机名`,而这个命令默认会扫描`id_`开头的密钥文件,而我此时的密钥对文件名是`rsa_pair`,程序自然就找不到对应的密钥对了,也就无法正常进行认证。
56+
57+
其实这种情况下手动指定密钥文件路径就OK啦,`ssh``ssh-copy-id`命令都能接受参数`-i`,指定密钥文件路径:
58+
59+
```bash
60+
ssh -i /root/.ssh/rsa_pair root@HOST
61+
```
62+
63+
我这小脑袋瓜儿当时硬是没想到这点,所以说有的时候小错误往往可能浪费更多时间哇!╰(‵□′)╯
64+
65+
吃一堑长一智!
66+
67+
------
68+
69+
</details>
70+
71+
## 利用Bash脚本实现SSH公钥自动交换
72+
73+
### Dockerfile
74+
75+
76+
77+
78+
79+

0 commit comments

Comments
 (0)