SSH(安全外壳协议)为 Secure Shell 的缩写,SSH 为建立在应用层基础上的安全协议。
SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议。
利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。很多时候用户希望通过远程登录服务器来进行管理,但是Docker的很多镜像是不带SSH服务的,所以,需要我们只能自己给容器加上SSH服务。
下面介绍为 Docker镜像添加SSH服务的两种方法:
一、基于docker commit 命令创建docker commit 命令:从容器创建一个新的镜像。支持用户提交自己对制定容器的修改,并生成新的镜像。
基本语法:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS说明:
- -a :提交的镜像作者;
- -c :使用Dockerfile指令来创建镜像;
- -m :提交时的说明文字;
- -p :在commit时,将容器暂停。
示例:使用docker commit 命令为 ubuntu:18.04镜像添加SSH服务。
1、准备工作
利用 ubuntu:18.04镜像创建并启动一个容器:
[root@centos7 ~]# docker pull ubuntu:18.04
[root@centos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 c14bccfdea1c 3 days ago 63.2MB
[root@centos7 ~]# docker run -it c14bccfdea1c /bin/bash
2、更新apt缓存和配置国内软件源
检查软件源,并使用 apt-get update命令来更新软件源信息。
root@6b59e1de5111:/# apt-get update
配置为国内的仓库源,比如:163、sohu等镜像的源。这里配置为163源。
在容器内创建 /etc/apt/sources.list.d/163.list文件,并添加如下内容到文件中,最后重新执行 apt-get update 命令即可。
root@6b59e1de5111:/# apt-get install -y vim
root@6b59e1de5111:/# vim /etc/apt/sources.list.d/163.list
root@6b59e1de5111:/# cat /etc/apt/sources.list.d/163.list
deb http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse
root@6b59e1de5111:/# apt-get update
3、安装和配置SSH服务
1. 安装SSH服务
更新软件包缓存后可以安装SSH服务了。这里选择主流的 openssh-server作为服务端。
root@6b59e1de5111:/# apt-get install -y openssh-server
2. 如果需要正常启动SSH服务,则目录/var/run/sshd 必须存在。
手动创建 /var/run/sshd,然后启动SSH服务:
root@6b59e1de5111:/# mkdir -p /var/run/sshd
root@6b59e1de5111:/# /usr/sbin/sshd -D &
[1] 4477
此时使用 netstat命令查看容器的 22端口(SSH服务默认监听的端口),可见此端口已经处于监听状态:
root@6b59e1de5111:/# apt-get install net-tools
root@6b59e1de5111:/# netstat -an | grep 22
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp6 0 0 :::22 :::* LISTEN
3. 修改 SSH服务的安全登录配置,取消 pam登录限制:
pam_loginuid.so模块:
session类型,用来设置已通过认证的进程的uid,以使程序通过正常的审核(audit)。在使用sshd docker 镜像时,发现一个问题,有些启动的容器可以连接,,有些不能。原因就是当PAM的pam_loginuid.so模块配置为必需时,会导致一些内部调用失败的致命错误。所以,谨慎起见,建议把这个模块关掉(注释掉即可)。
# vim /etc/pam.d/sshd
# session required pam_loginuid.so
随便了解下PAM:
PAM(即linux可插入认证模块)是一套共享库,使本地系统管理员可以随意选择程序的认证方式。
换句话说,不用(重新编写)重新编译一个包含PAM功能的应用程序,就可以改变它使用的认证机制,这种方式下,就算升级本地认证机制,也不用修改程序。
PAM使用配置 /etc/pam.d/下的文件,来管理对程序的认证方式。SSH服务对应的权限认证的配置文件(安装好就会生成):/etc/pam.d/sshd
以上图为例:pam配置文件分为四列:
- 第一列代表模块类型
- 第二列代表控制标记
- 第三列代表模块路径
- 第四列代表模块参数
1)第一列:PAM的模块类型
Linux-PAM有四种模块类型,分别代表四种不同的任务,它们是:
- 认证管理(auth)
- 账号管理(account)
- 会话管理(session)
- 密码(password)管理
一个类型可能有多行,它们按顺序依次由PAM模块调用。
2)第二列:PAM的控制标记
PAM使用控制标记来处理和判断各个模块的返回值.(在此只说明简单的认证标记)。
3)第三列:PAM的模块路径
模块路径:即要调用模块的位置.。如果是64位系统,一般保存在/lib64/security,如: pam_unix.so,同一个模块,可以出现在不同的类型中。它在不同的类型中所执行的操作都不相同、这是由于每个模块,针对不同的模块类型,编制了不同的执行函数。
4)第四列:PAM的模块参数
模块参数:即传递给模块的参数。参数可以有多个,之间用空格分隔开,如:password required pam_unix.so nullok obscure min=4 max=8 md5。
4. 在宿主机上的 root用户家目录下,使用 ssh-keygen -t rsa 命令生产公钥和私钥文件。
一路回车即可
[root@centos7 ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:djAAcgiznrTCl4LkrFhEn7zwVPceolIfKGXwccCbLGE root@centos7.6
The key's randomart image is:
+---[RSA 2048]----+
|o.o.++B.o |
| +.=E*.* . |
|.oo.*o+o= o |
|O.o+o++o * . |
|oO.o+.. S o |
|+.o . . . |
|o |
| |
| |
+----[SHA256]-----+
[root@centos7 ~]# ls /root/.ssh/
id_rsa id_rsa.pub
5. 在容器的 root用户目录下创建 .ssh目录,并在.ssh目录下的authorized_keys文件中,然后将上面的公钥信息复制到authorized_keys文件中:
root@6b59e1de5111:/# mkdir /root/.ssh
root@6b59e1de5111:/# cat /root/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCumYp9sHZ7ziSVp1YVR9t+PmJB//hE43Am55mrDeTr16yXkalVqp6Ew5l8UivKOR1hUccdi7y8rE2PoIDmWMOWwn2RavT16OqNUVExyE406FN1m2qDEPWRA2BHwemzluEKQvB46fHZXN8l1cL8VIOqZ9Gl77dGyUPygcJFFlcTRM/KGMQRuSu80eXAkFAK+H+UpLPERY9Y1F1vKLS5jYA3MnA8J+TExT4aoZAex3NegSuZ+Cb4H0nmAMDa618YRuFfQ9Y5UQ3nX0NWO4W4PYTaTsFYFIpG0XP04iqcLd3vZue8xJnKsODBdLEC2fdtqbJ8KIeZXLosvkoOQKYDuxsb root@centos7.6
6. 在容器中 创建自动启动SSH服务的可执行文件 /run.sh。编辑内容。并添加可执行权限。最后,exit退出容器即可。
root@6b59e1de5111:/# vim /run.sh
root@6b59e1de5111:/# cat /run.sh
#! /bin/bash
/usr/sbin/sshd -D
root@6b59e1de5111:/# chmod +x /run.sh
root@6b59e1de5111:/# ll /run.sh
-rwxr-xr-x 1 root root 32 Sep 20 13:50 /run.sh*
root@6b59e1de5111:/# exit
exit
[root@centos7 ~]#
4、保存镜像
将所退出的容器用 docker commit 命令保存为一个新的 sshd:ubuntu镜像。并查看本地生成的新镜像 sshd : ubuntu。
[root@centos7 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6b59e1de5111 c14bccfdea1c "/bin/bash" 51 minutes ago Exited (0) 4 minutes ago jolly_haibt
[root@centos7 ~]# docker commit 6b59e1de5111 sshd:ubuntu
sha256:b94dd56ade966ac6b9ddb9622de684a2b166a61b7298e12e21c6abe4d8640336
[root@centos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sshd ubuntu b94dd56ade96 32 seconds ago 297MB
5、使用新镜像 sshd : ubuntu,启动容器
启动容器,并添加端口映射到容器的22端口(10022:22)。其中10022是宿主主机的端口,22是容器的SSH服务监听端口。
[root@centos7 ~]# docker run -p 10022:22 -d sshd:ubuntu /run.sh
e2770124e0e1d30afaf66810c6acfc5c7f496af116e545650ba0bfa9e7fbb36e
[root@centos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e2770124e0e1 sshd:ubuntu "/run.sh" 11 seconds ago Up 9 seconds 0.0.0.0:10022->22/tcp vibrant_poincare
6. 在宿主主机或其他主机上,可以通过SSH访问10022端口来登录进入容器。
# ssh root@ip地址 -p 10022
或 # ssh -i /root/.ssh/id_rsa root@ip地址 -p 10022
-i 的意思是指定登录使用的私钥
二、使用 Dockerfile创建(推荐使用)
1、创建上下文路径
首先,创建一个sshd_ubuntu 工作目录,并在其中,创建 Dockerfile 和 run.sh文件。
[root@centos7 ~]# mkdir sshd_ubuntu
[root@centos7 ~]# cd /root/sshd_ubuntu/
[root@centos7 sshd_ubuntu]# touch Dockerfile run.sh
2、编写 run.ah脚本和 authorized_keys文件
编写 run.sh脚本文件:
[root@centos7 sshd_ubuntu]# cat run.sh
#! /bin/bash
/usr/sbin/sshd -D
根据上面使用 ssh-keygen -t rsa 命令生产公钥和私钥文件。
我们把公钥信息复制到 authorized_keys文件(touch 命令,文件不存在时会创建)中:
[root@centos7 sshd_ubuntu]# cat /root/.ssh/id_rsa.pub > authorized_keys
[root@centos7 sshd_ubuntu]# tree
.
├── authorized_keys
├── Dockerfile
└── run.sh
3、编写 Dockerfile
/etc/apt/sources.list 是官方默认的文件,我们覆盖掉它,也可以使用 上面方式,放到另一个自定义目录中。
[root@centos7 sshd_ubuntu]# cat Dockerfile
#设置继承镜像
FROM ubuntu:18.04
LABEL author="zhonghao"
#下面开始运行命令,此处更改ubuntu的源为国内163的源
RUN echo "deb http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse" > /etc/apt/sources.list
RUN echo "deb http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse" >> /etc/apt/sources.list
RUN echo "deb http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse" >> /etc/apt/sources.list
RUN echo "deb http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse" >> /etc/apt/sources.list
RUN echo "deb http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse" >> /etc/apt/sources.list
RUN apt-get update
#安装ssh服务
RUN apt-get install -y openssh-server
RUN mkdir -p /var/run/sshd
RUN mkdir -p /root/.ssh
#取消pam限制
RUN sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd
#复制配置文件到相应位置,并赋予脚本可执行权限
COPY authorized_keys /root/.ssh/authorized_keys
COPY run.sh /run.sh
RUN chmod 755 /run.sh
#开放端口
EXPOSE 22
#设置自启动命令
CMD ["/run.sh"]
4、构建镜像
[root@centos7 sshd_ubuntu]# docker build -t sshd2:ubuntu .
[root@centos7 sshd_ubuntu]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sshd2 ubuntu 1f075a2c9f56 23 seconds ago 208MB
5、使用新镜像 sshd2:ubuntu,启动容器
[root@centos7 sshd_ubuntu]# docker run -p 10033:22 -d sshd2:ubuntu /run.sh
4be1aac5e4e4a1eeb971de9d33d746e15252898194aa74937ed6cff2eb394708
[root@centos7 sshd_ubuntu]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4be1aac5e4e4 sshd2:ubuntu "/run.sh" 29 seconds ago Up 28 seconds 0.0.0.0:10033->22/tcp relaxed_kilby
6. 在宿主主机或其他主机上,可以通过SSH访问10022端口来登录进入容器。
参考文章:https://www.cnblogs.com/jie-fang/p/7928406.html
—— Stay Hungry. Stay Foolish. 求知若饥,虚心若愚。