首页 > 其他分享 >rsync 学习笔记(一)编译

rsync 学习笔记(一)编译

时间:2024-09-11 11:48:00浏览次数:10  
标签:opt wf rsync -- Wl 笔记 编译

一、背景

  rsync二进制程序依赖外部库,由于安全问题,有时会单独升级依赖的外部库。另外为了防止因为栈溢出攻击导致服务器被黑,需要对rsync及其依赖的外部库重新编译,开启安全编译选项,增加黑客破解的复杂度。

  所有的库编译必须要求加上如下编译选项:

  • 栈保护(-fstack-protector-all/-fstack-protector-strong)
  • 堆栈不可执行(-Wl,-z,noexecstack)
  • GOT表保护(-Wl,-z,relro)
  • 地址无关代码/地址无关可执行(-fPIC/-fPIE -pie)
  • 立即加载(-Wl,-z,now)
  • strip
  • 指定动态库搜索路径(-Wl,--disable-new-dtags,–rpath,./)

栈保护选项,编译器如果支持strong则开启 -fstack-protector-strong,编译器如果不支持则开启-fstack-protector-all

-Wl,--disable-new-dtags,–rpath,./  指定动态库搜索路径,根据实际引用的库的相对路径配置,如果组件不依赖其它库则不需要

二、操作步骤

1、 rsync依赖的开源库

(1)   通过 ldd rsync 命令查看 rsync二进制软件依赖的库

远程到安装rsync的服务器上,执行 ldd rsync,查看rsync依赖哪些库。

 

通过上图的执行结果,可以看到 rsync 依赖的开源库包括如下:

  • libattr
  • libacl
  • libz
  • liblz4
  • libzstd
  • libxxhash
  • libcrypto

(2)   访问 rsync的github代码库,查看其说明再次确认依赖的库情况

访问地址:https://github.com/RsyncProject/rsync/blob/master/INSTALL.md

从上面可以看到官方介绍依赖的开源库是:

  • acl
  • xattr
  • xxhash
  • zstd
  • lz4
  • openssl crypto

和 ldd 查看比较发现缺少一个libz,而这个对应的是zlib,观察rsync的代码库可以发现其内置了zlib,但是我们需要安全编译,也方便日后可以单独升级 zlib,因此需要关闭不使用其内置的zlib,直接依赖外部的zlib库。

总结以上,rsync依赖的开源库如下

  • acl
  • xattr
  • xxhash
  • zstd
  • lz4
  • openssl crypto
  • zlib

2、 准备工作

2.1 准备编译服务器

准备一台编译服务器,其上已经安装了gcc,用于开源库编译,这里以 10.33.43.42服务器为例,该服务器为一台x64结构服务器。

2.2 下载所有开源库源码

2.2.1 下载 rsync 开源库源码

 

 

 

这里选择 3.3.0 版本。

2.2.2 下载 Acl  开源库源码

  • 远程到编译服务器
  •  执行yum info acl

 

可以看到其中有两个版本,第一个地址访问不了,所以选择第二个地址

 

点击 download 可以看到所有能下载的源码:

https://download.savannah.nongnu.org/releases/acl/

 

选择下载最新 2.3.2 版本。

2.2.3 下载 xxHash 开源库源码

https://github.com/Cyan4973/xxHash

https://github.com/Cyan4973/xxHash/releases

点击 右下角的 release链接可以看到所有的发布版本

 

这里选择 0.8.2 版本

2.2.4 下载 attr 开源库源码

  •  在编译服务器上通过yum info attr方式,发现找不到它的rmp文件,基于此,从网上直接查找
  •  网络搜索 libattr.so 官网,可以找到如下

 

 

 

这里选择使用 2.5.2 版本。

2.2.5 下载 zstd 开源库源码

  • 在 rsync 的install.cmd 上直接点击 zstd 的链接,跳转到 zstd 官网

 

  • 直接在官网上点击github

  • Github上点击 右下角的 release 链接可以看到多个发布版本

 

这里选择 1.5.6 版本

2.2.6 下载 lz4 开源库源码

  • 在 rsync 的install.cmd 上直接点击 lz4的链接,跳转到lz4官网

 

这里选择 1.10.0版本

2.2.7 下载 zlib 开源库源码

 

 

