SFTP 知识合集

Posted huang6450

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SFTP 知识合集相关的知识,希望对你有一定的参考价值。

SFTP协议的工作原理

AS2(Applicability Statement 2)协议是一种应用广泛的企业间B2B通信协议,它被设计用来安全的交换EDI信息,以使交易的双方确保信息交换可靠、安全的完成。AS2协议是基于HTTP/S来进行数据交换。通过使用加密和数据签名传输将数据封装为S/MIME(安全多用途互联网邮件扩展协议)的数据,并且使用MDM(消息处理通知)确保数据在网络上能够安全可靠地传输。下面为AS2通信信息传递的流程图:
技术图片

AS2通信流程图(图片来源:http://www.edinet.cn/EDITransmission/WhatIsAS2.html

这东西看起来很高端,也很安全,并且通过HTTP/S来传输数据,这个很符合我们的口味。但是,它维护的成本非常高,防火墙设置,AS2配置定期维护变更,传输文件名称长度限制在45bytes以内等等,这一系列配置与限制,不得不让我对这一复杂的协议望而却步。并且银行建议我们去购买成熟的AS2商业套件来与他们对接。这条路径还仅仅只是为上传付款文件到银行而铺设,我们要获取付款确认文件和MT940对账单还是需要通过FTP之类的方式传递给我们。那么,通过这个方案进行直连就太不划算了。

既然AS2不划算,那我们自然就会询问银行是否还有其它的直连方案。银行便给我们SFTP和FTPS这两种方案供我们选择。后来,在聊天的过程中,了解到用户选择这三种方案进行直连的一个比例:其中,AS2大概是100多个,SFTP有几千个,FTPS相对于SFTP少一点。

最终我们选择使用了SFTP的方式进行直连。

在谈我们如何通过SFTP方式与银行进行直连之前,我想先带大家理清一下FTP, FTPS以及SFTP这几个协议的工作原理以及它们的联系和区别。

FTP协议

大家应该都知道FTP是一个非常古老的文件传输协议。那大家清晰的知道FTP进行文件传输的细节吗?大家又清晰的知道FTP除了传输上的安全性问题外,在它这样的工作模式下又会出现怎样的网络限制呢?如果大家都非常清楚的话,就可以直接跳过这一节。^_^

首先从FTP协议所使用的端口说起,FTP服务器端会使用到如下两个端口:

命令通道(默认为port 21)

数据传输通道(默认为port 20)

FTP的连接又分为两种模式:

主动模式(Active)

被动模式(PASV)

下面就先以FTP默认的主动式(Active)连接来看一下FTP的两个端口是如果配合使用的。FTP服务器的主动式连接如下面所示:
技术图片

FTP服务器主动连接模式(图片来源:鸟哥的LINUX私房菜-服务器架构篇)

从图中我们可以看到,FTP客户端在经过TCP三次握手后与FTP服务端建立起命令通道连接。命令通道连接建立后,客户端每次发起命令(如:ls,get,put)都是利用这个通道来执行。但是,当牵涉到数据流的传输时,就不一样了。在主动连接模式下,客户端会随机启动一个高位端口(如下面Port BB,端口号大于1024),并通过之前所建立的命令通道,将连接方式(Activ)以及客户端所启用的端口(Port BB)告知给FTP服务端,并等待服务端的连接。FTP服务端此时就会主动的由Port 20向客户端的Port BB发起连接,建立数据传输通道。

大家应该会注意到两个连接(命令通道,数据传输通道)的发起端是不一样的。命令通道连接是由客户端发起,而数据传输通道连接是由服务器发起。

这样看来这个协议似乎很正常,没什么毛病,只是有点绕,毕竟是很老的协议了嘛,可以理解。但是,如果客户端躲在防火墙或NAT服务器后端呢?会不会有什么不一样呢?

下图是一个客户端在防火墙后端的一个模拟场景:
技术图片

FTP客户端经防火墙主动式访问FTP服务器(图片来源:鸟哥的LINUX私房菜-服务器架构篇)

由于NAT会主动记录由内部发往外部的连接信息,而命令通道的建立又是由客户端发起,所以命令通道这条连接就可以顺利的建立起来。同样,当有数据进行传输时,客户端也会将随机启动的端口Port BB以及模式Activ告知给FTP服务器,并等待服务器端的主动连接。

那么,问题来了!Port BB端口是客户端启起来的,并没有任何指令告知NAT需要启动一个Port BB来监听FTP服务端的连接,也就自然不会把来自服务端的连接转给客户端。这就是为什么明明连上的服务器,但却始终获取不到文件名列表,并超过一段时间显示“Can‘t build data connection: Connection refused”的信息了。

那客户端躲在防火墙的背后连FTP服务器是不是就不行了呢?当然不是!有个很简单的方法,使用iptables所提供的FTP检测模块就可以解决上面的问题。使用modprode来加载ip_conntrack_ftp和ip_nat_ftp等模块,这几个模块会主动分析目地端口是21的连接信息,就可以得到Port BB端口相关信息。这样一来,当接收到FTP服务器的主动连接时,就会把数据正确的导向后端FTP客户端。但是,这个功能仅限FTP服务器标准端口21,如果服务器端提供的FTP控制端口非21端口,那么这两个模块就不起作用了。很不幸,银行提供的就不是标准端口!

除了设置iptables来避免防火墙所带来的问题外,还有一种方法可以规避这种问题,那就是FTP连接的另外一种模式:被动模式。
技术图片

下图为FTP的被动式连接流程:

FTP服务器被动连接模式(图片来源:鸟哥的LINUX私房菜-服务器架构篇)

从上面可以看到FTP被动模式在命令通道连接的建立上与主动模式一样。不同点就在于,当需要创建数据传输通道连接时,不再是由客户端随机启动一个高位端口,并等待服务端的连接。而仅仅只是发送一个连接模式PASV到FTP服务端,当服务端收到PASV后,会随机启动一个高位端口Port PASV,并将启动的这个端口告知客户端。最后,客户端会主动发起对FTP服务端Port PASV端口的连接。

由于被动式FTP数据通道的连接是由客户端向服务端发起,这样就避免了因服务器主动发起连接而带来的客户端防火墙无法识别客户端所启用的端口连接问题。

这样一来,我们出于安全考虑在FTP客户端的前端构建一道防火墙,防火墙后端的FTP客户端开启被动连接模式,就可以完美的解决了我们的FTP调用问题了!

等等,还没完~要是FTP服务器的前端也有个防火墙呢??? ^_^ 单纯的被动模式对于FTP服务端来说是没那么简单了。

这个问题就不在这阐述了。因为搭接一个FTP的风险非常高,当初我们提出要搭建一个FTP/SFTP对外网公开时,直接被安平给拒绝了,所以FTP/SFTP服务端搭建就不在此讨论了。直接进入下一节~

FTPS协议

终于把FTP数据传输的工作原理说完了,这也就省去了很大的篇幅来讲FTPS的工作原理。也就是说,想了解FTPS的数据传输原理请参考FTP,他们的数据传输逻辑一样。^_^

FTPS相对FTP而言,唯一重要的改变就在于数据传输的安全方面,在数据传输过程中,FTPS利用SSL对数据进行加密。关于FTPS所涉及到的隐式SSL和显式SSL的区别就不在此展开讲述了。

好了,FTPS就结束了~接下来就是我们所选择的对接方案:SFTP。

SFTP协议

可能很多同学在没有深扒FTP和SFTP的时候,都会简单地从字面上来认为FTP与SFTP原理差不多,就是SFTP在传输上安全些,它们客户端的调用方式也是差不了多少。在这里,先给大家一个明确的态度:

FTP与SFTP的关系就像JAVA与javascript、雷锋与雷峰塔、卡巴斯基与巴基斯坦,虽然名字比较相似,但本质上没有半毛钱关系;

不要将已知的FTP数据传输逻辑往SFTP上套,这样会让你想得太多;

不要因为SFTP部署调用上简单,来推断出FTP协议同样也很简单,这样会导致你考虑得太少;

大家在网上稍微查一下,都会给大家一个结果“SFTP是基于SSH的一个安全文件传输协议”。其实,这个表述不怎么准确,为什么呢?原因在于SSH是有两个互不兼容的版本:SSH1和SSH2。而准确的说,SFTP是基于SSH2。如果有同学还想理清一下SSH与文件传输(SCP,SFTP)的关系,请参考 https://nnc3.com/mags/Networking2/ssh/ch03_08.htm。

并不像FTP是基于文本的传输,SFTP是基于数据包的传输,SFTP会将一些文本指令转化为二进制指令来进行传输。从长远来看,SFTP相对于FTP在这方面也或多或少的减少了数据的传输。

另外,SFTP也不像FTP那样需要构建两个连接来进行数据传输。在SFTP中仅仅只是通过一条主控制连接来完成文件的传输,不需要还为数据的传输另外开辟一条独立的数据连接,一个端口就可以搞定。这样就省去了考虑很多防火墙在网络中所带来的限制问题。

还有就是通过SFTP进行文件传输时,能传递更多的文件属性,比如文件权限,时间,大小等等。这些在FTP中是做不到的。

哦,差点忘说了一点,SFTP的默认标准端口是22,这也是跟FTP有区别的一点。

SFTP-中间人攻击

铺垫了这么久,终于到了我想说的重点了!^_^ 如果我们在内网或专线玩的话,这个就不用太在意。但要是在公网,并且传输的还是非常敏感的数据的话。。。嘿嘿~

我们先来看看SFTP是如何构建一套安全的文件传输机制的。

看过之前的“OpenPGP的那点事儿”应该对接下来的这个原理不会陌生。SFTP同样是利用对称key与非对称key相结合的方式来进行数据交换,其数据交换步骤如下:

客户端对SFTP服务器发起连接;

服务器将public key发送给客户端;

客户端接收到服务端发过来的public key后,生成一个session key;

客户端通过public key对session key进行非对称式加密;

客户端将加密后的session key发送给服务端;

服务端收到加密后的session key后,用private key对加密的session key进行解密,得到原本的session key;

客户端通过session key对要传输的文件进行对称式加密,然后发送给服务端;

服务端收到加密的文件后,使用之前解密出来的session key对加密文件进行解密,最终得到原文件;

好像一切都来得那么自然,没什么毛病。为了不让session key晃大家眼睛,我再简化一下。大家应该都知道,在利用SFTP进行数据交换之前,你首先得登录上SFTP服务器吧。我们现在来看看用密码登录SFTP的过程:

客户端向服务端发起登录请求;

服务端收到登录请求后,将其public key发送给客户端;

客户端收到public key后,通过public key对登录密码进行非对称加密,发送给服务端;

服务端收到加密后的登录密码后,使用private key进行解密。如果解密后的密码正确的话,就同意用户登录;

好了,这样是不是就简洁多了。^_^ 毫无疑问,现阶段这整个过程是安全的,但是如果客户端收到的public key不是真实的服务端发过来的呢?

攻击者在客户端与真实的服务端之间截获了用户的登录请求,然后伪造一个自己的public key发送给用户,但用户并没有察觉到它现在所收到的public key是伪造的,接着用户便用这个伪造的public key对密码进行正常的加密并发送出去,那么这个加密的密码就会被攻击者轻松地通过伪造的public key所对应的private key解密。这样一来,攻击者就顺利的获取到了SFTP登录密码了。

SFTP并不像HTTPS一样,SFTP协议的公钥是没有证书中心公证的,也就是说这些公钥都是自己签发的。对,都是自己签发的!同样的道理,我们在实施https时,如果使用的是自己签发的证书,并且还只是单向认证的话,那么就要警惕了。会出现和上面一样的中间人攻击的遭遇。

那么作为SFTP的客户端该如何应对呢?其实很简单,但这事必须谨慎!当我们在第一次连接SFTP服务端时,会显示给我们一个“公钥指纹”,让我们选择是否继续。如下面所示:
技术图片

那这个“公钥指纹”又是怎么来的呢?由于公钥长度比较长,一般都会达到1024位,这样就很难去判断这个公钥是否是真实SFTP服务端的公钥,所以就对其进行MD5计算,将其变成一个128位的指纹。这样比较起来就方便多了!

等等,SFTP登录的时候不就显示了一个“公钥指纹”吗?哪里还有什么第二个公钥指纹与这个比较?额...正常的流程是合作方在将SFTP服务端地址告知你的同时,也需要将SFTP服务端的公钥指纹告知你!

对比公钥指纹没有问题后,即可同意进入下一步连接。这样就会在./ssh目录下的known_hosts文件中生成一条我们刚刚同意的公钥记录。只有在known_hosts里面的公钥,我们才能去访问。这样就规避了不认识的host我们也去连接,从而避免遭受中间人的攻击。

SFTP Client JAVA 实现

JSch,一个SSH2的纯JAVA的实现!通过这个jar,我们可以实现SFTP服务端的连接。这个jar包的使用就比Bouncycastle中的OpenPGP好用得多了,也就不再给大家上代码链接了(是不是找到了一个很好的不用上代码的借口 ^_^)。在网上也可以找到很多可用的样例代码(仅仅只是可以work,至于靠不靠谱我下面会说)。

在使用JSch进行开发过程中,我们需要注意如下几点:

JCE扩展包;在之前的文章中提到过,jdk对加密key的长度限制,需要下载与jdk对应的jce版本,替换jdk原装目录security下的local_policy.jar和US_export_policy.jar。

Bouncycastle包引入;又一次与BC相见是不是有种很熟悉的感觉^_^。在使用Jsch时,需要通过Bouncycastle来对jdk的安全策略进行扩展。这个步骤稍微复杂点,需要做两件事:

将bcprov-jdk15on-1.54.jar放入$JAVA_HOME/jre/lib/ext中;

在java.security文件中添加一条security.provider记录,将BouncyCastleProvider加进去;

known_hosts文件设置;设置known_hosts的必要性已在之前阐述了,但网上的很多样例代码中都会把StrictHostKeyChecking设置为no,这样就会导致程序不再校验host key的合法性了。这点大家千万别忽视了!开启StrictHostKeyChecking后,可将之前登录在./ssh/known_hosts中生成的连接记录copy出来,放入项目文件中的某个配置文件中,然后在程序中指定加载这个配置文件即可。

SftpProgressMonitor使用;在使用JSch进行文件上传和下载时,建议大家加入Monitor的使用,通过Monitor来监控文件上传下载的情况。

以上就是大家使用JSch进行开发时所要注意的几个重要点。

SFTP Client 部署

SFTP Client开发完了后,就要考虑把程序部署到正式环境了。那是不是直接把程序丢到一个可以直接访问外网的机器上呢(SFPT服务端通过公网访问)?

在回答这个问题之前,先问这样一个问题:程序在调用SFTP服务端时是要读取密码的,那么这个密码是怎么初始化到程序的运行时内存里面的呢?是程序在初始化时读取配置文件中的配置还是怎样?

有同学会说,我就是把密码明文写在配置文件里面怎么了嘛,我又不是把端口开放出去让别人来调我的接口,我只是去SFTP服务拉文件或者把文件推到SFTP服务端,再说了,我把防火墙也开启了,这样应该就够安全了吧!

的确,这样已经是够安全了。但小心驶得万年船,你就这么确定你所使用的这个机器永远只会跑你这样一个小小的Client端服务?在未来不会跑其它某些对外的服务?你就这么确定你这个机器上跑的所有服务都是没有bug,不会给坏人留下任何机会?只要是有外网IP的机器,就会有机率被人入侵。一旦入侵,你的程序还有配置信息就有可能不保!

所以,我们把SFTP Client程序直接丢到有外网IP的机器上是一种不可取的方式。那这个要怎么部署才更加安全呢?推荐方案如下:

改造SFTP Client程序,使用Jsch通过HTTP Proxy创建连接,以及数据交换;

将改造好的程序发布在一个无外网IP的机器上(可以通过内网来访问具有外网IP的机器),同时开启相应的防火墙策略。

在具有外网IP的机器上安装squid作为外网出口代理,严控squid策略配置,同时开启相应的防火枪策略。

非明文保存密码等重要信息。这里有两个办法:一个是在程序启动之初,在shell中设置一个临时环境变量,程序在这个shell中进行启动,程序启动的逻辑是读取设置在环境变量中的参数来初始化密码,这样在关闭这个shell后,即使别人进入这台机器以后也找不到当初是设置的什么密码了。另一个方法就是配置文件中保存的是加密后的密码,至于解密的秘钥就写死在程序中。

搭建一个sftp服务
sftp命令是一款交互式的文件传输程序,命令的运行和使用方式与ftp命令相似,
但是,sftp命令对传输的所有信息使用ssh加密,它还支持公钥认证和压缩等功能。
工作中我们可能会需要搭建一个sftp服务,来进行文件的上传和下载。本文将讲解一下在linux系统服务器上sftp服务的搭建过程。

1.创建一个用户组sftp

创建sftp用户组

groupadd sftp

查看用户组信息

cat /etc/grou
2.创建一个用户tester,并将其加入sftp用户组中,同时修改用户密码

useradd -g sftp -s /bin/false tester

修改新建用户密码

passwd tester
3.新建用户主目录,并设置权限

mkdir -p /data/sftp/tester

指定为用户主目录

usermod -d /data/sftp/tester tester
chown root:sftp /data/sftp/tester #文件夹所有者必须为root,用户组可以不是root
chmod 755 /data/sftp/tester #权限不能超过755,否则会导致登录报错,可以是755
4.新建用户文件上传目录,并设置权限

mkdir /data/sftp/tester/upload
chown tester:sftp /data/sftp/tester/upload
chmod 755 /data/sftp/tester/upload
5.编辑修改配置文件/etc/ssh/sshd_config

打开配置文件/etc/ssh/sshd_config,将如下内容添加至配置文件末尾

Subsystem sftp internal-sftp
Match Group sftp

设置sftp登录之后的目录

ChrootDirectory /data/sftp/tester/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no

注意。一般原配置文件中已经存在Subsystem配置,只需将其注释掉即可。如下

Subsystem sftp /usr/libexec/openssh/sftp-server

6.重启服务

setenforce 0
service sshd restart
7.验证

登录另一台服务器,执行

此处测试IP

sftp tester@127.0.0.1
执行命令后,按照提示输入密码,登陆成功。ok,大功告成,可以愉快的上传和下载文件了。

实现多个ssh服务器的免密码登陆
无论是登陆服务器进行运算,还是登陆git托管的服务器进行代码的管理,都需要使用ssh的方式进行登陆。

那么ssh登陆的 验证方式常用的有密码,公钥-私钥验证 两种。

第一步,我们审问服务器
连接服务器时,服务器把自己的公钥发给我们,由于公钥较长,为了降低验证的难度,使用MD5或者sha256进行digest生成服务器的指纹,与本地~/.ssh/known_hosts 里面已经储存的模式来进行匹配,之前没存储,就会提醒我们,这台机器不可信,是否要继续连接。
技术图片

选择 yes 就会把这台服务器添加到known_hosts中

第二步,服务器审问我们
下图我们可以看到,ssh服务器所采取的验证方式,主要有4种,最最倾向的方式是公钥验证。因为公钥验证可以提供常规密码不能比拟的长度。
技术图片

服务器会按照上面的四种方式,先去寻找public key发现下面任何一种情况,公钥验证都会失败,会转入密码验证步骤

电脑上没有找到公钥(RSA,DSA 或者ECDSA)

公钥找到了,但是没找到同名的私钥

公钥私钥都在,服务器的 authorized_keys 中不存在这个公钥记录

即使公钥已经存在了服务器上,还需要进行验证。服务器给我们发送一段随机字符串,本地对这个字符串使用自己的私钥进行加密,回传给服务器。 服务器对这段加密对字符串用client的提供的公钥进行解密,如果与最初发送的随机字符串匹配,才算验证通过。 由于公钥和私钥是匹配的,不知道私钥,就无法进行正确的加密,也就无法通过验证。
技术图片

TO-DO LIST
知道了原理之后,我们就可以着手准备材料了

根据原理我们发现,最重要的是一对相辅相成,互为加密解密对公钥和私钥,它们就表明了我们的身份,见钥如见人。

  1. 生成密钥 (本地进行)
    生成对方法可以用ssh-keygen

ssh-keygen -f ~/.ssh/server1 -t rsa -P ‘your_own_passphrase‘
-C ‘your_comment‘
基本最常用的就是这4个参数。

-f 自定义密钥的路径和名称,如果不指定,一般就会直接在~/.ssh下面创建 id_rsa 和 id_rsa.pub, ssh 服务器验证的过程中如果没有发现手动指配的key,也会默认去搜索这个名字的公钥私钥
-t 加密的算法,默认是使用rsa,也可以选择dsa, ecdsa
-P 设置密码,如果设置了密码,只有输入密码才能够使用私钥
-C comment,给自己的备注,提醒这对密钥是干啥用的
上面的几个参数,都可以留空不填。都有自己的默认值。

  1. 把公钥交给服务器管理员,或者自己添加到 authorized_keys文件中
    服务器端,首先我们要确定的是,已经安装并开启了sshd服务
    只需要把我们本地的公钥添加到 authorized_keys 文件中去,,服务器端的设置就完成了

no more 密码!直接ssh user@server.com 即可登陆

  1. 进阶讲究人,不同服务器用不同的key登陆
    虽然这个意义不是特别大,但有的时候,就是不想所有登陆的服务器都使用同一对密钥。
    我个人能想到的好处就是

可以不用输入完整的站点名称了。。。

可以把密钥 放到其他的移动设备上,不用明晃晃的放在.ssh目录下

实现的方法就是在本地的~/.ssh/文件夹下建立一个config文件,内容如下。
每一个Host 就是一台服务器,可以自定义个名称,比如s1,s2
HostName 是主机的地址,可以是网址,也可以是IP地址
User,就是你在服务器的登陆用户名
IdentityFile 就是指定登陆该主机使用哪一对key的具体路径

Host s1
HostName this_is_a_long_name_server1.com
User john.doe
IdentityFile ~/.ssh/key1
Host s2
HostName 10.101.102.103
User john.doe
IdentityFile ~/.ssh/key2
此时,你登陆服务器的时候,就可以用
ssh s1
代替
ssh john.doe@this_is_a_long_name_server1.com

扩展

  1. ssh-keygen 的 -P 参数,对私钥的使用加以限制
    这里需要注意的是-P 参数, 可以理解为存放钥匙的保险柜的钥匙。。。 就是每次要使用密钥的时候,还需要再验证一下这个密码(passphrase)
    技术图片

在生成key的过程中,包含了-P 参数,登陆过程中请求使用密钥,被要求输入passphrase
这边注意的是,这个passphrase 和你要登陆的服务器的登陆密码没有一毛钱关系,使用ssh-key登陆,就算你完全不知道自己的服务器登陆密码都没有关系。

当然,你也可以留空不填,那么,只要私钥存在,就直接可以登陆成功

  1. 允许一段时间内无限访问私钥
    我既想把私钥文件加密(也就是设置了-P 参数),又不想每次连接服务器都输入一遍这个密码,会不会挨揍?
    这个也是ok的,方法就是使用ssh-add -K ~/.ssh/your_key
    意思就是把这个私钥加入到当前的缓存中,只在运行ssh-add的这一次要求你输入passphrase验证一遍,在重启之前,或者手动清除出缓存之前,都可以访问私钥

  2. 清除缓存中保存的私钥
    经过测试发现,一旦把私钥保存到了缓存里,即使把私钥删除了,也照样可以登陆。。。
    用完之后,还是想着能够清除才好,毕竟电脑不会经常重启,方法如下
    ssh-add -D
    即可

  3. 在服务器开启立ssh服务,顺便让sftp可用
    以操作系统为centos为例,其他的系统也类似,只是安装sshd的命令不同而已
    rpm -qa | grep openssh-server 可以看到系统中ssh安装包
    技术图片

如果没有安装,则可以手动安装
sudo yum install openssh-server -y
OpenSSH的主配置文件:/etc/ssh/sshd_config, 常见的配置如下

PubkeyAuthentication yes #允许使用公钥进行验证
RSAAuthentication yes #允许使用RSA验证
AuthorizedKeysFile .ssh/authorized_keys #指定授权文件的位置
netstat -an|grep 22,查看22端口是否打开,如果找开,则证明SSH服务开启了。
安装好之后,启动服务
systemctl start sshd 开启sshd
netstat -tnl 查看服务是否启动
systemctl status sshd.service 查看工作的状态

此时,你不光可以使用ssh服务远程登陆,你还拥有了一台sftp的服务器

为sftp设置public key

Public Key认证是什么
这是一种认证方法,类似于常见的用户名密码认证方法。不同的是需要在客户端机器上保留一个很长很长的加密key,而在服务器端需要做出相应的配置。当客户 端想要访问服务器时,服务器则会检查自身配置并根据客户端所提供的用户名来识别客户端。说白了就是实现了无密码访问,并同时兼有安全保障措施。

认证过程简要说明
Public key对数据进行加密而且只能用于加密,Private key只能对所匹配的Public key加密过的数据进行解密。我们把Public key放在远程系统合适的位置,然后从本地开始进行ssh连接。此时,远程的sshd会产生一个随机数并用我们产生的Public key进行加密后发给本地,本地会用Private key进行解密并把这个随机数发回给远程系统。最后,远程系统的sshd会得出结论我们拥有匹配的Private key允许我们登录。

客户端配置
登陆客户端服务器,然后运行命令(不是在sftp命令下,就linux命令下允许)“ssh-keygen -t dsa”生成Public Key和Private Key

例如:

[root@SWEBVM000438 /]# ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/root/.ssh/id_dsa): /root/.ssh/id_dsa (说明:这里输入放Public Key和Private Key的文件夹,可照抄给出的/root/.ssh/id_dsa)
Enter passphrase (empty for no passphrase): (不输入,直接回车)
Enter same passphrase again: (不输入,直接回车)
Your identification has been saved in /root/.ssh/id_dsa.
Your public key has been saved in /root/.ssh/id_dsa.pub.
The key fingerprint is:
48:6a:bf:34:b7:ef:65:cf:e0:be:13:b9:c3:7c:ce:24 root@SWEBVM000438
The key‘s randomart image is:
+--[ DSA 1024]----+
| |
| |
| . |
| o . |
| o . S . |
| . . o |
| + . oEo. |
| . + . +B. |
| . .oo.+
= |
+-----------------+

服务器端配置
一、从目录/etc/或/etc/ssh/或/etc/conf.d/中找到sshd_config文件,并用vi编辑器打开
二、启用RSAAuthentication和PubkeyAuthentication,并同时指定authorized_keys文件位置,设置如下:
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile ~/.ssh/authorized_keys
三、更新并保存sshd_config文件后,运行命令“service sshd restart”重新启动服务,不同版本Linux的服务启动方式见:http://theos.in/desktop-linux/tip-that- matters/how-do-i-restart-linux-network-service/
四、以上三步只是启用无密码验证功能,想要这个功能生效,还必须把客户端生成的Public Key配置到服务器的authorized_keys文件中去。把之前在客户端生成的id_rsa.pub文件内容拷贝到authorized_keys 中,如果有多个客户端,那么需要把每个客户端生成的Public Key都拷贝进来,注意换行,一个客户端一行。

测试
一、登录客户端,运行命令“ssh username@servername”,运行命令“ssh -vvv -o PreferredAuthentications=publickey username@servername”可以强制使用Public Key验证方法。
二、测试SFTP可以使用命令“sftp username@servername”

注意事项
.ssh目录的属主、属组使用当前用户与用户组
.ssh目录的权限请保持700
authorized_keys的权限为644
id_rsa的权限为600
id_rsa.pub的权限为644
检查用户$HOME目录权限必须为755

相关sftp命令
1、登陆:
格式:sftp @
sftp root@10.10.10.10 然后输入密码

2.查看sftp支持的命令

  使用help命令,查看支持的命令,如:

  sftp>help

   (其中命令前面有“l”表示本地执行,其他表示在所登录的远程主机上面执行)

3、文件下载
get /root/xxx/testlist.dat ./
将远程/root/xxx目录下的文件testlist.dat下载到本地当前目录文件夹中。

4、文件上传
put .bashrc /root/xxx
将本地当前目录下的.bashrc文件传送到远程的sftp服务器的/root/xxx目录下。

5、pwd 查询远程主机的当前路径

6、查询列表:

格式:sftp>ls <查询列表的路劲>
例如:
sftp> ls /root/xxx
/root/xxx/test.DAT
/root/xxx/BackUp

参考:http://blog.csdn.net/rcom10002/article/details/19069075

以上是关于SFTP 知识合集的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发小知识合集1000篇251

压缩感知合集2(背景知识)信号稀疏表示的数学推导和解释理解

iOS知识合集

压缩感知合集1(背景知识)香农奈奎斯特采样定理的数学推导和图解分析

Linux技术专题系列「必备基础知识」一起探索和实践sftp配置之密钥方式登录

python小知识合集