简介
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.log
ll 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 test
chmod 6755 test
ll 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/
最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!
欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!