ssh跨服务器免密传输----使用spawn scp

本文详细介绍了如何使用spawnscp和expect工具在Linux服务器之间自动进行SSH跨服务文件传输,包括安装tcl和expect、设置环境变量、编写shell脚本以及处理密码输入过程。

跨服务传输文件需要手动输入密码很麻烦,在使用定时任务时更头痛。下面介绍下使用spawn scp进行ssh跨服务器传输。

准备工作:需要安装tcl8.6.12-src.tar.gz、expect5.45.4.tar.gz两个包

例如:从A服务器向B服务器传文件,两个安装包安装在A服务器即可。

1、tcl命令安装

下载tcl安装包:https://sourceforge.net/projects/tcl/files/Tcl/8.6.12/tcl8.6.12-src.tar.gz/download
 
tar -zxf tcl8.6.12-src.tar.gz
cd tcl8.6.12/unix/
./configure --prefix=/usr/tcl --enable-shared
make
make install
 
# 目录tcl8.6.12/unix/下的tclUnixPort.h复制到generic中
cp tclUnixPort.h ../generic/

2、安装expect

# 下载expect地址:https://jaist.dl.sourceforge.net/project/expect/Expect/5.45.4/expect5.45.4.tar.gz
 
tar -zxf expect5.45.4.tar.gz
cd expect5.45.4


# 配置expect的安装路径,--with-tcl为告诉configure脚本tcl解释器位置,--with-tclinclude为告诉脚本tcl头文件位置(此处需要根据系统架构指定架构
./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=../tcl8.6.12/generic

./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=../tcl8.6.12/generic --build=arm-linux  (指定arm, 系统是arm的)    

make
make install
ln -s /usr/tcl/bin/expect /usr/expect/bin/expect

3、写入环境变量

vi /etc/profile
# 写入下面内容内容
export PATH=$PATH:/usr/expect/bin/
 
# 更新配置文件
source  /etc/profile

4、验证

输入expect回车,看是否进入形如expect1.1>这样的命令行。

5.shell脚本

1.centos使用的

#!/usr/expect/bin/expect

#设置连接时长
#set timeout 10    

#将本机/data/upload/下的A,B,C 传输到B服务器的/data/uploaad目录下,不加{A,B,C} ,是将/data/upload/目录下所以文件传到B服务器
spawn scp -p -r  /data/upload/{A,B,C}  root@B服务IP:/data/uploaad
expect "*password:"

#设置B服务器访问密码
send "B服务器访问密码\r"
expect "100%"  
expect eof  

2.ubuntu系统使用

#!/usr/expect/bin/expect
#set timeout 10  
spawn scp -p -r /data/maildata root@B服务IP:/data/uploaad
expect "*password:"
send "B服务器访问密码\r"
expect "100%"  
expect eof  

