- 使用apt-get 工具安装vsftpd
sudo apt-get install vsftpd
如果你是管理员可以使用
apt-get install vsftpd
- 启动服务,vsftp的相关指令(如果不是管理员,需要使用sudo获取权限,如:sudo service vsftpd start 下方的指令同理)
service vsftpd start 开启vsftpd服务 service vsftpd stop 停止vsftpd服务 service vsftpd restart 重启vsftpd服务 service vsftpd status 查看vsftpd服务状态(run,filed等)
- 使用vim修改vsftp的配置文件conf([vim使用详情]
(https://blog.csdn.net/yangshuainan/article/details/78219604?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165129076616780357231614%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165129076616780357231614&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-1-78219604.142%5Ev9%5Epc_search_result_cache,157%5Ev4%5Econtrol&utm_term=vim%E4%BD%BF%E7%94%A8&spm=1018.2226.3001.4187))
sudo vim /etc/vsftpd.conf
- 使用配置(我将其中大部分进行了翻译方便阅读,少部分可以自行搜索)
# Example config file /etc/vsftpd.conf # # The default compiled in settings are fairly paranoid. This sample file # loosens things up a bit, to make the ftp daemon more usable. # Please see vsftpd.conf.5 for all compiled in defaults. # # READ THIS: This example file is NOT an exhaustive list of vsftpd options. # Please read the vsftpd.conf.5 manual page to get a full idea of vsftpd's # capabilities. # # # 是否允许监听。 # 如果设置为YES,则vsftpd将以独立模式运行,由vsftpd自己监听和处理IPv4端口的连接 # 请求 listen=YES # # 设定是否支持IPV6。如要同时监听IPv4和IPv6端口, # 则必须运行两套vsftpd,采用两套配置文件 # 同时确保其中有一个监听选项是被注释掉的 listen_ipv6=NO # # 是否允许匿名登录FTP服务器,默认设置为YES允许 # 用户可使用用户名ftp或anonymous进行ftp登录,口令为用户的E-mail地址。 # 如不允许匿名访问则设置为NO anonymous_enable=YES # # 是否允许本地用户(即linux系统中的用户帐号)登录FTP服务器,默认设置为YES允许 # 本地用户登录后会进入用户主目录,而匿名用户登录后进入匿名用户的下载目录: # /var/ftp/pub # 若只允许匿名用户访问,前面加上#注释掉即可阻止本地用户访问FTP服务器 local_enable=YES # # 是否允许本地用户对FTP服务器文件具有写权限,默认设置为YES允许 write_enable=YES # # Default umask for local users is 077. You may wish to change this to 022, # if your users expect that (022 is used by most other ftpd's) #local_umask=022 # # Uncomment this to allow the anonymous FTP user to upload files. This only # has an effect if the above global write enable is activated. Also, you will # obviously need to create a directory writable by the FTP user. #anon_upload_enable=YES # # 是否允许匿名用户创建新文件夹 #anon_mkdir_write_enable=YES # # 是否激活目录欢迎信息功能 # 当用户用CMD模式首次访问服务器上某个目录时,FTP服务器将显示欢迎信息 # 默认情况下,欢迎信息是通过该目录下的.message文件获得的 # 此文件保存自定义的欢迎信息,由用户自己建立 dirmessage_enable=YES # # If enabled, vsftpd will display directory listings with the time # in your local time zone. The default is to display GMT. The # times returned by the MDTM FTP command are also affected by this # option. use_localtime=YES # # Activate logging of uploads/downloads. xferlog_enable=YES # # 是否设定FTP服务器将启用FTP数据端口的连接请求 # ftp-data数据传输,21为连接控制端口 connect_from_port_20=YES # # 设定是否允许改变上传文件的属主,与下面一个设定项配合使用 # 注意,不推荐使用root用户上传文件 #chown_uploads=YES # 设置想要改变的上传文件的属主,如果需要,则输入一个系统用户名 # 可以把上传的文件都改成root属主。whoever:任何人 #chown_username=whoever # # 表明将记录的上传下载情况写在xferlog_file所指定的文件中,即xferlog_file选项指定的文件中 #xferlog_file=/var/log/vsftpd.log # # If you want, you can have your log file in standard ftpd xferlog format. # Note that the default log file location is /var/log/xferlog in this case. #xferlog_std_format=YES # # 设置数据传输中断间隔时间,此语句表示空闲的用户会话中断时间为600秒 # 即当数据传输结束后,用户连接FTP服务器的时间不应超过600秒。可以根据实际情况对该值 # 进行修改 #idle_session_timeout=600 # # 设置数据连接超时时间,该语句表示数据连接超时时间为120秒,可根据实际情况对其个修 # 改 #data_connection_timeout=120 # # 运行vsftpd需要的非特权系统用户,缺省是nobody #nopriv_user=ftpsecure # # 是否识别异步ABOR请求。 # 如果FTP client会下达“async ABOR”这个指令时,这个设定才需要启用 # 而一般此设定并不安全,所以通常将其取消 #async_abor_enable=YES # # 是否以ASCII方式传输数据。默认情况下,服务器会忽略ASCII方式的请求。 # 启用此选项将允许服务器以ASCII方式传输数据 # 不过,这样可能会导致由"SIZE /big/file"方式引起的DoS攻击 #ascii_upload_enable=YES #ascii_download_enable=YES # # 登录FTP服务器时显示的欢迎信息 # 如有需要,可在更改目录欢迎信息的目录下创建名为.message的文件,并写入欢迎信息保 # 存后 #ftpd_banner=Welcome to blah FTP service. # # 黑名单设置。如果很讨厌某些email address,就可以使用此设定来取消他的登录权限 # 可以将某些特殊的email address抵挡住。 #deny_email_enable=YES # 当上面的deny_email_enable=YES时,可以利用这个设定项来规定哪些邮件地址不可登 # 录vsftpd服务器 # 此文件需用户自己创建,一行一个email address即 #banned_email_file=/etc/vsftpd.banned_emails # # You may restrict local users to their home directories. See the FAQ for # the possible risks in this before using chroot_local_user or # chroot_list_enable below. #chroot_local_user=YES # # 用户登录FTP服务器后是否具有访问自己目录以外的其他文件的权限 # 设置为YES时,用户被锁定在自己的home目录中,vsftpd将在下面chroot_list_file选 # 项值的位置寻找chroot_list文件 # 必须与下面的设置项配合 #chroot_list_enable=YES # 用于指定用户列表文件中的用户是否允许切换到上级目录。默认值为NO。 #chroot_local_user=YES #禁用的列表名单,格式为一行一个用户,用于指定用户列表文件,该文件用于控制哪些用户可以切换到用户家目录的上级目录。 #chroot_list_file=/etc/vsftpd.chroot_list # # 是否允许递归查询。默认为关闭,以防止远程用户造成过量的I/O #ls_recurse_enable=YES # # Customization # # Some of vsftpd's settings don't fit the filesystem layout by # default. # # This option should be the name of a directory which is empty. Also, the # directory should not be writable by the ftp user. This directory is used # as a secure chroot() jail at times vsftpd does not require filesystem # access. secure_chroot_dir=/var/run/vsftpd/empty # # 设置PAM外挂模块提供的认证服务所使用的配置文件名,即/etc/pam.d/vsftpd文件 # 此文件中file=/etc/vsftpd/ftpusers字段,说明了PAM模块能抵挡的帐号内容来自文 # 件/etc/vsftpd/ftpusers中 pam_service_name=vsftpd # # This option specifies the location of the RSA certificate to use for SSL # encrypted connections. rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key ssl_enable=NO # # Uncomment this to indicate that vsftpd use a utf8 filesystem. #utf8_filesystem=YES
- 将vsftp重启,查看确认其状态处于running中(也可以使用sudo /etc/init.d/vsftpd restart 重启)
- 创建用户并创建密码,指定用户主目录
sudo useradd ftp10test -d /home/ftp10test -m;echo ftp10test:admin123 | sudo chpasswd
如果你想删除创建过的用户可以使用以下指令:
sudo userdel -r [用户名] //删除用户并删除该用户的文件夹(/home下的) sudo userdel [用户名] //删除用户
如果你想修改用户的主目录等操作,可以使用usermod相关指令,usermode格式如下:
usermod [选项] 用户名
示例:我需要将用户test的主目录修改为/home/testhome,记得,如果使用的是普通用户,要使用sudo命令来执行(如: sudo usermod -d /home/testhome test)
usermod -d /home/testhome test
usermod选项:
- -c 用户说明:修改用户的说明信息,即修改 /etc/passwd 文件目标用户信息的第 5 个字段;
- -d 主目录:修改用户的主目录,即修改 /etc/passwd 文件中目标用户信息的第 6 个字段,需要注意的是,主目录必须写绝对路径;
- -e 日期:修改用户的失效曰期,格式为 “YYYY-MM-DD”,即修改 /etc/shadow 文件目标用户密码信息的第 8 个字段;
- -g 组名:修改用户的初始组,即修改 /etc/passwd 文件目标用户信息的第 4 个字段(GID);
- -u UID:修改用户的UID,即修改 /etc/passwd 文件目标用户信息的第 3 个字段(UID);
- -G 组名:修改用户的附加组,其实就是把用户加入其他用户组,即修改 /etc/group 文件;
- -l 用户名:修改用户名称;
- -L:临时锁定用户(Lock);
- -U:解锁用户(Unlock),和 -L 对应;
- -s shell:修改用户的登录 Shell,默认是 /bin/bash。
如果你仔细观察会发现,其实 usermod 命令提供的选项和 useradd 命令的选项相似,因为 usermod 命令就是用来调整使用 useradd 命令添加的用户信息的。
- 有时,业务可能要求我们自己用户的文件不给别人看,这时我们可以将文件所属用户为对应用户的文件进行权限设置,如:
chmod -R 700 [文件夹路径]
- 卸载vsftp服务
sudo apt-get remove --purge vsftpd
注意:本文使用方式使用取巧的方法进行,并未搭建ftp服务器,使用xftp等工具通过ftp协议进行链接。
// 用sudo的用这个发送指令再下方write写入密码
public void sudoJschPool(String command) {
SshConfig sshConfig = new SshConfig();
sshConfig.setHost("地址");
sshConfig.setPort(端口);
sshConfig.setUsername("用户名");
sshConfig.setPassword("密码");
try {
Session session = SshPool.getInstance().getPool().borrowObject(sshConfig);
try {
ChannelExec exec = (ChannelExec) session.openChannel("exec");
// String command = "useradd ftp1testr";
exec.setCommand("sudo -S " + command);
InputStream in = exec.getInputStream();
OutputStream out = exec.getOutputStream();
exec.connect();
out.write(("密码" + "n").getBytes()); //这里是密码后跟了一个换行符
out.flush();
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) break;
String s = new String(tmp, 0, i);
System.out.print(s);
}
if (exec.isClosed()) {
System.out.println("exit-status: " + exec.getExitStatus());
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee) {
}
}
exec.disconnect();
} catch (JSchException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
SshPool.getInstance().getPool().returnObject(sshConfig, session);
}
} catch (Exception e) {
e.printStackTrace();
}
}
package com.msdc.xd.common.utils;
import java.security.AccessController;
import java.security.PrivilegedAction;
import com.msdc.xd.common.utils.SshConfig;
import org.apache.commons.pool2.BaseKeyedPooledObjectFactory;
import org.apache.commons.pool2.KeyedObjectPool;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class SshPool {
private GenericKeyedObjectPool pool;
private static class SingletonHolder{
public static final SshPool INSTANCE = new SshPool();
}
public static SshPool getInstance(){
return SingletonHolder.INSTANCE;
}
private SshPool(){
startPool();
}
public KeyedObjectPool getPool(){
return pool;
}
public void startPool() {
pool = AccessController.doPrivileged(
new PrivilegedAction>() {
@Override
public GenericKeyedObjectPool run() {
try {
return new GenericKeyedObjectPool<>(
new SshPoolFactory(), new GenericKeyedObjectPoolConfig());
} catch ( Exception e) {
throw e;
}
}
});
}
private static class SshPoolFactory
extends BaseKeyedPooledObjectFactory {
@Override
public Session create(final SshConfig config) throws Exception {
final JSch jsch = new JSch();
if (config.getKnownHosts() != null
&& !config.getKnownHosts().isEmpty()) {
jsch.setKnownHosts(config.getKnownHosts());
}
if (config.getPrivateKey() != null
&& !config.getPrivateKey().isEmpty()) {
if (config.getPassphrase() != null) {
jsch.addIdentity(config.getPrivateKey(),
config.getPassphrase());
} else {
jsch.addIdentity(config.getPrivateKey());
}
}
final Session session = jsch.getSession(config.getUsername(),
config.getHost(), config.getPort());
if (config.getPassword() != null) {
session.setPassword(config.getPassword());
}
if (config.isIgnoreHostKeyChecking()) {
session.setConfig("StrictHostKeyChecking", "no");
}
session.connect();
return session;
}
@Override
public PooledObject wrap(final Session session) {
return new DefaultPooledObject<>(session);
}
@Override
public boolean validateObject(final SshConfig key,
final PooledObject pooledObject) {
return pooledObject.getObject().isConnected();
}
@Override
public void destroyObject(final SshConfig key,
final PooledObject pooledObject) {
if (pooledObject != null) {
pooledObject.getObject().disconnect();
}
}
}
}
package com.msdc.xd.common.utils;
import java.util.Objects;
public class SshConfig {
private String host;
private int port;
private String username;
private String password;
private String knownHosts;
private boolean ignoreHostKeyChecking = true;
private String privateKey;
private String passphrase;
private String location;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public String getPassphrase() {
return passphrase;
}
public void setPassphrase(String passphrase) {
this.passphrase = passphrase;
}
public void setPassword(String password) {
this.password = password;
}
public String getKnownHosts() {
return knownHosts;
}
public void setKnownHosts(String knownHosts) {
this.knownHosts = knownHosts;
}
public boolean isIgnoreHostKeyChecking() {
return ignoreHostKeyChecking;
}
public void setIgnoreHostKeyChecking(boolean ignoreHostKeyChecking) {
this.ignoreHostKeyChecking = ignoreHostKeyChecking;
}
public String getPrivateKey() {
return privateKey;
}
public void setPrivateKey(String privateKey) {
this.privateKey = privateKey;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SshConfig sshConfig = (SshConfig) o;
return port == sshConfig.port &&
ignoreHostKeyChecking == sshConfig.ignoreHostKeyChecking &&
Objects.equals(host, sshConfig.host) &&
Objects.equals(username, sshConfig.username) &&
Objects.equals(password, sshConfig.password) &&
Objects.equals(knownHosts, sshConfig.knownHosts) &&
Objects.equals(privateKey, sshConfig.privateKey) &&
Objects.equals(passphrase, sshConfig.passphrase) &&
Objects.equals(location, sshConfig.location);
}
@Override
public int hashCode() {
return Objects.hash(host, port, username, password, knownHosts, ignoreHostKeyChecking, privateKey, passphrase, location);
}
}
public static Session exeCommand() throws JSchException, IOException {
JSch jsch = new JSch();
Session session = jsch.getSession(username, host, port);
session.setConfig("StrictHostKeyChecking", "no");
// java.util.Properties config = new java.util.Properties();
// config.put("StrictHostKeyChecking", "no");
session.setPassword(password);
session.connect();
return session;
}



