返回
Featured image of post Deb 详解

Deb 详解

解析并打包 Deb 软件包

什么是 Deb

DEB 是 Debian 软件包格式的文件扩展名,跟 Debian 的命名一样,DEB 也是因 Debra Murdock 而得名。

目录结构

deb 包里面的目录结构

xxx.deb
├── control.tar.gz  # 包含deb的安装说明,标识,脚本等
├── data.tar.gz     # 程序数据
└── debian-binary   # deb包的打包版本,一般为2.0

使用 dpkg 打包所需要的目录结构

.
├── DEBIAN  # 包信息
│   ├── control     # 记录软件标识,版本号,平台,依赖信息等数据
│   ├── copyright   # 许可条款
│   ├── changelog   # 更新日志
│   ├── conffiles   # 当软件包升级的时候,你将会被询问是否要保留你的旧配置文件
│   ├── config      # 启动配置
│   ├── md5sums     # md5校验
│   ├── preinst     # 安装时,程序文件被解压前执行的脚本
│   ├── postinst    # 安装时,程序文件被解压后执行的脚本
│   ├── prerm       # 卸载时,程序文件被删除前执行的脚本
│   ├── postrm      # 卸载时,程序文件被删除后执行的脚本
│   └── templates   # 模板
└── ...     # 存放程序所需文件,包括二进制文件、配置等等

其中 DEBIAN/control 是必须的

实战: 为树莓派创建 Clash 安装包

首先,按照上述格式创建文件

DEBIAN/control: 参考文档

Package: clash # 包名(必要字段)
Version: 1.6.5 # 版本(必要字段)
Section: net # 分类
Priority: optional # 重要性
Architecture: arm64 # 架构(必要字段),使用 dpkg-architecture -L 指令查看(可使用any通配符),或填写`all`、`source`
Depends: iptables # 依赖
Maintainer: negoces <negoces@163.com> # 维护者信息(必要字段)
Description: A rule-based tunnel in Go.
Homepage: https://github.com/Dreamacro/clash

DEBIAN/preinst:

#!/bin/sh
set -e

case "$1" in
  install)
    rm -rf /opt/clash
    ;;

  upgrade)
    if [ -e /opt/clash/clash ]; then
      rm -f /opt/clash/clash
    fi
    ;;

  abort-upgrade)
    ;;

  *)
    echo "preinst called with unknown argument \`$1'" >&2
    exit 1
    ;;
esac

exit 0

DEBIAN/postinst:

#!/bin/sh
set -e

case "$1" in
  configure)
    user=clash

    if ! dpkg-statoverride --list "/opt/clash" >/dev/null; then
      echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/clash.conf
      sysctl -p /etc/sysctl.d/clash.conf
      egrep "^$user" /etc/passwd > /dev/null
      if [ $? -ne 0 ]; then
          useradd -M -r -s /bin/bash -U clash
      fi
      chown -R clash:clash /opt/clash
      chmod -R 0755 /opt/clash
    fi
    ;;

  abort-upgrade|abort-remove|abort-deconfigure)
    ;;

  *)
    echo "postinst called with unknown argument \`$1'" >&2
    exit 1
    ;;
esac

exit 0

DEBIAN/prerm:

#!/bin/sh
set -e
if [ -d /run/systemd/system ] && [ "$1" = remove ]; then
	deb-systemd-invoke stop 'clash.service' >/dev/null || true
fi

DEBIAN/postrm:

#!/bin/sh
set -e

case "$1" in
  purge)
    rm -rf /opt/clash
    ;;

  upgrade|remove|failed-upgrade|abort-install|abort-upgrade|disappear)
    ;;

  *)
    echo "postrm called with unknown argument \`$1'" >&2
    exit 1
    ;;
esac

if [ -d /run/systemd/system ] && [ "$1" = remove ]; then
	systemctl --system daemon-reload >/dev/null || true
fi

