RPM(Red Hat Package Manager)是用于 Linux 分发版(distribution)的最常见的软件包管理器。
制作RPM包不复杂,关键是对SPEC文件的编写,所以我们需要了解spec的文件语法。
服务器ip
[root@master ~]# 10.10.10.10 master
#关闭防火墙
[root@master ~]# systemctl stop firewalld.service
[root@master ~]# systemctl disable firewalld.service
#关闭selinux,需要重启
[root@master ~]# sed -i 's:SELINUX=enforcing:SELINUX=disabled:g' /etc/selinux/config
#临时关闭seLinux
[root@master ~]# setenforce 0
#重启
[root@master ~]# reboot
# 安装rpm打包工具
[root@master ~]# yum -y install rpm-build rpmdevtools
# 编译打包工具
[root@master ~]# yum -y install gcc gcc-c++ autoconf automake make
# 创建rpm目录
[root@master ~]# rpmdev-setuptree
# 查看目录结构
[root@master ~]# tree ~/rpmbuild
/root/rpmbuild
├── BUILD
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS
5 directories, 0 files
SPEC指令 定义
Name 包基本名称,应于spec文件名匹配
Version 版本号
Release 打包次数,递增。初始值为 1%{?dist}
Summary 简介
License 软件许可
URL 通常为软件官网
Source0 源代码压缩归档的路径或URL,多个时使用 SourceX
Patch0 补丁,多个时 PatchX
BuildArch 系统架构,如x86_64 noarch
BuildRequires 以逗号或空格分隔的依赖包列表,用于构建过程,可以有多个条目
Requires 以逗号或空格分隔的运行时依赖列表,用于安装过程,可以有多个条目
ExcludeArch 需要排除的系统架构
%description 软件的完整描述,可跨多行,以空行结束
%prep 准备阶段,常为解压源码归档,可包含shell脚本
%build 构建阶段
%install 安装阶段,将文件从%builddir复制到%buildroot
%pre 安装前执行的脚本
%setup 不加任何选项,仅将软件包打开。
%setup -a 切换目录前,解压指定 Source 文件,例如 `-a 0` 表示解压 `Source0`
%setup -n newdir 将软件包解压在newdir目录。
%setup -c 解压缩之前先产生目录。
%setup -b num 将第 num 个 source 文件解压缩。
%setup -D 解压前不删除目录
%setup -T 不使用default的解压缩操作。
%setup -T -b 0 将第 0 个源代码文件解压缩。
%setup -c -n newdir 指定目录名称 newdir,并在此目录产生 rpm 套件。
%patch 最简单的补丁方式,自动指定patch level。
%patch 0 使用第0个补丁文件,相当于%patch ?p 0。
%patch -s 不显示打补丁时的信息。
%patch -T 将所有打补丁时产生的输出文件删除
%post 安装后执行的脚本
%preun 卸载前执行的脚本,升级的时候会执行
%postun 卸载后执行的脚本,升级 rpm 包的时候不会执行
%pretrans 在事务开始时执行脚本
%posttrans 在事务结束时执行脚本
%check 测试阶段,通常运行单元测试
%files 指定最终需要安装的文件列表
%clean 删除缓存文件
%changelog 本段是修改日志段,记录 spec 的修改日志段
%changelog 更新记录
%pre 在安装软件包之前执行
%post 在安装软件包之后执行
%preun 在卸载软件包之前执行
%postun 在卸载软件包之后执行
%defattr(文件权限,用户名,组名,目录权限)
rpmbuild -bp:执行%prep
rpmbuild -bc:执行%build
rpmbuild -bi:执行%install
rpmbuild -ba:编译后做成rpm包和src.rpm包
rpmbuild -bs:仅制作src.rpm包
rpmbuild -bb:仅制作rpm包
#
# 编译一个单纯独立项目的软件,以nginx为例
# 进入目录
[root@master ~]# cd ~/rpmbuild
# 下载代码
[root@master rpmbuild]# wget http://nginx.org/download/nginx-1.14.0.tar.gz -P SOURCES
# 创建spec文件
[root@master rpmbuild]# rpmdev-newspec -o SPECS/nginx-1.14.0.spec
# 编辑nginx.spec文件
[root@master rpmbuild]# cat SPECS/nginx-1.14.0.spec
Name: nginx
Version: 1.14.0
Release: 3%{?dist}
Summary: 010sec team
License: GPL
URL: http://010sec.com,http://nginx.org/download/
Source0: nginx-1.14.0.tar.gz
%description
010sec
%prep
%setup -q
%build
./configure --prefix=/opt/nginx --without-http_rewrite_module --without-http_gzip_module
make %{?_smp_mflags}
make install DESTDIR=%{buildroot}
%clean
%files
/opt/xd/xxxxnginx
%doc
%changelog
# 编译
[root@master rpmbuild]# rpmbuild -bb SPECS/nginx-1.14.0.spec
[root@master rpmbuild]# ll /root/rpmbuild/RPMS/x86_64/
-rw-r--r-- 1 root root 1739644 Jan 23 15:02 nginx-1.14.0-3.el7.centos.x86_64.rpm
# 查看rpm信息
[root@master ~]# rpm -qpi rpmbuild/RPMS/x86_64/nginx-1.14.0-3.el7.centos.x86_64.rpm
Name : nginx
Version : 1.14.0
Release : 3.el7.centos
Architecture: x86_64
Install Date: (not installed)
Group : Unspecified
Size : 7158015
License : GPL
Signature : (none)
Source RPM : nginx-1.14.0-3.el7.centos.src.rpm
Build Date : Wed 23 Oct 2019 03:02:37 PM CST
Build Host : master
Relocations : (not relocatable)
URL : http://010sec.com,http://nginx.org/download/
Summary : 010sec team
Description :
010sec
# 安装方法很简单,方法一
[root@master rpmbuild]# rpm -ivh nginx-1.14.0-3.el7.centos.x86_64.rpm
# 方法二
[root@master rpmbuild]# yum localinstall nginx-1.14.0-3.el7.centos.x86_64.rpm -y
# 不放在rpm标准目录编译
[root@master rpmbuild]# tar zxf SOURCE/nginx-1.14.0.tar.gz -C ~/
[root@master rpmbuild]# cd ~/nginx-1.14.0
[root@master nginx-1.14.0]# cat nginx.spec
Summary: High Performance Web Server ##
Name: nginx
Version: 1.14.0
Release: el7
License: GPL
Group: Applications/Server
Source: http://nginx.org/download/nginx-%{version}.tar.gz
URL: http://nginx.org/
Distribution: Linux
Packager: c4rt1y<c4rt1y@010sec.com>
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}
%define srcdir /root/nginx-1.14.0
%description
nginx [engine x] is a HTTP and reverse proxy server, as well as a mail proxy server
%prep
%build
cd %{srcdir}
./configure --prefix=/opt/xd/testnginx --without-http_rewrite_module --without-http_gzip_module
make -j8
%install
cd %{srcdir}
make DESTDIR=%{buildroot} install
%preun
if [ -z "`ps aux | grep nginx | grep -v grep`" ];then
killall nginx >/dev/null
exit 0
fi
%files
/opt/xd/testnginx
[root@master nginx-1.14.0]# rpmbuild -bb nginx-1.14.0.spec
[root@master rpmbuild]# ll /root/rpmbuild/RPMS/x86_64/
-rw-r--r-- 1 root root 1739644 Jan 09 13:02 nginx-1.14.0-3.el7.centos.x86_64.rpm
-rw-r--r-- 1 root root 273236 Jan 09 15:23 nginx-1.14.0-el7.x86_64.rpm
# 标准目录下,多文件操作
[root@master rpmbuild]# wget http://distfiles.macports.org/openssl/openssl-1.0.2l.tar.gz -P SOURCES
[root@master rpmbuild]# wget http://ftp.pcre.org/pub/pcre/pcre-8.41.tar.gz -P SOURCES
[root@master rpmbuild]# wget http://tengine.taobao.org/download/tengine-2.1.2.tar.gz -P SOURCES
[root@master rpmbuild]# wget http://www.zlib.net/fossils/zlib-1.2.11.tar.gz -P SOURCES
[root@master rpmbuild]# cat SOURCES/nginx.conf
user 010sec;
worker_processes auto;
worker_cpu_affinity auto;
error_log "pipe:/usr/sbin/cronolog /home/010sec/logs/nginx/%Y%m%d-error.log";
pid /home/010sec/logs/nginx/nginx.pid;
events {
use epoll;
worker_connections 65535;
accept_mutex off;
}
http {
#定义日志格式
log_format main '$remote_addr||$time_iso8601||$http_host||$server_port||$request_method||$scheme||$request_uri||$server_protocol||$status||$body_bytes_sent||$http_referer||$http_user_agent||$http_x_real_ip||$http_x_forwarded_for||$request_time||$upstream_addr||$upstream_response_time||$upstream_status||';
access_log "pipe:/usr/sbin/cronolog /home/010sec/logs/nginx/%Y%m%d-access_log-default" main;
sendfile on;
sendfile_max_chunk 512k; #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限
send_timeout 30; #客户端响应超时时间,若客户端停止读取数据,释放过期的客户端连接,默认60s
tcp_nopush on; #告诉nginx在一个数据包里发送所有头文件,而不一个接一个的发送
tcp_nodelay on; #是否启用 nagle 缓存算法,告诉nginx不要缓存数据
server_tokens off; #Nginx打开网页报错时,关闭版本号显示
autoindex off;
keepalive_timeout 65; #HTTP连接持续时间,值越大无用的线程变的越多,0:关闭此功能,默认为75
types_hash_max_size 2048;
# 以上两项是设置请求头和请求体各自的超时时间
client_header_timeout 10;
client_body_timeout 10;
# 告诉nginx关闭不响应的客户端连接
reset_timedout_connection on;
# 用于保存各种key,如:当前连接数的共享内存的参数,5m是5兆字节,这个值应该被设置的足够大,以存储(32K*5)32byte状态或者(16K*5)64byte状态
limit_conn_zone $binary_remote_addr zone=addr:5m;
# key最大连接数,这里key是addr,我设置的值是100,这样就允许每个IP地址最多同时打开100个连接数
limit_conn addr 100;
#客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小进行设置
client_body_buffer_size 10K;
client_header_buffer_size 32k;
# 上传文件大小设置,一般是动态应用类型
large_client_header_buffers 4 32k;
client_max_body_size 10m;
#nginx启动出现could not build the server_names_hash, you should increase错误时,请提高这个参数的值一般设成64就够了
server_names_hash_bucket_size 64;
server_name_in_redirect off;
# 使用的默认的 MIME-type
include mime.types;
default_type application/octet-stream;
# GZIP性能优化
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any; #允许或者禁止压缩基于请求和响应的响应流,若设置为any,将会压缩所有请求
gzip_min_length 1k; #对数据启用压缩的最少字节数,大于1k才压缩
gzip_comp_level 6; #gzip压缩等级在0-9内,数值越大压缩率越高,CPU消耗也就越大
gzip_buffers 4 16k;
gzip_http_version 1.1; # 版本号
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
#静态文件的缓存性能调优
open_file_cache max=65535 inactive=20s;
#这个将为打开文件指定缓存,max 指定缓存数量.建议和打开文件数一致.inactive 是指经过多长时间文件没被请求后删除缓存
open_file_cache_valid 30s;
#这个是指多长时间检查一次缓存的有效信息,例如我一直访问这个文件,30秒后检查是否更新,反之更新
open_file_cache_min_uses 2;
#定义了open_file_cache中指令参数不活动时间期间里最小的文件数
open_file_cache_errors on;
#NGINX可以缓存在文件访问期间发生的错误,这需要设置该值才能有效,如果启用错误缓存.则在访问资源(不查找资源)时.NGINX会报告相同的错误
#响应头
add_header X-Cache $upstream_cache_status;
#缓存命中
add_header X-Frame-Options SAMEORIGIN;
#是为了减少点击劫持(Clickjacking)而引入的一个响应头
add_header X-Content-Type-Options nosniff;
# qps
req_status_zone domainport "$host:$server_port" 10M;
req_status_zone domainporturi "$host:$server_port:$uri" 10M;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
include vhosts/*.conf;
}
[root@master rpmbuild]# cat SPECS/tengine-2.1.2.spec
Name: tengine
Version: 2.1.2
Release: 3%{?dist}
Summary: 010sec team
License: GPL
URL: http://010sec.com
AutoReq: 0
AutoProv: 0
%define nginx_user admin
%define nginx_group admin
Source0: tengine-2.1.2.tar.gz
Source1: zlib-1.2.11.tar.gz
Source2: openssl-1.0.2l.tar.gz
Source3: jemalloc-5.1.0.tar.bz2
Source4: pcre-8.41.tar.gz
Source5: nginx.conf
%description
010sec team
%prep
%setup -q -b 1 -b 2 -b 3 -b 4
%build
cd ../zlib-1.2.11
./configure --prefix=/opt/zlib
make %{?_smp_mflags}
make install DESTDIR=%{buildroot}
cd ../openssl-1.0.2l
./config --prefix=/opt/openssl
make %{?_smp_mflags}
make install DESTDIR=%{buildroot}
cd ../jemalloc-5.1.0
./configure --prefix=/opt/jemalloc --libdir=/usr/local/lib
make %{?_smp_mflags}
make install DESTDIR=%{buildroot}
echo /usr/local/lib >> /etc/ld.so.conf
cd ../pcre-8.41
./configure --prefix=/opt/pcre
make %{?_smp_mflags}
make install DESTDIR=%{buildroot}
cd ../tengine-2.1.2
./configure --prefix=/opt/tengine --user=%{nginx_user} --group=%{nginx_group} --without-http_memcached_module --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-openssl=/root/rpmbuild/BUILD/openssl-1.0.2l --with-zlib=/root/rpmbuild/BUILD/zlib-1.2.11 --with-pcre=/root/rpmbuild/BUILD/pcre-8.41 --with-jemalloc=/root/rpmbuild/BUILD/jemalloc-5.1.0
make %{?_smp_mflags}
make install DESTDIR=%{buildroot}
install -p -D -m 0644 %{SOURCE5} %{buildroot}/opt/tengine/conf/nginx.conf
%post
cat >/etc/profile.d/nginx.sh<<EOF
PATH=$PATH:/opt/tengine/sbin
EOF
source /etc/profile
/bin/sed -i 's/010sec/'%{nginx_user}'/g' /opt/tengine/conf/nginx.conf
%preun
if [ "$1" = 0 ] ; then
if [ -z "`ps aux | grep nginx | grep -v grep`" ];then
/opt/tengine/sbin/nginx -s stop > /dev/null 2>&1
exit 0
fi
fi
%postun
if [ "$1" = 0 ] ; then
/bin/rm -rf /opt/tengine
/bin/rm -rf /etc/profile.d/nginx.sh
source /etc/profile
fi
%files
/opt/tengine
%doc
%changelog
# 这里出现问题,因为由于某些文件安装未包含,导致报错,所以我们需要屏蔽一行打包编译内容
[root@master rpmbuild]# sed -i 's/%__check_files/#%__check_files/' /usr/lib/rpm/macros
# 编译
[root@master rpmbuild]# rpmbuild -bb SPEC/tengine-2.1.2.spec
# 查看版本
[root@master rpmbuild]# ll /root/rpmbuild/RPMS/x86_64/
-rw-r--r-- 1 root root 1739644 Jan 09 13:02 nginx-1.14.0-3.el7.centos.x86_64.rpm
-rw-r--r-- 1 root root 273236 Jan 09 15:23 nginx-1.14.0-el7.x86_64.rpm
-rw-r--r-- 1 root root 3448816 Jan 09 06:18 tengine-2.1.2-3.el7.centos.x86_64.rpm
# 安装证书编译工具
[root@master ~]# yum install rpm-sign
[root@master ~]# yum install rng-tools -y
# 随机证书熵池,加快运行速度
[root@master ~]# cat /etc/sysconfig/rngd
EXTRAOPTIONS="-r /dev/urandom"
[root@master ~]# systemctl start rngd
# 速度会比较慢,需要等待
[root@master ~]# gpg --gen-key
Please select what kind of key you want: 默认
What keysize do you want? (2048) 默认
Key is valid for? (0) 默认
is this correct? (y/N) y
Real name: c4rt1y
Email address: c4rt1y@010sec.com
Comment: GPG-RPM-KEY
hange (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
这步之后会要求输入密码,可以为空
# 将gpg证书运行到rpm里面
[root@master ~]# %_signature gpg' >> ~/.rpmmacros
[root@master ~]# echo '%_gpg_name c4rt1y' >> ~/.rpmmacros
# 查看熵池
[root@master ~]# cat /proc/sys/kernel/random/entropy_avail
# 对rpm软件包签名:
[root@master ~]# rpm --addsign nginx-1.14.0-3.el7.centos.x86_64.rpm
Enter pass phrase: gpg密码,这里没有设置
Pass phrase is good.
nginx-1.14.0-3.el7.centos.x86_64.rpm
# 在rpmbuild打包时签名:
[root@master ~]# rpmbuild --sign --bb ~/rpmbuild/SPECS/nginx-1.14.0.spec
[root@master ~]# rpm -K rpmbuild/RPMS/x86_64/rpm -K nginx-1.14.0-3.el7.centos.x86_64.rpm
rpmbuild/RPMS/x86_64/nginx-1.14.0-3.el7.centos.x86_64.rpm: rsa sha1 (md5) pgp md5 OK
https://blog.csdn.net/trochiluses/article/details/11179901 centos下rpm包的制作
https://blog.51cto.com/13689359/2165975
https://blog.csdn.net/zhangxuechao_/article/details/82823359
https://www.jb51.net/article/51992.htm
https://www.cnblogs.com/weijing24/p/5691283.html
https://www.cnblogs.com/zafu/p/7423758.html
http://nginx.org/download/
https://www.52os.net/articles/howto-create-and-sign-rpm-package.html