<think> 首先,用户的问题是关于如何使用shell脚本实现通过SSH无密钥登录服务器的方法。用户提供了多个引用内容,我需要参考这些引用来构建回答。 引用[1]讨论了三种方法: 1. 使用远程登录工具。 2. 建立主机间的SSH信任依赖关系。 3. 用脚本模拟SCP命令的密码输入过程。 引用[2]展示了使用expect来实现SSH密钥文件的批量传输以实现免密登录。 引用[3]提到了第三种方法:将密码写入shell文件并使用sshpass工具进行免密登录,但强调这不安全。 用户明确要求了“无密钥登录”,但从上下文看,用户可能指的是免密登录,包括使用密钥对的方法。在SSH语境中,“无密钥登录”通常指的是使用公钥-私钥对进行认证,而不是输入密码。用户说“ssh无密钥登陆”,所以我应该专注于基于密钥的免密登录方法。 用户的需求是:使用shell脚本实现SSH无密钥登录服务器。 关键点: - SSH无密钥登录通常涉及生成SSH密钥对(公钥和私钥),并将公钥复制到远程服务器上的authorized_keys文件中。 - 在脚本中自动化这个过程,避免手动输入密码。 引用[2]提供了一个批量实现免密登录的脚本,使用了expect工具来处理交互式提示。 所以,我应该基于这个方法构建回答: 1. 生成SSH密钥对。 2. 使用ssh-copy-id或类似工具复制公钥到远程服务器。 3. 使用expect或sshpass来自动化输入密码过程。 但引用[3]提到sshpass方法不安全,因为密码存储在脚本中。所以,我应该推荐更安全的方法:使用密钥对和expect。 回答结构: - 系统级指令要求: - 所有行内数学表达式用$...$(但这个问题不涉及数学,所以可能不需要)。 - 独立公式用$$...$$(同样,可能不需要)。 - LaTeX语法正确(不适用)。 - 用中文回答。 - 生成相关问题(在结尾)。 - 回答中引用的段落末尾添加引用标识。 用户可见层要求: - 回答结构清晰,逐步解决问题。 - 尽量真实可靠。 最终回答结构: 1. 解释基本概念:SSH无密钥登录的原理。 2. 提供shell脚本方法。 - 基于expect的方法(来自引用[2])。 - 可选:提及sshpass方法,但警告其不安全性。 3. 确保脚本安全可靠。 4. 添加引用标识。 5. 生成相关问题。 生成相关问题: - 根据主题,如如何批量处理、如何加强安全等。 脚本示例: 从引用[2]中提取: ```bash #!/bin/bash rm -rf ~/.ssh/{known_hosts,id_rsa*} ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa yum -y install expect tcl expect << EOF spawn ssh-copy-id 192.168.163.70 expect "(yes/no)?" {send "yes\r"} expect "password:" {send "docker\r"} expect "#" {send "exit\r"} EOF ``` 对于批量版本: ```bash #!/bin/bash rm -rf ~/.ssh/{known_hosts,id_rsa*} ssh-keygen -t rsa -N '' <<EOF /root/.ssh/id_rsa yes EOF yum -y install expect tcl for i in {21..59} do expect << EOF spawn ssh-copy-id 192.168.163.$i expect "(yes/no)?" {send "yes\r"} expect "password:" {send "123456\r"} # 使用实际密码 expect "#" {send "exit\r"} EOF done ``` 安全考虑: - 在脚本中硬编码密码不安全。建议提示用户输入或在安全环境中使用- 替代方案:使用SSH代理或配置密钥时使用空密码,但需谨慎。 回答步骤: 1. 介绍SSH免密登录原理:使用公钥认证。 2. 提供脚本示例。 3. 解释脚本步骤。 4. 添加警告和安全建议。 5. 结尾生成相关问题。 相关问题: 1. 如何批量配置多台服务器SSH免密登录? 2. SSH公钥认证的安全性如何加强? 3. 除了expect,还有其他方法实现自动化SSH登录吗? 确保中文回答。 </think> ### 使用Shell脚本实现SSH无密钥登录服务器的方法 SSH无密钥登录的本质是通过公钥认证(Public Key Authentication)实现免密访问,原理是将本地生成的公钥添加到远程服务器的`~/.ssh/authorized_keys`文件中[^1][^2]。以下是基于Shell脚本的自动化实现方法,采用安全可靠的`expect`工具处理交互提示(避免密码硬编码风险)。 #### 方法:使用expect工具自动化密钥分发 此方法通过脚本生成SSH密钥对,并自动将公钥复制到目标服务器。脚本分为两步:生成密钥和分发密钥。 **完整脚本示例:** ```bash #!/bin/bash # 步骤1: 清理旧密钥并生成新密钥对 rm -rf ~/.ssh/{known_hosts,id_rsa*,authorized_keys} # 移除残留文件 ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa -q # 生成RSA密钥对,空密码 # 步骤2: 安装expect工具(如果未安装) if ! command -v expect &> /dev/null; then sudo yum install -y expect tcl || sudo apt-get install -y expect # 支持CentOS/Ubuntu fi # 步骤3: 定义目标服务器信息(示例IP和密码) REMOTE_IP="192.168.1.100" # 替换为远程服务器IP REMOTE_USER="root" # 替换为远程用户名 REMOTE_PASSWORD="your_password" # 替换为远程用户密码 # 步骤4: 使用expect自动复制公钥 expect << EOF spawn ssh-copy-id -i ~/.ssh/id_rsa.pub ${REMOTE_USER}@${REMOTE_IP} expect { "(yes/no)?" {send "yes\r"; exp_continue} # 处理首次连接确认 "password:" {send "${REMOTE_PASSWORD}\r"} # 发送密码 } expect eof # 等待命令结束 EOF echo "SSH无密钥登录配置完成!尝试测试连接:ssh ${REMOTE_USER}@${REMOTE_IP}" ``` #### 脚本说明和安全建议: 1. **关键步骤解析**: - `ssh-keygen`:生成RSA密钥对(`-N ""`表示私钥无密码)。 - `ssh-copy-id`:将公钥复制到远程服务器的`authorized_keys`文件。 - `expect`:自动化交互流程,响应`(yes/no)?`和`password:`提示。 2. **安全注意事项**: - **避免密码硬编码**:示例中密码直接写在脚本中存在安全风险。实际使用时,应通过环境变量或交互式输入获取: ```bash read -s -p "输入远程服务器密码:" REMOTE_PASSWORD # 安全读取密码 ``` - **批量处理**:需为多台服务器配置时,使用循环(如`for ip in 192.168.1.{100..105}`)扩展脚本[^2]。 - **权限设置**:确保远程服务器的`~/.ssh`目录权限为700,`authorized_keys`文件权限为600。 3. **备选方案警告**: - `sshpass`工具(如引用[^3])虽能简化流程,但因密码暴露在脚本中,**不推荐用于生产环境**,仅限测试使用: ```bash sshpass -p "password" ssh-copy-id user@host # 高风险方法 ``` 此方法建立了本地主机对远程服务器的单向信任,后续SSH连接无需输入密码[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值