使用diff和patch工具打补丁

优化提升常见网络服务的安全性

  • 使用diff对比文件差异
  • 使用diff生成补丁文件
  • 使用patch命令为旧版本打补丁

程序是人设计出来的,总是会有这样那样的问题与漏洞,目前的主流解决方法就是为有问题的程序打补丁,升级新版本。
在Linux系统中diff命令可以为我们生成补丁文件,然后使用patch命令为有问题的程序代码打补丁。

步骤一:对比单个文件差异

** 编写两个版本的脚本,一个为v1版本,一个为v2版本**

cat test1.sh            #v1版本脚本
    #!/bin/bash
    echo "hello wrld"
cat test2.sh            #v2版本脚本
    #!/bin/bash
    echo "hello world"
    echo "test file"

使用diff命令语法

 diff  test1.sh test2.sh                                #查看文件差异
         @@ -1,3 +1,3 @@
         #!/bin/bash
        -echo "hello world"
        -echo "test"
        +echo "hello the world"
        +echo "test file"
[roo@svr5 ~]# diff -u test1.sh test2.sh         #查看差异,包含头部信息
        --- test1.sh    2018-02-07 22:20:02.723971251 +0800
        +++ test2.sh    2018-02-07 22:20:13.358760687 +0800
        @@ -1,3 +1,3 @@
         #!/bin/bash
        -echo "hello world"
        -echo "test"
        +echo "hello the world"
        +echo "test file"

diff制作补丁文件的原理

告诉我们怎么修改第一个文件后能得到第二个文件。
这样如果第一个版本的脚本有漏洞,我们不需要将整个脚本都替换,仅需要修改有问题的一小部分代码即可,diff刚好可以满足这个需求!
像Linux内核这样的大块头,一旦发现有一个小漏洞,我们不可能把整个内核都重新下载,全部替换一遍,而仅需要更新有问题的那一小部分代码即可!

diff命令常用选项:

-u  输出统一内容的头部信息(打补丁使用),计算机知道是哪个文件需要修改
-r  递归对比目录中的所有资源(可以对比目录)
-a  所有文件视为文本(包括二进制程序)
-N  无文件视为空文件(空文件怎么变成第二个文件)
-N选项备注说明:
A目录下没有txt文件,B目录下有txt文件
diff比较两个目录时,默认会提示txt仅在B目录有(无法对比差异,修复文件)
diff比较时使用N选项,则diff会拿B下的txt与A下的空文件对比,补丁信息会明确说明如何从空文件修改后变成txt文件,打补丁即可成功!

对比目录中所有文件的差异

[roo@svr5 demo]# diff -u source1/ source2/
#仅对比了文本文件test.sh;二进制文件、tmp都没有对比差异,仅提示,因为没有-a和-N选项

[roo@svr5 demo]# diff -Nu source1/ source2/
#对比了test.sh,并且使用source2目录的tmp.txt与source1的空文件对比差异。

[roo@svr5 demo]# diff -Nua source1/ source2/
#对比了test.sh、tmp.txt、find(程序)。

diff -Nura source1/ source2/  >  source.patch       #生成补丁文件

使用patch命令对单文件代码打补丁

[roo@svr5 ~]# cd demo
[roo@svr5 demo]# vim test1.sh
        #!/bin/bash
        echo "hello world"
        echo "test"
[roo@svr5 demo]# vim test2.sh 
        #!/bin/bash
        echo "hello the world"
        echo "test file"

** 生成补丁文件**

diff -Nua test1.sh test2.sh > test.patch

使用patch命令打补丁

[roo@svr5 demo]# yum -y install patch
[roo@svr5 demo]# patch -p0 < test.patch             #打补丁
        patching file test1.sh
        #patch -pnum(其中num为数字,指定删除补丁文件中多少层路径前缀)
        #如原始路径为/u/howard/src/blurfl/blurfl.c
        #-p0则整个路径不变
        #-p1则修改路径为u/howard/src/blurfl/blurfl.c
        #-p4则修改路径为blurfl/blurfl.c
        #-R(reverse)反向修复,-E修复后如果文件为空,则删除该文件
[roo@svr5 demo]# patch -RE < test.patch             #还原旧版本,反向修复

在不同目录下为代码打补丁

[roo@svr5 demo]# cd ..
[roo@svr5 ~]# diff -Nura demo/test1.sh demo/test2.sh > source.patch
[roo@svr5 ~]# cat source.patch                  #补丁文件带路径信息
        --- demo/test1.sh    2018-02-08 22:03:14.284229418 +0800
        +++ demo/test2.sh    2018-02-07 22:20:13.358760687 +0800
[roo@svr7 ~]# patch -p0 < test.patch            #在demo外打补丁
[roo@svr7 ~]# cd demo
[roo@svr7 demo]# patch -p1 < ../test.patch  #在demo内打补丁

使用patch命令对目录下的所有代码打补丁

使用前面创建的source1和source2目录下的代码为素材,生成补丁文件
[roo@svr5 ~]# cd demo
[roo@svr5 demo]# diff -Nuar source1/ source2/ > source.patch

使用patch命令为代码打补丁
[roo@svr7 demo]# ls
        source1  source2  source.patch
[roo@svr7 demo]# cat source.patch                //对比的文件有路径信息
        --- source1/test.sh 2018-02-07 22:51:33.034879417 +0800
        +++ source2/test.sh 2018-02-07 22:47:32.531754268 +0800
        @@ -1 +1 @@
        -hello world
        +hello the world
[roo@svr7 demo]# cd source1
[roo@svr7 source1]# patch  -p1 < ../source.patch

发表评论