/tmp 目录过大,文件没有被清理
CentOS7 使用 systemd-tmpfiles
服务来自动清理。
执行如下语句,debug:
env SYSTEMD_LOG_LEVEL=debug systemd-tmpfiles --clean
结果如下:
[root@VM_21_11_centos ~]# env SYSTEMD_LOG_LEVEL=debug systemd-tmpfiles --clean
Reading config file "/usr/lib/tmpfiles.d/abrt.conf".
Reading config file "/usr/lib/tmpfiles.d/etc.conf".
Reading config file "/usr/lib/tmpfiles.d/initscripts.conf".
Reading config file "/run/tmpfiles.d/kmod.conf".
...
Ignoring "/tmp/systemd-private-efd50cf1e5d449869ef8aa70024cea90-tomcat.service-fw1f9j": a separate glob exists.
...
Ignoring "/var/tmp/systemd-private-efd50cf1e5d449869ef8aa70024cea90-tomcat.service-DXvB2O": a separate glob exists.
原因
关于文件 /usr/lib/tmpfiles.d/tmp.conf
,显示
[root@VM_21_11_centos tmpfiles.d]# cat tmp.conf
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# See tmpfiles.d(5) for details
# Clear tmp directories separately, to make them easier to override
v /tmp 1777 root root 10d
v /var/tmp 1777 root root 30d
# Exclude namespace mountpoints created with PrivateTmp=yes
x /tmp/systemd-private-%b-*
X /tmp/systemd-private-%b-*/tmp
x /var/tmp/systemd-private-%b-*
X /var/tmp/systemd-private-%b-*/tmp
保留 PrivateTmp=yes
的目录,即 /tmp/systemd-private*
目录不被管理。
什么是 PrivateTmp
New Red Hat Enterprise Linux 7 Security Feature: PrivateTmp
只要使用Systemd这个进程作为启动进程的linux系统,其子进程都会有PrivateTmp这么一个属性,用于设置是否使用私有的tmp目录。
那么只要设置使用这个属性的service,都会使用私有的tmp目录。
man systemd.exec
PrivateTmp=
Takes a boolean argument. If true, sets up a new file system namespace for the executed processes and mounts private /tmp and /var/tmp directories inside it that is not shared by processes outside of the
namespace. This is useful to secure access to temporary files of the process, but makes sharing between processes via /tmp or /var/tmp impossible. If this is enabled, all temporary files created by a service
in these directories will be removed after the service is stopped. Defaults to false. It is possible to run two or more units within the same private /tmp and /var/tmp namespace by using the
JoinsNamespaceOf= directive, see systemd.unit(5) for details. Note that using this setting will disconnect propagation of mounts from the service to the host (propagation in the opposite direction continues
to work). This means that this setting may not be used for services which shall be able to install mount points in the main mount namespace.
使用PrivateTmp属性有什么好处吗?
- /tmp目录一般是所有用户和所有service都共享的,对于所有用户和service来说,都会有写和读的权限。
那么这里会存在安全性的问题。把各个service的tmp目录隔离开的话,可以保证一定的安全性。 - 对于每个service的tmp目录,会在服务启动(start)时创建该目录,并且在关闭(stop)服务时删除该目录。如果我们是使用自己定义的临时目录路径的话,就需要我们自己定义相关的维护机制了(如:定期删除这些临时文件等),而使用这个PrivateTmp的话,就不需要我们自己去维护了。
解决办法
Disabling “PrivateTmp” for a given service
-
Edit the service file and change PrivateTmp from “true” to “false”
-
Reload systemd
systemctl daemon-reload -
Finally restart the affected service
疑问
- PrivateTmp 会在重启服务的时候,自动清理tmp目录吗?
- 红帽文章表明,systemd-tmpfiles 会自动清理 private tmp 创建的目录。不确定。
801943 – remove empty private tmp directories after use (redhat.com) - 有文章表明,设置privatetmp目录保护不被访问,导致 systemd-tmpfiles清理失败。不确定。
Automatically clean /tmp or /var/tmp files that are in protected PrivateTmp directories in CentOS / RHEL 7 – it.megocollector.com - PHP-FPM类似问题,手动清理。
PHP-FPM security setting "PrivateTmp=true" writes PHP session files to /tmp instead of session.save_path – cPanel
find /tmp/systemd-private*php-fpm.service* -name sess_* ! -mtime -1 -exec rm -f '{}' \;