2.2.8 下载 openssl 开源库源码

 

 

这里使用 openssl 3.0.15 版本

3、 开源库编译

  通过第二章节,准备的开源库源码包或者已经编译好的库如下:

  

3.1 准备工作

 远程到编译服务器,创建如下目录

/opt/wf

     |-- openssl

     |--rsync

         |--include

         |--lib

  •  将本地准备的openssl(已经编译好的)目录下的所有目录和文件上传到编译服务器/opt/wf/openssl目录下;
  • 将本地准备的 libz.so.1 文件上传到编译服务器/opt/wf/rsync/lib目录下;
  • 将本地准备的所有tar.gz包上传到编译服务器/opt/wf/rsync/include目录下;

3.1 attr开源库编译

远程到编译服务器,执行以下命令

  • 解压源码

cd /opt/wf/rsync/include

tar -zxvf attr-2.5.2.tar.gz

mv attr-2.5.2 attr

  • ./configure

cd attr

./configure CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

 

  • make
  • make install

 

可以看到so文件被安装到了/usr/lib目录下,编译好的库文件为libattr.so.1.1.2502

  • 将libattr.so.1.1.2502拷贝并重命名到指定目录下

cp /usr/lib/libattr.so.1.1.2502 /opt/wf/rsync/lib/libattr.so.1

3.2 acl 开源库编译

远程到编译服务器,执行以下命令

  • 解压源码

cd /opt/wf/rsync/include

tar -zxvf acl-2.3.2.tar.gz

mv acl-2.3.2 acl

  • ./configure

cd acl

./configure CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

 

  • make
  • make install

 

可以看到so文件被安装到了/usr/lib目录下,编译好的库文件为libacl.so.1.1.2302

  • 将libacl.so.1.1.2302拷贝并重命名到指定目录下

cp /usr/lib/libacl.so.1.1.2302 /opt/wf/rsync/lib/libacl.so.1

3.3 xxHash 开源库编译

xxHash 源码中没有提供configure,已经存在MakeFile文件,所以需要将编译选项直接作为make 的参数传递进去。

 远程到编译服务器,执行以下命令

  • 解压源码

cd /opt/wf/rsync/include

tar -zxvf xxHash-0.8.2.tar.gz

mv xxHash-0.8.2 xxHash

cd xxHash

  •  make

make CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-shared -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

  •  make install

可以看到xxHash目录下有编译好的so文件libxxhash.so.0.8.2

  • 将libxxhash.so.0.8.2拷贝并重命名到指定目录下

cp libxxhash.so.0.8.2 /opt/wf/rsync/lib/libxxhash.so.0

3.4 zstd 开源库编译

zstd源码中没有提供configure,已经存在MakeFile文件,所以需要将编译选项直接作为make 的参数传递进去。

远程到编译服务器,执行以下命令

  • 解压源码

cd /opt/wf/rsync/include

tar -zxvf zstd-1.5.6.tar.gz

mv zstd-1.5.6 zstd

cd zstd

  • make

make CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-shared -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

  • make install

 

可以看到zstd/lib目录下有编译好的so文件libzstd.so.1.5.6

  • 将libzstd.so.1.5.6拷贝并重命名到指定目录下

cp lib/libzstd.so.1.5.6 /opt/wf/rsync/lib/libzstd.so.1

3.5 lz4 开源库编译

Lz4源码中没有提供configure,已经存在MakeFile文件,所以需要将编译选项直接作为make 的参数传递进去。

远程到编译服务器,执行以下命令

  • 解压源码

cd /opt/wf/rsync/include

tar -zxvf lz4-1.10.0.tar.gz

mv lz4-1.10.0 lz4

cd lz4

  • make

make  CFLAGS="-fstack-protector-all -fPIC -I/opt/wf/rsync/include/lz4/lib"  CPPFLAGS="-fstack-protector-strong -fPIC -I/opt/wf/rsync/include/lz4/lib"  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

  • make install

 

可以看到lz4/lib目录下有编译好的so文件liblz4.so.1.10.0

  • 将liblz4.so.1.10.0拷贝并重命名到指定目录下

cp lib/liblz4.so.1.10.0 /opt/wf/rsync/lib/liblz4.so.1

