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

FTP服务-vsftp协议实现

我们常用的是FTP协议,主要是通过VSFTP是一个基于GPL发布的类Unix系统上使用的FTP服务器软件,它的全称是Very Secure FTP 从此名称可以看出来,编制者的初衷是代码的安全。

SFTP服务-ssh协议实现

由于vsftp采用明文传输,用户名密码可通过抓包得到,为了安全性,需使用sftp,锁定目录且不允许sftp用户登到服务器。由于sftp使用的是ssh协议,需保证用户只能使用sftp,不能ssh到机器进行操作,且使用密钥登陆、不是22端口。

  1. 创建sftp服务用户组,创建sftp服务根目录,通过groupadd指令进行创建对应的sftp服务用户组。
groupadd sftp
  1. 常见对应的sftp服务器的目录地址。
mkdir /data/sftp
  1. 此目录及上级目录的所有者必须为root,权限不高于755,此目录的组最好设定为sftp
chown -R root:sftp /data/sftp
chmod -R 0755 /data/sftp
  1. 备份sshd_config配置文件
cp /etc/ssh/sshd_config_bk
  1. 修改sshd配置文件

保证原来22端口可以

sed -i 's@#Port 22@Port 22@' /etc/ssh/sshd_config 
vi /etc/ssh/sshd_config

注释掉/etc/ssh/sshd_config文件中的此行代码:

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

添加如下代码:

Port 2222
Subsystem sftp internal-sftp -l INFO -f AUTH
Match Group sftp
ChrootDirectory /data/sftp/%u
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp -l INFO -f AUTH

凡是在用户组sftp里的用户,都可以使用sftp服务;使用sftp服务连接上之后,可访问目录为/data/sftp/username

案例说明

  • test是一个sftp组的用户,它通过sftp连接服务器上之后,只能看到/data/sftp/test目录下的内容
  • test2也是一个sftp组的用户,它通过sftp连接服务器之后,只能看到/data/sftp/test2目录下的内容
  1. 创建sftp用户,此例将创建一个名称为test的sftp帐号

创建test sftp家目录:test目录的所有者必须是root,组最好设定为sftp,权限不高于755

mkdir /data/sftp/test
chmod 0755 /data/sftp/test
chown root:sftp /data/sftp/test
useradd -g sftp -s /sbin/nologin test #添加用户,参数-s /sbin/nologin禁止用户通过命令行登录
  1. 创建test用户密钥对:
mkdir /home/test/.ssh
ssh-keygen -t rsa
cp /root/.ssh/id_rsa.pub /home/test/.ssh/authorized_keys
chown -R test.sftp /home/test

在test目录下创建一个可以写的upload目录

mkdir /data/sftp/test/upload
chown -R test:sftp /data/sftp/test/upload

注:sftp服务的根目录的所有者必须是root,权限不能超过755(上级目录也必须遵循此规则),sftp的用户目录所有者也必须是root,且最高权限不能超过755。

  1. 测试sftp
service sshd restart

本文来自博客园,作者:洛神灬殇,转载请注明原文链接:http://www.cnblogs.com/liboware/p/17064409.html,任何足够先进的科技,都与魔法无异。

本文转载于网络 如有侵权请联系删除

