(18) selinux

一、内核级防火墙 selinux

 1.三种级别
   1 强制(E)   0 警告(P)    关闭(D)

 


 2.安全标签:安全上下文

   当selinux插件处于关闭状态,vsftp服务无安全标签
  

   当selinux插件处于强制/警告状态,重启时给所有服务添加安全标签(例 ps auxZ | grep vsftpd)

  



 

二、selinux级别管理

(注意:修改完配置文件要重起服务:systemctl restart vsftpd)


 1.selinux配置文件 /etc/sysconfig/selinux  
    1 强制:警告,并拒绝访问(enforcing)
    0 警告:不被拒绝,但会产生警告日志 (permissive)

    关闭:不被拒绝,可正常访问 (disabled)



 2.selinux级别信息
   查看selinux级别 getenforce
   设置selinux级别 setenforce  0 | 1
   注意:强制和警告级别可相互切换,两者之前切换不用reboot;但若关闭selinux插件,修改配置文件后必须reboot;若打开selinux插件,同样必须reboot;

 3.selinux不同级别的文件管理
   disable    ##客户端可看到移动到pub目录的文件

   touch /mnt/hello
   mv /mnt/hello /var/ftp/pub/
[kiosk@foundation48 Desktop]$ lftp 172.25.254.148
lftp 172.25.254.148:~> cd pub/
lftp 172.25.254.148:/pub> ls

-rw-r--r--    1 0        0               0 Apr 20 01:47 hello


  

Enforcing  ##客户端不能看到移动到pub目录的文件



   touch /mnt/nihao

   mv /mnt/nihao /var/ftp/pub/
[kiosk@foundation48 Desktop]$ lftp 172.25.254.148
lftp 172.25.254.148:~> cd pub/

lftp 172.25.254.148:/pub> ls




   Permissive ##客户端可看到移动到pub目录的文件,但会产生警告日志

   touch /mnt/hi

   mv /mnt/hi /var/ftp/pub/
[kiosk@foundation48 Desktop]$ lftp 172.25.254.148
lftp 172.25.254.148:~> cd pub/
lftp 172.25.254.148:/pub> ls
-rw-r--r--    1 0        0               0 Apr 20 01:47 hello
-rw-r--r--    1 0        0               0 Apr 20 01:51 hi

-rw-r--r--    1 0        0               0 Apr 20 01:50 nihao


   警告日志:
Apr 19 22:24:45 localhost setroubleshoot: Plugin Exception restorecon_source
Apr 19 22:24:45 localhost setroubleshoot: SELinux is preventing /usr/sbin/vsftpd from getattr access on the file . For complete SELinux messages. run sealert -l 02aabd5f-5815-4de5-b686-c6a8de8d6b66
Apr 19 22:24:45 localhost python: SELinux is preventing /usr/sbin/vsftpd from getattr access on the file .
 
三、文件的安全上下文设置

 1.实验环境(修改ftp的默认发布目录)  
   配置文件 /etc/vsftpd/vsftpd.conf
   anon_root=/westos
   注意:需要新建相关目录和文件
   mkdir /westos/test -p

   touch /westos/test/file



 2.查看文件安全上下文   ls -Z 文件绝对路径
[root@localhost ~]# ls -Z /var/ftp/pub/
 
   查看目录安全上下文   ls -Zd 目录绝对路径

[root@localhost ~]# ls -Zd /westos/




 3.临时修改上下文,重启后失效    ##命令行chcon
  chcon -t 安全上下文类型  目录绝对路径  -R(递归)
[root@localhost ~]# chcon -t public_content_t /westos/ -R
[root@localhost ~]# ls -Zd /westos/

drwxr-xr-x. root root unconfined_u:object_r:public_content_t:s0 /westos/


 
 4.永久修改上下文   ##安全上下文列表
   查看安全上下文列表  semanage fcontext
[root@localhost ~]# semanage fcontext -l | grep /var/ftp/
/var/ftp/bin(/.*)?                                 all files          system_u:object_r:bin_t:s0
/var/ftp/etc(/.*)?                                 all files          system_u:object_r:etc_t:s0
/var/ftp/lib(/.*)?                                 all files          system_u:object_r:lib_t:s0

/var/ftp/lib/ld[^/]*\.so(\.[^/]*)*                 regular file       system_u:object_r:ld_so_t:s0



   将指定目录加入安全上下文列表
[root@localhost ~]# semanage fcontext -a -t public_content_t '/westos(/.*)?'
[root@localhost ~]# semanage fcontext -l | grep /westos
/westos(/.*)?                    all files          system_u:object_r:public_content_t:s0

   重新加载安全上下文列表  restorecon -RvvF
