测试SFTP登录状态的脚本?

测试SFTP登录状态的脚本?

我需要执行连接到 SFTP 服务器的自动备份任务。第一阶段涉及通过连接到服务器来测试服务器连接。为了绝对确保它连接到正确的服务器,我将StrictHostKeyCheckingssh_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 协议进行基于脚本的文件传输,请查看scplftp

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'

相关内容