更改 postgres 副本到导出文件的权限

Mit*_*ent 5 postgresql linux export copy

我已经在 SO 上问过这个问题,但也许那是错误的位置。对于重复发帖表示歉意,但这个问题可能在这里有更好的受众。

原来的问题是:/sf/ask/1793350331/

正文如下。谢谢。


当运行 postgresql [9.3]“COPY TO”功能时,postgres 用户创建一个文件。我已经告诉它把文件放在 tmp 目录中(尽管如果需要的话可以更改)。

这是作为 cron 作业的一部分运行的,用户是专门为此任务设置的“导出”用户。最终目标是导出的文件最终位于 /home/export/created_file.csv 中。

1)postgres如果不将文件夹设置得过于宽松,则无法将导出的文件直接存储到另一个用户的主目录中。

2) 导出用户可以将文件从其/tmp主目录复制到其主目录,但随后无法清理(删除)postgres中拥有的文件/tmp

这是一个日常过程,因此需要以某种方式删除旧文件。我可以添加一个 cron 作业来清理文件,但我希望有一个更干净的解决方案 - 要么是一种更改创建文件的权限的方法postgres,要么是某种方式为导出用户提供能够删除的额外权限该文件在创建之前。

然而,为导出用户提供与postgres一般情况相同的权限并不是一种选择,因为这样它将可以自由控制数据库。

任何建议,无论是基于 unix 还是基于 postgres,都将非常受欢迎,谢谢。

Cra*_*ger 6

您需要创建一个没有设置t(粘性)权限位的目录,并让 PostgreSQL 将文件复制到那里。您还应该设置目录 setgid ( g+s),因为这使得组继承自该目录,而不是创建过程;请参阅setgid 目录

You could put this directory in /tmp but personally I'd put it some neutral location like /var/lib, or mounted volume somewhere, as /tmp gets cleaned out automatically so you'll need to have the directory re-created if it's missing.

Assuming you do use /tmp:

mkdir -p /tmp/pgcsv
chgrp users /tmp/pgcsv
chmod u=rwX,g=rwsX,o= /tmp/pgcsv
Run Code Online (Sandbox Code Playgroud)

then create the csv in there. It'll be automatically created with group-owner users, which will make it readable by your users (unless PostgreSQL's umask is too restrictive). Because the directory is group-writable by users (or whatever group you use) and does not have the t (sticky) bit set your users can delete files they do not own from it.

The reason this doesn't work when using /tmp/ directly is that the sticky bit is set in /tmp for security, so that user1 can't delete a file created by user2 and replace it with a symlink that user2 then writes to, allowing user1 to steal their data / trick them into overwriting things.


Other options:

  • Run the cron job as user export, using psql's \copy command, so it writes the data over the client/server socket and the file is created as the export user in the first place. This is by far the simplest option, and only slightly slower than a direct COPY.
  • Have a cron job running as root invoke the PostgreSQL copy then move the data file and change its ownership once the COPY finishes.
  • Give the export user the ability to run a very restricted command as root via sudo to move/delete.
  • Use POSIX ACLs to grant the postgres user special permission to write to /home/export (if POSIX ACLs are enabled on your file system)
  • Set group-owner of /home/export to postgres and make its permissions g=wx. PostgreSQL can add new entries, and overwrite anything within that it has write permission to, but not list entries. I don't like this option much.