libfaketime 不适用于 golang

问题描述 投票:0回答:2

我希望我的 go 程序在 ubuntu 服务器(14.04)上运行,并由主管守护,以使用假服务器时间。

在我的主管配置中,我使用它作为执行命令:

"faketime 'last Friday 5 pm' /home/user/main"

程序运行,但显示当前时间。

根据这篇文章: 使用 libfaketime 更改进程认为的时间

libfaketime 不能与静态链接或 setuid 程序一起使用,因为 LD_PRELOAD 不适用于此类程序。

有没有办法让我编译的go程序使用faketime?

ubuntu go supervisord
2个回答
8
投票

问题是

faketime
使用
LD_PRELOAD
环境变量来指示程序的动态加载器在启动时加载
libfaketime
libfaketime
将执行所谓的“插入”操作 - 用其自己的例程副本替换正常的动态库例程 - 这样,当将来进行动态库调用时,
libfaketime
可以影响发生的情况。特别是,
libfaketime
插入了与时间相关的调用,因此它能够向程序返回假值。

这适用于大多数程序的原因是它们使用

libc
进行系统调用。
libc
提供了与系统调用交互的高级函数,使系统编程变得更容易。在大多数使用
libc
的语言中,二进制文件是动态链接的,这意味着
libc
实际上并不包含在二进制文件中,而是预计
libc
的编译版本(称为“目标文件”)将包含在二进制文件中。当二进制文件运行时,动态库就存在于系统中,此时可以加载动态库。这种动态加载使得通过
faketime
指令实现
LD_PRELOAD
成为可能,这改变了加载器的行为。

然而,Go 有两点不同。首先,它是静态链接的,因此没有加载程序可以关注

LD_PRELOAD
。其次,它不使用
libc
,所以即使它是动态链接的,并且
LD_PRELOAD
技巧起作用了,
libc
也永远不会被调用,所以它实际上仍然无法实现欺骗的预期目标编程使用假时间函数。


0
投票

https://github.com/harkaitz/go-faketime 可以用于此目的。

import "github.com/harkaitz/go-faketime"

ftime.now() //reads the time set for faketime    

在内部检查环境变量

LD_PRELOAD
是否包含字符串
libfaketime

// code snippet from https://github.com/harkaitz/go-faketime/blob/master/faketime.go
if strings.Index(os.Getenv("LD_PRELOAD"), "libfaketime") == -1 {
    return time.Now()
}

cmd = exec.Command("date", "+%s")
stdout, err = cmd.Output()

我希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.