简介
java程序是跨平台的,能够运行在windows也能够运行在linux。然而平台不同,平台中的文件权限也是不同的。windows大家常常应用,并且是可视化的权限治理,这里就不多讲了。
本文次要讲讲linux上面的文件的权限和安全性问题,并且探讨一下如何在java程序中思考文件的安全性。
linux下的文件根本权限
chmod是linux上面的权限治理命令,咱们能够通过chmod来对文件的权限进行批改。
一般文件的权限有三种,rwx别离是读,写和执行。再加上三个用户分组:owner,group,other 咱们能够很不便的应用三个0-7的数字来示意一个文件的权限。
举个例子,咱们创立一个文件:
touch test.log
看一下默认的文件权限:
ll test.log-rw-r--r-- 1 flydean wheel 0B 8 16 10:36 test.log
默认的文件权限是644,也就是说owner权限是读写,group权限是读,其余权限是读。
咱们能够应用chmod命令对其进行批改,比方:
chmod 777 test.logll test.log-rwxrwxrwx 1 flydean wheel 0B 8 16 10:36 test.log
能够看出权限被批改成为777。
linux文件的非凡权限
讲完一般权限,咱们接下来讲一下linux文件中的非凡权限。
Set UID 和 Set GID
思考一个罕用的批改明码的例子,批改明码调用的是/usr/bin/passwd,看下这个文件的权限:
ll /usr/bin/passwd-rwsr-xr-x. 1 root root 27832 Jun 10 2014 /usr/bin/passwd
能够看到有个很奇怪的s权限。这个s是什么意思呢?s理论是x的变种,是一种非凡的可执行权限。
非凡在哪里呢?passwd是批改用户的明码,密码文件实际上是寄存在 /etc/shadow中的。
咱们看下/etc/shadow的权限:
ll /etc/shadow---------- 1 root root 707 Jan 2 2020 /etc/shadow
/etc/shadow的owner是root,只有root才权限强行写入这个文件。
那么问题来了,普通用户调用passwd是怎么批改的/etc/shadow呢?
这就是s的妙用,s示意Set UID,简称为SUID,这个UID示意User的ID,而User示意这个程序(/usr/bin/passwd)的拥有者(root),那么咱们在调用passwd的过程时候,就会临时领有passwd owner的权限,也就是root权限。
留神,SUID只能用在二进制文件中,它是对x权限的一个替换,并且SUID对目录是有效的。
同样的,咱们也能够给group设置UID权限,也就是Set GID。
不同的是SGID能够应用在文件和目录两个中央。
用在文件中是和SUID一样的,用在目录中的意思是在该目录中所建的文件或目录的用户组都和该目录的用户组是一样的。
Sticky Bit
Sticky Bit示意的是非凡的other权限,用t来示意。
/tmp目录就是一个Sticky Bit的例子: drwxrwxrwt 。
SBit对目录的作用是:“在具备SBit的目录下,用户若在该目录下具备w及x权限,则当用户在该目录下建设文件或目录时,只有文件拥有者与root才有势力删除”
这个个性就是为了爱护咱们在共享目录下的文件不被他人删除。
SUID/SGID/SBIT权限设置
怎么设置这些权限呢?
一般权限咱们是用3个数字来示意的,咱们能够在3个数字之前再加上一个数字示意SUID/SGID/SBIT权限。
和一般权限一样,咱们用4来示意SUID,2示意SGID,1示意SBIT。
举个例子:
touch testchmod 6755 testll test-rwsr-sr-x 1 crawler crawler 0 Aug 16 11:43 test
留神,有时候咱们会遇到大写的S与T的状况,这种状况呈现在user、group以及others都没有x这个可执行的标记,所以大写的S和T示意为空。
文件暗藏属性
有些linux零碎提供了chattr命令来设置文件暗藏属性。
咱们看下chattr的应用:
Usage: chattr [-RVf] [-+=aAcCdDeijsStTu] [-v version] files...
参数:
- : 减少某个非凡参数,其余本来存在的参数不动。
- : 删除某个非凡参数,其余本来存在的参数不动。
= : 设置肯定,且仅有前面接的参数
A : 当设置了A属性时,这个文件(或目录)的存取时间atime(access)将不可被批改,可防止例如手提电脑有磁盘I/O谬误的状况产生。
S : 这个性能有点相似sync.就是将数据同步写入磁盘中。能够无效地防止数据散失。
a : 设置a之后,这个文件将只能减少数据,而不能删除,只有root能力设置这个属性。
c : 这个属性设置之后,将会主动将此文件“压缩”,在读取的时候将会主动解压缩,但在存储的时候,将会先进行压缩后再存储(对于大文件有用)。
d : 当执行dump(备份)程序的时候,设置d属性将可使该文件(或目录)具备转储效用。
i : i的作用很大。它能够让一个文件“不能被删除、改名、设置连贯,也无奈写入或新增数据”。对于零碎安全性有相当大的帮忙。
j : 当应用ext3文件系统格局时,设置j属性将会使文件在写入时先记录在journal中。然而,当文件系统设置参数为data=journalled时,因为曾经设置日志了,所以这个属性有效。
s : 当文件设置了s参数时,它将会从这个硬盘空间齐全删除。
u : 与s相同,当应用u来设置文件时,则数据内容其实还存在磁盘中,能够用来还原删除。
非凡文件
linux中还有一些非凡的文件,比方链接文件和设施文件。
在解决链接文件的时候,咱们须要留神判断链接文件的实在指向。
而设施文件咱们须要留神不合理的受权拜访。
java中在共享目录中应用文件要留神的问题
共享目录中因为所有人都有操作文件的权限,所以,咱们须要特地留神在java中共享目录中文件的操作。
依据java的标准, java.nio.channels.FileLock能够用来示意文件的锁定。
通常来讲,锁定有两种,一种是排他锁,一种是共享锁。
共享锁可避免其余同时运行的程序获取重叠的排他锁,但的确容许它们获取重叠的共享锁。排他锁可避免其余程序获取任一类型的重叠锁。
共享锁反对来自多个过程的并发读取拜访;独占锁反对独占写访问。
然而,加锁是否真正的阻塞其余程序对该文件的拜访,理论是取决于操作系统。
在应用中,咱们须要对用户用户传入的文件进行一些必要的校验,比方是否是惯例文件:
String filename = /* Provided by user */;Path path = new File(filename).toPath();try { BasicFileAttributes attr = Files.readAttributes( path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS); // Check if (!attr.isRegularFile()) { System.out.println("Not a regular file"); return; } // Other necessary checks // Use try (InputStream in = Files.newInputStream(path)) { // Read file };} catch (IOException x) { // Handle error}
下面的例子中,咱们通过获取File的属性,来判断这个属性是否regularFile,留神,咱们在读取文件属性的时候,传入了一个LinkOption.NOFOLLOW_LINKS,示意的是不要follow链接。
尽管咱们首先判断了file的权限,而后再对其进行操作,然而下面的例子还是会有问题的。因为存在时间差的问题,如果歹意用户在判断之后将文件替换成了歹意的链接文件,就会呈现问题。
平安目录
为了保障用户的文件操作安全性,咱们引入一个平安目录的概念,所谓平安目录就是目录除了用户自身和超级管理员之外,没有其余用户的写访问权限,并且给定文件的父目录不会被除了系统管理员之外的其余任何用户删除或重命名。
在下方的源码链接中,我提供了一个查看平安目录的class,大家能够自行查看。
本文的代码:
learn-java-base-9-to-20/tree/master/security
本文已收录于 http://www.flydean.com/java-security-code-line-file-security/最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!
欢送关注我的公众号:「程序那些事」,懂技术,更懂你!