3.6 rsync 开源库编译

远程到编译服务器,执行以下命令

  • 解压源码

cd /opt/wf/rsync/include

tar -zxvf rsync-3.3.0.tar.gz

mv rsync-3.3.0 rsync

cd rsync

  • 修改checksum.c 中的源码

将文件中的 EVP_MD_CTX_create 全部修改成 EVP_MD_CTX_new

 

  • 指定openssl库的位置

先通过export 指定 openssl 的库路径,这里使用的是openssl 3 ,位置在/opt/wf/openssl

export LD_LIBRARY_PATH=/opt/wf/openssl/lib:$LD_LIBRARY_PATH

  • ./configure

./configure --disable-md2man --with-included-zlib=no --with-included-popt CFLAGS="-fstack-protector-all -fPIC -I/opt/wf/openssl/include"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./  -L/opt/wf/openssl/lib -lssl -lcrypto"

  • 修改configure.status

将该文件拿到本地,搜索关键字SIZEOF_,将其内容修改成如下:

 

  • make

 

可以看到编译好的rsync文件就在当前目录下

ldd rsync 可以看到这个二进制文件依赖的库

 

  • 将openssl/lib下的libcrypto.so.3\libssl.so.3 以及 rsync 移动到 /opt/wf/rsync/lib下

cp rsync /opt/wf/rsync/lib/

cp /opt/wf/openssl/lib/libssl.so.3 /opt/wf/rsync/lib/

cp /opt/wf/openssl/lib/libcrypto.so.3 /opt/wf/rsync/lib/

  • 进入到/opt/wf/rsync/lib 下,再次执行ldd rsync ,查看其依赖的库是否都在当前目录下(最好重新打开一个远程)

 

可以看到到此rsync编译完毕,只要将 /opt/wf/rsync/lib 下所有库和文件拿到本地即可,这样rsync 编译完成。

3.7 检查编译出来的库是否都是安全的

使用公共安全库提供的checksec.sh-2.7.1.zip 程序进行校验,将该包放置到编译服务器/opt/wf下,进行如下操作:

cd /opt/wf

unzip checksec.sh-2.7.1.zip

mv checksec.sh-2.7.1 check

cd check

./checksec  --dir=/opt/wf/rsync/lib    #如果检查单个文件使用 --file=xxxx.so

 

明显以上库是安全的。

四、问题与总结

1、Acl 编译报错提示缺失“attr/error_context.h”

  在执行 ./configure 命令时,直接报错了,配置不通过,如下:

 

原因分析

提示缺失 attr/error_context.h 找不到,因此acl 依赖attr,需要先编译attr开源库和安装。

解决办法

先编译和安装attr开源库,再编译acl 开源库。

2、xxHash编译报错提示“undefined reference to main”

现象

