# 面（Linux）：安装。假 Debian 12 amd64（v3），systemctl / groupadd 等是只记账的桩；不下内核。包按 build --platform linux 的布局
### install.sh 退出码
0
### install.sh 输出
# mode 644
***********************************************
**        欢迎使用 科技熊 Linux 版
**   基于 ShellCrash（GPL-3.0，作者 Juewuy）
***********************************************
安装包版本：\e[32m1.0.0\e[0m
系统：\e[32mDebian GNU/Linux 12 (bookworm)\e[0m  内核架构：\e[32mamd64-v3\e[0m
-----------------------------------------------
正在安装到 @ROOT/opt/kejibear ……
\e[32m文件安装完成。\e[0m
-----------------------------------------------
\e[32m科技熊 Linux 版 1.0.0 安装成功！\e[0m
-----------------------------------------------
下一步：输入 \e[30;47m kjx \e[0m（root 身份）打开菜单，用科技熊账号登录。
登录后服务会自动启动；本机代理端口只在 127.0.0.1 上开放，菜单里有设置说明。
命令行用法：kjx help
-----------------------------------------------
### 安装目录文件树（类型 权限 路径）
d 700 .
f 644 KJX_UPSTREAM
f 644 LICENSE.txt
f 644 NOTICE.kejibear
d 755 bin
f 644 brand.id
d 755 configs
f 644 configs/ShellCrash.cfg
f 644 configs/command.env
d 755 configs/task
f 644 fake_ip_filter.list
f 755 init.sh
f 755 install.sh
d 700 kjx
f 600 kjx/state
d 755 lang
d 755 lang/chs
f 644 lang/chs/1_start.lang
f 644 lang/chs/2_settings.lang
f 644 lang/chs/5_task.lang
f 644 lang/chs/7_gateway.lang
f 644 lang/chs/8_tools.lang
f 644 lang/chs/9_upgrade.lang
f 644 lang/chs/check_port.lang
f 644 lang/chs/common.lang
f 644 lang/chs/ddns.lang
f 644 lang/chs/dns.lang
f 644 lang/chs/fw_filter.lang
f 644 lang/chs/menu.lang
f 644 lang/chs/override.lang
f 644 lang/chs/set_crashdir.lang
f 644 lang/chs/setboot.lang
f 644 lang/chs/task_cmd.lang
f 644 lang/chs/uninstall.lang
f 644 lang/chs/userguide.lang
d 755 lang/en
f 644 lang/en/1_start.lang
f 644 lang/en/2_settings.lang
f 644 lang/en/5_task.lang
f 644 lang/en/7_gateway.lang
f 644 lang/en/8_tools.lang
f 644 lang/en/9_upgrade.lang
f 644 lang/en/check_port.lang
f 644 lang/en/common.lang
f 644 lang/en/ddns.lang
f 644 lang/en/dns.lang
f 644 lang/en/fw_filter.lang
f 644 lang/en/menu.lang
f 644 lang/en/override.lang
f 644 lang/en/set_crashdir.lang
f 644 lang/en/setboot.lang
f 644 lang/en/task_cmd.lang
f 644 lang/en/uninstall.lang
f 644 lang/en/userguide.lang
d 755 libs
f 644 libs/README.md
f 755 libs/check_autostart.sh
f 755 libs/check_cmd.sh
f 755 libs/check_cpucore.sh
f 755 libs/check_dir_avail.sh
f 755 libs/check_target.sh
f 755 libs/compare.sh
f 755 libs/core_tools.sh
f 755 libs/gen_base64.sh
f 755 libs/get_config.sh
f 755 libs/get_ecsip.sh
f 755 libs/i18n.sh
f 755 libs/kjx.sh
f 755 libs/kjx_age.sh
f 755 libs/kjx_assert.sh
f 755 libs/kjx_auth.sh
f 755 libs/kjx_brand.sh
f 755 libs/kjx_common.sh
f 755 libs/kjx_config.sh
f 755 libs/kjx_core.sh
f 755 libs/kjx_cron.sh
f 755 libs/kjx_dash.sh
f 755 libs/kjx_dns.sh
f 755 libs/kjx_entry.sh
f 644 libs/kjx_split.awk
f 755 libs/kjx_update.sh
f 755 libs/logger.sh
f 755 libs/meta_listeners.sh
f 755 libs/sb_endpoints.sh
f 755 libs/sb_inbounds.sh
f 755 libs/set_config.sh
f 755 libs/set_cron.sh
f 755 libs/set_profile.sh
f 755 libs/set_proxy.sh
f 755 libs/start_wait.sh
f 755 libs/urlencode.sh
f 755 libs/web_get.sh
f 755 libs/web_get_bin.sh
f 755 libs/web_get_curlbar.sh
f 755 libs/web_get_lite.sh
f 755 libs/web_json.sh
f 755 libs/web_restore.sh
f 755 libs/web_save.sh
d 755 linux
f 755 linux/kjx_cmd.sh
f 755 linux/kjx_linux.sh
f 755 linux/kjx_lx_fw.sh
d 755 linux/systemd
f 644 linux/systemd/boot.service.in
f 644 linux/systemd/service.in
f 644 linux/systemd/timer.in
f 644 linux/systemd/timer.service.in
f 644 linux/systemd/tmpfiles.conf.in
f 755 menu.sh
d 755 menus
f 755 menus/1_start.sh
f 755 menus/2_settings.sh
f 755 menus/4_setboot.sh
f 755 menus/5_task.sh
f 755 menus/7_gateway.sh
f 755 menus/8_tools.sh
f 755 menus/9_upgrade.sh
f 644 menus/README.md
f 755 menus/check_port.sh
f 755 menus/common.sh
f 755 menus/ddns.sh
f 755 menus/dns.sh
f 755 menus/fw_filter.sh
f 755 menus/kjx_menu.sh
f 755 menus/override.sh
f 755 menus/running_status.sh
f 755 menus/set_crashdir.sh
f 755 menus/task_cmd.sh
f 755 menus/tui_layout.sh
f 755 menus/tui_lite.sh
f 755 menus/uninstall.sh
f 755 menus/userguide.sh
d 755 providers
d 755 ruleset
f 755 start.sh
d 755 starts
f 644 starts/README.md
f 755 starts/afstart.sh
f 755 starts/bfstart.sh
f 755 starts/check_cnip.sh
f 755 starts/check_core.sh
f 755 starts/check_geo.sh
f 755 starts/check_network.sh
f 755 starts/clash_check.sh
f 755 starts/clash_config_check.sh
f 755 starts/clash_modify.sh
f 755 starts/core_config.sh
f 755 starts/core_exchange.sh
f 755 starts/fw_getlanip.sh
f 755 starts/fw_iptables.sh
f 755 starts/fw_nftables.sh
f 755 starts/fw_start.sh
f 755 starts/fw_stop.sh
f 755 starts/general_init.sh
f 755 starts/kjx_core_exec.sh
f 644 starts/shellcrash.openrc
f 644 starts/shellcrash.procd
f 644 starts/shellcrash.service
f 755 starts/snapshot_init.sh
f 755 starts/start_error.sh
f 755 starts/start_legacy.sh
f 755 starts/start_legacy_wd.sh
d 755 task
f 644 task_chs.list
f 644 task_en.list
f 644 version
d 755 yamls
### configs/ShellCrash.cfg
# mode 644
#ShellCrash配置文件，不明勿动！
userguide=1
crashcore=meta
firewall_area=4
redir_mod=Redir
dns_mod=fake-ip
zip_type=tar.gz
cpucore=amd64-v3
start_old=OFF
versionsh_l=1.0.0
systype=linux
firewall_mod=iptables
### configs/command.env
# mode 644
TMPDIR=/run/kejibear/ShellCrash
BINDIR=@ROOT/opt/kejibear
COMMAND="@ROOT/opt/kejibear/starts/kjx_core_exec.sh -d $BINDIR -f $TMPDIR/config.yaml"
### brand.id
# mode 644
kejibear
### /etc/systemd/system/kejibear.service
# mode 644
# 科技熊 Linux 版 服务（A1 本机代理端口）。由 @ROOT/opt/kejibear/linux/kjx_linux.sh 按品牌档案生成，升级、切换用法时会重写，不要手改。
# 运行身份 root + 系统组 kejibear（只建组，不建第二个 uid 0 账号；A2 按这个组放过内核自己的流量）；托管私钥由
# kjx_core_exec.sh 在 exec 内核前只注入给内核进程（不用 EnvironmentFile / LoadCredential）。运行目录在内存盘
# /run/kejibear/ShellCrash，内核在安装目录 bin/ 下。
# ExecCondition：同机装着别的品牌、当前启用的不是本品牌时跳过（不算失败，不触发 Restart=）。
# ExecStopPost：停止、崩溃、被 kill 都会清掉本品牌的防火墙规则和策略路由（A2）。
[Unit]
Description=科技熊 Linux 版
After=network-online.target
Wants=network-online.target
Conflicts=
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
Type=simple
User=root
Group=kejibear
Environment=CRASHDIR=@ROOT/opt/kejibear
Environment=USER=root
RuntimeDirectory=kejibear/ShellCrash
RuntimeDirectoryMode=0700
RuntimeDirectoryPreserve=yes
ExecCondition=@SH @ROOT/opt/kejibear/linux/kjx_linux.sh gate svc
# A1 不写防火墙，不用预先加载内核模块
ExecStartPre=@SH @ROOT/opt/kejibear/starts/bfstart.sh
ExecStart=@ROOT/opt/kejibear/starts/kjx_core_exec.sh -d @ROOT/opt/kejibear -f /run/kejibear/ShellCrash/config.yaml
ExecStartPost=@SH @ROOT/opt/kejibear/starts/afstart.sh
ExecStopPost=@SH @ROOT/opt/kejibear/starts/fw_stop.sh
StandardOutput=null
LimitNOFILE=1048576
Restart=on-failure
RestartSec=10s
TimeoutStartSec=180
# 加固（按用法给最小权限，见 kjx_linux.sh 的 kjx_lx_harden）
CapabilityBoundingSet=CAP_CHOWN CAP_FOWNER
NoNewPrivileges=yes
ProtectSystem=strict
# /run/xtables.lock：iptables-legacy 写规则前要锁它（tmpfiles 开机建好；iptables-nft 不用）
ReadWritePaths=-@ROOT/opt/kejibear -/run/kejibear -/run/xtables.lock
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes
DevicePolicy=auto
DeviceAllow=
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectControlGroups=yes
ProtectClock=yes
ProtectHostname=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
LockPersonality=yes
SystemCallArchitectures=native
UMask=0077

[Install]
WantedBy=multi-user.target
### /etc/systemd/system/kjx-boot.service
# mode 644
# 科技熊 Linux 版 开机任务（补定时器、补密钥、托管配置缺了就后台补拉）。由 kjx_linux.sh 生成，不要手改。
# RemainAfterExit：补拉配置在后台退避重试，不能随这个一次性任务结束被一起清掉
[Unit]
Description=科技熊 Linux 版 开机任务
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
Environment=CRASHDIR=@ROOT/opt/kejibear
Environment=USER=root
# 同机装着别的品牌、当前启用的不是本品牌时跳过
ExecCondition=@SH @ROOT/opt/kejibear/linux/kjx_linux.sh gate
ExecStart=@SH @ROOT/opt/kejibear/libs/kjx.sh boot
StandardOutput=null
NoNewPrivileges=yes
ProtectHome=yes
PrivateTmp=yes

[Install]
WantedBy=multi-user.target
### /etc/systemd/system/kjx-daily.service
# mode 644
# 科技熊 Linux 版 定时任务 daily：每天拉一次托管配置。由 kjx_linux.sh 生成，不要手改。
[Unit]
Description=科技熊 Linux 版 每天拉一次托管配置
After=network-online.target

[Service]
Type=oneshot
Environment=CRASHDIR=@ROOT/opt/kejibear
Environment=USER=root
# 同机装着别的品牌、当前启用的不是本品牌时跳过
ExecCondition=@SH @ROOT/opt/kejibear/linux/kjx_linux.sh gate
ExecStart=@SH @ROOT/opt/kejibear/libs/kjx.sh pull
# oneshot 默认不限启动时长：卡住的一次（网络半通时拉配置）会让定时器之后一直不再触发
TimeoutStartSec=15min
StandardOutput=null
NoNewPrivileges=yes
ProtectHome=yes
PrivateTmp=yes
### /etc/systemd/system/kjx-daily.timer
# mode 644
# 科技熊 Linux 版 定时器 daily：每天拉一次托管配置。时间按账号错峰（同梅林版），登录后会自动改写。由 kjx_linux.sh 生成，不要手改。
[Unit]
Description=科技熊 Linux 版 每天拉一次托管配置

[Timer]
OnCalendar=*-*-* 12:17:00
Persistent=true
Unit=kjx-daily.service

[Install]
WantedBy=timers.target
### /etc/systemd/system/kjx-hourly.service
# mode 644
# 科技熊 Linux 版 定时任务 hourly：每小时续期登录、刷新会员信息。由 kjx_linux.sh 生成，不要手改。
[Unit]
Description=科技熊 Linux 版 每小时续期登录、刷新会员信息
After=network-online.target

[Service]
Type=oneshot
Environment=CRASHDIR=@ROOT/opt/kejibear
Environment=USER=root
# 同机装着别的品牌、当前启用的不是本品牌时跳过
ExecCondition=@SH @ROOT/opt/kejibear/linux/kjx_linux.sh gate
ExecStart=@SH @ROOT/opt/kejibear/libs/kjx.sh cron
# oneshot 默认不限启动时长：卡住的一次（网络半通时拉配置）会让定时器之后一直不再触发
TimeoutStartSec=15min
StandardOutput=null
NoNewPrivileges=yes
ProtectHome=yes
PrivateTmp=yes
### /etc/systemd/system/kjx-hourly.timer
# mode 644
# 科技熊 Linux 版 定时器 hourly：每小时续期登录、刷新会员信息。时间按账号错峰（同梅林版），登录后会自动改写。由 kjx_linux.sh 生成，不要手改。
[Unit]
Description=科技熊 Linux 版 每小时续期登录、刷新会员信息

[Timer]
OnCalendar=*-*-* *:17:00
Persistent=true
Unit=kjx-hourly.service

[Install]
WantedBy=timers.target
### /etc/systemd/system/kjx-updchk.service
# mode 644
# 科技熊 Linux 版 定时任务 updchk：每天检查一次更新（只查不装）。由 kjx_linux.sh 生成，不要手改。
[Unit]
Description=科技熊 Linux 版 每天检查一次更新（只查不装）
After=network-online.target

[Service]
Type=oneshot
Environment=CRASHDIR=@ROOT/opt/kejibear
Environment=USER=root
# 同机装着别的品牌、当前启用的不是本品牌时跳过
ExecCondition=@SH @ROOT/opt/kejibear/linux/kjx_linux.sh gate
ExecStart=@SH @ROOT/opt/kejibear/libs/kjx.sh update_check
# oneshot 默认不限启动时长：卡住的一次（网络半通时拉配置）会让定时器之后一直不再触发
TimeoutStartSec=15min
StandardOutput=null
NoNewPrivileges=yes
ProtectHome=yes
PrivateTmp=yes
### /etc/systemd/system/kjx-updchk.timer
# mode 644
# 科技熊 Linux 版 定时器 updchk：每天检查一次更新（只查不装）。时间按账号错峰（同梅林版），登录后会自动改写。由 kjx_linux.sh 生成，不要手改。
[Unit]
Description=科技熊 Linux 版 每天检查一次更新（只查不装）

[Timer]
OnCalendar=*-*-* 00:17:00
Persistent=true
Unit=kjx-updchk.service

[Install]
WantedBy=timers.target
### /etc/tmpfiles.d/kejibear.conf
# mode 644
# 科技熊 Linux 版：运行时明文只放内存盘，开机建好根目录（只有 root 能进）。由 kjx_linux.sh 生成，卸载时删除。
d /run/kejibear 0700 root root -
# iptables-legacy 的锁文件（系统公用；没有才建、不改已有的）：服务单元 ProtectSystem=strict 下 /run 只读，要事先建好
f /run/xtables.lock 0600 root root -
### /usr/local/bin/kjx
# mode 755
#!/bin/sh
# 科技熊 Linux 版 命令入口（安装程序生成，卸载时删除）
CRASHDIR='@ROOT/opt/kejibear'
export CRASHDIR
[ -x /bin/bash ] && exec /bin/bash "$CRASHDIR/linux/kjx_cmd.sh" "$@"
exec /bin/sh "$CRASHDIR/linux/kjx_cmd.sh" "$@"
### /etc/group
# mode 644
root:x:0:
sudo:x:27:
kejibear:x:7890:
### /etc/passwd
# mode 644
root:x:0:0:root:/root:/bin/bash
### groupadd 调用
# mode 644
groupadd -r -g 7890 kejibear
### systemctl 调用
# mode 644
systemctl is-active -q kejibear.service
systemctl daemon-reload
systemd-tmpfiles --create @ROOT/etc/tmpfiles.d/kejibear.conf
systemctl enable kjx-boot.service
systemctl daemon-reload
systemctl is-active -q kjx-daily.timer
systemctl is-enabled -q kjx-daily.timer
systemctl enable --now kjx-daily.timer
systemctl is-active -q kjx-hourly.timer
systemctl is-enabled -q kjx-hourly.timer
systemctl enable --now kjx-hourly.timer
systemctl is-active -q kjx-updchk.timer
systemctl is-enabled -q kjx-updchk.timer
systemctl enable --now kjx-updchk.timer
### @ROOT/etc 下的文件
etc
etc/group
etc/hosts
etc/os-release
etc/passwd
etc/resolv.conf
etc/systemd
etc/systemd/system
etc/systemd/system/kejibear.service
etc/systemd/system/kjx-boot.service
etc/systemd/system/kjx-daily.service
etc/systemd/system/kjx-daily.timer
etc/systemd/system/kjx-hourly.service
etc/systemd/system/kjx-hourly.timer
etc/systemd/system/kjx-updchk.service
etc/systemd/system/kjx-updchk.timer
etc/tmpfiles.d
etc/tmpfiles.d/kejibear.conf
