使用faketime修改docker内的时间,解决date: cannot set date: Operation not permitted问题

docker本质是个进程,有很多资源是使用宿主机的,比如系统时间。正常使用时是会觉得很方便,但涉及到对系统资源的修改时,就比较麻烦了。

场景

使用docker部署了一个后端服务,测试需要改系统时间,如果直接改宿主机时间则会影响到其他的docker(不管是在宿主机上改还是通过–cap-add SYS_TIME参数在docker中修改)。有没有什么既能满足测试要求又不影响其他docker的方法呢?答案就是通过faketime来欺骗docker,达到此目的。

faketime

github地址

https://github.com/wolfcw/libfaketime

安装
git clone https://github.com/wolfcw/libfaketime
cd libfaketime
make
make install

安装完成后,在/usr/local/lib/下有个kaketime的目录

使用

比如想修改时间为2019-08-12 10:30:22,执行如下命令

export LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME="2019-08-12 10:30:22" 

docker实践

dockerfile

先看一个使用Ubuntu基础镜像做的,可用于laravel的dockerfile

FROM ubuntu:16.04

# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY php-7.3.0.tar.bz2 php-7.3.0.tar.bz2

# 更新源,安装nginx
RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list \
    && sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list \
    && apt-get clean \
    && rm -fR /var/lib/apt/lists/* \
    && mkdir /var/lib/apt/lists/partial \
    && apt-get update  \
    && apt-get upgrade -y \
    && apt-get install -y wget autoconf make gcc nginx procps libfreetype6-dev libpng-dev libzip-dev libcurl3-openssl-dev libbz2-dev libjpeg-dev libxpm-dev libfreetype6-dev libmcrypt-dev libmysql++-dev libxslt1-dev  pkg-config libssl-dev libsslcommon2-dev zip unzip \
    && tar xvf php-7.3.0.tar.bz2 \
    && cd php-7.3.0/ \
    && ./configure  --prefix=/usr/local/php --enable-fpm --enable-sockets --enable-mbstring=all  -enable-mysqlnd  --with-config-file-path=/usr/local/php/etc --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-curl --with-gd  --with-openssl \
    && make \
    && make install \
    && cd ext/zip \
    && /usr/local/php/bin/phpize \
    && ./configure --with-php-config=/usr/local/php/bin/php-config \
    && make ; make install \
    && cd ../../ext/bcmath \
    && /usr/local/php/bin/phpize \
    && ./configure --with-php-config=/usr/local/php/bin/php-config \
    && make ; make install \
    && cd ../../.. ; rm -fr php-7.3.0 ; rm -fr php-7.3.0.tar.bz2 

# 安装 Composer
ENV COMPOSER_HOME /root/composer
COPY composer /usr/bin/composer
COPY composer /usr/local/bin/composer
RUN cp /usr/local/php/bin/php /usr/bin && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

# 复制文件和代码
WORKDIR /data
COPY app/ /data/
COPY php.ini /usr/local/etc/php/php.ini
COPY libfaketime/ /data/
RUN echo 'extension=zip.so' >> /usr/local/php/etc/php.ini \
    && echo 'extension=bcmath.so' >> /usr/local/php/etc/php.ini \
    && cd /data/libfaketime && make ; make install \
    && rm -fr /data/libfaketime
COPY php-fpm.conf /usr/local/php/etc/php-fpm.conf
COPY nginx.conf /etc/nginx/nginx.conf
COPY env-example /data/.env

# Write Permission
RUN chmod -R 777 /data && usermod -u 1000 www-data
CMD ["nginx", "-g", "daemon off;"]
说明
  1. dockerfile的大概过程是:安装基本工具和依赖;编译安装php;复制composer,faketime到docker,编译安装faktime;复制项目代码,nginx配置,php配置到docker;使用nginx做前台进程启动docker。
  2. 用Ubuntu而不用PHP做docker基础镜像的原因是: 测试修改时间时要重启php-fpm,如果直接使用PHP的docker则重启php-fpm后docker会重启,faketime修改无效。
  3. 在docker里面下载php-7.3.0.tar.bz2,composer和faketime,如果网络不好则时间会比较长,这改成先下载好,然后拷贝到docker里打包,节省点时间。nginx,php-fpm的配置也要事先准备好。
  4. 由于是编译安装php,时间会长一点
使用

先使用该dockerfile打个包

docker build -t laravel:v1 .

打完之后运行起来

docker run -itd  -p 9091:80 laravel:v1

docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
d5fcc8f42bd4        laravel:v1          "nginx -g 'daemon of…"   37 seconds ago      Up 35 seconds       0.0.0.0:9091->80/tcp   trusting_darwin

进入docker

docker exec -it d5fcc8f42bd4 /bin/bash
root@d5fcc8f42bd4:/data# 

修改时间下时间

root@d5fcc8f42bd4:/data# date
Sun Aug 25 15:24:40 Asia 2019
root@d5fcc8f42bd4:/data# 
root@d5fcc8f42bd4:/data# export LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME="2019-08-12 10:30:22" 
root@d5fcc8f42bd4:/data# date
Mon Aug 12 10:30:22 Asia 2019

可以看到当前终端的时间已经改了。
看看当前终端下php的时间是不是也改了:

root@d5fcc8f42bd4:/data# echo "<?php echo date('Y-m-d H:i:s'); " > time.php
root@d5fcc8f42bd4:/data# echo 'echo "\n";' >> time.php
root@d5fcc8f42bd4:/data# date
Mon Aug 12 10:30:22 Asia 2019
root@d5fcc8f42bd4:/data# php time.php 
2019-08-12 10:30:22

可以看到也修改了。
再来改下php-fpm的时间

pkill php-fpm ; /usr/local/php/sbin/php-fpm 

访问http://127.0.0.1:9091/time.php ,可以看到当前的运行时间也改了。
不过目前测试php-fpm的生效时间比较短,只有10秒左右,之后会还原,后续在找下原因完善下
-------------- 关于php-fpm时间还原问题的更新
对于php-fpm模式,可以在配置文件中加一个参数clear_env = no,启动php-fpm时则不会清空环境变量,修改的时间就能一直生效了。
对于CLI或swoole模式则没有这个问题,修改时间后重启即可。

国外网友基于faketime做的burp loader的unlimited版本. 需要一堆dll或者so. 详情见如下描述,没有分的可以去github上找. ======================== BurpUnlimited version 1.7.26 release 1.0 + Created by: mxcx@fosec.vn + Email: mxcxvn@gmail.com + Based on: BurpLoader by larry_lau + Github: https://github.com/mxcxvn/BurpUnlimited it's opensource ======================== This project is NOT intended to replace BurpLoader. It just EXTENDS BurpLoader's license! To run the project from the command line: java -javaagent:BurpUnlimited.jar -agentpath:lib/libfaketime -jar BurpUnlimited.jar or double click on BurpUnlimited.jar (set permision before) ## Notes: - There are some requirements files in lib at current folder: + burpsuite_pro_v1.7.26.jar is main object + libfaketime* Lib for hook time activation. Sourcecode is at https://github.com/faketime-java/faketime - For windows, vcredist is required: https://www.microsoft.com/en-gb/download/details.aspx?id=48145 - The folder for_windows_if_you_dont_wanna_install_vcredist is for anyone who don't wana install vcredist, please chose the file for x64 or x86, rename to vcruntime140.dll and copy to BurpUnlimited.jar's folder - To have no unexpected error, please leave all file in the folders which have not any space character (including java binary file in case not run with default java). - This version is tested run stable on MACOSX 64 bit, Ubuntu 64 bit, Windows 64 and 32 bit. If you have any error in starting, please try some ways: + Change manually your datetime to before 01/10/2017 + Build your own libfaketime, sourcecode is at https://github.com/faketime-java/faketime + Or contact me mxcxvn@gmail.com ## Hash MD5 version release 1 BurpUnlimited.jar 5cf68ad0cc2d4ee265d0da1469decf21 lib/ burpsuite_pro_v1.7.26.jar 5d1cbbebc7fb59a399ae7bcacbe05f74 libfaketime32.dll e3842711a065b672dec322c4140b950f libfaketime32.jnilib d2b62d06a972035149bfdefe1605c041 libfaketime32.so 5c2baa272037207533d74faa4291e91d libfaketime64.dll 6659efeee9698609a9ffd9ea8c9d07d1 libfaketime64.jnilib ff3dbde6a28f1c59d829cf5665c8e628 libfaketime64.so 5c2baa272037207533d74faa4291e91d for_windows_if_you_dont_wanna_install_vcredist/ vcruntime140_x32.dll b77eeaeaf5f8493189b89852f3a7a712 vcruntime140_x64.dll 6c2c88ff1b3da84b44d23a253a06c01b
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值