前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除
目录
一、文件传输协议
FTP(File Transfer Protocol)文件传输协议;是一种在互联网中进行文件传输的协议,基于客户端/服务器模式,默认使用20、21端口,其中20端口进行数据传输、端口21用于接收客户段发出的相关FTP命令与参数。FTP服务器普遍部署于内网中,具有容易搭建、方便管理的特点。而有些FTP客户端工具还可以支持文件的多点下载以及断点续传技术。FTP协议的传输拓扑如图:
FTP服务器是按照FTP协议在互联网上提供文件存储和访问服务的主机,FTP客户端是向服务器发送连接的请求,以建立数据传输链路的主机。FTP协议有两种工作模式;防火墙学习时提到:防火墙一般是用于过滤从外网进入内网的流量,因此有时候需要将FTP的工作模式设置为主动模式,才可以传输数据。
- 主动模式:FTP服务器主动向客户端发起连接请求
- 被动模式:FTP服务器等待客户端发起连接请求(默认工作模式)
由于FTP、HTTP、Telent等协议的数据都是经过明文进行传输的,因此设计有了vsftpd服务程序。vsftpd(very secure ftp daemon,非常安全的FTP守护进程)是一款运行在Linux操作系统上的FTP服务程序,开源且免费,此外,有高安全、高传输速度以及支持虚拟用户验证等其他FTP服务程序的特点。
安装vsftpd服务程序:
[root@Linux ~]# yum install vsftpd
iptables防火墙管理工具默认禁止了FTP传输协议的端口号,因此在正式配置vsftpd服务程序之前,为了避免这些,清空iptables防火墙的默认策略,并把当前已经被清理的防火墙策略状态保存下来:
[root@Linux ~]# iptables -F [root@Linux ~]# iptables-save
然后在把FTP协议添加到firewalld服务的允许列表中:
[root@Linux ~]# firewall-cmd --permanent --zone=public --add-service=ftp success [root@Linux ~]# firewall-cmd --reload success
缩小文件内容:vsftpd服务程序的主配置文件(/etc/vsftpd/vsftpd.conf)内容总达127行;可以在grep命令后面添加-v参数,过滤并反选出没有包含#号的参数行,然后将过滤后的参数行通过输出重定向符写回原始的主配置文件中,只剩下12行有效参数了:
[root@Linux ~]# mv /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf_bak [root@Linux ~]# grep -v "#" /etc/vsftpd/vsftpd.conf_bak > /etc/vsftpd/vsftpd.conf [root@Linux ~]# cat /etc/vsftpd/vsftpd.conf anonymous_enable=NO local_enable=YES write_enable=YES local_umask=022 dirmessage_enable=YES xferlog_enable=YES connect_from_port_20=YES xferlog_std_format=YES listen=NO listen_ipv6=YES pam_service_name=vsftpd userlist_enable=YES
下面是vsftpd服务程序主配置文件中常用的参数以及作用。简单了解即可:
参数 | 作用 |
---|---|
listen=[YES|NO] | 是否以独立运行的方式监听服务 |
listen_address=IP地址 | 设置要监听的IP地址 |
listen_port=21 | 设置FTP服务的监听端口 |
download_enable=[YES|NO] | 是否允许下载文件 |
userlist_enable=[YES|NO] userlist_deny=[YES|NO] | 设置用户列表为"允许"还是"禁止"操作 |
max_clients=0 | 最大客户端连接数,0为不限制 |
max_per_ip=0 | 同一IP地址的最大连接数,0为不限制 |
anonymous_enable=[YES|NO] | 是否允许匿名用户访问 |
anon_upload_eable=[YES|NO] | 是否允许匿名用户上传文件 |
anon_umask=022 | 匿名用户上传文件的umask值 |
anon_root=/var/ftp | 匿名用户的FTP根目录 |
anon_mkdir_write_enable=[YES|NO] | 是否允许匿名用户创建目录 |
anon_other_write_enable=[YES|NO] | 是否开放匿名用户的其他写入权限(包括重命名、删除等操作权限) |
anon_max_rate=0 | 匿名用户的最大传输速率(字节/秒),0为不限制 |
local_enable=[YES|NO] | 是否允许本地用户目录登录FTP |
local_umask=022 | 本地用户上传文件的umask值 |
local_root=/var/ftp | 本地用户的FTP目录 |
chroot_local_user=[YES|NO] | 是否将用户权限禁锢在FTP目录,以确保安全 |
local_max_rate=0 | 本地用户最大传输速率(字节/秒),0为不限制 |
二、Vsftpd服务程序
vsftpd作为更加安全的文件传输协议服务程序,允许用户以三种认证模式登录到FTP服务器上
- 匿名开放模式:是一种最不安全的认证方式,任何人都可以无需密码验证而直接登录到FTP服务器
- 本地用户模式:通过Linux系统本地的账户密码信息进行认证的模式,较安全,配置也简单;
- 虚拟用户模式:更安全的一种认证模式,它需要为FTP服务单独建立用户数据库文件,虚拟出用来进行口令验证的账户信息;而这些账户信息在服务器中实际是不存在的,仅供FTP服务程序进行认证使用
ftp是Linux系统中以命令行界面的方式来管理FTP传输服务的客户端工具;安装:
[root@Linux ~]# yum install ftp
当然可以在Windows主机上测试实验的效果,软件有:FileZilla、FileFTP、SmartFTP、WinSCP和Cyberduck等
1、匿名访问模式
此模式一般用来访问不重要的文件。当然,如果使用防火墙管理工具将vsftpd服务程序允许访问的主机范围设置为企业内网,也可以提供基本的安全性。
vsftpd服务程序默认关闭了匿名开放模式,需要做的就是开放匿名用户的上传、下载文件的权限,以及让匿名用户创建、删除、更名文件的权限。注意:针对匿名用户放开这些权限会带来潜在危险,不建议在生产环境中配置;
向匿名用户开放的参数以及作用:
参数 | 作用 |
---|---|
annoymous_enable=YES | 允许匿名访问模式 |
anon_umask=022 | 匿名用户上传文件的umask值 |
anon_upload_enable=YES | 允许匿名用户上传文件 |
anon_mkdir_write_enable=YES | 允许匿名用户创建目录 |
anon_other_write_enable=YES | 允许匿名用户修改目录名称或删除目录 |
[root@Linux ~]# cat /etc/vsftpd/vsftpd.conf anonymous_enable=YES anon_umask=022 anon_upload_enable=YES anon_mkdir_write_enable=YES anon_other_write_enable=YES ...
保存退出后还需要重启vsftpd服务程序,让新的配置参数生效;提醒:在生产环境或在RHEL等认证考试中一定要把配置过的服务程序加入到开机启动项中,以保证服务器在重启后依然能够正常提供传输服务;
[root@Linux ~]# systemctl restart vsftpd [root@Linux ~]# systemctl enable vsftpd Created symlink /etc/systemd/system/multi-user.target.wants/vsftpd.service → /usr/lib/systemd/system/vsftpd.service.
可以在客户端执行ftp命令连接到远程的FTP服务器了。在vsftpd服务程序的匿名开放认证模式下,其账户统一为anonymous,密码为空。并且连接到FTP服务器后,默认访问/var/ftp目录。因此可以在该目录下的pub目录中,尝试创建一个新的目录文件,以检验是否拥有权限:
[root@Linux ~]# ftp 10.0.0.2 Connected to 10.0.0.2 (10.0.0.2). 220 (vsFTPd 3.0.3) Name (10.0.0.2:root): anonymous 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> cd pub 250 Directory successfully changed. ftp> mkdir files 550 Permission denied.
系统显示拒绝创建目录!查看目录的权限得知,只有root管理员才有写入的权限;下面将目录的所有者身份改成系统账户ftp即可:
[root@Linux ~]# ls -ld /var/ftp/pub drwxr-xr-x. 2 root root 6 Apr 7 2023 /var/ftp/pub [root@Linux ~]# chown -R ftp /var/ftp/pub [root@Linux ~]# ls -ld /var/ftp/pub drwxr-xr-x. 2 ftp root 6 Apr 7 2023 /var/ftp/pub [root@Linux ~]# ftp 10.0.0.2 Connected to 10.0.0.2 (10.0.0.2). 220 (vsFTPd 3.0.3) Name (10.0.0.2:root): anonymous 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> cd pub 250 Directory successfully changed. ftp> mkdir files 550 Create directory operation failed.
再次报错!猜测是SELinux的问题;使用getdebool命令查看与FTP相关的SELinux域策略都有哪些
[root@Linux ~]# getsebool -a | grep ftp ftpd_anon_write --> off ftpd_connect_all_unreserved --> off ftpd_connect_db --> off ftpd_full_access --> off ftpd_use_cifs --> off ftpd_use_fusefs --> off ftpd_use_nfs --> off ftpd_use_passive_mode --> off httpd_can_connect_ftp --> off httpd_enable_ftp_server --> off tftp_anon_write --> off tftp_home_dir --> off
根据经验和策略的名称判断是ftpd_full_accedd --> off策略规则导致了操作失败。修改此策略规则,并且在设置时使用-P参数让修改过的策略永久生效;
[root@Linux ~]# setsebool -P ftpd_full_access=on
现在便能顺利执行文件创建、修改及删除等操作了:
[root@Linux ~]# ftp 10.0.0.2 Connected to 10.0.0.2 (10.0.0.2). 220 (vsFTPd 3.0.3) Name (10.0.0.2:root): anonymous 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> cd pub 250 Directory successfully changed. ftp> mkdir files 257 "/pub/files" created ftp> rename files database 350 Ready for RNTO. 250 Rename successful. ftp> rmdir database 250 Remove directory operation successful. ftp> exit 221 Goodbye.
当然,由于权限不足所以将/var/ftp/pub目录的所有者设置成了用户本身,还可以通过设置权限为777这样的权限让其他用户获取到写入的权限,但是由于vsftpd服务自带有安全保护机制,不要对/var/ftp直接修改权限,可能导致服务被"安全锁定"而不能登录,记得是里面的pub目录:
[root@Linux ~]# chmod -R 777 /var/ftp [root@Linux ~]# ftp 10.0.0.2 Connected to 10.0.0.2 (10.0.0.2). 220 (vsFTPd 3.0.3) Name (10.0.0.2:root): anonymous 331 Please specify the password. Password: 500 OOPS: vsftpd: refusing to run with writable root inside chroot() Login failed. 421 Service not available, remote server has closed connection
2、本地用户模式
恢复环境,开启本地用户模式,针对本地用户模式的权限参数以及作用如下:
参数 | 作用 |
---|---|
anonymous_enable=NO | 禁止匿名访问模式 |
local_enable=YES | 允许本地用户模式 |
write_enable=YES | 设置可写权限 |
local_umask=022 | 本地用户模式创建文件的umask值 |
userlist_deny=YES | 启用"禁止用户名单",名单文件为ftpusers和user_list |
userlist_enable=YES | 开启用户作用名单文件功能 |
默认情况下本地用户所需参数都已经存在;umask参数一般中文被称为权限掩码或权限补码,能够直接影响文件的权限值。例:Linux系统中新建普通文件后的权限是644,新建的目录权限是755,为什么是这个数呢?
其实普通文件的默认权限是666,目录权限是777,这是写在系统配置文件中的。但默认值不等于最终权限,根据公式"默认权限 - umask = 实际权限",而umask值默认是022,所以实际文件到手就剩下633,目录为755了
配置本地用户参数:
[root@Linux ~]# vim /etc/vsftpd/vsftpd.conf anonymous_enable=NO local_enable=YES write_enable=YES local_umask=022 ...
保存退出并重启vsftpd服务程序;并且添加到开机自启项中;
[root@Linux ~]# systemctl restart vsftpd [root@Linux ~]# systemctl enable vsftpd Created symlink /etc/systemd/system/multi-user.target.wants/vsftpd.service → /usr/lib/systemd/system/vsftpd.service.
按理现在可以使用本地用户身份登录FTP服务器了。但是报错:
[root@Linux ~]# ftp 10.0.0.2 Connected to 10.0.0.2 (10.0.0.2). 220 (vsFTPd 3.0.3) Name (10.0.0.2:root): root 530 Permission denied. Login failed. ftp>
因为vsftpd服务程序所在的目录中默认存放着两个名为"用户名单"的文件(ftpusers和user_list);只要其中有某位用户的名字,就不再允许这位用户登录到FTP服务器:
[root@Linux ~]# cat /etc/vsftpd/user_list # vsftpd userlist # If userlist_deny=NO, only allow users in this file # If userlist_deny=YES (default), never allow users in this file, and # do not even prompt for a password. # Note that the default vsftpd pam config also checks /etc/vsftpd/ftpusers # for users that are denied. root bin daemon adm lp sync shutdown halt mail news uucp operator games nobody [root@Linux ~]# cat /etc/vsftpd/ftpusers # Users that are not allowed to login via ftp root bin daemon adm lp sync shutdown halt mail news uucp operator games nobody
发现vsftpd服务程序为了保证服务器的安全性而默认禁止了root管理员和大多数系统用户的登录行为,这样有效避免黑客通过FTP服务对root管理员密码进行暴力破解。因此可以在文件中删掉root用户名或使用文件中没有的用户名进行尝试登录:
[root@Linux ~]# ftp 10.0.0.2 Connected to 10.0.0.2 (10.0.0.2). 220 (vsFTPd 3.0.3) Name (10.0.0.2:root): root 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp>
为什么要两个一模一样的的文件呢,其实,如果把主配置文件中的userlist_deny参数值改成NO,那么user_list列表就会变成了强制白名单,功能完全是反过来的,只允许列表内的用户访问;
另外采用此模式登录后,默认访问的是该用户的家目录,而该目录的默认所有者、所属组都是该用户自己;但是我们恢复实验环境了,因此再次开启SELinux域中对FTP服务的允许策略:
[root@Linux ~]# getsebool -a | grep ftp ftpd_anon_write --> off ftpd_connect_all_unreserved --> off ftpd_connect_db --> off ftpd_full_access --> off ftpd_use_cifs --> off ftpd_use_fusefs --> off ftpd_use_nfs --> off ftpd_use_passive_mode --> off httpd_can_connect_ftp --> off httpd_enable_ftp_server --> off tftp_anon_write --> off tftp_home_dir --> off [root@Linux ~]# setsebool -P ftpd_full_access=on
一定记得加-P参数,否则服务器在重启后就会按照原有的策略进行控制,从而导致配置过的服务无法使用;完成后使用本地用户登录,发现操作均成功!!
[root@Linux ~]# ftp 10.0.0.2 Connected to 10.0.0.2 (10.0.0.2). 220 (vsFTPd 3.0.3) Name (10.0.0.2:root): root 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> mkdir files 257 "/root/files" created ftp> rename files database 350 Ready for RNTO. 250 Rename successful. ftp> rmdir database 250 Remove directory operation successful. ftp> exit 221 Goodbye.
3、虚拟用户模式
这是最安全的一种认证模式,是专门创建出一个账号来登录FTP传输服务的,而不能用于SSH登录服务器
第1步:重置安装vsftpd服务后。创建用于进行FTP认证的用户数据库文件,其中奇数行为账户名,偶数行为密码。示例:分别创建出zhangsan和lisi两个用户,密码均为redhat;
[root@Linux ~]# cd /etc/vsftpd/ [root@Linux vsftpd]# vim vuser.list zhangsan redhat lisi redhat
但是,明文信息不安全也不符合vsftpd服务程序直接加载的格式,因此需要使用db_load命令用哈希(hash)算法将原始的明文信息转换成数据库文件,并且降低数据库文件的权限,然后再把原始的明文信息删掉:
[root@Linux vsftpd]# db_load -T -t hash -f vuser.list vuser.db [root@Linux vsftpd]# chmod 600 vuser.db [root@Linux vsftpd]# rm -f vuser.list
第2步:创建vsftpd服务程序用于存储文件的根目录以及虚拟用户映射的系统本地用户。FTP服务用于存储文件的根目录指的是当虚拟用户登录后所访问的默认位置;
为了方便管理FTP服务器上的数据,可以把这个系统本地用户的家目录设置为/var目录(该目录用来存放经常发生改变的数据)。为安全起见,我们将这个系统本地用户设置为不允许登录FTP服务器,还能避免黑客通过这个系统本地用户进行登录;
[root@Linux vsftpd]# useradd -d /var/ftproot -s /sbin/nologin virtual [root@Linux vsftpd]# ls -ld /var/ftproot/ drwx------ 3 virtual virtual 78 Jul 8 21:03 /var/ftproot/ [root@Linux vsftpd]# chmod -Rf 755 /var/ftproot/
第3步:建立用于支持虚拟用户的PAM文件
PAM可插拔认证模块是一种认证机制,通过一些动态链接库和统一的API把系统提供的服务与认证方式分开,使得系统管理员可以根据需求灵活调整服务程序的不同认证方式。
通俗来讲,PAM是一组安全机制的模块,系统管理员可以用来轻易地调整服务程序的认证方式,而不必对应用程序进行任何修改。PAM采取分层设计的思想,包含应用程序层、应用接口层、鉴别模块层:
新建一个用于虚拟用户认证的PAM文件vsftpd.vu,其中PAM文件内的"db="参数为使用db_load命令生成的账户密码数据库文件的路径,但不要写数据库文件名的后缀:
[root@Linux vsftpd]# vim /etc/pam.d/vsftpd.vu auth required pam_userdb.so db=/etc/vsftpd/vuser account required pam_userdb.so db=/etc/vsftpd/vuser
第4步:在vsftpd服务程序的主配置文件通过pam_service_name参数将PAM认证文件的名称修改为vsftpd.vu,PAM作为应用程序层与鉴别模块层的连接纽带,可以让应用程序根据需求灵活地在自身插入所需的鉴别功能模块。当应用程序需要PAM认证时,则需要在应用程序中定义负责认证的PAM配置文件,实现所需的功能。
示例:在vsftpd服务程序的主配置文件中默认就带有参数pam_service_name=vsftpd,表示登录FTP服务器时是根据/etc/pam.d/vsftpd文件进行安全认证的。现在我们要做的就是把这个修改为新建的vsftpd.vu文件即可;用到的参数如下:
参数 | 作用 |
---|---|
anonymous_enable=NO | 禁止匿名开放模式 |
local_enable=YES | 允许本地用户模式 |
guest_enable=YES | 开启虚拟用户模式 |
guest_username=virtual | 指定虚拟用户账户 |
pam_service_name=vsftpd.vu | 指定PAM文件 |
allow_writeable_chroot=YES | 允许对禁锢的FTP根目录执行写入操作,而且不拒绝用户的登录请求 |
[root@Linux vsftpd]# cat /etc/vsftpd/vsftpd.conf anonymous_enable=NO local_enable=YES write_enable=YES guest_enable=YES guest_username=virtual ... pam_service_name=vsftpd.vu
第5步:为虚拟用户设置不同的权限。
示例:允许张三上传、创建、修改、查看、删除文件,只允许李四查看文件:新建一个目录,在里面分别创建两个以zhangsan和lisi命名的文件,其中在名为zhangsan的文件中写入允许相关的权限(使用匿名用户的参数):
[root@Linux ~]# mkdir /etc/vsftpd/vusers_dir/ [root@Linux ~]# cd /etc/vsftpd/vusers_dir/ [root@Linux vusers_dir]# touch lisi [root@Linux vusers_dir]# vim zhangsan anon_upload_enable=YES anon_mkdir_write_enable=YES anon_other_write_enable=YES
再次修改vsftpd主配置文件,通过添加user_config_dir参数来定义这两个虚拟用户不同权限的配置文件所存放的路径。保存退出并重启vsftpd并添加到开机启动项中:
[root@Linux vusers_dir]# vim /etc/vsftpd/vsftpd.conf ... user_config_dir=/etc/vsftpd/vusers_dir [root@Linux vusers_dir]# systemctl restart vsftpd [root@Linux vusers_dir]# systemctl enable vsftpd Created symlink /etc/systemd/system/multi-user.target.wants/vsftpd.service → /usr/lib/systemd/system/vsftpd.service.
第6步:设置SELinux域允许策略,然后使用虚拟用户模式登录FTP服务器;
[root@Linux ~]# getsebool -a | grep ftp ... ftpd_full_access --> off [root@Linux ~]# setsebool -P ftpd_full_access=on
此时,不但可以使用虚拟用户模式成功登录到FTP服务器,还可以分别使用账户zhangsan和lisi来检验他们的权限。lisi只能登录,没有其他权限:
[root@Linux ~]# ftp 10.0.0.2 Connected to 10.0.0.2 (10.0.0.2). 220 (vsFTPd 3.0.3) Name (10.0.0.2:root): lisi 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> mkdir files 550 Permission denied. ftp> exit 221 Goodbye.
zhangsan可以登录、创建、改名和删除文件,满权限状态:
[root@Linux ~]# ftp 10.0.0.2 Connected to 10.0.0.2 (10.0.0.2). 220 (vsFTPd 3.0.3) Name (10.0.0.2:root): zhangsan 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> mkdir files 257 "/files" created ftp> rename files database 350 Ready for RNTO. 250 Rename successful. ftp> rmdir database 250 Remove directory operation successful.
最后总结FTP文件传输服务登录后默认所在的位置:
登录方式 | 默认目录 |
---|---|
匿名用户 | /var/ftp |
本地用户 | 该用户的家目录 |
虚拟用户 | 对应映射用户的家目录 |
三、TFTP简单文件传输协议
简单文件传输协议(Trivial File Transfer Protocal,TFTP)是一种基于UDP协议在客户端和服务器之间进行简单文件传输协议。它提供不复杂、开销不大的文件传输服务,可将其作FTP协议的简化版本。
TFTP不需要客户端的权限验证,就减少了无谓的系统和网络资源消耗,因此在传输琐碎(trivial)不大的文件时,效率更高;传输文件时采用UDP协议,占用的端口是69;
下面安装相关的软件包,进行体验。tftp-server是服务程序。tftp是用于连接测试的客户端工具,xinetd是管理服务:
[root@Linux ~]# yum install tftp-server tftp xinetd
在Linux系统中,TFTP服务是使用xinetd服务程序来管理的。xinetd服务可以用来管理多种轻量级的网络服务,而且具有强大的功能日志功能,专门用于管理那些较小的应用程序的开关工作,类似于插线板;想开启那个服务就编辑对应xinetd配置文件的开关参数;
在安装TFTP软件包后,还需要在xinetd服务程序中将其开启。在RHEL 8版本系统中ftpd所对应的配置文件默认不存在,需要用户根据示例文件(usr/share/doc/xinetd/smaple.conf)自行创建
[root@Linux ~]# vim /etc/xinetd.d/tftp service tftp { socket_type = dgram protocol = udp wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s /var/lib/tftpboot disable = no per_source = 11 cps = 100 2 flags = IPv4 }
然后重启xinetd服务并将其添加到开机启动项中,以确保TFTP服务在系统重启后依然处于运行状态。考虑到有些系统的防火墙默认允许UDP协议的69端口,手动开启:
[root@Linux ~]# systemctl restart xinetd [root@Linux ~]# systemctl enable xinetd [root@Linux ~]# firewall-cmd --zone=public --permanent --add-port=69/udp success [root@Linux ~]# firewall-cmd --reload success
TFTP的根目录为/var/lib/tftpboot;使用刚安装的ftpd命令尝试访问其中的文件;常用参数:
参数 | 作用 |
---|---|
? | 帮助信息 |
put | 上传文件 |
get | 下载文件 |
verbose | 显示详细的处理信息 |
status | 显示当前的状态信息 |
binary | 使用二进制进行传输 |
ascii | 使用ASCII码进行传输 |
timeout | 设置重传的超时时间 |
quit | 退出 |
[root@Linux ~]# echo "I love linux" > /var/lib/tftpboot/readme.txt [root@Linux ~]# tftp 10.0.0.2 tftp> get readme.txt tftp> qui [root@Linux ~]# ls anaconda-ks.cfg Desktop Documents Downloads initial-setup-ks.cfg Music Pictures Public readme.txt Templates Videos [root@Linux ~]# cat readme.txt I love linux
致谢
在此,我要对所有为知识共享做出贡献的个人和机构表示最深切的感谢。同时也感谢每一位花时间阅读这篇文章的读者,如果文章中有任何错误,欢迎留言指正。
学习永无止境,让我们共同进步!!