• 关于git的一些谜


    关于git的一些谜

      话说五一前去了趟省中心开会,主要讲应急预案文档。开完会之后,那边的技术对接人提到一个类似金钟罩防护的东西,想下班之后锁死静态网页目录下所有文件,啥人啥操作都不能改(不查不知道,原来“金钟罩”是个中国传统武术中的一种武术功能,突然发现很多技术人员都自带各种诗情画意。。。),叫我查下市面上有没有这种产品,然后最后他提到linux上好像有命令能锁死,具体他不知道叫什么(我当然知道他说什么了),回到公司就准备试试chattr,那会最担心的是对所有文件上锁会不会特别久,解锁也是。实测,很快!

     

      第1天的时候,我在线上一台有公网的服务器上,把前几天静态网页目录备份文件拷过来(压缩备份的时候我是排除.git备份的,因为奇大无比),所以测试非常成功。参考了这篇文章:https://www.cnblogs.com/kevingrace/p/8277820.html

    for A in `ls -l /data/test/|grep -v total|awk '{print $9}'`;do
    
         /usr/bin/chattr +ai /data/test/${A}

    他这条命令有点问题,或者说我的测试环境不适合。只能对 /data/test 下的第一层目录进行上锁,但是目录下递归到的文件,全部没有起效!

       

     我的改良版变成这样,成功把子目录下的所有文件都上锁了,包括隐藏文件。

    find . -name "[!.]*"  这句好像没用的
     find $PWD | find . -name "[!.]*" | xargs ls -ld | grep -v total|awk '{print $9}' |  xargs chattr +ai

       然后我就充满信心地,第二天拿备机去模拟生产(对了,当天的日志,我提到我做的测试工作,老板都有点害怕,评论叫我多测几次才上生产),确实,发现很多问题。。。  

      第二天用备机测试,假设静态目录叫status_ljy,整个目录连.git,共16G,.git目录有6.7G。(主服务器更大,30G,.git目录20G,这个是后话哈~~~)

      为了更真实地模拟生产环境,我把主服务器的防篡改监控脚本拎了过来:运行git status命令,看是否有“nothing to commit”字样,有就代表线上没被人改过东西,否则就要查下具体是什么原因了(大家可以结合该文一起看:【网站防篡改内容监控】https://www.cnblogs.com/windysai/p/14354460.html)

      写好加锁脚本:addchattr.sh

     1 #!/bin/bash
     2 
     3 gitDir='/home/hahah/data/html/status_ljy'
     4 DATE=`date +%F_%H:%M`
     5 recordfile='/tmp/addchattr.log'
     6 >${recordfile}
     7 
     8 echo "脚本功能:给文件特殊权限,不能作任何修改" >> ${recordfile}
     9 echo "开始运行脚本时间为: $DATE" >> ${recordfile}
    10 
    11 cd $gitDir
    12 ## 1、去掉隐藏文件, 筛选第9列文件名,然后递归文件上锁 ——》 .git 目录下还是会加锁
    13 find $PWD | find . -name "[!.]*" | xargs ls -ld | grep -v total|awk '{print $9}' | xargs chattr +ai 
    14 
    15 #改良(好像有bug)
    16 #find $PWD | find . -name "[!.]*" | grep -v .git |grep -v .gitignore |xargs ls -ld | grep -v total|awk '{print $9}'
    17  | xargs chattr +ai
    18 
    19 
    20 ## 2、去掉.git目录的加锁
    21 #cd $gitDir/.git
    22 #find $PWD | xargs ls -ld | grep -v total|awk '{print $9}' | xargs chattr -ai
    23 #cd $gitDir
    24 #chattr -ai .git
    25 
    26 echo "############################" >> ${recordfile}
    27 echo "" >> ${recordfile}
    28 DATE1=`date +%F_%H:%M`
    29 echo "结束运行脚本时间为: $DATE1" >> ${recordfile}

      敲黑板!!!一开始我是跑这条的,没有放后台跑,直接sh -x  /root/scripts/addchattr.sh

      find $PWD | find . -name "[!.]*" | xargs ls -ld | grep -v total|awk '{print $9}' | xargs chattr +ai 

      然后就静静地看着git status定时脚本监控的结果,竟然报警了,

    核心命令如下: 

    git status > ${gd_gitstatus}
    cat ${gd_gitstatus} |grep "nothing to commit"
    status=`echo $?`
    
    if [ $status -ne 0 ]; then
        curl 报警  
    fi

         原来这个文件为空了,导致误报,而且另一个终端屏开着个top -c 看着服务器负载

      负载很高,我都怕了,虽然测试的是网站备用服务器,但却是另外一个项目的正式服务器来的,当时交付过来的机器不太够,所以两个项目就装一块去了。

      我马上干掉git status 的脚本,然后停了这个监控,手动测试下。确实一运行git staus服务器负载就飙高,我特意测下究竟跑一轮有返回结果的git status需要多长时间(是的,真的是铤而走险了,别的项目的正式服务器哦)

       我印象中git status 没有这么慢的,所以这是第一个谜。说来也奇怪,第二次运行,会快很多。当时我在想是不是.git目录过大导致的,还是因为我对整个.git 目录也上锁导致的。脚本上这条命令是没用的,隐藏目录下的文件照样上锁。

    find . -name "[!.]*"

      我就想着验证下猜想,给.git 目录解锁重测,实际上有没有对.git目录加锁,只要对静态目录status_ljy 里面的文件加锁了,第一次运行git status 返回的结果都很慢!

      然后就有了上面的改良命令

    find $PWD | find . -name "[!.]*" | grep -v .git |grep -v .gitignore |xargs ls -ld | grep -v total|awk '{print $9}'  | xargs chattr +ai

      当然旧的那条命令还用的话也行,换成:“2、去掉.git目录的加锁”  就可以了。

      

    ###### 2021-05-11

      第二个谜,这个真是有点莫名其妙。如果有热心小伙伴知道是什么原因,欢迎交流 ^___^

      话说测试git status返回时间的时候,我一直在status_ljy路径下。当时不想开那么多终端屏,所以直接放后台运行脚本加锁:nohup sh /root/scripts/addchattr.sh &

      不查不知道,这条命令会在当前目录下产生一个nohup_out 日志文件的。解锁之后就试着删除(不删除的话,git status肯定会报错,防修改测试就无法继续下去了),连root都删除不了!但可以追加,lsattr 查看文件正常,没有ia的上锁标记。

      

     解锁核心命令就两条,无论我运行多少次 chattr -ai nohup.out,然后再rm -rf nohup.out 都会报错“Permission denied”

    cd ${gitDir}
    find $PWD | find . -name "[!.]*" | xargs ls -ld | grep -v total|awk '{print $9}' | xargs chattr -ai

      当时我就想最有可能的是git的本地暂存区上,果然:

       然后各种查资料,用 git clean 去删除git库中untracked files(未监控)的文件;先git add 再commit,然后git rm -r --cached ;甚至添加到.gitignore隐藏文件,忽略这些untracked files,然后再删。统统都无法解决。

      当我绝望之际,就想改个名,叫status_ljy_bad(mv staus_ljy status_ljy_bad),这样我还能重新建个status_ljy,git去初始化,让nginx去代理这个目录,这个后缀bad目录就放着吧。

    神奇的事情发生了,进去后发现里面的东西没了,只剩一个html/calc 的目录(初时还以为服务器被入侵,因为打开的文件内容看着比较奇葩),里面有隐藏的 .svn 目录,lsattr .svn 也是看不出带有 ai 标志,但其实都是已经上锁了的,所以需要把每层.svn去ai操作(chattr -ai .svn),然后逐级目录删才行。

       细心的读者其实可以看出加锁命令是没有针对 .svn 分类讨论的,当时我也没想过项目里面有隐藏的 .svn,跟开发沟通过,说以前这个系统就是用.svn,也真的发现内网服务器也有,通过gitlab同步到线上的,开发说能删除所有.svn。

      至此,算是告一段落了~~~ 这个谜等到时自己知识储备充足再回头看可能会有点眉目,先记下。。。。 

  • 相关阅读:
    php 将富文本编辑后的内容取出
    阿里云Windows远程连接出现身份验证错误,要求的函数不正确”的报错。
    composer切换中国镜像
    php获取当月天数及当月第一天及最后一天、上月第一天及最后一天实现方法
    golang ioutil 包源码阅读
    ssh 远程登录 REMOTE HOST IDENTIFICATION HAS CHANGED 问题
    Golang -- fallthrough
    Golang 执行 go run main.go 显示 undefined
    Golang Playground 进度条示例
    关系型数据库和非关系型数据库(NOSQL)
  • 原文地址:https://www.cnblogs.com/windysai/p/14746912.html
Copyright © 2020-2023  润新知