上篇发出后,网友
figo
留言提到了他的实现方法,和老苏不谋而合👍
老苏给自己提了几点要求,希望能实现:
- 不需要使用
root
来运行容器,这样的话图形界面安装的OliveTin
也能正常使用; - 不需要映射
/var/run/docker.sock
也能控制容器(因为即使映射了还是需要有root
权限); - 能使用不同的身份来执行不同的命令;
解决思路
老苏打算从容器内 ssh
登录到宿主机,然后在宿主机上执行命令,这可以控制登录宿主机的用户权限,不需要用 root
或者提升权限来运行容器,也不需要映射 /var/run/docker.sock
,看起来似乎所有的问题都解决了,但其实还有一个问题,就是 ssh
命令行存在交互操作,需要输入密码,接下来要做的事:
- 先解决
ssh
命令行输入密码; - 然后从容器内
ssh
到群晖宿主机,再执行命令,包括ping
等等,这样就可以完成任何可以在命令行完成的任务;
说干就干,老苏在网上经过一番搜索找到了 sshpass
,可以实现非交互的 ssh
密码验证,需要进入容器里安装
因为需要
root
权限才能安装软件,所以不能从终端机或者portainer
进容器,需要用SSH
客户端登录到群晖,然后直接用下面的命令行即可
# 以 root 身份进入容器
docker exec -it --user root olivetin /bin/bash
# 安装 sshpass
dnf install -y sshpass
# 退出容器
exit
安装完成后,可以输入 sshpass
来检查是否安装成功
输入 exit
退出容器后,再次以普通身份进入容器,先执行一次 ssh
命令,就是前面 shell
中设定的 ssh root@192.168.0.197 'ping baidu.com -c 4'
,
# 普通身份进入容器
docker exec -it olivetin /bin/bash
# 执行一次 ssh 命令
ssh root@192.168.0.197 'ping baidu.com -c 4'
目的是记住凭证,使之不再出现交互界面
这一步很重要,不然后面执行命令会超时或者返回
exit code
代码而不是success
如果是
ssh
登录其他主机,第一次也需要做一次记住凭证的操作
一个标准的 sshpass
命令是下面这样
示例中用了
root
只是为了演示方便,你需要根据不同的任务选择登录主机的ssh
用户,即便是非要root
才能执行的命令,也可以尝试用sudo
来提升权限
sshpass -p [password] ssh -p [port] root@192.168.X.X `[command line]`
如果你用的标准端口 22
,可以不用指定,所以给原来的 shell
前面加上了 sshpass -p [passwd]
,变成了下面的样子
从实际看,网页上执行的时间比较长,比较容易超时,所以把
timeout
做了延长
- title: 登录到 ds3617xs ping 百度
shell: sshpass -p [passwd] ssh root@192.168.0.197 'ping baidu.com -c 4'
icon: "📌"
timeout: 50
现在执行终于成功了,证实了老苏的解决思路是对的
接下来可以做你任何你想要的操作了
- 下面是老苏的完整的示例,记得保存为
UTF-8
编码格式,不然中文会乱码- 你可以在示例的基础上做任意的修改,完成你需要的功能
# 侦听端口
listenAddressSingleHTTPFrontend: 0.0.0.0:1337
# 日志级别:INFO (default), WARN 和 DEBUG
logLevel: "INFO"
# 显示新版本
showNewVersions: true
# Actions (buttons) to show up on the WebUI:
actions:
# 从最简单的开始
- title: 运行echo
icon: "📝"
shell: echo "我是老苏."
# 假设主机 192.168.0.197 的 ssh 用户为 root ,密码为 123456(老苏并不建议用 root 用户)
- title: 登录到 ds3617xs ping 百度
shell: sshpass -p 123456 ssh root@192.168.0.197 'ping baidu.com -c 4'
icon: "📌"
timeout: 50
- title: docker容器操作
icon: "🖥"
shell: sshpass -p 123456 ssh root@192.168.0.197 '/usr/local/bin/docker {{ act }} {{ container }}'
timeout: 500
arguments:
- name: act
title: 动作
choices:
- value: restart
- value: stop
- value: start
- name: container
title: 容器名称
choices:
- value: portainer
- value: olivetin
- title: Ping 主机
shell: sshpass -p 123456 ssh root@192.168.0.197 'ping {{ host }} -c {{ count }}'
icon: ping
timeout: 50
arguments:
- name: host
title: 主机
type: ascii_identifier
choices:
- title: R6300V2
value: 192.168.0.1
- title: DS918(蜗牛)
value: 192.168.0.198
- title: DS918
value: 192.168.0.199
- name: count
title: 次数
type: int
default: 4
运行效果
可能遇到的问题
因为都是通过 SSH
执行命令,有可能会遇到 ssh
相关的问题,比如:
kex_exchange_identification: read: Connection reset by peer
Connection reset by 192.168.0.197 port 22
很可能是因为登录太频繁被群晖锁定了
可以考虑将 IP
添加到 允许名单
小结
OliveTin
没有身份验证,虽然 OliveTin
可以不需要以 root
身份运行,但是,以 root
身份运行非常方便,因为许多用户需要运行需要 root
权限的操作和作业。
出于安全性考虑,建议:
1、以非特权用户身份运行 OliveTin
;
2、ssh
尽量不要用 root
账号;
3、使用 sudo
规则来控制它可以做什么和不能做什么;
但这要求我们对 Linux
操作系统有一定的了解,无论如何请不要在公共服务器上使用它,局域网也不能说无所谓,只是起码不会有故意的破坏行为。
参考文档
List of common exit codes for GNU/Linux
地址:https://slg.ddnss.de/list-of-common-exit-codes-for-gnu-linux/
【随笔】ssh登录时如何直接在参数中加入登录密码 - linxiong - 博客园
地址:https://www.cnblogs.com/linxiong945/p/4226211.html
How To Install sshpass on CentOS 8 | Installati.one
地址:https://installati.one/centos/8/sshpass/
ssh登陆概率性失败,报错:kex_exchange_identification_86网络的技术博客_51CTO博客
地址:https://blog.51cto.com/86net/2452445
OliveTin - Documentation
地址:https://docs.rockylinux.org/guides/automation/olivetin/
server - bash: docker: command not found - Ask Ubuntu
地址:https://askubuntu.com/questions/1215020/bash-docker-command-not-found