相关文章

  • 手把手教你在 SpringBoot 中自定义参数解析器

    TienChin项目出视频啦~SpringBoot+Vue3,和松哥一起做一个完成率超90%的项目,戳戳戳这里-->TienChin项目配套视频来啦。1.自定义参数解析器为了搞清楚这个问题,我们先来自定义一个参数解析器看看。自定义参数解析器需要实现HandlerMethodArgumentResolver接口,我们先来看看该接口:public interface HandlerMethodArgumentResolver {  boolean supportsParameter(MethodParameter parameter);  @Nullable  Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,    NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception; }复制这个接口中就两个方法:supports

  • WordPress后台登录添加算术验证码

    给WordPress网站登录添加验证码功能在一定程度上可以有效减少机器人软件暴力破解暴力登录,对于wordpress程序可以有很多相关插件可以实现,不过这么简单的功能其实没有必要安装一个插件,通过简单的代码也很容易实现。效果图:使用:把以下代码添加到主题模板函数functions.php文件里就可以啦!PS:编辑之前请备份。//后台登陆数学验证码 functionrhymo_add_login_fields(){ //获取两个随机数,范围0~9 $num1=rand(0,9); $num2=rand(0,9); //最终网页中的具体内容 echo"<p><labelfor='math'class='small'>验证码</label><br/><inputtype='text'name='sum'placeholder='$num1+$num2=?'class='input'value='&#x

  • 02_iOS 沙盒及各个目录详解

    处于安全考虑,一个iosAPP对系统文件的交互权限被限制在app的沙盒目录下。在安装一个新的app的时候,安装程序会在沙盒目录下创建许多的容器,每个容器目录都有特定的角色。bundle容器目录:保存应用程序的包(主bundle的资源等)数据容器目录:就是我们平时开发中用到的Documents,librarytemp。运行的时候app可以额外的申请容器目录,比如icloud。应用程序通常是被禁止在容器外访问或者创建文件的,不过app可以利用一些公开的接口去访问一些信息,比如通讯录,音乐等等,系统有提供专门的方法去访问和修改这些信息。各个目录的详解:APPName.app是app的bundle,包含了app以及所以的资源。这个目录你不能去进行写操作,为了防止篡改,在app装的时候就行了签名处理,一但你进行了写操作,签名就会修改,app无法启动这个目录的内容不会被itunes和icloud进行备份Documents使用该目录主要是存储用户的相关数据,这个目录下的文件可以通过文件共享提供给用户,因此这个目录下最好只存储app希望公开给用户的数据信息。这个目录的内容会被itunes或者icoul

  • Docker 实战(3)- 搭建 Gitlab 容器并上传本地项目代码

    如果你还想从头学起Docker,可以看看这个系列的文章哦!https://www.cnblogs.com/poloyy/category/1870863.html搭建Gitlab容器搜索gitlab镜像dockersearchgitlab复制创建gitlab容器前置操作由于是docker镜像运行,所以我们需要把gitlab容器的配置、数据、日志存到容器外面,即将其目录映射到主机上先准备三个目录:#切到srv目录 cd/srv #创建gitlab文件夹 mkdirgitlab cdgitlab mkdirconfiglogsdata复制创建容器如果参数不懂,可以看这篇文章:https://www.cnblogs.com/poloyy/p/13926296.htmldockerrun-d-p443:443-p9001:80-p8022:22\ --namegitlab\ --restartalways\ --privileged=true\ -v/srv/gitlab/config:/etc/gitlab\ -v/srv/gitlab/logs:/var/log/gitlab\ -v/

  • Android UI控件之Gallery实现拖动式图片浏览效果

    我们知道现在智能手机上都有这样一种功能,就是你在浏览图片的时候。不是硬性的点击按钮而是可以实现手指的拖动,划开效果。使用户具有更好的交互体验,不过这种效果是如何实现的呢?在Android中是通过Gallery来实现拖动效果的。通过Gallery可以实现各种各样的效果,此篇文章只是简要谈谈他的用法,至于后续的一些效果有机会的时候做一个整理。首先看看其简单实现吧!本次实例是通过选取图片实现类似设置背景的功能!不过需要说明的是:图片不宜过大,否则容易内存溢出,android对大图片的支持不好!我们来看看切换之后的效果吧看看重新设置一幅背景图片!怎么样一个简单的效果就出来了吧!下面是具体的实现方法:xml文件:<?xmlversion="1.0"encoding="utf-8"? <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:la

  • php5对象复制、clone、浅复制与深复制实例详解

    本文实例讲述了php5对象复制、clone、浅复制与深复制。分享给大家供大家参考,具体如下:对象复制的由来为什么对象会有“复制”这个概念,这与PHP5中对象的传值方式是密切相关的,让我们看看下面这段简单的代码PHP代码/** *电视机类 */ classTelevision { /** 屏幕高度 */ protected$_screenLength=300; /** 屏幕宽度 */ protected$_screenHight=200; /** 电视机外观颜色 */ protected$_color='black'; /** 返回电视外观颜色 */ publicfunctiongetColor() { return$this-_color; } /** 设置电视机外观颜色 */ publicfunctionsetColor($color) { $this-_color=(string)$color; return$this; } } $tv1=newTelevision(); $tv2=$tv1;复制这段代码定义了一个电视机的类Television,tv1为一个电视

  • Java基础:五、枚举类型 (10)

    publicenumSpiciness{ NOT,MILD,MEDIUM,HOT,FLAMING }复制这里创建了一个名为Spiciness的枚举类型,它具有5个具名值,由于枚举类型的实例是常量,因此按照命名惯例它们都用大写字母表示(如果在一个名字中有多个单词,用下划线将它们隔开)为了使用enum,需要创建一个该类型的引用,并将其赋值给某个实例:publicclassSimpleEnumUse{ publicstaticvoidmain(String[]args){ SpicinesshowHot=Spiciness.MEDIUM; System.out.println(howHot); } }复制在你创建enum时,编译器会自动添加一些有用的特性。例如,它会创建toString()方法,以便你可以很方便地显示某个enum实例的名字,这正是上面的打印语句如何产生其输出的答案。编译器还会创建ordinal()方法,用来表示某个特定enum常量的声明顺序,以及staticvalues()方法,用来按照enum常量的声明顺序,产生由这些常量值构成的数组publicclassEnumOrder

  • scala读取配置文件

    Class:packagelibparser importscala.collection.mutable importscala.util.matching.Regex classconf{ defparser(value:String)={ varcs=mutable.Map.empty[String,String] valpattern=newRegex("""(^[a-zA-Z0-9_-]+?)\s+([\w\W]+?)$""") try{ if(value!=null){ //字符串拼接 //value.concat("234556") vallines=value.split("\n") for(line<-lines){ if((patternfindAllInline).mkString!=null){ if(line!=""){ vark=line.split("=")(0).replaceAll("&q

  • Unity音效

    AudioListener组件用来接收音效AudioSource组件用来播放音效 PlayOnAwake:在组件Awake时播放声音 Loop:循环播放音效 PlayClipAtPoint()静态方法,在一个世界坐标的点上进行播放音乐AudioSource.PlayClipAtPoint(_clip,newVector3(0,0,0))复制PlayerOneShot()方法,在一个AudioSource中插播一段短的ClipvoidStart() { audioSource=gameObject.GetComponent<AudioSource>(); } voidjumpClipPlay() { audioSource.PlayOneShot(jumpClip,10f); }复制声音管理类: 单例模式(Mono中与C#中的单例有区别)AudioSourceaudioSource; //单例保证AudioManager的唯一性 privatestaticAudioManagerinstance; publicstaticAudioManagerInstance { get

  • BZOJ2115: [Wc2011] Xor(线性基)

    TimeLimit: 10Sec  MemoryLimit: 259MBSubmit: 4848  Solved: 2030[Submit][Status][Discuss]DescriptionInput第一行包含两个整数N和M,表示该无向图中点的数目与边的数目。接下来M行描述M条边,每行三个整数Si,Ti,Di,表示Si与Ti之间存在一条权值为Di的无向边。图中可能有重边或自环。Output仅包含一个整数,表示最大的XOR和(十进制结果),注意输出后加换行回车。SampleInput57 122 132 241 251 453 534 432SampleOutput6HINTSource感觉std的思路比较套路好首先我们求出任意一条路径的xor值然后我们假设有另外一条路径的xor值比当前优,我们考虑如何把当前路径一步步替换为最优路径有两种情况1:当前路径和最优路径不存在交集,那么这两条路径构成一个环2:当前路径和最优路径存在交集,那么这两条路径的并中会出现一些环,我们只需要把当前路径在环上的部分替换掉就好因此,不论哪种情况,我们都需要找到异或和最大的环然后dfs一边找出所有环,扔到

  • POJ 1985 Cow Marathon(树的直径)

    DescriptionAfterhearingabouttheepidemicofobesityintheUSA,FarmerJohnwantshiscowstogetmoreexercise,sohehascommittedtocreateabovinemarathonforhiscowstorun.Themarathonroutewillincludeapairoffarmsandapathcomprisedofasequenceofroadsbetweenthem.SinceFJwantsthecowstogetasmuchexerciseaspossiblehewantstofindthetwofarmsonhismapthatarethefarthestapartfromeachother(distancebeingmeasuredintermsoftotallengthofroadonthepathbetweenthetwofarms).Helphimdeterminethedistancesbetweenthisfarthestpairoffarms. Input*Lin

  • 【愚公系列】2022年08月 Go教学课程 032-结构体方法继承

    文章目录一、结构体方法继承1.继承的概念2.go中的继承3.方法继承4.方法继承案例一、结构体方法继承1.继承的概念继承是指一个子类(或称为派生类)继承父类(或称为基类)的特征(属性和操作)。继承是面向对象程序设计时实现代码复用的重要手段,它允许在原有的类的基础上进行扩展,增加功能,这样新产生的类称为子类。2.go中的继承但在Go语言本身并不支持继承。但可以使用组合的方法,实现类似继承的效果。Go语言中,把一个结构体嵌入到另一个结构体的方法,称之为组合。3.方法继承packagemain import"fmt" typeStudentstruct{ Person scorefloat64 } typePersonstruct{ idint namestring ageint } func(p*Person)PrintInfo(){ fmt.Println(*p) } funcmain(){ stu:=Student{Person{101,"张三",18},90} stu.PrintInfo() }复制4.方法继承案例pac

  • 腾讯云腾讯会议PSTN外呼状态更新事件订阅(Webhook)

    事件描述事件名:meeting.phone.participant-status-updated事件说明:当PSTN外呼的状态发生变化时,触发该事件。 示例{ "event":"meeting.phone.participant-status-updated",//事件名 "trace_id":"e7aa65dd-f7e6-4b62-912c-2035173b34a9",//事件的唯一序列值 "payload":[ { "operate_time":1609313201465,//毫秒级别事件操作时间戳 "operator":{//事件操作者 "userid":"tester",//事件操作者id(同企业用户才返回用户id,OAuth用户返回openId,rooms返回roomsId) "open_id":"KM4Ss******gUw1JiK", "ms_o

  • 自用官方文档索引(日常更新)

    spring-boot-maven-plugin插件文档 https://docs.spring.io/spring-boot/docs/2.5.5/maven-plugin/reference/pdf/spring-boot-maven-plugin-reference.pdf mysql5.7文档 https://dev.mysql.com/doc/refman/5.7/en/json.html 三分热血值得你十二分努力。

  • 【JDBC第4章】操作BLOB类型字段

    第4章:操作BLOB类型字段 4.1MySQLBLOB类型 MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。 插入BLOB类型的数据必须使用PreparedStatement,因为BLOB类型的数据无法使用字符串拼接写的。 MySQL的四种BLOB类型(除了在存储的最大信息量上不同外,他们是等同的) 实际使用中根据需要存入的数据大小定义不同的BLOB类型。 需要注意的是:如果存储的文件过大,数据库的性能会下降。 如果在指定了相关的Blob类型以后,还报错:xxxtoolarge,那么在mysql的安装目录下,找my.ini文件加上如下的配置参数:max_allowed_packet=16M。同时注意:修改了my.ini文件之后,需要重新启动mysql服务。 4.2向数据表中插入大数据类型 //获取连接 Connectionconn=JDBCUtils.getConnection(); Stringsql="insertintocustomers(name,email,birth,photo)values(?,?,?,?)";

  • 19使用变量的一般事项

    1.变量定义 1.1.隐式声明 ​ 针对支持隐式声明的语言,我们的策略: 关闭隐式声明 声明全部的变量 遵循某种命名规则 检查变量名 2.变量初始化 2.1.初始化错误问题 从未对变量赋值。它的值知识程序启动时变量所处内存区域的值。 变量值已经过期。变量在某个地方曾经被赋值,但该值已经不再有效。 变量的一部分被赋值,而另一部分没有。 2.2.解决办法 在声明变量的时候初始化 在靠近变量第一次使用的位置初始化它 理想情况下,在靠近第一次使用比那两的位置声明和定义该变量 在可能的情况下使用funal或者const,确保变量初始化后不被修改 特别注意计数器和累加器 在类的构造函数里初始化该类的数据成员 检查是否需要重新初始化 一次性初始化具名常量;用可执行代码来初始化变量 使用编译器设置来自动初始化所有变量 利用编译器的警告信息 检查输入参数的合法性 使用内存访问检查工具来检查错误的指针 在程序开始时初始化工作内存 可以用某种在程序运行前预先填充内存的工具来把程序的工作内存填充为一个可以预料的值。对于某些检测目而言,0是个很好的填充值。因为它会确保那些尚未初始化的指针指

  • Tomcat初识

    Tomcat的由来 1995年美国的一个民间组织根据美国NCSA项目源代码,自行组织开发并发布了ApacheWebServer,该组织于1999年创建团体,称为ApacheSoftwareFoundation(ASF)。Apache项目包括子项目有HTTPServer、APR、Jakarta、Perl、PHP、TCL、XML等,现在已经发展到43个项目。 而Tomcat是Jakarta的子项目,JakartaTomcat最初是为了JavaServlet技术而开发的,Servlet嵌入到特定的WebServer中,称为Servlet容器。Sun创建的第一个Servlet容器是JavaWebServer,与此同时ASF组织创建了JServ,它是一个与Apache服务器集成的Servlet引擎。 1999年,Sun将JavaWebServer容器贡献给了ASF,使JavaWebServer和JServ两个项目合并为Tomcat。Tomcat作为Sun的官方参考时限,也标志这它支持Servlet和JSP的参考标准。 综上,Tomcat第一个版本是从3.1.1开始的,它完全支持Servlet2.

  • HEOI2021AFOOOOOO记

    滚蛋了 大概到了能平静的面对一些事的时候就会更了吧 如初见与初见

  • leetcode--整数反转

    给出一个32位的有符号整数,你需要将这个整数中每位上的数字进行反转。 示例1:输入:123输出:321示例2:输入:-123输出:-321示例3:输入:120输出:21 defreverse_integer(integer): #overrange,returnzero ifinteger<-2**32orinteger>2**32-1: return0 #negativenumber flag=1 ifinteger<0: flag=-1 integer=abs(integer) #reverseinteger s=0 whileTrue: s*=10 r=integer%10 integer=integer//10 s+=r ifinteger==0: break returnflag*s x=-123 y=reverse_integer(x) print(x,y) s=120 t=reverse_integer(s) print(s,t) s=123 t=reverse_integer(s) print(s,t)复制  

  • 动态规划:区间DP、状压DP

    区间DP:区间dp就是在区间上进行动态规划,求解一段区间上的最优解。主要是通过合并小区间的最优解进而得出整个大区间上最优解的dp算法。例题洛谷P1880、P2858、P1063,POJ1390、POJ2955、POJ3042、POJ1141(POJ的这几道比较难... 将大区间分割为小区间,dp[i][j]=dp[i][k]+dp[k+1][j]。但是考虑到状态的可到达性,直接对i、j循环遍历是不行的。这时候引入l作为区间长度,循环遍历l、i,j可以被表示为i+l 对于是一个环的区间来说,可以将原来单个的区间复制一遍形成双倍的区间,在这个大区间上dp即可。大区间的话,限制条件就要发生改变:i+l<2*n&&i<2*n //P1880 #include<bits/stdc++.h> usingnamespacestd; intn; intnum[300],sum[300],f1[300][300],f2[300][300]; intd(inti,intj) { returnsum[j]-sum[i-1]; } intmain() { scanf

  • nginx http跳https

    if($scheme="http"){rewrite^(.*)$https://$host$1permanent;}   http状态码301和302   官方的比较简洁的说明:     301redirect:301代表永久性转移(PermanentlyMoved)     302redirect:302代表暂时性转移(TemporarilyMoved)     ps:这里也顺带记住了两个比较相近的英语单词(permanently、temporarily),嘻哈!       详细来说,301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。他们的不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),

相关推荐

推荐阅读