openEuler-22.03-SP4离线编译安装vsftp

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常用命令

  1. 显示服务器当前路径
    ftp>pwd
  2. 显示本地路径,用户可以将该路径下的文件上传到FTP服务器对应位置
    ftp>lcd
  3. 退出当前窗口(!或 quit),返回本地Linux终端
    ftp>!或 quit
  4. 下载文件
    通常使用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 *.*
  1. 上传文件
    通常使用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
  1. 删除文件
    通常使用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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值