if [ "$1" = "remove" ]; then
	if [ -x "/usr/bin/deb-systemd-helper" ]; then
		deb-systemd-helper mask 'clash.service' >/dev/null || true
	fi
fi

if [ "$1" = "purge" ]; then
	if [ -x "/usr/bin/deb-systemd-helper" ]; then
		deb-systemd-helper purge 'clash.service' >/dev/null || true
		deb-systemd-helper unmask 'clash.service' >/dev/null || true
	fi
fi

exit 0

创建默认配置文件以及其他目录

mkdir opt
mkdir opt/clash
mkdir opt/clash/subconf
echo "mixed-port: 7890" > opt/clash/config.yaml

透明代理防火墙设置脚本 tproxy.sh:

#!/bin/sh
export tproxy_port=1082
sudo ip rule add fwmark 1 table 100
sudo ip route add local default dev lo table 100
sudo iptables -t mangle -N clash
sudo iptables -t mangle -A clash -d 0.0.0.0/8 -j RETURN
sudo iptables -t mangle -A clash -d 10.0.0.0/8 -j RETURN
sudo iptables -t mangle -A clash -d 127.0.0.0/8 -j RETURN
sudo iptables -t mangle -A clash -d 169.254.0.0/16 -j RETURN
sudo iptables -t mangle -A clash -d 172.16.0.0/12 -j RETURN
sudo iptables -t mangle -A clash -d 192.168.0.0/16 -j RETURN
sudo iptables -t mangle -A clash -d 224.0.0.0/4 -j RETURN
sudo iptables -t mangle -A clash -d 240.0.0.0/4 -j RETURN
sudo iptables -t mangle -A clash -p tcp -j TPROXY --on-port $tproxy_port --tproxy-mark 1
sudo iptables -t mangle -A PREROUTING -p tcp -j clash
sudo iptables -t mangle -A PREROUTING -p udp -j clash

etc/systemd/system/clash.service

[Unit]
Description=clash
Documentation=https://lancellc.gitbook.io/clash
After=network.target network-online.target nss-lookup.target

[Service]
Type=simple
StandardError=journal
Group=clash
User=clash
AmbientCapabilities=CAP_NET_RAW
AmbientCapabilities=CAP_NET_BIND_SERVICE
ExecStart=/opt/clash/clash -d /opt/clash
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=3s

[Install]
WantedBy=multi-user.target

etc/systemd/system/clash-tproxy.service

[Unit]
Description=clash-tproxy
Documentation=https://lancellc.gitbook.io/clash
After=network.target network-online.target nss-lookup.target

[Service]
Type=oneshot
StandardError=journal
Group=root
User=root
ExecStart=/opt/clash/tproxy.sh
RemainAfterExit=yes
Restart=on-failure
RestartSec=3s

[Install]
WantedBy=multi-user.target

最后将 clash 二进制文件下载下来放进去

最终目录结构

.
├── DEBIAN
│   ├── control
│   ├── postinst
│   ├── postrm
│   ├── preinst
│   └── prerm
├── etc
│   └── systemd
│       └── system
│           ├── clash.service
│           └── clash-tproxy.service
└── opt
    └── clash
        ├── clash
        ├── config.yaml
        ├── subconf
        └── tproxy.sh

生成 deb 包:

chmod -R 0775 DEBIAN
dpkg -b . ../clash-1.6.5-armv8.deb

安装测试

sudo dpkg -i clash-1.6.5-armv8.deb
sudo systemctl enable --now clash # Clash 开机自启
sudo systemctl restart clash
sudo systemctl enable --now clash-tproxy # 开机自动设置 Tproxy 防火墙 (请勿重复使用)

因本人能力有限,使用上述步骤导致的数据丢失本人概不负责
通过上述步骤生成的deb: clash-1.6.5-armv8.deb

参考文档

Built with Hugo
Theme Stack designed by Jimmy