FTP简介
FTP(File Transfer Protocol)即文件传输协议,是互联网最早的传输协议之一,其最主要的功能是服务器和客户端之间的文件传输。FTP使用户可以通过一套标准的命令访问远程系统上的文件,而不需要直接登录远程系统。FTP协议提供了两种工作模式:标准模式和被动模式。在标准模式下,客户端通过控制连接建立与服务器的连接,并通过数据连接进行数据传输。在被动模式下,客户端发出PASV命令,服务器返回一个端口号,客户端通过端口号与服务器建立数据连接,进行数据传输。FTP协议通常用于网站维护、文件共享和软件下载等方面。
另外,FTP服务器还提供了如下主要功能:
用户分类
默认情况下,FTP服务器依据登录情况,将用户分为实体用户(real user)、访客(guest)、匿名用户(anonymous)三类。三类用户对系统的访问权限差异较大,实体用户具有较完整的访问权限,匿名用户仅有下载资源的权限。
命令记录和日志文件记录
FTP可以利用系统的syslogd记录数据,这些数据包括用户历史使用命令与用户传输数据(传输时间、文件大小等),用户可以在/var/log/中获得各项日志信息。
限制用户的访问范围
FTP可以将用户的工作范围限定在用户主目录。用户通过FTP登录后系统显示的根目录就是用户主目录,这种环境被称为change root,简称chroot。这种方式可以限制用户只能访问主目录,而不允许访问/etc、/home、/usr/local等系统的重要目录,从而保护系统,使系统更安全。
FTP使用到的端口
FTP的正常工作需要使用到多个网络端口,服务器端会使用到的端口主要有:
命令通道,默认端口为21
数据通道,默认端口为20
两者的连接发起端不同,端口21主要接收来自客户端的连接,端口20则是FTP服务器主动连接至客户端。
vsftpd是一个开源的FTP服务器软件,它是“非常安全的FTP守护进程”的缩写。它具有快速、安全、高效的特点,支持IPv6、SSL、TLS加密协议,可以大幅度地提高FTP服务器的安全性。vsftpd软件具有安装方便、性能可靠、系统资源占用低等特点,广泛应用于各种服务器环境。由于其安全性和性能方面的优势,vsftpd已成为Linux服务器上常见的FTP服务器软件之一。
下载离线安装文件
mkdir -p /home/rpm/tools/vsftpd
cd /home/rpm/tools/vsftpd
dnf download --resolve vsftpd
mkdir -p /home/rpm/tools/ftp
cd /home/rpm/tools/ftp
dnf download --resolve ftp
在目标机安装
# 安装vsftpd
cd /home/rpm/tools/vsftpd
rpm -ivh --nosignature *.rpm
# 安装ftp
cd /home/rpm/tools/ftp
rpm -ivh --nosignature *.rpm
配置FTP
添加常用加密方法
OpenSSH_8.8p1版本(8.x或者更新)对接jsch1.55版本会出现Algorithm negotiation fail,原因是新版本的openssh取消了一些加密方法ssh-rsa,ssh-dss,解决方案是在服务器上修改sshd_config文件,增加这两个方法。
# 备份 sshd_config
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
vi /etc/ssh/sshd_config
# 找到
HostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-512
PubkeyAcceptedKeyTypes ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-512
# 分别增加,ssh-rsa,ssh-dss
修改后如下:
HostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-512,ssh-rsa,ssh-dss
PubkeyAcceptedKeyTypes ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-512,ssh-rsa,ssh-dss
保存退出,重启sshd服务
systemctl restart sshd
查看配置文件
vsftp自带的配置文件可以不用修改
cat /etc/vsftpd/vsftpd.conf | grep -v "#"
## 内容如下:
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
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd
userlist_enable=YES
allow_writeable_chroot=YES
local_root=/home/ftp
开放服务
firewall-cmd --permanent --zone=public --add-service=ftp
firewall-cmd --reload
firewall-cmd --zone=public --list-services
启动服务
设置为开机自启动
systemctl enable --now vsftpd
启动vsftpd服务
systemctl start vsftpd
停止vsftpd服务
systemctl stop vsftpd
重启vsftpd服务
systemctl restart vsftpd
可以通过netstat命令查看通信端口21是否开启
netstat -tulnp | grep 21
配置用户信息
多次配置/etc/vsftpd/vsftpd.conf 后,发现匿名用户设置不成功,故采用普通用户的方式
adduser -d /opt/ftp/test -g ftp test
echo "MyPassWd@2024" | passwd test --stdin
touch /opt/ftp/test/readme.txt
chown -R test:users /opt/ftp/test/*
测试
在windows10下测试
以下均可连接ftp服务
sftp -P 22 test@192.168.43.60
sftp test@192.168.43.60
ftp 192.168.43.60
在Java中测试
jsch是SSH2的一个纯Java实现。它允许你连接到一个sshd 服务器,使用端口转发,X11转发,文件传输等等。你可以将它的功能集成到你自己的 程序中,下载地址:jsch
public class SSHRemoteCall {
// 私有的对象
private static SSHRemoteCall sshRemoteCall;
/**
* 私有的构造方法
*/
private SSHRemoteCall() {
}
// 懒汉式,线程不安全,适合单线程
public static SSHRemoteCall getInstance() {
if (sshRemoteCall == null) {
sshRemoteCall = new SSHRemoteCall();
}
return sshRemoteCall;
}
// 懒汉式,线程安全,适合多线程
public static synchronized SSHRemoteCall getInstance2() {
if (sshRemoteCall == null) {
sshRemoteCall = new SSHRemoteCall();
}
return sshRemoteCall;
}
private static final int DEFAULT_PORT = 22;// 默认端口号
// ip地址
private static String _ipAddress = "192.168.43.60";
// 账号
private static String _userName = "test";
// 密码
private static String _password = "MyPassWd@2024";
// JSCH session
private Session session;
// 是否登陆
private boolean logined = false;
/**
* 远程登陆
*
* @throws Exception
*/
public void sshRemoteCallLogin(String ipAddress, String userName, String password) throws Exception {
return sshRemoteCallLogin( ipAddress, userName, password, DEFAULT_PORT);
}
/**
* 远程登陆
*
* @throws Exception
*/
public void sshRemoteCallLogin(String ipAddress, String userName, String password, int port) throws Exception {
// 如果登陆就直接返回
if (logined) {
return;
}
// 创建jSch对象
JSch jSch = new JSch();
try {
// 获取到jSch的session, 根据用户名、主机ip、端口号获取一个Session对象
session = jSch.getSession(userName, ipAddress, port);
// 设置密码
session.setPassword(password);
// 方式一,通过Session建立连接
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
// 方式二,通过Session建立连接
// java.util.Properties;
// Properties config = new Properties();
// config.put("StrictHostKeyChecking", "no");
// session.setConfig(config);// 为Session对象设置properties
// session.setTimeout(3000);// 设置超时
// session.connect();//// 通过Session建立连接
// 设置登陆状态
logined = true;
} catch (JSchException e) {
// 设置登陆状态为false
logined = false;
throw new Exception(
"主机登录失败, IP = " + ipAddress + ", USERNAME = " + userName + ", Exception:" + e.getMessage());
}
}
/**
* 关闭连接
*/
public void closeSession() {
// 调用session的关闭连接的方法
if (session != null) {
// 如果session不为空,调用session的关闭连接的方法
session.disconnect();
}
}
/**
* 执行相关的命令
*
* @param command
* @throws IOException
*/
public void execCommand(String command) throws IOException {
InputStream in = null;// 输入流(读)
Channel channel = null;// 定义channel变量
try {
// 如果命令command不等于null
if (command != null) {
// 打开channel
// 说明:exec用于执行命令;sftp用于文件处理
channel = session.openChannel("exec");
// 设置command
((ChannelExec) channel).setCommand(command);
// channel进行连接
channel.connect();
// 获取到输入流
in = channel.getInputStream();
// 执行相关的命令
String processDataStream = processDataStream(in);
// 打印相关的命令
System.out.println("打印相关返回的命令: " + processDataStream);
}
} catch (JSchException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
in.close();
}
if (channel != null) {
channel.disconnect();
}
}
}
/**
* 对将要执行的linux的命令进行遍历
*
* @param in
* @return
* @throws Exception
*/
public String processDataStream(InputStream in) throws Exception {
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String result = "";
try {
while ((result = br.readLine()) != null) {
sb.append(result);
// System.out.println(sb.toString());
}
} catch (Exception e) {
throw new Exception("获取数据流失败: " + e);
} finally {
br.close();
}
return sb.toString();
}
/**
* 上传文件
*
* @param directory 上传文件的目录
* @param uploadFile 将要上传的文件
*/
public void uploadFile(String directory, String uploadFile) {
try {
// 打开channelSftp
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect();
// 创建一个文件名称问uploadFile的文件
File file = new File(uploadFile);
// 将文件进行上传(sftp协议)
// 将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同.
// 采用默认的传输模式:OVERWRITE
channelSftp.put(new FileInputStream(file), directory, ChannelSftp.OVERWRITE);
// 切断远程连接
channelSftp.exit();
System.out.println(file.getName() + " 文件上传成功.....");
} catch (JSchException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/**
* 下载文件 采用默认的传输模式:OVERWRITE
*
* @param src linux服务器文件地址
* @param dst 本地存放地址
* @throws JSchException
* @throws SftpException
*/
public void fileDownload(String src, String dst) throws JSchException, SftpException {
// src 是linux服务器文件地址,dst 本地存放地址
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect();
// 下载文件,多个重载方法
channelSftp.get(src, dst);
// 切断远程连接,quit()等同于exit(),都是调用disconnect()
channelSftp.quit();
// channelSftp.disconnect();
System.out.println(src + " ,下载文件成功.....");
}
/**
* 删除文件
*
* @param directory 要删除文件所在目录
* @param deleteFile 要删除的文件
* @param sftp
* @throws SftpException
* @throws JSchException
*/
public void deleteFile(String directoryFile) throws SftpException, JSchException {
// 打开openChannel的sftp
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect();
// 删除文件
channelSftp.rm(directoryFile);
// 切断远程连接
channelSftp.exit();
System.out.println(directoryFile + " 删除的文件");
}
/**
* 列出目录下的文件
*
* @param directory 要列出的目录
* @param sftp
* @return
* @throws SftpException
* @throws JSchException
*/
public Vector<LsEntry> listFiles(String directory) throws JSchException, SftpException {
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect();
// 显示目录信息
@SuppressWarnings("unchecked")
Vector<LsEntry> ls = channelSftp.ls(directory);
System.out.println(ls);
// 断开连接
channelSftp.exit();
return ls;
}
public static void main(String[] args) {
// 连接到指定的服务器
try {
// 1、首先远程连接ssh
SSHRemoteCall.getInstance().sshRemoteCallLogin(_ipAddress, _userName, _password, _port);
// 打印信息
System.out.println("ip地址: " + _ipAddress + ",账号: " + _userName + ",连接成功");
// 2、执行相关的命令
// 查看目录信息
// String command = "ls ";
// 查看文件信息
// String command = "pwd";
// 查看磁盘空间大小
// String command = "df -lh ";
// 查看cpu的使用情况
// String command = "top -bn 1 -i -c ";
// 查看内存的使用情况
// String command = "free ";
// SSHRemoteCall.getInstance().execCommand(command);
// 3、上传文件
String directory = "wasi_test076.log";// 目标文件名
String uploadFile = "D:\\2.log";// 本地文件名
SSHRemoteCall.getInstance().uploadFile(directory, uploadFile);
// 4、下载文件
// src 是linux服务器文件地址,dst 本地存放地址,采用默认的传输模式:OVERWRITE
// test为文件名称哈
String src = "wasi_test076.log";
String dst = "D:\\";
SSHRemoteCall.getInstance().fileDownload(src, dst);
// 5、刪除文件
// String deleteDirectoryFile = "wasi_test076.log";
// SSHRemoteCall.getInstance().deleteFile(deleteDirectoryFile);
// 6、展示目录下的文件信息
String lsDirectory = ".";
SSHRemoteCall.getInstance().listFiles(lsDirectory);
// 7、关闭连接
SSHRemoteCall.getInstance().closeSession();
} catch (Exception e) {
// 打印错误信息
System.err.println("远程连接失败......");
e.printStackTrace();
}
}
}
FTP常用命令
- 显示服务器当前路径
ftp>pwd - 显示本地路径,用户可以将该路径下的文件上传到FTP服务器对应位置
ftp>lcd - 退出当前窗口(!或 quit),返回本地Linux终端
ftp>!或 quit - 下载文件
通常使用get或mget命令下载文件。
get使用方法
功能说明:将文件从远端主机中传送至本地主机中
命令格式:get [remote-file] [local-file]
其中 remote-file 为远程文件,local-file 为本地文件
ftp> get /home/fpt/1.log d:/123.log
mget使用方法
功能说明:从远端主机接收一批文件至本地主机
命令格式:mget [remote-file]
其中 remote-file 为远程文件
ftp> cd /home/ftp/wasi/
ftp> mget *.*
- 上传文件
通常使用put或mput命令上传文件。
put使用方法
功能说明:将本地的一个文件传送到远端主机中
命令格式:put [local-file] [remote-file]
其中 remote-file 为远程文件,local-file 为本地文件
ftp> put d:/1.log 123.log
mput使用方法
功能说明:将本地主机中一批文件传送至远端主机
命令格式:mput [local-file]
其中 local-file 为本地文件
ftp> cd /home/ftp/
ftp> mput *.log
- 删除文件
通常使用delete或mdelete命令删除文件。
delete使用方法
功能说明:删除远程服务器上的一个或多个文件
命令格式:delete [remote-file]
其中 remote-file 为远程文件
ftp> cd /home/ftp/
ftp> delete 123.log
mdelete使用方法
功能说明:删除远程服务器上的文件,常用于批量删除
命令格式:mdelete [remote-file]
其中 remote-file 为远程文件
ftp> cd /home/ftp/
ftp> mdelete wasi2024*.log

844

被折叠的 条评论
为什么被折叠?



