我在 openssh/telnet 代码中使用以下内容,它设置用户环境。
setenv("TEST_ENV", "testing", 1);
但这可以由用户修改,有没有办法使它成为只读环境变量?
答案1
常规中没有什么工艺环境要使变量只读,只有 shell 对其自己的环境/变量具有该概念(两者在方式上重叠,但必须将它们理解为不同的)。这同样适用于类型属性,如整数、数组、函数等。
您是否考虑过使用受限制的 shell,例如rbash
?您可以在其启动脚本中rbash
设置运行) 。虽然可能限制性太大,但它在很大程度上解决了评论中提出的问题。readonly TEST_ENV
rbash
环境是每个进程的读/写部分(参见这里和这里详细信息),进程不仅可以直接写入数据部分(通过environ[]
),还可以更改指向它的指针。如果您精通汇编并且可以找到解决启动代码的方法,您也许可以对此做一些事情(即重新定位到只读页面),crt
但我不建议这样做;-)
如果用户运行的特定命令必须具有特定环境,您可以仅设置组执行并使用它sudo
来设置正确的变量(例如通过/etc/environment
或env_file
指令)并作为特定组运行命令(保留 uid)。最新版本支持noexec
大多数平台,可用于防止运行新的 shell(尽管可能会破坏合法的程序fork()
)exec()
。
作为最后一个选项,您可以使用LD_PRELOAD
自己的库通过包装相关的 libc 函数(等)来为某些/所有用户进程设置受控环境getenv() putenv()
。libfaketime与时间相关的 libc 函数正是这样做的。有一个不太为人所知的工具叫做时间旅行这确实相似,但是还钩子setenv()
,getenv()
以便LD_PRELOAD
在逆境中保持控制。
最可靠的方法是过滤setenv() unsetenv() putenv()
(可能还有clearnv()
)调用以防止修改,并进行过滤getenv()
以使其始终返回所需的值(可能来自文件)。这种方法不会阻止通过直接操作环境内存environ[]
,但只要您控制getenv()
任何依赖 libc API 的进程,就应该看到您的值。初始化时直接bash
使用,但也调用.environ[]
getenv()
答案2
可以使用命令在 POSIX 兼容 shell 中设置只读变量readonly
。
readonly VAR=foo # POSIX
declare -r VAR=foo # bash
export VAR
这绝不是阻止用户更改它的安全功能。用户始终可以生成新的 shell 并更改变量。
答案3
您可以设置/etc/skel/.bashrc
或每个用户的~/.bashrc
readonly TEST_ENV