[root@localhost ~]# restorecon -RvvF /westos/
restorecon reset /westos context unconfined_u:object_r:public_content_t:s0->system_u:object_r:public_content_t:s0
restorecon reset /westos/test context unconfined_u:object_r:public_content_t:s0->system_u:object_r:public_content_t:s0
restorecon reset /westos/test/file context unconfined_u:object_r:public_content_t:s0->system_u:object_r:public_content_t:s0
 
 5.此时匿名用户登陆时,可正常访问
[kiosk@foundation48 Desktop]$ lftp 172.25.254.148
lftp 172.25.254.148:~> ls
drwxr-xr-x    2 0        0              17 Apr 20 02:50 test
lftp 172.25.254.148:/> cd test
lftp 172.25.254.148:/test> ls

-rw-r--r--    1 0        0               0 Apr 20 02:50 file



四、selinux的bool值  
   

 1.查看selinux中服务的bool值  getsebool -a

(查看bool值,selinux状态必须是强制状态Enforcing)

[root@localhost ~]# getsebool -a | grep ftp
ftp_home_dir --> off
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



 2.当ftp_home_dir功能关闭时,本地用户登陆不能后操作
[kiosk@foundation8 Desktop]$ lftp 172.25.254.108 -u student
Password:
lftp student@172.25.254.108:~> ls      
-rw-r--r--    1 1000     1000         2381 Apr 20 03:28 passwd
lftp student@172.25.254.108:~> rm passwd
rm: Access failed: 550 Delete operation failed. (passwd)

 3.修改sebool值,打开服务
[root@localhost ~]# setsebool -P ftp_home_dir 1
     -P ##永久修改  0  ##关闭服务      1  ##开启服务

 4.打开ftp_home_dir功能时,本地用户登陆后具备相应权限