在执行make(make CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./")命令时,直接报错,具体如下

 

解决办法

   将make命令中的系列参数 –pie修改成 -shared

make CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-shared -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./" 将-pie去掉换成-shared 才正常  (分析出来是这个原因是直接make可以成功,将直接make过程与添加编译选择的执行过程做了比较,发现需要改成shared)

3、zstd编译报错提示“undefined reference to main”

现象

在执行make(make CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./")命令时,直接报错,具体如下

 

解决办法

   将make命令中的系列参数 –pie修改成 -shared

make CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-shared -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./" 将-pie去掉换成-shared 才正常  (分析出来是这个原因是直接make可以成功,将直接make过程与添加编译选择的执行过程做了比较,发现需要改成shared)

 

4、 lz4编译报错提示“fatal error:xxhash.h:No such file or directory”

现象

在执行make(make CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./")命令时,直接报错,具体如下

根据错误提示,貌似是在提示找不到 xxhash.h 文件

分析

   深入会发现xxhash.h 文件其实在 lz4的lib目录下,也就是说make时其无法自动搜索到lib目录,找到这个文件,为此编译时需要加上-I指定追加的文件搜索路径。

 

解决办法

make  CFLAGS="-fstack-protector-all -fPIC -I/opt/wf/rsync/include/lz4/lib"  CPPFLAGS="-fstack-protector-strong -fPIC -I/opt/wf/rsync/include/lz4/lib"  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

在CFLAGS和CPPFLAGS上都加上-I/opt/wf/rsync/include/lz4/lib选项,在进行编译可以成功。

 

5、 rsync configure命令执行完之后,make报错“error:unknown type name ‘int32’”

现象

首先执行:./configure --disable-md2man --with-included-zlib=no --with-included-popt CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

再次执行make命令,执行的时候报如下错误

 

分析

   在rsync github issue 上查到有人提过这个问题,查看作者的回复发现是因为rsync默认是32位上编译的,而我们当前编译服务器是64位操作系统,所以检测不通过,需要手动更改configure命令执行完成之后生成的config.status文件。

 

从图上可以看到这些值全是0,需要修改成正确的值。

解决方案

   将config.status文件拿到本地,按照关键字“SIZEOF_”,将对应的key值修改成如下的值。

 

6、 rsync 编译需要指定openssl

现象

由于openssl 也需要重新安全编译,因此rsync只能依赖我们编译好的openssl,不能使用系统默认的openssl。对此,rsync编译的时候需要指定openssl,否则会出现如下错误:

配置的命令为

 ./configure --disable-md2man --with-included-zlib=no --with-included-popt CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

  make 之后 生成的 rsync文件使用 ldd 查看依赖的库

 

提示:version ‘libcrypto.so.10’ not found (required by ./rsync)

通过查看资料和网上百度,需要在LDFLAGS上添加-lssl –lcrypto 表示使用指定的openssl 库进行编译,添加-L/opt/wf/openssl/lib表示在编译的时候从指定的openssl 的库目录加载库文件;在CFLAGS上添加-I/opt/wf/openssl11/openssl/include表示在编译的时候从指定的openssl的头文件目录加载需要的头文件。

因此 最终的configure命令调整成如下:

./configure --disable-md2man --with-included-zlib=no --with-included-popt CFLAGS="-fstack-protector-all -fPIC -I/opt/wf/openssl/include"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./  -L/opt/wf/openssl/lib -lssl -lcrypto"

7、 rsync configure时提示“./configtest:error while loading shared libraries:libssl.so.1”

现象

    执行了./configure --disable-md2man --with-included-zlib=no --with-included-popt CFLAGS="-fstack-protector-all -fPIC -I/opt/wf/openssl/include"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./  -L/opt/wf/openssl/lib -lssl -lcrypto" 命令过程中,发现自行失败,提示的具体信息如下:

 

分析

    通过界面提示的错误分析,发现 gcc 编译成功生成了configtest二进制文件,但是在执行的时候提示configtest需要libssl.so.1 库,但是加载不到这个库。在编译configtest二进制文件,虽然在编译的时候通过rpath指定了./ 相对路径,但是libssl.so.1 文件的确不在configtest 所属当前目录下,其在 /opt/wf/openssl/lib 下,因此想到使用export 的方式指定库搜索路径。

解决方案

为了解决上述找不到ssl库的问题,需要在执行configure命令之前,先通过export 指定 openssl 的库路径,export LD_LIBRARY_PATH=/opt/wf/openssl/lib

8、 rsync configure时提示”libssl.so:file format not recognized;treating as linker script”

现象

  执行了./configure --disable-md2man --with-included-zlib=no --with-included-popt CFLAGS="-fstack-protector-all -fPIC -I/opt/wf/openssl/include"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./  -L/opt/wf/openssl/lib -lssl -lcrypto" 命令过程中,发现自行失败,提示的具体信息如下:

分析

   通过查找相关资料,发现是 openssl/lib 下的libssl.so 文件是 ASCII text 格式的

  执行命令 file libssl.so

 

解决方案

  不能在本地解压 openssl.zip 文件之后再上传到编译服务器上,需要将zip包直接上传到编译服务器上,然后通过 unzip 命令进行解压,才不会改变so文件的编码格式。

 

五、小知识点

1、查看so的编码信息

  file xxx.so

2、编译时可指定 头文件路径

gcc xxx xxx -I/opt/wf/test/include

3、编译时可指定依赖库的所在路径

gc xxx xxx -L/opt/wf/test/lib

4、编译时可指定运行的时候从哪个目录搜索依赖的库

gc xxx xxx -Wl,-rpath=.       

-Wl,-rpath=.  表示从运行文件的当前目录去搜索库

 

标签:opt,wf,rsync,--,Wl,笔记,编译
From: https://www.cnblogs.com/sandyflower/p/18407939

相关文章

  • OJ在线判题系统项目笔记
    项目介绍在线评测编程题目代码的系统,出题人预先设置题目的输入样例和输出样例,根据用户提交代码,进行编译代码,运行代码,判断代码执行结果是否正确。后端服务网关服务接收前端请求,转发到对应的服务用户服务用户注册、用户登录、用户退出题目服务题目浏览,在线做题,题目提......
  • PMP模拟考试第48题笔记
    注:quiteresistan 相当抵抗 originally 起初engage参与stakeholderengagementassessmentmatrix 利益相关者参与评估矩阵assessment 评估riskregister  风险登记册stakeholderoutlining  利益相关者概述在管理大型项目时,处理利益相关者的支持和抗拒......
  • kafka入门(千峰)学习笔记
    前言视频链接https://www.bilibili.com/video/BV1Xy4y1G7zA一、kafka介绍1、为什么使用消息队列实现异步通信2、消息队列的流派消息队列解决了通信问题(1)、有broker(类似消息中转站)a.重topic:kafka、activemq、rocketmqb.轻topic:rabbitmq(2)、无broker:zeromq3、kafka安......
  • LAMAR论文阅读笔记
    LargeLanguageModelsAugmentedRatingPredictioninRecommenderSystem论文阅读笔记Abstract现存的问题:​ 由于对推荐中的协作信息缺乏了解,它们在推荐任务(如评分预测任务)中的直接应用往往达不到最佳效果。提出方法:​ 在本文中,我们提出了LargelAnguageModelAugmented......
  • 【爬虫软件】小红书按关键词批量采集笔记,含笔记正文、转评赞藏等!
    一、背景介绍1.1爬取目标熟悉我的小伙伴都了解,我之前开发过2款软件:【GUI软件】小红书搜索结果批量采集,支持多个关键词同时抓取!【GUI软件】小红书详情数据批量采集,含笔记内容、转评赞藏等!现在介绍的这个软件,相当于以上2个软件的结合版,即根据关键词爬取笔记的详情数......
  • shader 案例学习笔记之绘制圆
    环境搭建:参考glslvscode环境搭建先上代码#ifdefGL_ESprecisionmediumpfloat;#endifuniformvec2u_resolution;voidmain(){vec2st=gl_FragCoord.xy/u_resolution.xy;st-=0.5;st.x*=u_resolution.x/u_resolution.y;floatr=length(st);......
  • C#笔记9 对线程Thread的万字解读 小小多线程直接拿下!
    上一条笔记有些潦草,这是因为昨天并没有很好的理解线程可以进行的操作。今天准备细化自己对这方面的理解和记录。来看看细节吧!环境:VS2022系统:windows10环境:.Net8.0以及.NetFrameWork4.7.2(winform)线程是什么?线程是什么?每个操作系统上运行的应用程序都是一个进程,一个......
  • 思源笔记-S3-七牛云-多设备同步
    文档参考:思源笔记配置S3同步、思源笔记使用七牛云编写日期:2024.9.9一、思源笔记安装思源笔记官方下载地址选择对应系统版本进行下载双击【SiYuanInstaller.exe】进行安装二、注册账号注册账号是为了购买订阅,订阅后才提供S3/WEBDAV同步功能打开SiYuan......
  • 代码整洁之道--读书笔记(7)
    代码整洁之道简介:本书是编程大师“Bob大叔”40余年编程生涯的心得体会的总结,讲解要成为真正专业的程序员需要具备什么样的态度,需要遵循什么样的原则,需要采取什么样的行动。作者以自己以及身边的同事走过的弯路、犯过的错误为例,意在为后来者引路,助其职业生涯迈上更高台阶。本......
  • 痞子衡嵌入式:在MDK开发环境下自定义安装与切换不同编译器版本的方法
    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是在MDK开发环境下自定义安装与切换不同编译器版本的方法。KeilMDK想必是嵌入式开发者最熟悉的工具之一了,自2005年Arm公司收购Keil公司之后,MDK就走上了发展快车道,从v2.50a一路狂奔到现在最新的v......