我需要执行连接到 SFTP 服务器的自动备份任务。第一阶段涉及通过连接到服务器来测试服务器连接。为了绝对确保它连接到正确的服务器,我将StrictHostKeyChecking
ssh_config 设置为 yes。
那么,当建立与 SFTP 服务器的连接时,如何编写服务器响应的脚本。伪代码如下:
If connection success
disconnect
initiate backup procedure
Else
log error
exit script
附加信息:
ForceCommand internal-sftp
我在备份服务器的 sshd_config 中使用,因此运行ssh
命令是不可能的。
答案1
大多数“SSH 文件传输协议 (SFTP) 客户端”主要/最初是为交互式使用而构建的。
这并不意味着它们缺少批处理模式选项等,但如果您正在寻找通过 SSH 协议进行基于脚本的文件传输,请查看scp
或lftp
。
lftp
(主页)是我在所有自动文件传输中使用的,它具有出色的错误处理能力和可靠的退出状态。它的设计考虑到了可靠性。
有大量选项lftp
,您可以提供ssh
您喜欢的任何选项,例如-oStrictHostKeyChecking=yes
指定要使用的特定连接程序。
例子:
MYSSHOPTIONS="-oStrictHostKeyChecking=yes"
CONNPROG="ssh -a -x ${MYSSHOPTIONS}"
cat > ${cmdfile} <<- EOF
set sftp:max-packets-in-flight 16
set sftp:connect-program ${CONNPROG}
open -u ${remoteuser},${password-unless-pubkey-setup} sftp://${remotehost}
put localfile -o remotepathname
EOF
lftp -f ${cmdfile} > ${sendlog} 2>&1
RC=$?
if test $RC -ne 0
then
failed
else
reliably OK
fi
例子有点长。它创建一个命令文件,设置一些选项并上传一个文件,另一侧localfile
可选地上传另一个文件。remotepathname
如果您不想使用,可以使用 sftp 变体lftp
:
如果您有兴趣检查 sftp 登录访问权限,您可以使用此模板作为进一步实验的起点:
#!/bin/sh - mykey=/home/localuser/.ssh/id_rsa remusr=bupuser remhost=server.destination.domain.com tmpfile=/tmp/sftptest.$$ 清理() { rm -f ${tmpfile} } 陷阱清理 0 # 这尊重来自 ~/.ssh/config 的选项(也可能是 /etc/ssh/ssh_config.d/*.conf # 如果它包含在 /etc/ssh/ssh_config 中),但以此处提供的选项为准。 sftp -i $mykey -oPubkeyAuthentication=yes -oPasswordAuthentication=no -oKbdInteractiveAuthentication=no -oStrictHostKeyChecking=yes ${remusr}@${remhost} ${tmpfile} 2>&1 目录 出口 EOF ST=$? 如果测试 $ST -ne 0 然后 echo SFTP 登录失败。 RC=${ST} 1>&2 退出$ST 菲 cat ${tmpfile} # 或者对其进行一些巧妙的 grep 操作 退出$ST
答案2
我已经编写了 Expect 和 bash 脚本来完成此操作......(尽管如上所述它可以变得更奇特)。
Bash 脚本:使用三个参数执行:用户、通行证和主机。例如./bwrap.sh ninja_user ninja_star1234 ninja.com
该脚本创建一个日志文件,稍后用于检查是否成功登录/退出。
#!/bin/bash
# log file
log="connection_test.log"
if [ -f $log ];
then
echo "Older file $log exists, removing and creating new..."
rm -rf $log
touch $log
else
echo "Creating log file"
touch $log
fi
# running expect script.
# arg 1 is user, arg 2 is pass, arg 3 is host
./one.exp $1 $2 $3 >> $log
# checking log for connections
if grep --quiet logout $log; then
echo "connection successful, proceeding to backup" >> $log
else
echo "connection failed, please check server" >> $log
exit 1
fi
现在对于期望脚本,它有 10 秒的超时,实际上我更喜欢在没有严格主机密钥的情况下工作。如果您确实想使用严格的主机密钥,请编辑相关行并添加预期的“是/否”....
#!/usr/bin/expect -f
set user [lindex $argv 0];
set password [lindex $argv 1];
set host [lindex $argv 2];
set timeout 10
# now ssh
spawn ssh $user@$host -o StrictHostKeyChecking=no
match_max 100000 # Look for passwod prompt
expect "*?assword:*"
# Send password aka $password
send -- "$password\r"
expect "*$ "
send -- "whoami\r"
expect "<user name>" # change user
send -- "exit\r"
expect eof
希望这可以帮助。
如需连接,请:在脚本sftp
中添加行,其中端口在哪里bash
$4
./one.exp $1 $2 $3 $4 >> $log
将行添加到expect
脚本:
set port [lindex $argv 3];
替换期望脚本中的
spawn ssh $user@$host -o StrictHostKeyChecking=no
和
spawn sftp $host@$user -o Port=$port StrictHostKeyChecking=no
和
expect "*$ "
和
expect "sftp>"
由于我没有SFTP服务器来测试它,所以更改是基于[这个问题]进行的:使用 shell 脚本 sftp 文件
另外,[预计主页]:http://expect.sourceforge.net/ 可能会很方便。
最后,阅读您关于直接方法的评论,可以简单地使用nc
并查看主机:端口是否已启动。为此,您可以使用:
#!/bin/bash
# log file
log="connection_test.log"
if [ -f $log ];
then
echo "Older file $log exists, removing and creating new..."
rm -rf $log
touch $log
else
echo "Creating log file"
touch $log
fi
# nc
nc_command=`nc -z -w 5 $1 $2 | tee -a $log`
if [[ $nc_command == *succeeded* ]];
then
echo "Server is listening, ready for backup" | tee -a $log
else
echo " Server seems to be offline, please check" | tee -a $log
exit 1
fi
要运行最后一个脚本,请使用:./test.sh host port
答案3
如果碰巧您的备份脚本是基于 Python 的,您可能需要查看一下检查_sftp,Checkmk 带来的所谓主动检查。它具有检查 SFTP 服务器的特定用例。由于它基于 Python 和纯 Python SSH 实现帕拉米科,你只需要Python。它包含一些 Checkmk 细节,例如密码存储和 OMD_ROOT 集成,您可能需要将其删除才能使其独立工作。但它有点复杂,包括 PUT 或 GET 文件的选项,甚至比较服务器上的时间戳,因此可能值得一试。由于它遵循Nagios 检查插件指南,您可以依靠退出代码0
来成功。
另一个基于 Python 的选项可能是织物(也是基于 Paramiko),或者使用Paramiko 的 SFTP 模块直接地。
答案4
您可以sftp
通过执行ssh
连接测试来测试连接:
if $(ssh -q [email protected] exit)
then
echo yes
fi
如果服务器不允许ssh
,您可以使用nmap
,但这不会测试密钥身份验证:
nmap myserver.bfworks.com -PN -p ssh | grep 'open'