[kiosk@foundation8 Desktop]$ lftp 172.25.254.108 -u student
Password:
lftp student@172.25.254.108:~> ls      
lftp student@172.25.254.108:~> put /etc/passwd
2381 bytes transferred
lftp student@172.25.254.108:~> ls
-rw-r--r--    1 1000     1000         2381 Apr 20 04:40 passwd
lftp student@172.25.254.108:~> rm passwd
rm ok, `passwd' removed


 5.当客户端登陆报错时,/var/log/messages日志中
   客户端登陆:
[kiosk@foundation8 Desktop]$ lftp 172.25.254.108 -u student
Password:
lftp student@172.25.254.108:~> ls      
lftp student@172.25.254.108:~> put /etc/passwd
put: Access failed: 553 Could not create file. (passwd)

   日志信息:
You can read 'None' man page for more details.
Do
setsebool -P ftp_home_dir 1

*****  Plugin catchall_boolean (47.5 confidence) suggests   ******************

If you want to allow ftpd to full access
Then you must tell SELinux about this by enabling the 'ftpd_full_access' boolean.
You can read 'None' man page for more details.
Do
setsebool -P ftpd_full_access 1
  注意:日志给出的解决方案,安全性不好!!
  ##该功能由setroubleshoot软件提供,若没有该软件,则系统不会给出解决方案

  而selinux服务本身产生的日志存放在/var/log/audit/audit.log中:
type=CRYPTO_KEY_USER msg=audit(1524270564.867:107): pid=1703 uid=0 auid=0 ses=2 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=destroy kind=server fp=eb:24:0e:07:96:26:b1:04:c2:37:0c:78:2d:bc:b0:08 direction=? spid=1703 suid=0  exe="/usr/sbin/sshd" hostname=? addr=172.25.254.77 terminal=pts/0 res=success'





public class FTPUtil { private FTPClient ftpClient=null; private boolean result = false; private FileInputStream fis; String ftpHost = "10.16.111.111"; String port = 21 String ftpUserName = "ftpuser11; String ftpPassword = "1234561"; /** * 登录服务器 * @param ftpInfo * @return * @throws IOException */ public FTPClient login() throws IOException { ftpClient = new FTPClient(); ftpClient.connect(ftpHost); boolean login = ftpClient.login(ftpUserName,ftpPassword); int reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); } if(login){ System.out.println("ftp连接成功!"); }else{ System.out.println("ftp连接失败!"); } //ftpClient.setControlEncoding("GBK"); return ftpClient; } /** * 字符串作为文件上传指定目录 下 * @param content 源字符串 * @param uploadDir 上传目录 * @param ftpFileName 上传文件名称 * @throws Exception */ public void ftpUploadByText(String content ,String uploadDir,String ftpFileName) throws Exception{ try { ftpClient = this.login(); //创建目录 createDir(ftpClient,uploadDir); // 设置上传目录 这个也应该用配置文件读取 ftpClient.changeWorkingDirectory(uploadDir); ftpClient.setBufferSize(1024); ftpClient.setControlEncoding("GBK"); // 设置文件类型(二进制) ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); String fileName = new String(ftpFileName.getBytes("GBK"),"iso-8859-1"); OutputStream os = ftpClient.storeFileStream(fileName); byte[] bytes = content.getBytes(); os.write(bytes); os.flush(); os.close(); } catch (Exception e) { ftpClient.disconnect(); ftpClient = null; e.printStackTrace(); throw e; }finally{ ftpClient.disconnect(); ftpClient = null; } } /** * 移动文件 * @param ftpInfo * @return * @throws Exception */ public boolean moveFile(FTPInfo ftpInfo)throws Exception { boolean flag = false; try { ftpClient = this.login(); flag = this.moveFile(ftpClient, ftpInfo.getChangeWorkingDirectoryPath(), ftpInfo.getFilePath()); } catch (IOException e) { e.printStackTrace(); throw e; } finally { try { ftpClient.disconnect(); ftpClient = null; } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("关闭FTP连接发生异常!", e); }catch (Exception e) { e.printStackTrace(); throw e; } } return flag; } /** * 删除文件 * @param ftpInfo * @return * @throws Exception */ public boolean deleteFile(FTPInfo ftpInfo)throws Exception { boolean flag = false; try { ftpClient = this.login(); flag = this.deleteByFolder(ftpClient, ftpInfo.getChangeWorkingDirectoryPath()); } catch (IOException e) { e.printStackTrace(); throw e; } finally { try { ftpClient.disconnect(); ftpClient = null; } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("关闭FTP连接发生异常!", e); }catch (Exception e) { e.printStackTrace(); throw e; } } return flag; } /** * 实现文件的移动,这里做的是一个文件夹下的所有内容移动到新的文件, * 如果要做指定文件移动,加个判断判断文件名 * 如果不需要移动,只是需要文件重命名,可以使用ftp.rename(oleName,newName) * @param ftp * @param oldPath * @param newPath * @return */ public boolean moveFile(FTPClient ftp,String oldPath,String newPath){ boolean flag = false; try { ftp.changeWorkingDirectory(oldPath); ftp.enterLocalPassiveMode(); //获取文件数组 FTPFile[] files = ftp.listFiles(); //新文件夹不存在则创建 if(!ftp.changeWorkingDirectory(newPath)){ ftp.makeDirectory(newPath); } //回到原有工作目录 ftp.changeWorkingDirectory(oldPath); for (FTPFile file : files) { if(file.isDirectory()) { moveFile(ftp,oldPath+file.getName()+"/" ,newPath+file.getName()+"/"); }else{ //转存目录 flag = ftp.rename(oldPath+new String(file.getName().getBytes("GBK"),"ISO-8859-1"), newPath+"/"+new String(file.getName().getBytes("GBK"),"ISO-8859-1")); } if(flag){ System.out.println(file.getName()+"移动成功"); }else{ System.out.println(file.getName()+"移动失败"); } } ftp.removeDirectory(new String(oldPath.getBytes("GBK"),"ISO-8859-1")); } catch (Exception e) { e.printStackTrace(); System.out.println("移动文件失败"); } return flag; } /** * 删除FTP上指定文件夹下文件及其子文件方法,添加了对中文目录的支持 * @param ftp FTPClient对象 * @param FtpFolder 需要删除的文件夹 * @return */ public boolean deleteByFolder(FTPClient ftp,String FtpFolder){ boolean flag = false; try { ftp.changeWorkingDirectory(new String(FtpFolder.getBytes("GBK"),"ISO-8859-1")); ftp.enterLocalPassiveMode(); FTPFile[] files = ftp.listFiles(); for (FTPFile file : files) { //判断为文件则删除 if(file.isFile()){ ftp.deleteFile(FtpFolder+new String(file.getName().getBytes("GBK"),"ISO-8859-1")); } //判断是文件夹 if(file.isDirectory()){ String childPath = FtpFolder +file.getName()+ "/"; //递归删除子文件夹 deleteByFolder(ftp,childPath); } } //循环完成后删除文件夹 flag = ftp.removeDirectory(new String(FtpFolder.getBytes("GBK"),"ISO-8859-1")); if(flag){ System.out.println(FtpFolder+"文件夹删除成功"); }else{ System.out.println(FtpFolder+"文件夹删除成功"); } } catch (Exception e) { e.printStackTrace(); System.out.println("删除失败"); } return flag; } /** * 创建目录 * @param createpath * @param sftp */ public void createDir(FTPClient ftpClient,String createpath) throws Exception { try { if(ftpClient.changeWorkingDirectory(createpath)) { return; } String pathArry[] = createpath.split("/"); StringBuffer filePath = new StringBuffer("/"); for (String path : pathArry) { if (path.equals("")) { continue; } filePath.append(path + "/"); if(!ftpClient.changeWorkingDirectory(filePath.toString())) { ftpClient.makeDirectory(filePath.toString()); ftpClient.changeWorkingDirectory(filePath.toString()); } } ftpClient.changeWorkingDirectory(createpath); }catch (Exception e) { e.printStackTrace(); throw new Exception("创建路径错误:" + createpath); } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值