尊敬的读者们,大家好!SFTP是一种基于SSH的加密文件传输协议,可确保您的数据在传输过程中得到保护,是一种可信赖的文件传输解决方案。在实际生产环境中,连接第三方SFTP服务器是许多企业进行文件传输的常见需求。然而,有时候当第三方SFTP服务器切换节点后,我们的服务连接却会出现失败的情况。我们今天就遇到了这种情况,第三方服务因国产化需求切换到了新的节点,导致我们的服务连接sftp服务器失败。在本文中,我将与您分享这个问题的原因以及解决方法以及如何使用Docker Compose快速部署SFTP(Secure File Transfer Protocol)服务,帮助您轻松应对类似的挑战。
问题现象
首先,让我们来了解一下这个问题的现象。当第三方SFTP服务器切换到新的节点后,您的服务尝试连接该服务器可能会遇到连接失败的情况。这种问题通常表现为无法建立SFTP连接,错误信息可能包括"Connection refused"、"Host key verification failed"或"Permission denied"等。我们的报错信息如下:
2023-07-19 10:30:52,166 [queueListenerContainer-13] ERROR [cn.xj.common.ftp.FtpUtils] - 链接FTP异常 connection is closed by foreign host
com.jcraft.jsch.JSchException: connection is closed by foreign host
at com.jcraft.jsch.Session.connect(Session.java:269)
at com.jcraft.jsch.Session.connect(Session.java:183)
at cn.leadeon.common.ftp.FtpUtils.getConnect(FtpUtils.java:64)
at cn.leadeon.activemq.MessageReceiverListener.downJsonFile(MessageReceiverListener.java:152)
at cn.leadeon.activemq.MessageReceiverListener.onMessage(MessageReceiverListener.java:128)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:744)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:682)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:649)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:317)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:255)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1167)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1159)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1056)
at java.lang.Thread.run(Thread.java:745)
问题原因
SFTP连接失败的主要原因是与新节点相关的SSH密钥变化。每个SFTP服务器都有其独特的SSH密钥对(公钥和私钥),用于加密通信和身份验证。当SFTP服务器切换到新的节点时,其密钥对可能会发生变化,导致我们之前保存的旧密钥无法通过新节点进行验证,从而引起连接失败。
解决方法
我们手动在服务器是上连接第三方sftp,并重新生成秘钥
sftp服务部署(docker-compose)
确保我们的服务器已经安装了docker及docker-compose。
在您选择的目录下创建一个新文件,并将其命名为 docker-compose.yml。在该文件中,我们将定义 sftp 服务的配置。
docker-compose.yml
version: '3.3'
services:
sftp-server:
image: atmoz/sftp:latest
container_name: sftp-server
restart: always
ports:
# 将主机的端口2222映射到容器的端口22(SFTP默认端口)
- "2222:22"
volumes:
- ./data:/home
command: admin:admin:1100
启动服务
dockerr-compose up -d
终端连接sftp,首次连接需要生成生成密钥
sftp -P2222 admin@192.168.10.106
上传文件
put /home/xiuji/a.png
若出现权限问题,则修改挂载用户目录的权限
sudo chmod -R 777 admin
创建文件夹、上传、下载文件
mkdir test
cd test
put /home/xiuji/a.png
get a.png
结语
通过使用Docker Compose快速部署SFTP服务,我们成功创建了一个安全、高效的文件传输环境。SFTP不仅保护了您的数据安全,而且在搭建和管理过程中也非常便捷。希望本文对您在实现安全文件传输方面有所帮助。